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

Bill Wendling isanbard at gmail.com
Thu Sep 28 00:10:40 PDT 2006



Changes in directory llvm/lib/CodeGen:

PHIElimination.cpp updated: 1.50 -> 1.51
---
Log message:

"Once more into the breach, dear friends, once more, or fill the wall up
with our English dead."

No! Really! Serious this time...It was how the vreg uses were being
adjusted that was causing hte Olden tests to fail. I corrected this and
the Olden and Regression tests all passed.


---
Diffs of the changes:  (+42 -26)

 PHIElimination.cpp |   68 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 42 insertions(+), 26 deletions(-)


Index: llvm/lib/CodeGen/PHIElimination.cpp
diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.50 llvm/lib/CodeGen/PHIElimination.cpp:1.51
--- llvm/lib/CodeGen/PHIElimination.cpp:1.50	Wed Sep 27 19:11:54 2006
+++ llvm/lib/CodeGen/PHIElimination.cpp	Thu Sep 28 02:10:24 2006
@@ -34,12 +34,15 @@
   
   struct VISIBILITY_HIDDEN PNE : public MachineFunctionPass {
     bool runOnMachineFunction(MachineFunction &Fn) {
+      analyzePHINodes(Fn);
+
       bool Changed = false;
 
       // Eliminate PHI instructions by inserting copies into predecessor blocks.
       for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
         Changed |= EliminatePHINodes(Fn, *I);
 
+      VRegPHIUseCount.clear();
       return Changed;
     }
 
@@ -54,15 +57,26 @@
     ///
     bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB);
     void LowerAtomicPHINode(MachineBasicBlock &MBB,
-                            MachineBasicBlock::iterator AfterPHIsIt,
-                            DenseMap<unsigned, VirtReg2IndexFunctor> &VUC);
+                            MachineBasicBlock::iterator AfterPHIsIt);
+
+    /// analyzePHINodes - Gather information about the PHI nodes in
+    /// here. In particular, we want to map the number of uses of a virtual
+    /// register which is used in a PHI node. We map that to the BB the
+    /// vreg is coming from. This is used later to determine when the vreg
+    /// is killed in the BB.
+    ///
+    void analyzePHINodes(const MachineFunction& Fn);
+
+    typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair;
+    typedef std::map<BBVRegPair, unsigned> VRegPHIUse;
+
+    VRegPHIUse VRegPHIUseCount;
   };
 
   RegisterPass<PNE> X("phi-node-elimination",
                       "Eliminate PHI nodes for register allocation");
 }
 
-
 const PassInfo *llvm::PHIEliminationID = X.getPassInfo();
 
 /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
@@ -72,20 +86,6 @@
   if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)
     return false;   // Quick exit for basic blocks without PHIs.
 
-  // VRegPHIUseCount - Keep track of the number of times each virtual register
-  // is used by PHI nodes in successors of this block.
-  DenseMap<unsigned, VirtReg2IndexFunctor> VRegPHIUseCount;
-  VRegPHIUseCount.grow(MF.getSSARegMap()->getLastVirtReg());
-
-  for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin(),
-         E = MBB.pred_end(); PI != E; ++PI)
-    for (MachineBasicBlock::succ_iterator SI = (*PI)->succ_begin(),
-           E = (*PI)->succ_end(); SI != E; ++SI)
-      for (MachineBasicBlock::iterator BBI = (*SI)->begin(), E = (*SI)->end();
-           BBI != E && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
-        for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
-          VRegPHIUseCount[BBI->getOperand(i).getReg()]++;
-      
   // Get an iterator to the first instruction after the last PHI node (this may
   // also be the end of the basic block).
   MachineBasicBlock::iterator AfterPHIsIt = MBB.begin();
@@ -93,9 +93,9 @@
          AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI)
     ++AfterPHIsIt;    // Skip over all of the PHI nodes...
 
-  while (MBB.front().getOpcode() == TargetInstrInfo::PHI) {
-    LowerAtomicPHINode(MBB, AfterPHIsIt, VRegPHIUseCount);
-  }
+  while (MBB.front().getOpcode() == TargetInstrInfo::PHI)
+    LowerAtomicPHINode(MBB, AfterPHIsIt);
+
   return true;
 }
 
@@ -115,14 +115,13 @@
 /// atomic execution of PHIs.  This lowering method is always correct all of the
 /// time.
 void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,
-                             MachineBasicBlock::iterator AfterPHIsIt,
-                   DenseMap<unsigned, VirtReg2IndexFunctor> &VRegPHIUseCount) {
+                             MachineBasicBlock::iterator AfterPHIsIt) {
   // Unlink the PHI node from the basic block, but don't delete the PHI yet.
   MachineInstr *MPhi = MBB.remove(MBB.begin());
 
   unsigned DestReg = MPhi->getOperand(0).getReg();
 
-  // Create a new register for the incoming PHI arguments/
+  // Create a new register for the incoming PHI arguments.
   MachineFunction &MF = *MBB.getParent();
   const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg);
   unsigned IncomingReg = MF.getSSARegMap()->createVirtualRegister(RC);
@@ -165,9 +164,10 @@
 
   // Adjust the VRegPHIUseCount map to account for the removal of this PHI
   // node.
-  unsigned NumPreds = (MPhi->getNumOperands()-1)/2;
   for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2)
-    VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= NumPreds;
+    --VRegPHIUseCount[BBVRegPair(
+                        MPhi->getOperand(i + 1).getMachineBasicBlock(),
+                        MPhi->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.
@@ -219,7 +219,7 @@
     //
 
     // Is it used by any PHI instructions in this block?
-    bool ValueIsLive = VRegPHIUseCount[SrcReg] != 0;
+    bool ValueIsLive = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0;
 
     std::vector<MachineBasicBlock*> OpSuccBlocks;
     
@@ -317,3 +317,19 @@
   delete MPhi;
   ++NumAtomic;
 }
+
+/// analyzePHINodes - Gather information about the PHI nodes in here. In
+/// particular, we want to map the number of uses of a virtual register which is
+/// used in a PHI node. We map that to the BB the vreg is coming from. This is
+/// used later to determine when the vreg is killed in the BB.
+///
+void PNE::analyzePHINodes(const MachineFunction& Fn) {
+  for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
+       I != E; ++I)
+    for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
+         BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
+      for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
+        ++VRegPHIUseCount[BBVRegPair(
+                            BBI->getOperand(i + 1).getMachineBasicBlock(),
+                            BBI->getOperand(i).getReg())];
+}






More information about the llvm-commits mailing list