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

Bill Wendling isanbard at gmail.com
Wed Sep 27 02:04:30 PDT 2006



Changes in directory llvm/lib/CodeGen:

PHIElimination.cpp updated: 1.45 -> 1.46
---
Log message:

PR878: http://llvm.org/PR878 : Instead of calculating the vreg to PHI use count everytime we get
a function, do it up front in linear time (going through all of the
instructions once). We create a map out of them. Then it's no problem to
use the information in it during elimination...


---
Diffs of the changes:  (+44 -24)

 PHIElimination.cpp |   68 ++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 44 insertions(+), 24 deletions(-)


Index: llvm/lib/CodeGen/PHIElimination.cpp
diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.45 llvm/lib/CodeGen/PHIElimination.cpp:1.46
--- llvm/lib/CodeGen/PHIElimination.cpp:1.45	Sun Aug 27 07:54:01 2006
+++ llvm/lib/CodeGen/PHIElimination.cpp	Wed Sep 27 04:04:15 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,8 +115,7 @@
 /// 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());
 
@@ -167,7 +166,9 @@
   // 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())] -= NumPreds;
 
   // Now loop over all of the incoming arguments, changing them to copy into
   // the IncomingReg register in the corresponding predecessor basic block.
@@ -219,7 +220,10 @@
     //
 
     // Is it used by any PHI instructions in this block?
-    bool ValueIsLive = VRegPHIUseCount[SrcReg] != 0;
+    bool ValueIsLive = 
+      VRegPHIUseCount[BBVRegPair(
+                        MPhi->getOperand(i).getMachineBasicBlock(),
+                        SrcReg)] != 0;
 
     std::vector<MachineBasicBlock*> OpSuccBlocks;
     
@@ -317,3 +321,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