[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Sep 6 18:59:48 PDT 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAGISel.cpp updated: 1.272 -> 1.273
---
Log message:

Fix CodeGen/Generic/2006-09-06-SwitchLowering.ll, a bug where SDIsel inserted
too many phi operands when lowering a switch to branches in some cases.


---
Diffs of the changes:  (+32 -15)

 SelectionDAGISel.cpp |   47 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 15 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.272 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.273
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.272	Mon Sep  4 21:31:13 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Wed Sep  6 20:59:34 2006
@@ -922,7 +922,6 @@
   // If the switch has more than 5 blocks, and at least 31.25% dense, and the 
   // target supports indirect branches, then emit a jump table rather than 
   // lowering the switch to a binary tree of conditional branches.
-  // FIXME: Make this work with PIC code
   if (TLI.isOperationLegal(ISD::BRIND, TLI.getPointerTy()) &&
       Cases.size() > 5) {
     uint64_t First = cast<ConstantIntegral>(Cases.front().first)->getRawValue();
@@ -3412,12 +3411,14 @@
 
   // Emit constants only once even if used by multiple PHI nodes.
   std::map<Constant*, unsigned> ConstantsOut;
-
+  
   // Check successor nodes PHI nodes that expect a constant to be available from
   // this block.
   TerminatorInst *TI = LLVMBB->getTerminator();
   for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
     BasicBlock *SuccBB = TI->getSuccessor(succ);
+    if (!isa<PHINode>(SuccBB->begin())) continue;
+    
     MachineBasicBlock::iterator MBBI = FuncInfo.MBBMap[SuccBB]->begin();
     PHINode *PN;
 
@@ -3589,31 +3590,47 @@
   
   // If we generated any switch lowering information, build and codegen any
   // additional DAGs necessary.
-  for(unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
+  for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
     SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineDebugInfo>());
     CurDAG = &SDAG;
     SelectionDAGLowering SDL(SDAG, TLI, FuncInfo);
+    
     // Set the current basic block to the mbb we wish to insert the code into
     BB = SwitchCases[i].ThisBB;
     SDL.setCurrentBasicBlock(BB);
+    
     // Emit the code
     SDL.visitSwitchCase(SwitchCases[i]);
     SDAG.setRoot(SDL.getRoot());
     CodeGenAndEmitDAG(SDAG);
-    // Iterate over the phi nodes, if there is a phi node in a successor of this
-    // block (for instance, the default block), then add a pair of operands to
-    // the phi node for this block, as if we were coming from the original
-    // BB before switch expansion.
-    for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
-      MachineInstr *PHI = PHINodesToUpdate[pi].first;
-      MachineBasicBlock *PHIBB = PHI->getParent();
-      assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
-             "This is not a machine PHI node that we are updating!");
-      if (PHIBB == SwitchCases[i].LHSBB || PHIBB == SwitchCases[i].RHSBB) {
-        PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
-        PHI->addMachineBasicBlockOperand(BB);
+    
+    // Handle any PHI nodes in successors of this chunk, as if we were coming
+    // from the original BB before switch expansion.  Note that PHI nodes can
+    // occur multiple times in PHINodesToUpdate.  We have to be very careful to
+    // handle them the right number of times.
+    while ((BB = SwitchCases[i].LHSBB)) {  // Handle LHS and RHS.
+      for (MachineBasicBlock::iterator Phi = BB->begin();
+           Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI; ++Phi){
+        // This value for this PHI node is recorded in PHINodesToUpdate, get it.
+        for (unsigned pn = 0; ; ++pn) {
+          assert(pn != PHINodesToUpdate.size() && "Didn't find PHI entry!");
+          if (PHINodesToUpdate[pn].first == Phi) {
+            Phi->addRegOperand(PHINodesToUpdate[pn].second, false);
+            Phi->addMachineBasicBlockOperand(SwitchCases[i].ThisBB);
+            break;
+          }
+        }
       }
+      
+      // Don't process RHS if same block as LHS.
+      if (BB == SwitchCases[i].RHSBB)
+        SwitchCases[i].RHSBB = 0;
+      
+      // If we haven't handled the RHS, do so now.  Otherwise, we're done.
+      SwitchCases[i].LHSBB = SwitchCases[i].RHSBB;
+      SwitchCases[i].RHSBB = 0;
     }
+    assert(SwitchCases[i].LHSBB == 0 && SwitchCases[i].RHSBB == 0);
   }
 }
 






More information about the llvm-commits mailing list