Add initial support for selecting constant materializations that require constant
authorOwen Anderson <resistor@mac.com>
Fri, 5 Sep 2008 00:06:23 +0000 (00:06 +0000)
committerOwen Anderson <resistor@mac.com>
Fri, 5 Sep 2008 00:06:23 +0000 (00:06 +0000)
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

include/llvm/CodeGen/FastISel.h
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/Target/X86/X86FastISel.cpp

index 71c80d535389923c51199cc72b69735e18d2325f..9df3aa9ae6f9e30e1cab21ba841e409a191fbdcf 100644 (file)
@@ -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);
index d118eefd221b14b131f56d1d9f422235e85cd8ea..043691cf07149e2f96f06a68d5d5df4ef7d37bbf 100644 (file)
@@ -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
index 4cd3836e3e04f0cbec0cd50746099c6458dd6ac8..b6240ddc9408a61f6ecd6d01ccf5d7c51a5c89cd 100644 (file)
@@ -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,