mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
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
This commit is contained in:
parent
014264b70f
commit
0586d91bb3
@ -20,10 +20,12 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
class AllocaInst;
|
||||||
class ConstantFP;
|
class ConstantFP;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
class MachineConstantPool;
|
class MachineConstantPool;
|
||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
|
class MachineFrameInfo;
|
||||||
class MachineRegisterInfo;
|
class MachineRegisterInfo;
|
||||||
class TargetData;
|
class TargetData;
|
||||||
class TargetInstrInfo;
|
class TargetInstrInfo;
|
||||||
@ -40,8 +42,11 @@ protected:
|
|||||||
DenseMap<const Value *, unsigned> LocalValueMap;
|
DenseMap<const Value *, unsigned> LocalValueMap;
|
||||||
DenseMap<const Value *, unsigned> &ValueMap;
|
DenseMap<const Value *, unsigned> &ValueMap;
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
|
||||||
|
DenseMap<const AllocaInst *, int> &StaticAllocaMap;
|
||||||
MachineFunction &MF;
|
MachineFunction &MF;
|
||||||
MachineRegisterInfo &MRI;
|
MachineRegisterInfo &MRI;
|
||||||
|
MachineFrameInfo &MFI;
|
||||||
|
MachineConstantPool &MCP;
|
||||||
const TargetMachine &TM;
|
const TargetMachine &TM;
|
||||||
const TargetData &TD;
|
const TargetData &TD;
|
||||||
const TargetInstrInfo &TII;
|
const TargetInstrInfo &TII;
|
||||||
@ -90,7 +95,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
FastISel(MachineFunction &mf,
|
FastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &vm,
|
DenseMap<const Value *, unsigned> &vm,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm);
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||||
|
DenseMap<const AllocaInst *, int> &am);
|
||||||
|
|
||||||
/// FastEmit_r - This method is called by target-independent code
|
/// FastEmit_r - This method is called by target-independent code
|
||||||
/// to request that an instruction with the given type and opcode
|
/// to request that an instruction with the given type and opcode
|
||||||
@ -234,8 +240,13 @@ protected:
|
|||||||
|
|
||||||
/// TargetMaterializeConstant - Emit a constant in a register using
|
/// TargetMaterializeConstant - Emit a constant in a register using
|
||||||
/// target-specific logic, such as constant pool loads.
|
/// target-specific logic, such as constant pool loads.
|
||||||
virtual unsigned TargetMaterializeConstant(Constant* C,
|
virtual unsigned TargetMaterializeConstant(Constant* C) {
|
||||||
MachineConstantPool* MCP) {
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TargetMaterializeAlloca - Emit an alloca address in a register using
|
||||||
|
/// target-specific logic.
|
||||||
|
virtual unsigned TargetMaterializeAlloca(AllocaInst* C) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
class AllocaInst;
|
||||||
class Function;
|
class Function;
|
||||||
class FastISel;
|
class FastISel;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
@ -1120,7 +1121,8 @@ public:
|
|||||||
virtual FastISel *
|
virtual FastISel *
|
||||||
createFastISel(MachineFunction &,
|
createFastISel(MachineFunction &,
|
||||||
DenseMap<const Value *, unsigned> &,
|
DenseMap<const Value *, unsigned> &,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &) {
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||||
|
DenseMap<const AllocaInst *, int> &) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ unsigned FastISel::getRegForValue(Value *V) {
|
|||||||
return 0;
|
return 0;
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||||
if (CI->getValue().getActiveBits() > 64)
|
if (CI->getValue().getActiveBits() > 64)
|
||||||
return TargetMaterializeConstant(CI,
|
return TargetMaterializeConstant(CI);
|
||||||
MBB->getParent()->getConstantPool());
|
|
||||||
// Don't cache constant materializations. To do so would require
|
// Don't cache constant materializations. To do so would require
|
||||||
// tracking what uses they dominate.
|
// tracking what uses they dominate.
|
||||||
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
||||||
} else if (isa<GlobalValue>(V)) {
|
} else if (isa<GlobalValue>(V)) {
|
||||||
return TargetMaterializeConstant(dyn_cast<Constant>(V),
|
return TargetMaterializeConstant(cast<Constant>(V));
|
||||||
MBB->getParent()->getConstantPool());
|
} else if (isa<AllocaInst>(V)) {
|
||||||
|
return TargetMaterializeAlloca(cast<AllocaInst>(V));
|
||||||
} else if (isa<ConstantPointerNull>(V)) {
|
} else if (isa<ConstantPointerNull>(V)) {
|
||||||
Reg = FastEmit_i(VT, VT, ISD::Constant, 0);
|
Reg = FastEmit_i(VT, VT, ISD::Constant, 0);
|
||||||
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
||||||
@ -58,19 +58,16 @@ unsigned FastISel::getRegForValue(Value *V) {
|
|||||||
uint32_t IntBitWidth = IntVT.getSizeInBits();
|
uint32_t IntBitWidth = IntVT.getSizeInBits();
|
||||||
if (Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
|
if (Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
|
||||||
APFloat::rmTowardZero) != APFloat::opOK)
|
APFloat::rmTowardZero) != APFloat::opOK)
|
||||||
return TargetMaterializeConstant(CF,
|
return TargetMaterializeConstant(CF);
|
||||||
MBB->getParent()->getConstantPool());
|
|
||||||
APInt IntVal(IntBitWidth, 2, x);
|
APInt IntVal(IntBitWidth, 2, x);
|
||||||
|
|
||||||
unsigned IntegerReg = FastEmit_i(IntVT.getSimpleVT(), IntVT.getSimpleVT(),
|
unsigned IntegerReg = FastEmit_i(IntVT.getSimpleVT(), IntVT.getSimpleVT(),
|
||||||
ISD::Constant, IntVal.getZExtValue());
|
ISD::Constant, IntVal.getZExtValue());
|
||||||
if (IntegerReg == 0)
|
if (IntegerReg == 0)
|
||||||
return TargetMaterializeConstant(CF,
|
return TargetMaterializeConstant(CF);
|
||||||
MBB->getParent()->getConstantPool());
|
|
||||||
Reg = FastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, IntegerReg);
|
Reg = FastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, IntegerReg);
|
||||||
if (Reg == 0)
|
if (Reg == 0)
|
||||||
return TargetMaterializeConstant(CF,
|
return TargetMaterializeConstant(CF);
|
||||||
MBB->getParent()->getConstantPool());;
|
|
||||||
}
|
}
|
||||||
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||||
if (!SelectOperator(CE, CE->getOpcode())) return 0;
|
if (!SelectOperator(CE, CE->getOpcode())) return 0;
|
||||||
@ -83,8 +80,7 @@ unsigned FastISel::getRegForValue(Value *V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Reg && isa<Constant>(V))
|
if (!Reg && isa<Constant>(V))
|
||||||
return TargetMaterializeConstant(cast<Constant>(V),
|
return TargetMaterializeConstant(cast<Constant>(V));
|
||||||
MBB->getParent()->getConstantPool());
|
|
||||||
|
|
||||||
LocalValueMap[V] = Reg;
|
LocalValueMap[V] = Reg;
|
||||||
return Reg;
|
return Reg;
|
||||||
@ -416,6 +412,14 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
|
|||||||
case Instruction::PHI:
|
case Instruction::PHI:
|
||||||
// PHI nodes are already emitted.
|
// PHI nodes are already emitted.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case Instruction::Alloca:
|
||||||
|
// FunctionLowering has the static-sized case covered.
|
||||||
|
if (StaticAllocaMap.count(cast<AllocaInst>(I)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Dynamic-sized alloca is not handled yet.
|
||||||
|
return false;
|
||||||
|
|
||||||
case Instruction::BitCast:
|
case Instruction::BitCast:
|
||||||
return SelectBitCast(I);
|
return SelectBitCast(I);
|
||||||
@ -453,12 +457,16 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
|
|||||||
|
|
||||||
FastISel::FastISel(MachineFunction &mf,
|
FastISel::FastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &vm,
|
DenseMap<const Value *, unsigned> &vm,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||||
|
DenseMap<const AllocaInst *, int> &am)
|
||||||
: MBB(0),
|
: MBB(0),
|
||||||
ValueMap(vm),
|
ValueMap(vm),
|
||||||
MBBMap(bm),
|
MBBMap(bm),
|
||||||
|
StaticAllocaMap(am),
|
||||||
MF(mf),
|
MF(mf),
|
||||||
MRI(MF.getRegInfo()),
|
MRI(MF.getRegInfo()),
|
||||||
|
MFI(*MF.getFrameInfo()),
|
||||||
|
MCP(*MF.getConstantPool()),
|
||||||
TM(MF.getTarget()),
|
TM(MF.getTarget()),
|
||||||
TD(*TM.getTargetData()),
|
TD(*TM.getTargetData()),
|
||||||
TII(*TM.getInstrInfo()),
|
TII(*TM.getInstrInfo()),
|
||||||
|
@ -737,7 +737,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
|
|||||||
// FastISel doesn't support EH landing pads, which require special handling.
|
// FastISel doesn't support EH landing pads, which require special handling.
|
||||||
if (EnableFastISel && !BB->isLandingPad()) {
|
if (EnableFastISel && !BB->isLandingPad()) {
|
||||||
if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, FuncInfo->ValueMap,
|
if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, FuncInfo->ValueMap,
|
||||||
FuncInfo->MBBMap)) {
|
FuncInfo->MBBMap,
|
||||||
|
FuncInfo->StaticAllocaMap)) {
|
||||||
// Emit code for any incoming arguments. This must happen before
|
// Emit code for any incoming arguments. This must happen before
|
||||||
// beginning FastISel on the entry block.
|
// beginning FastISel on the entry block.
|
||||||
if (LLVMBB == &Fn.getEntryBlock()) {
|
if (LLVMBB == &Fn.getEntryBlock()) {
|
||||||
|
@ -31,10 +31,6 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
class X86FastISel : public FastISel {
|
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
|
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
||||||
/// make the right decision when generating code for different targets.
|
/// make the right decision when generating code for different targets.
|
||||||
const X86Subtarget *Subtarget;
|
const X86Subtarget *Subtarget;
|
||||||
@ -53,8 +49,9 @@ class X86FastISel : public FastISel {
|
|||||||
public:
|
public:
|
||||||
explicit X86FastISel(MachineFunction &mf,
|
explicit X86FastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &vm,
|
DenseMap<const Value *, unsigned> &vm,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||||
: FastISel(mf, vm, bm), MFI(MF.getFrameInfo()) {
|
DenseMap<const AllocaInst *, int> &am)
|
||||||
|
: FastISel(mf, vm, bm, am) {
|
||||||
Subtarget = &TM.getSubtarget<X86Subtarget>();
|
Subtarget = &TM.getSubtarget<X86Subtarget>();
|
||||||
StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
|
StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
|
||||||
X86ScalarSSEf64 = Subtarget->hasSSE2();
|
X86ScalarSSEf64 = Subtarget->hasSSE2();
|
||||||
@ -66,10 +63,10 @@ public:
|
|||||||
#include "X86GenFastISel.inc"
|
#include "X86GenFastISel.inc"
|
||||||
|
|
||||||
private:
|
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,
|
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,
|
bool X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, unsigned Src, MVT SrcVT,
|
||||||
unsigned &ResultReg);
|
unsigned &ResultReg);
|
||||||
@ -77,6 +74,8 @@ private:
|
|||||||
bool X86SelectConstAddr(Value *V, unsigned &Op0,
|
bool X86SelectConstAddr(Value *V, unsigned &Op0,
|
||||||
bool isCall = false, bool inReg = false);
|
bool isCall = false, bool inReg = false);
|
||||||
|
|
||||||
|
bool X86SelectAddress(Value *V, X86AddressMode &AM);
|
||||||
|
|
||||||
bool X86SelectLoad(Instruction *I);
|
bool X86SelectLoad(Instruction *I);
|
||||||
|
|
||||||
bool X86SelectStore(Instruction *I);
|
bool X86SelectStore(Instruction *I);
|
||||||
@ -97,7 +96,9 @@ private:
|
|||||||
|
|
||||||
CCAssignFn *CCAssignFnForCall(unsigned CC, bool isTailCall = false);
|
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
|
/// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is
|
||||||
/// computed in an SSE register, not on the X87 floating point stack.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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) {
|
unsigned &ResultReg) {
|
||||||
// Get opcode and regclass of the output for the given load instruction.
|
// Get opcode and regclass of the output for the given load instruction.
|
||||||
unsigned Opc = 0;
|
unsigned Opc = 0;
|
||||||
@ -200,12 +201,6 @@ bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ResultReg = createResultReg(RC);
|
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);
|
addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -216,7 +211,7 @@ bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV,
|
|||||||
/// i.e. V. Return true if it is possible.
|
/// i.e. V. Return true if it is possible.
|
||||||
bool
|
bool
|
||||||
X86FastISel::X86FastEmitStore(MVT VT, unsigned Val,
|
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.
|
// Get opcode and regclass of the output for the given store instruction.
|
||||||
unsigned Opc = 0;
|
unsigned Opc = 0;
|
||||||
const TargetRegisterClass *RC = NULL;
|
const TargetRegisterClass *RC = NULL;
|
||||||
@ -263,13 +258,6 @@ X86FastISel::X86FastEmitStore(MVT VT, unsigned Val,
|
|||||||
break;
|
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);
|
addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -331,6 +319,39 @@ bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0,
|
|||||||
return true;
|
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.
|
/// X86SelectStore - Select and emit code to implement store instructions.
|
||||||
bool X86FastISel::X86SelectStore(Instruction* I) {
|
bool X86FastISel::X86SelectStore(Instruction* I) {
|
||||||
MVT VT;
|
MVT VT;
|
||||||
@ -341,21 +362,11 @@ bool X86FastISel::X86SelectStore(Instruction* I) {
|
|||||||
// Unhandled operand. Halt "fast" selection and bail.
|
// Unhandled operand. Halt "fast" selection and bail.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Value *V = I->getOperand(1);
|
X86AddressMode AM;
|
||||||
unsigned Ptr = lookUpRegForValue(V);
|
if (!X86SelectAddress(I->getOperand(1), AM))
|
||||||
if (!Ptr) {
|
return false;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return X86FastEmitStore(VT, Val, Ptr, 0, V);
|
return X86FastEmitStore(VT, Val, AM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// X86SelectLoad - Select and emit code to implement load instructions.
|
/// X86SelectLoad - Select and emit code to implement load instructions.
|
||||||
@ -365,22 +376,12 @@ bool X86FastISel::X86SelectLoad(Instruction *I) {
|
|||||||
if (!isTypeLegal(I->getType(), TLI, VT))
|
if (!isTypeLegal(I->getType(), TLI, VT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Value *V = I->getOperand(0);
|
X86AddressMode AM;
|
||||||
unsigned Ptr = lookUpRegForValue(V);
|
if (!X86SelectAddress(I->getOperand(0), AM))
|
||||||
if (!Ptr) {
|
return false;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ResultReg = 0;
|
unsigned ResultReg = 0;
|
||||||
if (X86FastEmitLoad(VT, Ptr, V, ResultReg)) {
|
if (X86FastEmitLoad(VT, AM, ResultReg)) {
|
||||||
UpdateValueMap(I, ResultReg);
|
UpdateValueMap(I, ResultReg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -831,7 +832,10 @@ bool X86FastISel::X86SelectCall(Instruction *I) {
|
|||||||
RegArgs.push_back(VA.getLocReg());
|
RegArgs.push_back(VA.getLocReg());
|
||||||
} else {
|
} else {
|
||||||
unsigned LocMemOffset = VA.getLocMemOffset();
|
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();
|
MVT ResVT = RVLocs[0].getValVT();
|
||||||
unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
|
unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
|
||||||
unsigned MemSize = ResVT.getSizeInBits()/8;
|
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);
|
addFrameReference(BuildMI(MBB, TII.get(Opc)), FI).addReg(ResultReg);
|
||||||
DstRC = ResVT == MVT::f32
|
DstRC = ResVT == MVT::f32
|
||||||
? X86::FR32RegisterClass : X86::FR64RegisterClass;
|
? X86::FR32RegisterClass : X86::FR64RegisterClass;
|
||||||
@ -938,8 +942,7 @@ X86FastISel::TargetSelectInstruction(Instruction *I) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned X86FastISel::TargetMaterializeConstant(Constant *C,
|
unsigned X86FastISel::TargetMaterializeConstant(Constant *C) {
|
||||||
MachineConstantPool* MCP) {
|
|
||||||
// Can't handle PIC-mode yet.
|
// Can't handle PIC-mode yet.
|
||||||
if (TM.getRelocationModel() == Reloc::PIC_)
|
if (TM.getRelocationModel() == Reloc::PIC_)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1010,15 +1013,27 @@ unsigned X86FastISel::TargetMaterializeConstant(Constant *C,
|
|||||||
Align = Log2_64(Align);
|
Align = Log2_64(Align);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned MCPOffset = MCP->getConstantPoolIndex(C, Align);
|
unsigned MCPOffset = MCP.getConstantPoolIndex(C, Align);
|
||||||
addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
|
addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
|
||||||
return ResultReg;
|
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 {
|
namespace llvm {
|
||||||
llvm::FastISel *X86::createFastISel(MachineFunction &mf,
|
llvm::FastISel *X86::createFastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &vm,
|
DenseMap<const Value *, unsigned> &vm,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||||
return new X86FastISel(mf, vm, bm);
|
DenseMap<const AllocaInst *, int> &am) {
|
||||||
|
return new X86FastISel(mf, vm, bm, am);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1886,8 +1886,10 @@ FastISel *
|
|||||||
X86TargetLowering::createFastISel(MachineFunction &mf,
|
X86TargetLowering::createFastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &vm,
|
DenseMap<const Value *, unsigned> &vm,
|
||||||
DenseMap<const BasicBlock *,
|
DenseMap<const BasicBlock *,
|
||||||
MachineBasicBlock *> &bm) {
|
MachineBasicBlock *> &bm,
|
||||||
return X86::createFastISel(mf, vm, bm);
|
DenseMap<const AllocaInst *, int> &am) {
|
||||||
|
|
||||||
|
return X86::createFastISel(mf, vm, bm, am);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -473,7 +473,8 @@ namespace llvm {
|
|||||||
virtual FastISel *
|
virtual FastISel *
|
||||||
createFastISel(MachineFunction &mf,
|
createFastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &,
|
DenseMap<const Value *, unsigned> &,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &);
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||||
|
DenseMap<const AllocaInst *, int> &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
||||||
@ -604,7 +605,8 @@ namespace llvm {
|
|||||||
namespace X86 {
|
namespace X86 {
|
||||||
FastISel *createFastISel(MachineFunction &mf,
|
FastISel *createFastISel(MachineFunction &mf,
|
||||||
DenseMap<const Value *, unsigned> &,
|
DenseMap<const Value *, unsigned> &,
|
||||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &);
|
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||||
|
DenseMap<const AllocaInst *, int> &);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user