aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2008-09-05 00:06:23 +0000
committerOwen Anderson <resistor@mac.com>2008-09-05 00:06:23 +0000
commit95267a1e671efc3c14e916b6978bbb15973b4cdc (patch)
treeaa96525ef26e6b7a75ba4672ddc8cbe7bf845c0c
parent6e3f05f5cebe230bb95f01b5afcc3c8e94106402 (diff)
Add initial support for selecting constant materializations that require constant
pool loads on X86 in fast isel. This isn't actually used yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55814 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/FastISel.h8
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp2
-rw-r--r--lib/Target/X86/X86FastISel.cpp88
3 files changed, 96 insertions, 2 deletions
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 71c80d5353..9df3aa9ae6 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -22,6 +22,7 @@ namespace llvm {
class ConstantFP;
class MachineBasicBlock;
+class MachineConstantPool;
class MachineFunction;
class MachineRegisterInfo;
class TargetData;
@@ -215,9 +216,14 @@ protected:
/// from a specified index of a superregister.
unsigned FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx);
- void UpdateValueMap(Instruction* I, unsigned Reg);
+ void UpdateValueMap(Value* I, unsigned Reg);
unsigned createResultReg(const TargetRegisterClass *RC);
+
+ virtual unsigned TargetSelectConstantPoolLoad(Constant* C,
+ MachineConstantPool* MCP) {
+ return 0;
+ }
private:
bool SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode);
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index d118eefd22..043691cf07 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -80,7 +80,7 @@ unsigned FastISel::getRegForValue(Value *V) {
/// NOTE: This is only necessary because we might select a block that uses
/// a value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
-void FastISel::UpdateValueMap(Instruction* I, unsigned Reg) {
+void FastISel::UpdateValueMap(Value* I, unsigned Reg) {
if (!ValueMap.count(I))
ValueMap[I] = Reg;
else
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 4cd3836e3e..b6240ddc94 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -22,6 +22,7 @@
#include "llvm/InstrTypes.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/FastISel.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
using namespace llvm;
@@ -51,6 +52,8 @@ private:
bool X86SelectStore(Instruction *I);
bool X86SelectCmp(Instruction *I);
+
+ unsigned TargetSelectConstantPoolLoad(Constant *C, MachineConstantPool* MCP);
};
/// X86SelectConstAddr - Select and emit code to materialize constant address.
@@ -401,6 +404,91 @@ X86FastISel::TargetSelectInstruction(Instruction *I) {
return false;
}
+unsigned X86FastISel::TargetSelectConstantPoolLoad(Constant *C,
+ MachineConstantPool* MCP) {
+ unsigned CPLoad = getRegForValue(C);
+ if (CPLoad != 0)
+ return CPLoad;
+
+ // Can't handle PIC-mode yet.
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return 0;
+
+ MVT VT = MVT::getMVT(C->getType(), /*HandleUnknown=*/true);
+ if (VT == MVT::Other || !VT.isSimple())
+ // Unhandled type. Halt "fast" selection and bail.
+ return false;
+ if (VT == MVT::iPTR)
+ // Use pointer type.
+ VT = TLI.getPointerTy();
+ // We only handle legal types. For example, on x86-32 the instruction
+ // selector contains all of the 64-bit instructions from x86-64,
+ // under the assumption that i64 won't be used if the target doesn't
+ // support it.
+ if (!TLI.isTypeLegal(VT))
+ return false;
+
+ // Get opcode and regclass of the output for the given load instruction.
+ unsigned Opc = 0;
+ const TargetRegisterClass *RC = NULL;
+ switch (VT.getSimpleVT()) {
+ default: return false;
+ case MVT::i8:
+ Opc = X86::MOV8rm;
+ RC = X86::GR8RegisterClass;
+ break;
+ case MVT::i16:
+ Opc = X86::MOV16rm;
+ RC = X86::GR16RegisterClass;
+ break;
+ case MVT::i32:
+ Opc = X86::MOV32rm;
+ RC = X86::GR32RegisterClass;
+ break;
+ case MVT::i64:
+ // Must be in x86-64 mode.
+ Opc = X86::MOV64rm;
+ RC = X86::GR64RegisterClass;
+ break;
+ case MVT::f32:
+ if (Subtarget->hasSSE1()) {
+ Opc = X86::MOVSSrm;
+ RC = X86::FR32RegisterClass;
+ } else {
+ Opc = X86::LD_Fp32m;
+ RC = X86::RFP32RegisterClass;
+ }
+ break;
+ case MVT::f64:
+ if (Subtarget->hasSSE2()) {
+ Opc = X86::MOVSDrm;
+ RC = X86::FR64RegisterClass;
+ } else {
+ Opc = X86::LD_Fp64m;
+ RC = X86::RFP64RegisterClass;
+ }
+ break;
+ case MVT::f80:
+ Opc = X86::LD_Fp80m;
+ RC = X86::RFP80RegisterClass;
+ break;
+ }
+
+ unsigned ResultReg = createResultReg(RC);
+ if (isa<GlobalValue>(C)) {
+ if (X86SelectConstAddr(C, ResultReg))
+ return ResultReg;
+ else
+ return 0;
+ }
+
+
+ unsigned MCPOffset = MCP->getConstantPoolIndex(C, 0);
+ addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
+ UpdateValueMap(C, ResultReg);
+ return ResultReg;
+}
+
namespace llvm {
llvm::FastISel *X86::createFastISel(MachineFunction &mf,
DenseMap<const Value *, unsigned> &vm,