Testcase for PR2264.
[oota-llvm.git] / lib / CodeGen / StrongPHIElimination.cpp
index 05b38bb9931cfe9fa1ef8e359d671118a7c74f90..a632da6de09c550a4e1b69d9c03fe3ad80703af8 100644 (file)
@@ -174,7 +174,7 @@ void StrongPHIElimination::computeDFS(MachineFunction& MF) {
     }
     
     bool inserted = false;
-    for (MachineDomTreeNode::iterator I = node->begin(), E = node->end();
+    for (MachineDomTreeNode::iterator I = currNode->begin(), E = currNode->end();
          I != E; ++I)
       if (!frontier.count(*I) && !visited.count(*I)) {
         worklist.push_back(*I);
@@ -408,7 +408,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
   
   // Iterate over all the PHI nodes in this block
   MachineBasicBlock::iterator P = MBB->begin();
-  while (P->getOpcode() == TargetInstrInfo::PHI) {
+  while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) {
     unsigned DestReg = P->getOperand(0).getReg();
 
     // Don't both doing PHI elimination for dead PHI's.
@@ -483,8 +483,17 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
     std::vector<std::pair<unsigned, unsigned> > localInterferences;
     processPHIUnion(P, PHIUnion, DF, localInterferences);
     
+    // If one of the inputs is defined in the same block as the current PHI
+    // then we need to check for a local interference between that input and
+    // the PHI.
+    for (std::map<unsigned, unsigned>::iterator I = PHIUnion.begin(),
+         E = PHIUnion.end(); I != E; ++I)
+      if (MRI.getVRegDef(I->first)->getParent() == P->getParent())
+        localInterferences.push_back(std::make_pair(I->first,
+                                                    P->getOperand(0).getReg()));
+    
     // The dominator forest walk may have returned some register pairs whose
-    // interference cannot be determines from dominator analysis.  We now 
+    // interference cannot be determined from dominator analysis.  We now 
     // examine these pairs for local interferences.
     for (std::vector<std::pair<unsigned, unsigned> >::iterator I =
         localInterferences.begin(), E = localInterferences.end(); I != E; ++I) {
@@ -527,7 +536,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
       }
     }
     
-    // Add the renaming set for this PHI node to our overal renaming information
+    // Add the renaming set for this PHI node to our overall renaming information
     RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), PHIUnion));
     
     // Remember which registers are already renamed, so that we don't try to 
@@ -845,7 +854,6 @@ void StrongPHIElimination::mergeLiveIntervals(unsigned primary,
 }
 
 bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
-  
   LiveIntervals& LI = getAnalysis<LiveIntervals>();
   
   // Compute DFS numbers of each block
@@ -889,17 +897,21 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
     
     // If this is a dead PHI node, then remove it from LiveIntervals.
     unsigned DestReg = PInstr->getOperand(0).getReg();
+    LiveInterval& PI = LI.getInterval(DestReg);
     if (PInstr->registerDefIsDead(DestReg)) {
-      LiveInterval& PI = LI.getInterval(DestReg);
-      
       if (PI.containsOneValue()) {
         LI.removeInterval(DestReg);
       } else {
         unsigned idx = LI.getDefIndex(LI.getInstructionIndex(PInstr));
         PI.removeRange(*PI.getLiveRangeContaining(idx), true);
       }
+    } else {
+      // If the PHI is not dead, then the valno defined by the PHI
+      // now has an unknown def.
+      unsigned idx = LI.getDefIndex(LI.getInstructionIndex(PInstr));
+      PI.getLiveRangeContaining(idx)->valno->def = ~0U;
     }
-      
+    
     LI.RemoveMachineInstrFromMaps(PInstr);
     PInstr->eraseFromParent();
   }