Add support for updating LiveIntervals to MachineBasicBlock::SplitCriticalEdge().
authorCameron Zwarich <zwarich@apple.com>
Mon, 11 Feb 2013 09:24:47 +0000 (09:24 +0000)
committerCameron Zwarich <zwarich@apple.com>
Mon, 11 Feb 2013 09:24:47 +0000 (09:24 +0000)
This is currently a bit hairier than it needs to be, since depending on where the
split block resides the end ListEntry of the split block may be the end ListEntry
of the original block or a new entry. Some changes to the SlotIndexes updating
should make it possible to eliminate the two cases here.

This also isn't as optimized as it could be. In the future Liveinterval should
probably get a flag that indicates whether the LiveInterval is within a single
basic block. We could ignore all such intervals when splitting an edge.

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

lib/CodeGen/MachineBasicBlock.cpp
lib/CodeGen/PHIElimination.cpp

index 7457cd52012c54f7a5481bff00e2095da6d9d54c..7351302cc3221aa1aab006224f55115c6cd4a3c8 100644 (file)
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Assembly/Writer.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/DataLayout.h"
@@ -769,6 +771,72 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
     LV->addNewBlock(NMBB, this, Succ);
   }
 
+  if (LiveIntervals *LIS = P->getAnalysisIfAvailable<LiveIntervals>()) {
+    // After splitting the edge and updating SlotIndexes, live intervals may be
+    // in one of two situations, depending on whether this block was the last in
+    // the function. If the original block was the last in the function, all live
+    // intervals will end prior to the beginning of the new split block. If the
+    // original block was not at the end of the function, all live intervals will
+    // extend to the end of the new split block.
+
+    bool isLastMBB =
+      llvm::next(MachineFunction::iterator(NMBB)) == getParent()->end();
+
+    SlotIndex StartIndex = Indexes->getMBBEndIdx(this);
+    SlotIndex PrevIndex = StartIndex.getPrevSlot();
+    SlotIndex EndIndex = Indexes->getMBBEndIdx(NMBB);
+
+    // Find the registers used from NMBB in PHIs in Succ.
+    SmallSet<unsigned, 8> PHISrcRegs;
+    for (MachineBasicBlock::instr_iterator
+         I = Succ->instr_begin(), E = Succ->instr_end();
+         I != E && I->isPHI(); ++I) {
+      for (unsigned ni = 1, ne = I->getNumOperands(); ni != ne; ni += 2) {
+        if (I->getOperand(ni+1).getMBB() == NMBB) {
+          MachineOperand &MO = I->getOperand(ni);
+          unsigned Reg = MO.getReg();
+          PHISrcRegs.insert(Reg);
+          if (MO.isUndef() || !isLastMBB)
+            break;
+
+          LiveInterval &LI = LIS->getInterval(Reg);
+          VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
+          assert(VNI && "PHI sources should be live out of their predecessors.");
+          LI.addRange(LiveRange(StartIndex, EndIndex, VNI));
+        }
+      }
+    }
+
+    MachineRegisterInfo *MRI = &getParent()->getRegInfo();
+    for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
+      unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
+      if (PHISrcRegs.count(Reg) || !LIS->hasInterval(Reg))
+        continue;
+
+      LiveInterval &LI = LIS->getInterval(Reg);
+      if (!LI.liveAt(PrevIndex))
+        continue;
+
+      bool isLiveOut = false;
+      for (MachineBasicBlock::succ_iterator SI = succ_begin(),
+           SE = succ_end(); SI != SE; ++SI) {
+        MachineBasicBlock *SuccMBB = *SI == NMBB ? Succ : *SI;
+        if (LI.liveAt(LIS->getMBBStartIdx(SuccMBB))) {
+          isLiveOut = true;
+          break;
+        }
+      }
+
+      if (isLiveOut && isLastMBB) {
+        VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
+        assert(VNI && "LiveInterval should have VNInfo where it is live.");
+        LI.addRange(LiveRange(StartIndex, EndIndex, VNI));
+      } else if (!isLiveOut && !isLastMBB) {
+        LI.removeRange(StartIndex, EndIndex);
+      }
+    }
+  }
+
   if (MachineDominatorTree *MDT =
       P->getAnalysisIfAvailable<MachineDominatorTree>()) {
     // Update dominator information.
index bf2b95fd299ce8ce7bbb0091d50dc830a568e31c..aa84a60efdefce7b5026568a622418948ba898d9 100644 (file)
@@ -129,7 +129,7 @@ bool PHIElimination::runOnMachineFunction(MachineFunction &MF) {
 
   // Split critical edges to help the coalescer. This does not yet support
   // updating LiveIntervals, so we disable it.
-  if (!DisableEdgeSplitting && LV && !LIS) {
+  if (!DisableEdgeSplitting && (LV || LIS)) {
     MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
     for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
       Changed |= SplitPHIEdges(MF, *I, MLI);