From: Owen Anderson Date: Fri, 5 Sep 2008 00:06:23 +0000 (+0000) Subject: Add initial support for selecting constant materializations that require constant X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=95267a1e671efc3c14e916b6978bbb15973b4cdc;p=oota-llvm.git 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 --- diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 71c80d53538..9df3aa9ae6f 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 d118eefd221..043691cf071 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 4cd3836e3e0..b6240ddc940 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(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 &vm,