Be more clever about calculating live variables through new basic blocks.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 21 Nov 2009 02:05:21 +0000 (02:05 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 21 Nov 2009 02:05:21 +0000 (02:05 +0000)
When splitting a critical edge, the registers live through the edge are:

- Used in a PHI instruction, or
- Live out from the predecessor, and
- Live in to the successor.

This allows the coalescer to eliminate even more phi joins.

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

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

index b2be569bc10a7c6810771e4cf0493bfe656788fc..a37abd4645529a0ea328117fd303a1669efa18be 100644 (file)
@@ -107,6 +107,13 @@ public:
     /// findKill - Find a kill instruction in MBB. Return NULL if none is found.
     MachineInstr *findKill(const MachineBasicBlock *MBB) const;
 
+    /// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
+    /// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
+    /// MBB, it is not considered live in.
+    bool isLiveIn(const MachineBasicBlock &MBB,
+                  unsigned Reg,
+                  MachineRegisterInfo &MRI);
+
     void dump() const;
   };
 
@@ -267,11 +274,17 @@ public:
   void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
                         MachineInstr *MI);
 
-  /// addNewBlock - Add a new basic block BB as an empty succcessor to
-  /// DomBB. All variables that are live out of DomBB will be marked as passing
-  /// live through BB. This method assumes that the machine code is still in SSA
-  /// form.
-  void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB);
+  bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
+    return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
+  }
+
+  /// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
+  /// variables that are live out of DomBB and live into SuccBB will be marked
+  /// as passing live through BB. This method assumes that the machine code is
+  /// still in SSA form.
+  void addNewBlock(MachineBasicBlock *BB,
+                   MachineBasicBlock *DomBB,
+                   MachineBasicBlock *SuccBB);
 };
 
 } // End llvm namespace
index 16a79bb54e97678483f6d6c0e5e314b0ea25bf8b..bfc2d08528a197ad1666797a45aed282360db50b 100644 (file)
@@ -656,35 +656,45 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
           .push_back(BBI->getOperand(i).getReg());
 }
 
+bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
+                                      unsigned Reg,
+                                      MachineRegisterInfo &MRI) {
+  unsigned Num = MBB.getNumber();
+
+  // Reg is live-through.
+  if (AliveBlocks.test(Num))
+    return true;
+
+  // Registers defined in MBB cannot be live in.
+  const MachineInstr *Def = MRI.getVRegDef(Reg);
+  if (Def && Def->getParent() == &MBB)
+    return false;
+
+ // Reg was not defined in MBB, was it killed here?
+  return findKill(&MBB);
+}
+
 /// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All
 /// variables that are live out of DomBB will be marked as passing live through
 /// BB.
 void LiveVariables::addNewBlock(MachineBasicBlock *BB,
-                                MachineBasicBlock *DomBB) {
+                                MachineBasicBlock *DomBB,
+                                MachineBasicBlock *SuccBB) {
   const unsigned NumNew = BB->getNumber();
-  const unsigned NumDom = DomBB->getNumber();
+
+  // All registers used by PHI nodes in SuccBB must be live through BB.
+  for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(),
+         BBE = SuccBB->end();
+       BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
+    for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
+      if (BBI->getOperand(i+1).getMBB() == BB)
+        getVarInfo(BBI->getOperand(i).getReg()).AliveBlocks.set(NumNew);
 
   // Update info for all live variables
   for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
          E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
     VarInfo &VI = getVarInfo(Reg);
-
-    // Anything live through DomBB is also live through BB.
-    if (VI.AliveBlocks.test(NumDom)) {
+    if (!VI.AliveBlocks.test(NumNew) && VI.isLiveIn(*SuccBB, Reg, *MRI))
       VI.AliveBlocks.set(NumNew);
-      continue;
-    }
-
-    // Variables not defined in DomBB cannot be live out.
-    const MachineInstr *Def = MRI->getVRegDef(Reg);
-    if (!Def || Def->getParent() != DomBB)
-      continue;
-
-    // Killed by DomBB?
-    if (VI.findKill(DomBB))
-      continue;
-
-    // This register is defined in DomBB and live out
-    VI.AliveBlocks.set(NumNew);
   }
 }
index 53ab8b03ee772fae84ce4c9eef07039d5d64bc70..2e30cc6abd3288c3a86b401245a57bac0d5885d6 100644 (file)
@@ -353,7 +353,7 @@ bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF,
       // We break edges when registers are live out from the predecessor block
       // (not considering PHI nodes). If the register is live in to this block
       // anyway, we would gain nothing from splitting.
-      if (isLiveOut(Reg, *PreMBB, LV) && !isLiveIn(Reg, MBB, LV))
+      if (!LV.isLiveIn(Reg, MBB) && isLiveOut(Reg, *PreMBB, LV))
         SplitCriticalEdge(PreMBB, &MBB);
     }
   }
@@ -406,22 +406,6 @@ bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
   return false;
 }
 
-bool llvm::PHIElimination::isLiveIn(unsigned Reg, const MachineBasicBlock &MBB,
-                                    LiveVariables &LV) {
-  LiveVariables::VarInfo &VI = LV.getVarInfo(Reg);
-
-  if (VI.AliveBlocks.test(MBB.getNumber()))
-    return true;
-
-  // defined in MBB?
-  const MachineInstr *Def = MRI->getVRegDef(Reg);
-  if (Def && Def->getParent() == &MBB)
-    return false;
-
-  // killed in MBB?
-  return VI.findKill(&MBB);
-}
-
 MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
                                                      MachineBasicBlock *B) {
   assert(A && B && "Missing MBB end point");
@@ -463,7 +447,7 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
         i->getOperand(ni+1).setMBB(NMBB);
 
   if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>())
-    LV->addNewBlock(NMBB, A);
+    LV->addNewBlock(NMBB, A, B);
 
   if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>())
     MDT->addNewBlock(NMBB, A);
index f8c9fe728457023124eed09ca9d8aea9be48e95a..f5872cbe8d5483a30cf1adeda36a13ec4ffd14c1 100644 (file)
@@ -99,12 +99,6 @@ namespace llvm {
     bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
                    LiveVariables &LV);
 
-    /// isLiveIn - Determine if Reg is live in to MBB, not considering PHI
-    /// source registers. This means that Reg is either killed by MBB or passes
-    /// through it.
-    bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB,
-                  LiveVariables &LV);
-
     /// SplitCriticalEdge - Split a critical edge from A to B by
     /// inserting a new MBB. Update branches in A and PHI instructions
     /// in B. Return the new block.