Fix an issue where a use might be selected before a def, and then we didn't respect...
authorOwen Anderson <resistor@mac.com>
Sat, 30 Aug 2008 00:38:46 +0000 (00:38 +0000)
committerOwen Anderson <resistor@mac.com>
Sat, 30 Aug 2008 00:38:46 +0000 (00:38 +0000)
assignment when selecting the def.  This is the naive solution to the problem: insert a copy to the pre-chosen
vreg.  Other solutions might be preferable, such as:
  1) Passing the dest reg into FastEmit_.  However, this would require the higher level code to know about reg classes, which they don't currently.
  2) Selecting blocks in reverse postorder.  This has some compile time cost for computing the order, and we'd need to measure its impact.

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

include/llvm/CodeGen/FastISel.h
lib/CodeGen/SelectionDAG/FastISel.cpp

index 364f82e0b48dce875df2aff67f6913f2bc37b7ec..61b4fb137c191c35d392d358240b357c3deeeb32 100644 (file)
@@ -225,6 +225,9 @@ private:
   
   bool SelectCast(Instruction *I, ISD::NodeType Opcode,
                   DenseMap<const Value*, unsigned> &ValueMap);
+                  
+  void UpdateValueMap(Instruction* I, unsigned Reg, 
+                      DenseMap<const Value*, unsigned> &ValueMap);
 };
 
 }
index 33da2b07f7bbe317e7b5d9488c1a083513ffc5e7..45920ba4906bc4fd82de91640fd6143085c3f0ff 100644 (file)
@@ -63,6 +63,21 @@ unsigned FastISel::getRegForValue(Value *V, DenseMap<const Value*, unsigned> &Va
   return Reg;
 }
 
+/// UpdateValueMap - Update the value map to include the new mapping for this
+/// instruction, or insert an extra copy to get the result in a previous
+/// determined register.
+/// 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, 
+                              DenseMap<const Value*, unsigned> &ValueMap) {
+  if (!ValueMap.count(I))
+    ValueMap[I] = Reg;
+  else
+     TII.copyRegToReg(*MBB, MBB->end(), ValueMap[I],
+                      Reg, MRI.getRegClass(Reg), MRI.getRegClass(Reg));
+}
+
 /// SelectBinaryOp - Select and emit code for a binary operator instruction,
 /// which has an opcode which directly corresponds to the given ISD opcode.
 ///
@@ -90,7 +105,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
                                      ISDOpcode, Op0, CI->getZExtValue());
     if (ResultReg != 0) {
       // We successfully emitted code for the given LLVM Instruction.
-      ValueMap[I] = ResultReg;
+      UpdateValueMap(I, ResultReg, ValueMap);
       return true;
     }
   }
@@ -101,7 +116,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
                                      ISDOpcode, Op0, CF);
     if (ResultReg != 0) {
       // We successfully emitted code for the given LLVM Instruction.
-      ValueMap[I] = ResultReg;
+      UpdateValueMap(I, ResultReg, ValueMap);
       return true;
     }
   }
@@ -120,7 +135,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
     return false;
 
   // We successfully emitted code for the given LLVM Instruction.
-  ValueMap[I] = ResultReg;
+  UpdateValueMap(I, ResultReg, ValueMap);
   return true;
 }
 
@@ -196,7 +211,7 @@ bool FastISel::SelectGetElementPtr(Instruction *I,
   }
 
   // We successfully emitted code for the given LLVM Instruction.
-  ValueMap[I] = N;
+  UpdateValueMap(I, N, ValueMap);
   return true;
 }
 
@@ -223,7 +238,7 @@ bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
   if (!ResultReg)
     return false;
     
-  ValueMap[I] = ResultReg;
+  UpdateValueMap(I, ResultReg, ValueMap);
   return true;
 }
 
@@ -234,7 +249,7 @@ bool FastISel::SelectBitCast(Instruction *I,
     unsigned Reg = getRegForValue(I->getOperand(0), ValueMap);
     if (Reg == 0)
       return false;
-    ValueMap[I] = Reg;
+    UpdateValueMap(I, Reg, ValueMap);
     return true;
   }
 
@@ -274,7 +289,7 @@ bool FastISel::SelectBitCast(Instruction *I,
   if (!ResultReg)
     return false;
   
-  ValueMap[I] = ResultReg;
+  UpdateValueMap(I, ResultReg, ValueMap);
   return true;
 }
 
@@ -384,7 +399,7 @@ FastISel::SelectInstructions(BasicBlock::iterator Begin,
       MVT DstVT = TLI.getValueType(I->getType());
       if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) {
         if (ValueMap[I->getOperand(0)]) {
-          ValueMap[I] = ValueMap[I->getOperand(0)];
+          UpdateValueMap(I, ValueMap[I->getOperand(0)], ValueMap);
           break;
         } else
           // Unhandled operand