diff options
author | Dan Gohman <gohman@apple.com> | 2008-09-10 20:11:02 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-09-10 20:11:02 +0000 |
commit | 0586d91bb3e516d5826826522d9a90ed6ef74d86 (patch) | |
tree | dca0b97efebf2a6ef9da0bb9d177b7050583027a /lib/Target | |
parent | 014264b70f2af002a41f8e36a9430fcf20e77bc7 (diff) | |
download | llvm-0586d91bb3e516d5826826522d9a90ed6ef74d86.tar.gz llvm-0586d91bb3e516d5826826522d9a90ed6ef74d86.tar.bz2 llvm-0586d91bb3e516d5826826522d9a90ed6ef74d86.tar.xz |
Add X86FastISel support for static allocas, and refences
to static allocas. As part of this change, refactor the
address mode code for laods and stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56066 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/X86FastISel.cpp | 133 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 6 |
3 files changed, 82 insertions, 63 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 3f5d6f99f6..343732e680 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -31,10 +31,6 @@ using namespace llvm; class X86FastISel : public FastISel { - /// MFI - Keep track of objects allocated on the stack. - /// - MachineFrameInfo *MFI; - /// Subtarget - Keep a pointer to the X86Subtarget around so that we can /// make the right decision when generating code for different targets. const X86Subtarget *Subtarget; @@ -53,8 +49,9 @@ class X86FastISel : public FastISel { public: explicit X86FastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &vm, - DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) - : FastISel(mf, vm, bm), MFI(MF.getFrameInfo()) { + DenseMap<const BasicBlock *, MachineBasicBlock *> &bm, + DenseMap<const AllocaInst *, int> &am) + : FastISel(mf, vm, bm, am) { Subtarget = &TM.getSubtarget<X86Subtarget>(); StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP; X86ScalarSSEf64 = Subtarget->hasSSE2(); @@ -66,10 +63,10 @@ public: #include "X86GenFastISel.inc" private: - bool X86FastEmitLoad(MVT VT, unsigned Op0, Value *V, unsigned &RR); + bool X86FastEmitLoad(MVT VT, const X86AddressMode &AM, unsigned &RR); bool X86FastEmitStore(MVT VT, unsigned Val, - unsigned Ptr, unsigned Offset, Value *V); + const X86AddressMode &AM); bool X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, unsigned Src, MVT SrcVT, unsigned &ResultReg); @@ -77,6 +74,8 @@ private: bool X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall = false, bool inReg = false); + bool X86SelectAddress(Value *V, X86AddressMode &AM); + bool X86SelectLoad(Instruction *I); bool X86SelectStore(Instruction *I); @@ -97,7 +96,9 @@ private: CCAssignFn *CCAssignFnForCall(unsigned CC, bool isTailCall = false); - unsigned TargetMaterializeConstant(Constant *C, MachineConstantPool* MCP); + unsigned TargetMaterializeConstant(Constant *C); + + unsigned TargetMaterializeAlloca(AllocaInst *C); /// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is /// computed in an SSE register, not on the X87 floating point stack. @@ -151,7 +152,7 @@ CCAssignFn *X86FastISel::CCAssignFnForCall(unsigned CC, bool isTaillCall) { /// X86FastEmitLoad - Emit a machine instruction to load a value of type VT. /// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV. /// Return true and the result register by reference if it is possible. -bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV, +bool X86FastISel::X86FastEmitLoad(MVT VT, const X86AddressMode &AM, unsigned &ResultReg) { // Get opcode and regclass of the output for the given load instruction. unsigned Opc = 0; @@ -200,12 +201,6 @@ bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV, } ResultReg = createResultReg(RC); - X86AddressMode AM; - if (Ptr) - // Address is in register. - AM.Base.Reg = Ptr; - else - AM.GV = cast<GlobalValue>(GV); addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM); return true; } @@ -216,7 +211,7 @@ bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV, /// i.e. V. Return true if it is possible. bool X86FastISel::X86FastEmitStore(MVT VT, unsigned Val, - unsigned Ptr, unsigned Offset, Value *V) { + const X86AddressMode &AM) { // Get opcode and regclass of the output for the given store instruction. unsigned Opc = 0; const TargetRegisterClass *RC = NULL; @@ -263,13 +258,6 @@ X86FastISel::X86FastEmitStore(MVT VT, unsigned Val, break; } - X86AddressMode AM; - if (Ptr) { - // Address is in register. - AM.Base.Reg = Ptr; - AM.Disp = Offset; - } else - AM.GV = cast<GlobalValue>(V); addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Val); return true; } @@ -331,6 +319,39 @@ bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0, return true; } +/// X86SelectAddress - Attempt to fill in an address from the given value. +/// +bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM) { + // Look past bitcasts. + if (const BitCastInst *BC = dyn_cast<BitCastInst>(V)) + return X86SelectAddress(BC->getOperand(0), AM); + + if (const AllocaInst *A = dyn_cast<AllocaInst>(V)) { + DenseMap<const AllocaInst*, int>::iterator SI = StaticAllocaMap.find(A); + if (SI == StaticAllocaMap.end()) + return false; + AM.BaseType = X86AddressMode::FrameIndexBase; + AM.Base.FrameIndex = SI->second; + } else if (unsigned Ptr = lookUpRegForValue(V)) { + AM.Base.Reg = Ptr; + } else { + // Handle constant address. + // FIXME: If load type is something we can't handle, this can result in + // a dead stub load instruction. + if (isa<Constant>(V) && X86SelectConstAddr(V, AM.Base.Reg)) { + if (AM.Base.Reg == 0) + AM.GV = cast<GlobalValue>(V); + } else { + AM.Base.Reg = getRegForValue(V); + if (AM.Base.Reg == 0) + // Unhandled operand. Halt "fast" selection and bail. + return false; + } + } + + return true; +} + /// X86SelectStore - Select and emit code to implement store instructions. bool X86FastISel::X86SelectStore(Instruction* I) { MVT VT; @@ -341,21 +362,11 @@ bool X86FastISel::X86SelectStore(Instruction* I) { // Unhandled operand. Halt "fast" selection and bail. return false; - Value *V = I->getOperand(1); - unsigned Ptr = lookUpRegForValue(V); - if (!Ptr) { - // Handle constant load address. - // FIXME: If load type is something we can't handle, this can result in - // a dead stub load instruction. - if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) { - Ptr = getRegForValue(V); - if (Ptr == 0) - // Unhandled operand. Halt "fast" selection and bail. - return false; - } - } + X86AddressMode AM; + if (!X86SelectAddress(I->getOperand(1), AM)) + return false; - return X86FastEmitStore(VT, Val, Ptr, 0, V); + return X86FastEmitStore(VT, Val, AM); } /// X86SelectLoad - Select and emit code to implement load instructions. @@ -365,22 +376,12 @@ bool X86FastISel::X86SelectLoad(Instruction *I) { if (!isTypeLegal(I->getType(), TLI, VT)) return false; - Value *V = I->getOperand(0); - unsigned Ptr = lookUpRegForValue(V); - if (!Ptr) { - // Handle constant load address. - // FIXME: If load type is something we can't handle, this can result in - // a dead stub load instruction. - if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) { - Ptr = getRegForValue(V); - if (Ptr == 0) - // Unhandled operand. Halt "fast" selection and bail. - return false; - } - } + X86AddressMode AM; + if (!X86SelectAddress(I->getOperand(0), AM)) + return false; unsigned ResultReg = 0; - if (X86FastEmitLoad(VT, Ptr, V, ResultReg)) { + if (X86FastEmitLoad(VT, AM, ResultReg)) { UpdateValueMap(I, ResultReg); return true; } @@ -831,7 +832,10 @@ bool X86FastISel::X86SelectCall(Instruction *I) { RegArgs.push_back(VA.getLocReg()); } else { unsigned LocMemOffset = VA.getLocMemOffset(); - X86FastEmitStore(ArgVT, Arg, StackPtr, LocMemOffset, NULL); + X86AddressMode AM; + AM.Base.Reg = StackPtr; + AM.Disp = LocMemOffset; + X86FastEmitStore(ArgVT, Arg, AM); } } @@ -885,7 +889,7 @@ bool X86FastISel::X86SelectCall(Instruction *I) { MVT ResVT = RVLocs[0].getValVT(); unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64; unsigned MemSize = ResVT.getSizeInBits()/8; - int FI = MFI->CreateStackObject(MemSize, MemSize); + int FI = MFI.CreateStackObject(MemSize, MemSize); addFrameReference(BuildMI(MBB, TII.get(Opc)), FI).addReg(ResultReg); DstRC = ResVT == MVT::f32 ? X86::FR32RegisterClass : X86::FR64RegisterClass; @@ -938,8 +942,7 @@ X86FastISel::TargetSelectInstruction(Instruction *I) { return false; } -unsigned X86FastISel::TargetMaterializeConstant(Constant *C, - MachineConstantPool* MCP) { +unsigned X86FastISel::TargetMaterializeConstant(Constant *C) { // Can't handle PIC-mode yet. if (TM.getRelocationModel() == Reloc::PIC_) return 0; @@ -1010,15 +1013,27 @@ unsigned X86FastISel::TargetMaterializeConstant(Constant *C, Align = Log2_64(Align); } - unsigned MCPOffset = MCP->getConstantPoolIndex(C, Align); + unsigned MCPOffset = MCP.getConstantPoolIndex(C, Align); addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset); return ResultReg; } +unsigned X86FastISel::TargetMaterializeAlloca(AllocaInst *C) { + X86AddressMode AM; + if (!X86SelectAddress(C, AM)) + return 0; + unsigned Opc = Subtarget->is64Bit() ? X86::LEA64r : X86::LEA32r; + TargetRegisterClass* RC = TLI.getRegClassFor(TLI.getPointerTy()); + unsigned ResultReg = createResultReg(RC); + addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM); + return ResultReg; +} + namespace llvm { llvm::FastISel *X86::createFastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &vm, - DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) { - return new X86FastISel(mf, vm, bm); + DenseMap<const BasicBlock *, MachineBasicBlock *> &bm, + DenseMap<const AllocaInst *, int> &am) { + return new X86FastISel(mf, vm, bm, am); } } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 2ddddf6fb1..ab4510a872 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1886,8 +1886,10 @@ FastISel * X86TargetLowering::createFastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &vm, DenseMap<const BasicBlock *, - MachineBasicBlock *> &bm) { - return X86::createFastISel(mf, vm, bm); + MachineBasicBlock *> &bm, + DenseMap<const AllocaInst *, int> &am) { + + return X86::createFastISel(mf, vm, bm, am); } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 6ff053f6fe..e5fc8ed4b7 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -473,7 +473,8 @@ namespace llvm { virtual FastISel * createFastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &, - DenseMap<const BasicBlock *, MachineBasicBlock *> &); + DenseMap<const BasicBlock *, MachineBasicBlock *> &, + DenseMap<const AllocaInst *, int> &); private: /// Subtarget - Keep a pointer to the X86Subtarget around so that we can @@ -604,7 +605,8 @@ namespace llvm { namespace X86 { FastISel *createFastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &, - DenseMap<const BasicBlock *, MachineBasicBlock *> &); + DenseMap<const BasicBlock *, MachineBasicBlock *> &, + DenseMap<const AllocaInst *, int> &); } } |