[llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp

Owen Anderson resistor at mac.com
Wed Jan 9 16:47:01 PST 2008


Author: resistor
Date: Wed Jan  9 18:47:01 2008
New Revision: 45799

URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev
Log:
Add more comments explaining the basics of how the decision of when to rename and when to insert
copies is made.

Modified:
    llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp

Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original)
+++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan  9 18:47:01 2008
@@ -390,7 +390,10 @@
   return interference;
 }
 
-/// processBlock - Eliminate PHIs in the given block
+/// processBlock - Determine how to break up PHIs in the current block.  Each
+/// PHI is broken up by some combination of renaming its operands and inserting
+/// copies.  This method is responsible for determining which operands receive
+/// which treatment.
 void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
   LiveVariables& LV = getAnalysis<LiveVariables>();
   
@@ -398,21 +401,37 @@
   // before the current one.
   std::set<unsigned> ProcessedNames;
   
+  // Iterate over all the PHI nodes in this block
   MachineBasicBlock::iterator P = MBB->begin();
   while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) {
     LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand(0).getReg());
 
     unsigned DestReg = P->getOperand(0).getReg();
 
-    // Hold the names that are currently in the candidate set.
+    // PHIUnion is the set of incoming registers to the PHI node that
+    // are going to be renames rather than having copies inserted.  This set
+    // is refinded over the course of this function.  UnionedBlocks is the set
+    // of corresponding MBBs.
     std::set<unsigned> PHIUnion;
     std::set<MachineBasicBlock*> UnionedBlocks;
   
+    // Iterate over the operands of the PHI node
     for (int i = P->getNumOperands() - 1; i >= 2; i-=2) {
       unsigned SrcReg = P->getOperand(i-1).getReg();
       LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg);
     
-      // Check for trivial interferences
+      // Check for trivial interferences via liveness information, allowing us
+      // to avoid extra work later.  Any registers that interfere cannot both
+      // be in the renaming set, so choose one and add copies for it instead.
+      // The conditions are:
+      //   1) if the operand is live into the PHI node's block OR
+      //   2) if the PHI node is live out of the operand's defining block OR
+      //   3) if the operand is itself a PHI node and the original PHI is
+      //      live into the operand's defining block OR
+      //   4) if the operand is already being renamed for another PHI node
+      //      in this block OR
+      //   5) if any two operands are defined in the same block, insert copies
+      //      for one of them
       if (isLiveIn(SrcInfo, P->getParent()) ||
           isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) ||
           ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI &&
@@ -420,24 +439,32 @@
           ProcessedNames.count(SrcReg) ||
           UnionedBlocks.count(SrcInfo.DefInst->getParent())) {
         
-        // add a copy from a_i to p in Waiting[From[a_i]]
+        // Add a copy for the selected register
         MachineBasicBlock* From = P->getOperand(i).getMBB();
         Waiting[From].insert(std::make_pair(SrcReg, DestReg));
         UsedByAnother.insert(SrcReg);
       } else {
+        // Otherwise, add it to the renaming set
         PHIUnion.insert(SrcReg);
         UnionedBlocks.insert(SrcInfo.DefInst->getParent());
       }
     }
     
+    // Compute the dominator forest for the renaming set.  This is a forest
+    // where the nodes are the registers and the edges represent dominance 
+    // relations between the defining blocks of the registers
     std::vector<StrongPHIElimination::DomForestNode*> DF = 
                                                      computeDomForest(PHIUnion);
     
-    // Walk DomForest to resolve interferences
+    // Walk DomForest to resolve interferences at an inter-block level.  This
+    // will remove registers from the renaming set (and insert copies for them)
+    // if interferences are found.
     std::vector<std::pair<unsigned, unsigned> > localInterferences;
     processPHIUnion(P, PHIUnion, DF, localInterferences);
     
-    // Check for local interferences
+    // The dominator forest walk may have returned some register pairs whose
+    // interference cannot be determines 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) {
       std::pair<unsigned, unsigned> p = *I;
@@ -481,10 +508,13 @@
       }
     }
     
-    // Cache renaming information
+    // Add the renaming set for this PHI node to our overal 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 
+    // rename them for another PHI node in this block
     ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end());
+    
     ++P;
   }
 }





More information about the llvm-commits mailing list