Add support for fast isel of (integer) immediate materialization pattens, and use...
authorOwen Anderson <resistor@mac.com>
Mon, 25 Aug 2008 20:20:32 +0000 (20:20 +0000)
committerOwen Anderson <resistor@mac.com>
Mon, 25 Aug 2008 20:20:32 +0000 (20:20 +0000)
bitcast of constants in fast isel.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55325 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/FastISel.h
lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/X86/fast-isel.ll
utils/TableGen/FastISelEmitter.cpp

index 636081f6b9a9081f12e81787a3a9c3d3d58f3075..c5d5f61bf96463e54583348560e7bc46c21eacf1 100644 (file)
@@ -81,11 +81,6 @@ protected:
                                ISD::NodeType Opcode,
                                unsigned Op0, unsigned Op1);
 
-  /// FastEmit_i - This method is called by target-independent code
-  /// to request that an instruction with the given type which materialize
-  /// the specified immediate value.
-  virtual unsigned FastEmit_i(MVT::SimpleValueType VT, uint64_t Imm);
-
   /// FastEmit_ri - This method is called by target-independent code
   /// to request that an instruction with the given type, opcode, and
   /// register and immediate operands be emitted.
@@ -110,6 +105,13 @@ protected:
                         ISD::NodeType Opcode,
                         unsigned Op0, uint64_t Imm,
                         MVT::SimpleValueType ImmType);
+  
+  /// FastEmit_i - This method is called by target-independent code
+  /// to request that an instruction with the given type, opcode, and
+  /// immediate operand be emitted.
+  virtual unsigned FastEmit_i(MVT::SimpleValueType VT,
+                              ISD::NodeType Opcode,
+                              uint64_t Imm);
 
   /// FastEmitInst_ - Emit a MachineInstr with no operands and a
   /// result register in the given register class.
@@ -144,6 +146,12 @@ protected:
   unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
                             const TargetRegisterClass *RC,
                             unsigned Op0, unsigned Op1, uint64_t Imm);
+  
+  /// FastEmitInst_i - Emit a MachineInstr with a single immediate
+  /// operand, and a result register in the given register class.
+  unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
+                          const TargetRegisterClass *RC,
+                          uint64_t Imm);
 
 private:
   unsigned createResultReg(const TargetRegisterClass *RC);
index ebac0fe33b206dcade3ddeb473207631d203531f..c8c219d39d4d8727eff54cc4818716f8398c9049 100644 (file)
@@ -221,6 +221,22 @@ FastISel::SelectInstructions(BasicBlock::iterator Begin,
     case Instruction::PHI:
       // PHI nodes are already emitted.
       break;
+      
+    case Instruction::BitCast:
+      // BitCast consists of either an immediate to register move
+      // or a register to register move.
+      if (ConstantInt* CI = dyn_cast<ConstantInt>(I->getOperand(0))) {
+        if (I->getType()->isInteger()) {
+          MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/false);
+          ValueMap[I] = FastEmit_i(VT.getSimpleVT(), ISD::Constant,
+                                   CI->getZExtValue());
+          break;
+        } else
+          // TODO: Support vector and fp constants.
+          return I;
+      } else
+        // TODO: Support non-constant bitcasts.
+        return I;
 
     default:
       // Unhandled instruction. Halt "fast" selection and bail.
@@ -256,7 +272,8 @@ unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
   return 0;
 }
 
-unsigned FastISel::FastEmit_i(MVT::SimpleValueType, uint64_t /*Imm*/) {
+unsigned FastISel::FastEmit_i(MVT::SimpleValueType, ISD::NodeType,
+                              uint64_t /*Imm*/) {
   return 0;
 }
 
@@ -284,7 +301,7 @@ unsigned FastISel::FastEmit_ri_(MVT::SimpleValueType VT, ISD::NodeType Opcode,
     ResultReg = FastEmit_ri(VT, Opcode, Op0, Imm);
   if (ResultReg != 0)
     return ResultReg;
-  unsigned MaterialReg = FastEmit_i(ImmType, Imm);
+  unsigned MaterialReg = FastEmit_i(ImmType, ISD::Constant, Imm);
   if (MaterialReg == 0)
     return 0;
   return FastEmit_rr(VT, Opcode, Op0, MaterialReg);
@@ -342,3 +359,13 @@ unsigned FastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
   BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm);
   return ResultReg;
 }
+
+unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode,
+                                  const TargetRegisterClass *RC,
+                                  uint64_t Imm) {
+  unsigned ResultReg = createResultReg(RC);
+  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
+  
+  BuildMI(MBB, II, ResultReg).addImm(Imm);
+  return ResultReg;
+}
\ No newline at end of file
index 601e38578c6f58db67d9f2341eab1054f477d3d6..9c10a7b82852aeee399f72f23e1a07a42647e5a3 100644 (file)
@@ -41,3 +41,8 @@ exit:
   ret double %t2
 }
 
+define i32 @cast(){
+entry:
+       %tmp2 = bitcast i32 0 to i32
+       ret i32 %tmp2
+}
index 5868a24e193f8a280da558d422ded7397b6cd2a1..f730f1d8c0832f6b8d04fda66b7aa7b126a2b9e3 100644 (file)
@@ -64,6 +64,12 @@ struct OperandsSignature {
                   const CodeGenTarget &Target,
                   MVT::SimpleValueType VT,
                   const CodeGenRegisterClass *DstRC) {
+    if (!InstPatNode->isLeaf() &&
+        InstPatNode->getOperator()->getName() == "imm") {
+      Operands.push_back("i");
+      return true;
+    }
+    
     for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
       TreePatternNode *Op = InstPatNode->getChild(i);
       // For now, filter out any operand with a predicate.
@@ -219,9 +225,6 @@ void FastISelEmitter::run(std::ostream &OS) {
     // an Operand or an immediate, like MOV32ri.
     if (InstPatOp->isSubClassOf("Operand"))
       continue;
-    if (InstPatOp->getName() == "imm" ||
-        InstPatOp->getName() == "fpimm")
-      continue;
 
     // For now, filter out any instructions with predicates.
     if (!InstPatNode->getPredicateFn().empty())