Create HandlePHINodesInSuccessorBlocksFast, a version of
HandlePHINodesInSuccessorBlocks that works FastISel-style. This
allows PHI nodes to be updated correctly while using FastISel.

This also involves some code reorganization; ValueMap and
MBBMap are now members of the FastISel class, so they needn't
be passed around explicitly anymore. Also, SelectInstructions
is changed to SelectInstruction, and only does one instruction
at a time.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55746 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 12f12bd..c057be5 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -25,8 +25,7 @@
 // tracking what uses they dominate.  Non-constants, however, already
 // have the SSA def-doms-use requirement enforced, so we can cache their
 // computations.
-unsigned FastISel::getRegForValue(Value *V,
-                                  DenseMap<const Value*, unsigned> &ValueMap) {
+unsigned FastISel::getRegForValue(Value *V) {
   if (ValueMap.count(V))
     return ValueMap[V];
 
@@ -78,8 +77,7 @@
 /// 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) {
+void FastISel::UpdateValueMap(Instruction* I, unsigned Reg) {
   if (!ValueMap.count(I))
     ValueMap[I] = Reg;
   else
@@ -90,8 +88,7 @@
 /// SelectBinaryOp - Select and emit code for a binary operator instruction,
 /// which has an opcode which directly corresponds to the given ISD opcode.
 ///
-bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
-                              DenseMap<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode) {
   MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
   if (VT == MVT::Other || !VT.isSimple())
     // Unhandled type. Halt "fast" selection and bail.
@@ -103,7 +100,7 @@
   if (!TLI.isTypeLegal(VT))
     return false;
 
-  unsigned Op0 = getRegForValue(I->getOperand(0), ValueMap);
+  unsigned Op0 = getRegForValue(I->getOperand(0));
   if (Op0 == 0)
     // Unhandled operand. Halt "fast" selection and bail.
     return false;
@@ -114,7 +111,7 @@
                                      ISDOpcode, Op0, CI->getZExtValue());
     if (ResultReg != 0) {
       // We successfully emitted code for the given LLVM Instruction.
-      UpdateValueMap(I, ResultReg, ValueMap);
+      UpdateValueMap(I, ResultReg);
       return true;
     }
   }
@@ -125,12 +122,12 @@
                                      ISDOpcode, Op0, CF);
     if (ResultReg != 0) {
       // We successfully emitted code for the given LLVM Instruction.
-      UpdateValueMap(I, ResultReg, ValueMap);
+      UpdateValueMap(I, ResultReg);
       return true;
     }
   }
 
-  unsigned Op1 = getRegForValue(I->getOperand(1), ValueMap);
+  unsigned Op1 = getRegForValue(I->getOperand(1));
   if (Op1 == 0)
     // Unhandled operand. Halt "fast" selection and bail.
     return false;
@@ -144,13 +141,12 @@
     return false;
 
   // We successfully emitted code for the given LLVM Instruction.
-  UpdateValueMap(I, ResultReg, ValueMap);
+  UpdateValueMap(I, ResultReg);
   return true;
 }
 
-bool FastISel::SelectGetElementPtr(Instruction *I,
-                                   DenseMap<const Value*, unsigned> &ValueMap) {
-  unsigned N = getRegForValue(I->getOperand(0), ValueMap);
+bool FastISel::SelectGetElementPtr(Instruction *I) {
+  unsigned N = getRegForValue(I->getOperand(0));
   if (N == 0)
     // Unhandled operand. Halt "fast" selection and bail.
     return false;
@@ -190,7 +186,7 @@
       
       // N = N + Idx * ElementSize;
       uint64_t ElementSize = TD.getABITypeSize(Ty);
-      unsigned IdxN = getRegForValue(Idx, ValueMap);
+      unsigned IdxN = getRegForValue(Idx);
       if (IdxN == 0)
         // Unhandled operand. Halt "fast" selection and bail.
         return false;
@@ -220,12 +216,11 @@
   }
 
   // We successfully emitted code for the given LLVM Instruction.
-  UpdateValueMap(I, N, ValueMap);
+  UpdateValueMap(I, N);
   return true;
 }
 
-bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
-                          DenseMap<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode) {
   MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
   MVT DstVT = TLI.getValueType(I->getType());
     
@@ -235,7 +230,7 @@
     // Unhandled type. Halt "fast" selection and bail.
     return false;
     
-  unsigned InputReg = getRegForValue(I->getOperand(0), ValueMap);
+  unsigned InputReg = getRegForValue(I->getOperand(0));
   if (!InputReg)
     // Unhandled operand.  Halt "fast" selection and bail.
     return false;
@@ -247,18 +242,17 @@
   if (!ResultReg)
     return false;
     
-  UpdateValueMap(I, ResultReg, ValueMap);
+  UpdateValueMap(I, ResultReg);
   return true;
 }
 
