Fix for PR929. The PHI nodes were being gone through for each instruction
authorBill Wendling <isanbard@gmail.com>
Tue, 3 Oct 2006 07:20:20 +0000 (07:20 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 3 Oct 2006 07:20:20 +0000 (07:20 +0000)
in a successor block for every block...resulting in some O(N^k) algorithm
which wasn't very good for performance. Calculating this information up
front and keeping it in a map made it much faster.

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

include/llvm/CodeGen/LiveVariables.h
lib/CodeGen/LiveVariables.cpp

index a61eca89c1525b866b0b040a9e4753f91ef4519d..95114c0b705e1371a665e2a1e764801c0765bb5f 100644 (file)
@@ -39,7 +39,7 @@ class MRegisterInfo;
 class LiveVariables : public MachineFunctionPass {
 public:
   /// VarInfo - This represents the regions where a virtual register is live in
-  /// the program.  We represent this with three difference pieces of
+  /// the program.  We represent this with three different pieces of
   /// information: the instruction that uniquely defines the value, the set of
   /// blocks the instruction is live into and live out of, and the set of 
   /// non-phi instructions that are the last users of the value.
@@ -136,9 +136,19 @@ private:   // Intermediate data structures
   MachineInstr **PhysRegInfo;
   bool          *PhysRegUsed;
 
+  typedef std::map<const MachineBasicBlock*,
+                   std::vector<unsigned> > PHIVarInfoMap;
+
+  PHIVarInfoMap PHIVarInfo;
+
   void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
   void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
 
+  /// analyzePHINodes - Gather information about the PHI nodes in here. In
+  /// particular, we want to map the variable information of a virtual
+  /// register which is used in a PHI node. We map that to the BB the vreg
+  /// is coming from.
+  void analyzePHINodes(const MachineFunction& Fn);
 public:
 
   virtual bool runOnMachineFunction(MachineFunction &MF);
index ddb6ded372d07beb740c2da9f136382b140a2804..5a73131b3e472f47ff7ff46f9309638ea86d3af2 100644 (file)
@@ -92,7 +92,6 @@ bool LiveVariables::RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const {
   return std::binary_search(I->second.begin(), I->second.end(), Reg);
 }
 
-
 void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
                                             MachineBasicBlock *MBB) {
   unsigned BBNum = MBB->getNumber();
@@ -212,6 +211,8 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
     HandlePhysRegDef(I->first, 0);
   }
 
+  analyzePHINodes(MF);
+
   // Calculate live variable information in depth first order on the CFG of the
   // function.  This guarantees that we will see the definition of a virtual
   // register before its uses due to dominance properties of SSA (except for PHI
@@ -288,26 +289,16 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
     // bottom of this basic block.  We check all of our successor blocks to see
     // if they have PHI nodes, and if so, we simulate an assignment at the end
     // of the current block.
-    for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
-           E = MBB->succ_end(); SI != E; ++SI) {
-      MachineBasicBlock *Succ = *SI;
-
-      // PHI nodes are guaranteed to be at the top of the block...
-      for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end();
-           MI != ME && MI->getOpcode() == TargetInstrInfo::PHI; ++MI) {
-        for (unsigned i = 1; ; i += 2) {
-          assert(MI->getNumOperands() > i+1 &&
-                 "Didn't find an entry for our predecessor??");
-          if (MI->getOperand(i+1).getMachineBasicBlock() == MBB) {
-            MachineOperand &MO = MI->getOperand(i);
-            VarInfo &VRInfo = getVarInfo(MO.getReg());
-            assert(VRInfo.DefInst && "Register use before def (or no def)!");
+    if (!PHIVarInfo[MBB].empty()) {
+      std::vector<unsigned>& VarInfoVec = PHIVarInfo[MBB];
 
-            // Only mark it alive only in the block we are representing.
-            MarkVirtRegAliveInBlock(VRInfo, MBB);
-            break;   // Found the PHI entry for this block.
-          }
-        }
+      for (std::vector<unsigned>::iterator I = VarInfoVec.begin(),
+             E = VarInfoVec.end(); I != E; ++I) {
+        VarInfo& VRInfo = getVarInfo(*I);
+        assert(VRInfo.DefInst && "Register use before def (or no def)!");
+
+        // Only mark it alive only in the block we are representing.
+        MarkVirtRegAliveInBlock(VRInfo, MBB);
       }
     }
 
@@ -362,6 +353,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
     assert(Visited.count(&*i) != 0 && "unreachable basic block found");
 #endif
 
+  PHIVarInfo.clear();
   return false;
 }
 
@@ -450,4 +442,17 @@ void LiveVariables::removeVirtualRegistersDead(MachineInstr *MI) {
   RegistersDead.erase(I);
 }
 
-
+/// analyzePHINodes - Gather information about the PHI nodes in here. In
+/// particular, we want to map the variable information of a virtual
+/// register which is used in a PHI node. We map that to the BB the vreg is
+/// coming from.
+///
+void LiveVariables::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)
+        PHIVarInfo[BBI->getOperand(i + 1).getMachineBasicBlock()].
+          push_back(BBI->getOperand(i).getReg());
+}