Use a new VRegPHIUseCount to compute uses of PHI values by other phi values
authorChris Lattner <sabre@nondot.org>
Mon, 10 May 2004 19:06:37 +0000 (19:06 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 10 May 2004 19:06:37 +0000 (19:06 +0000)
in the basic block being processed.  This fixes PhiElimination on kimwitu++
from taking 105s to taking a much more reasonable 0.6s (in a debug build).

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

lib/CodeGen/PHIElimination.cpp

index ffde4beaf0a221c12a867f78ff15cc65aa92a75b..5457dedbf26c731b8c2332943f168f6f449bca2e 100644 (file)
@@ -68,12 +68,21 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {
   const TargetInstrInfo &MII = MF.getTarget().getInstrInfo();
   const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
 
+  // VRegPHIUseCount - Keep track of the number of times each virtual register
+  // is used by PHI nodes in this block.
+  std::map<unsigned, unsigned> VRegPHIUseCount;
+
   // Get an iterator to the first instruction after the last PHI node (this may
-  // allso be the end of the basic block).
+  // allso be the end of the basic block).  While we are scanning the PHIs,
+  // populate the VRegPHIUseCount map.
   MachineBasicBlock::iterator AfterPHIsIt = MBB.begin();
   while (AfterPHIsIt != MBB.end() &&
-         AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI)
+         AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI) {
+    MachineInstr *PHI = AfterPHIsIt;
+    for (unsigned i = 1, e = PHI->getNumOperands(); i < e; i += 2)
+      VRegPHIUseCount[PHI->getOperand(i).getReg()]++;
     ++AfterPHIsIt;    // Skip over all of the PHI nodes...
+  }
 
   while (MBB.front().getOpcode() == TargetInstrInfo::PHI) {
     // Unlink the PHI node from the basic block... but don't delete the PHI yet
@@ -134,6 +143,11 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {
       }
     }
 
+    // Adjust the VRegPHIUseCount map to account for the removal of this PHI
+    // node.
+    for (unsigned i = 1; i != MI->getNumOperands(); i += 2)
+      VRegPHIUseCount[MI->getOperand(i).getReg()]--;
+
     // Now loop over all of the incoming arguments, changing them to copy into
     // the IncomingReg register in the corresponding predecessor basic block.
     //
@@ -217,18 +231,11 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {
               }
 
             // Is it used by any PHI instructions in this block?
-            if (ValueIsLive) break;
-
-            // Loop over all of the PHIs in this successor, checking to see if
-            // the register is being used...
-            for (MachineBasicBlock::iterator BBI = MBB->begin(), E=MBB->end();
-                 BBI != E && BBI->getOpcode() == TargetInstrInfo::PHI;
-                 ++BBI)
-              for (unsigned i = 1, e = BBI->getNumOperands(); i < e; i += 2)
-                if (BBI->getOperand(i).getReg() == SrcReg) {
-                  ValueIsLive = true;
-                  break;
-                }
+            if (!ValueIsLive) {
+              std::map<unsigned,unsigned>::iterator I =
+                VRegPHIUseCount.find(SrcReg);
+              ValueIsLive = I != VRegPHIUseCount.end() && I->second;
+            }
           }
           
           // Okay, if we now know that the value is not live out of the block,