-bool FastISel::SelectBitCast(Instruction *I,
-                             DenseMap<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectBitCast(Instruction *I) {
   // If the bitcast doesn't change the type, just use the operand value.
   if (I->getType() == I->getOperand(0)->getType()) {
-    unsigned Reg = getRegForValue(I->getOperand(0), ValueMap);
+    unsigned Reg = getRegForValue(I->getOperand(0));
     if (Reg == 0)
       return false;
-    UpdateValueMap(I, Reg, ValueMap);
+    UpdateValueMap(I, Reg);
     return true;
   }
 
@@ -272,7 +266,7 @@
     // Unhandled type. Halt "fast" selection and bail.
     return false;
   
-  unsigned Op0 = getRegForValue(I->getOperand(0), ValueMap);
+  unsigned Op0 = getRegForValue(I->getOperand(0));
   if (Op0 == 0)
     // Unhandled operand. Halt "fast" selection and bail.
     return false;
@@ -298,143 +292,124 @@
   if (!ResultReg)
     return false;
   
-  UpdateValueMap(I, ResultReg, ValueMap);
+  UpdateValueMap(I, ResultReg);
   return true;
 }
 
-BasicBlock::iterator
-FastISel::SelectInstructions(BasicBlock::iterator Begin,
-                             BasicBlock::iterator End,
-                             DenseMap<const Value*, unsigned> &ValueMap,
-                             DenseMap<const BasicBlock*,
-                                      MachineBasicBlock *> &MBBMap,
-                             MachineBasicBlock *mbb) {
-  MBB = mbb;
-  BasicBlock::iterator I = Begin;
+bool
+FastISel::SelectInstruction(Instruction *I) {
+  switch (I->getOpcode()) {
+  case Instruction::Add: {
+    ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
+    return SelectBinaryOp(I, Opc);
+  }
+  case Instruction::Sub: {
+    ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
+    return SelectBinaryOp(I, Opc);
+  }
+  case Instruction::Mul: {
+    ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
+    return SelectBinaryOp(I, Opc);
+  }
+  case Instruction::SDiv:
+    return SelectBinaryOp(I, ISD::SDIV);
+  case Instruction::UDiv:
+    return SelectBinaryOp(I, ISD::UDIV);
+  case Instruction::FDiv:
+    return SelectBinaryOp(I, ISD::FDIV);
+  case Instruction::SRem:
+    return SelectBinaryOp(I, ISD::SREM);
+  case Instruction::URem:
+    return SelectBinaryOp(I, ISD::UREM);
+  case Instruction::FRem:
+    return SelectBinaryOp(I, ISD::FREM);
+  case Instruction::Shl:
+    return SelectBinaryOp(I, ISD::SHL);
+  case Instruction::LShr:
+    return SelectBinaryOp(I, ISD::SRL);
+  case Instruction::AShr:
+    return SelectBinaryOp(I, ISD::SRA);
+  case Instruction::And:
+    return SelectBinaryOp(I, ISD::AND);
+  case Instruction::Or:
+    return SelectBinaryOp(I, ISD::OR);
+  case Instruction::Xor:
+    return SelectBinaryOp(I, ISD::XOR);
 
-  for (; I != End; ++I) {
-    switch (I->getOpcode()) {
-    case Instruction::Add: {
-      ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
-      if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
-    }
-    case Instruction::Sub: {
-      ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
-      if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
-    }
-    case Instruction::Mul: {
-      ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
-      if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
-    }
-    case Instruction::SDiv:
-      if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break;
-    case Instruction::UDiv:
-      if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break;
-    case Instruction::FDiv:
-      if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break;
-    case Instruction::SRem:
-      if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break;
-    case Instruction::URem:
-      if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break;
-    case Instruction::FRem:
-      if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break;
-    case Instruction::Shl:
-      if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break;
-    case Instruction::LShr:
-      if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break;
-    case Instruction::AShr:
-      if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break;
-    case Instruction::And:
-      if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break;
-    case Instruction::Or:
-      if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break;
-    case Instruction::Xor:
-      if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break;
+  case Instruction::GetElementPtr:
+    return SelectGetElementPtr(I);
 
-    case Instruction::GetElementPtr:
-      if (!SelectGetElementPtr(I, ValueMap)) return I;
-      break;
+  case Instruction::Br: {
+    BranchInst *BI = cast<BranchInst>(I);
 
-    case Instruction::Br: {
-      BranchInst *BI = cast<BranchInst>(I);
+    if (BI->isUnconditional()) {
+      MachineFunction::iterator NextMBB =
+         next(MachineFunction::iterator(MBB));
+      BasicBlock *LLVMSucc = BI->getSuccessor(0);
+      MachineBasicBlock *MSucc = MBBMap[LLVMSucc];
 
-      if (BI->isUnconditional()) {
-        MachineFunction::iterator NextMBB =
-           next(MachineFunction::iterator(MBB));
-        BasicBlock *LLVMSucc = BI->getSuccessor(0);
-        MachineBasicBlock *MSucc = MBBMap[LLVMSucc];
-
-        if (NextMBB != MF.end() && MSucc == NextMBB) {
-          // The unconditional fall-through case, which needs no instructions.
-        } else {
-          // The unconditional branch case.
-          TII.InsertBranch(*MBB, MSucc, NULL, SmallVector<MachineOperand, 0>());
-        }
-        MBB->addSuccessor(MSucc);
-        break;
-      }
-
-      // Conditional branches are not handed yet.
-      // Halt "fast" selection and bail.
-      return I;
-    }
-
-    case Instruction::PHI:
-      // PHI nodes are already emitted.
-      break;
-      
-    case Instruction::BitCast:
-      if (!SelectBitCast(I, ValueMap)) return I; break;
-
-    case Instruction::FPToSI:
-      if (!SelectCast(I, ISD::FP_TO_SINT, ValueMap)) return I; 
-      break;
-    case Instruction::ZExt:
-      if (!SelectCast(I, ISD::ZERO_EXTEND, ValueMap)) return I;
-      break;
-    case Instruction::SExt:
-      if (!SelectCast(I, ISD::SIGN_EXTEND, ValueMap)) return I;
-      break;
-    case Instruction::Trunc:
-      if (!SelectCast(I, ISD::TRUNCATE, ValueMap)) return I;
-      break;
-    case Instruction::SIToFP:
-      if (!SelectCast(I, ISD::SINT_TO_FP, ValueMap)) return I;
-      break;
-
-    case Instruction::IntToPtr: // Deliberate fall-through.
-    case Instruction::PtrToInt: {
-      MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
-      MVT DstVT = TLI.getValueType(I->getType());
-      if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) {
-        if (ValueMap[I->getOperand(0)]) {
-          UpdateValueMap(I, ValueMap[I->getOperand(0)], ValueMap);
-          break;
-        } else
-          // Unhandled operand
-          return I;
-      } else if (DstVT.bitsGT(SrcVT)) {
-        if (!SelectCast(I, ISD::ZERO_EXTEND, ValueMap)) return I;
-        break;
+      if (NextMBB != MF.end() && MSucc == NextMBB) {
+        // The unconditional fall-through case, which needs no instructions.
       } else {
-        // TODO: Handle SrcVT > DstVT, where truncation is needed.
-        return I;
+        // The unconditional branch case.
+        TII.InsertBranch(*MBB, MSucc, NULL, SmallVector<MachineOperand, 0>());
       }
+      MBB->addSuccessor(MSucc);
+      return true;
     }
-    
-    default:
-      // Unhandled instruction. Halt "fast" selection and bail.
-      return I;
-    }
+
+    // Conditional branches are not handed yet.
+    // Halt "fast" selection and bail.
+    return false;
   }
 
-  return I;
+  case Instruction::PHI:
+    // PHI nodes are already emitted.
+    return true;
+    
+  case Instruction::BitCast:
+    return SelectBitCast(I);
+
+  case Instruction::FPToSI:
+    return SelectCast(I, ISD::FP_TO_SINT);
+  case Instruction::ZExt:
+    return SelectCast(I, ISD::ZERO_EXTEND);
+  case Instruction::SExt:
+    return SelectCast(I, ISD::SIGN_EXTEND);
+  case Instruction::Trunc:
+    return SelectCast(I, ISD::TRUNCATE);
+  case Instruction::SIToFP:
+    return SelectCast(I, ISD::SINT_TO_FP);
+
+  case Instruction::IntToPtr: // Deliberate fall-through.
+  case Instruction::PtrToInt: {
+    MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
+    MVT DstVT = TLI.getValueType(I->getType());
+    if (DstVT.bitsGT(SrcVT))
+      return SelectCast(I, ISD::ZERO_EXTEND);
+    if (DstVT.bitsLT(SrcVT))
+      return SelectCast(I, ISD::TRUNCATE);
+    unsigned Reg = getRegForValue(I->getOperand(0));
+    if (Reg == 0) return false;
+    UpdateValueMap(I, Reg);
+    return true;
+  }
+  
+  default:
+    // Unhandled instruction. Halt "fast" selection and bail.
+    return false;
+  }
 }
 
-FastISel::FastISel(MachineFunction &mf)
-  : MF(mf),
-    MRI(mf.getRegInfo()),
-    TM(mf.getTarget()),
+FastISel::FastISel(MachineFunction &mf,
+                   DenseMap<const Value *, unsigned> &vm,
+                   DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
+  : MBB(0),
+    ValueMap(vm),
+    MBBMap(bm),
+    MF(mf),
+    MRI(MF.getRegInfo()),
+    TM(MF.getTarget()),
     TD(*TM.getTargetData()),
     TII(*TM.getInstrInfo()),
     TLI(*TM.getTargetLowering()) {