Add LiveIntervals::getLastSplitPoint().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 4 Feb 2011 19:33:11 +0000 (19:33 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 4 Feb 2011 19:33:11 +0000 (19:33 +0000)
A live range cannot be split everywhere in a basic block. A split must go before
the first terminator, and if the variable is live into a landing pad, the split
must happen before the call that can throw.

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

include/llvm/CodeGen/LiveIntervalAnalysis.h
include/llvm/CodeGen/MachineBasicBlock.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/MachineBasicBlock.cpp
lib/CodeGen/SplitKit.cpp

index e4fc062dc7bc3f9e0631dfb3fced573b335b849e..70f570212a073b47145ec7bdfba19bf34537ba10 100644 (file)
@@ -308,6 +308,12 @@ namespace llvm {
     /// within a single basic block.
     bool intervalIsInOneMBB(const LiveInterval &li) const;
 
+    /// getLastSplitPoint - Return the last possible insertion point in mbb for
+    /// spilling and splitting code. This is the first terminator, or the call
+    /// instruction if li is live into a landing pad successor.
+    MachineBasicBlock::iterator getLastSplitPoint(const LiveInterval &li,
+                                                  MachineBasicBlock *mbb);
+
   private:
     /// computeIntervals - Compute live intervals.
     void computeIntervals();
index 16cb5c9ce85da5087c6a3765f828747e5ed828b7..1785451c7ec505c4c8edc572663db3144b25e33b 100644 (file)
@@ -224,6 +224,10 @@ public:
   /// this basic block is entered via an exception handler.
   void setIsLandingPad() { IsLandingPad = true; }
 
+  /// getLandingPadSuccessor - If this block has a successor that is a landing
+  /// pad, return it. Otherwise return NULL.
+  const MachineBasicBlock *getLandingPadSuccessor() const;
+
   // Code Layout methods.
   
   /// moveBefore/moveAfter - move 'this' block before or after the specified
index 000fc40ac466fbd7857ecf48493ee6b3237ae9b7..32c553ff12d0ff6bd3eb7d7e3a004ad487c69f25 100644 (file)
@@ -746,6 +746,28 @@ LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
 // Register allocator hooks.
 //
 
+MachineBasicBlock::iterator
+LiveIntervals::getLastSplitPoint(const LiveInterval &li,
+                                 MachineBasicBlock *mbb) {
+  const MachineBasicBlock *lpad = mbb->getLandingPadSuccessor();
+
+  // If li is not live into a landing pad, we can insert spill code before the
+  // first terminator.
+  if (!lpad || !isLiveInToMBB(li, lpad))
+    return mbb->getFirstTerminator();
+
+  // When there is a landing pad, spill code must go before the call instruction
+  // that can throw.
+  MachineBasicBlock::iterator I = mbb->end(), B = mbb->begin();
+  while (I != B) {
+    --I;
+    if (I->getDesc().isCall())
+      return I;
+  }
+  assert(0 && "Block with landing pad successor contains no call instruction");
+  return mbb->getFirstTerminator();
+}
+
 /// getReMatImplicitUse - If the remat definition MI has one (for now, we only
 /// allow one) virtual register operand, then its uses are implicitly using
 /// the register. Returns the virtual register.
index 95b8f86df8d9a8c2cf3846f40fb7d5ceb6c9b469..ccbff0af5b2ca4cf19d621f4afcf5dbe9b4411cd 100644 (file)
@@ -175,6 +175,16 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
   return end();
 }
 
+const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {
+  // A block with a landing pad successor only has one other successor.
+  if (succ_size() > 2)
+    return 0;
+  for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
+    if ((*I)->isLandingPad())
+      return *I;
+  return 0;
+}
+
 void MachineBasicBlock::dump() const {
   print(dbgs());
 }
index e4a82adfb32b3adfd9d084de3a46054c10c9634d..68f782d280562c787ad4c796d783ab9019bff115 100644 (file)
@@ -826,7 +826,7 @@ SlotIndex SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
   }
   DEBUG(dbgs() << ": valno " << ParentVNI->id);
   VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Last, MBB,
-                              MBB.getFirstTerminator());
+                              LIS.getLastSplitPoint(Edit.getParent(), &MBB));
   RegAssign.insert(VNI->def, End, OpenIdx);
   DEBUG(dump());
   return VNI->def;