[llvm-commits] [llvm] r134047 - in /llvm/trunk/lib/CodeGen: RegAllocGreedy.cpp SplitKit.cpp SplitKit.h

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Jun 28 17:24:24 PDT 2011


Author: stoklund
Date: Tue Jun 28 19:24:24 2011
New Revision: 134047

URL: http://llvm.org/viewvc/llvm-project?rev=134047&view=rev
Log:
Rewrite RAGreedy::splitAroundRegion, now with cool ASCII art.

This function has to deal with a lot of special cases, and the old
version got it wrong sometimes. In particular, it would sometimes leave
multiple uses in the stack interval in a single block. That causes bad
code with multiple reloads in the same basic block.

The new version handles block entry and exit in a single pass. It first
eliminates all the easy cases, and then goes on to create a local
interval for the blocks with difficult interference. Previously, we
would only create the local interval for completely isolated blocks.

It can happen that the stack interval becomes completely empty because
we could allocate a register in all edge bundles, and the new local
intervals deal with the interference. The empty stack interval is
harmless, but we need to remove a SplitKit assertion that checks for
empty intervals.

Modified:
    llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp
    llvm/trunk/lib/CodeGen/SplitKit.cpp
    llvm/trunk/lib/CodeGen/SplitKit.h

Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=134047&r1=134046&r2=134047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Tue Jun 28 19:24:24 2011
@@ -763,32 +763,46 @@
   // Create the main cross-block interval.
   const unsigned MainIntv = SE->openIntv();
 
-  // First add all defs that are live out of a block.
+  // First handle all the blocks with uses.
   ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
   for (unsigned i = 0; i != UseBlocks.size(); ++i) {
     const SplitAnalysis::BlockInfo &BI = UseBlocks[i];
-    bool RegIn  = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
-    bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
+    bool RegIn  = BI.LiveIn &&
+                  LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
+    bool RegOut = BI.LiveOut &&
+                  LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
 
     // Create separate intervals for isolated blocks with multiple uses.
-    if (!RegIn && !RegOut && BI.FirstUse != BI.LastUse) {
+    //
+    //     |---o---o---|    Enter and leave on the stack.
+    //     ____-----____    Create local interval for uses.
+    //
+    //     |   o---o---|    Defined in block, leave on stack.
+    //         -----____    Create local interval for uses.
+    //
+    //     |---o---x   |    Enter on stack, killed in block.
+    //     ____-----        Create local interval for uses.
+    //
+    if (!RegIn && !RegOut) {
       DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " isolated.\n");
-      SE->splitSingleBlock(BI);
-      SE->selectIntv(MainIntv);
+      if (!BI.isOneInstr()) {
+        SE->splitSingleBlock(BI);
+        SE->selectIntv(MainIntv);
+      }
       continue;
     }
 
-    // Should the register be live out?
-    if (!BI.LiveOut || !RegOut)
-      continue;
-
     SlotIndex Start, Stop;
     tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
     Intf.moveToBlock(BI.MBB->getNumber());
-    DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " -> EB#"
-                 << Bundles->getBundle(BI.MBB->getNumber(), 1)
+    DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0)
+                 << (RegIn ? " => " : " -- ")
+                 << "BB#" << BI.MBB->getNumber()
+                 << (RegOut ? " => " : " -- ")
+                 << " EB#" << Bundles->getBundle(BI.MBB->getNumber(), 1)
                  << " [" << Start << ';'
                  << SA->getLastSplitPoint(BI.MBB->getNumber()) << '-' << Stop
+                 << ") uses [" << BI.FirstUse << ';' << BI.LastUse
                  << ") intf [" << Intf.first() << ';' << Intf.last() << ')');
 
     // The interference interval should either be invalid or overlap MBB.
@@ -797,150 +811,266 @@
     assert((!Intf.hasInterference() || Intf.last() > Start)
            && "Bad interference");
 
-    // Check interference leaving the block.
+    // We are now ready to decide where to split in the current block.  There
+    // are many variables guiding the decision:
+    //
+    // - RegIn / RegOut: The global splitting algorithm's decisions for our
+    //   ingoing and outgoing bundles.
+    //
+    // - BI.BlockIn / BI.BlockOut: Is the live range live-in and/or live-out
+    //   from this block.
+    //
+    // - Intf.hasInterference(): Is there interference in this block.
+    //
+    // - Intf.first() / Inft.last(): The range of interference.
+    //
+    // The live range should be split such that MainIntv is live-in when RegIn
+    // is set, and live-out when RegOut is set.  MainIntv should never overlap
+    // the interference, and the stack interval should never have more than one
+    // use per block.
+
+    // No splits can be inserted after LastSplitPoint, overlap instead.
+    SlotIndex LastSplitPoint = Stop;
+    if (BI.LiveOut)
+      LastSplitPoint = SA->getLastSplitPoint(BI.MBB->getNumber());
+
+    // At this point, we know that either RegIn or RegOut is set. We dealt with
+    // the all-stack case above.
+
+    // Blocks without interference are relatively easy.
     if (!Intf.hasInterference()) {
-      // Block is interference-free.
-      DEBUG(dbgs() << ", no interference");
-      if (!BI.LiveThrough) {
-        DEBUG(dbgs() << ", not live-through.\n");
-        SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
-        continue;
-      }
-      if (!RegIn) {
-        // Block is live-through, but entry bundle is on the stack.
-        // Reload just before the first use.
-        DEBUG(dbgs() << ", not live-in, enter before first use.\n");
-        SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
-        continue;
-      }
-      DEBUG(dbgs() << ", live-through.\n");
-      continue;
-    }
+      DEBUG(dbgs() << ", no interference.\n");
+      SE->selectIntv(MainIntv);
+      // The easiest case has MainIntv live through.
+      //
+      //     |---o---o---|    Live-in, live-out.
+      //     =============    Use MainIntv everywhere.
+      //
+      SlotIndex From = Start, To = Stop;
+
+      // Block entry. Reload before the first use if MainIntv is not live-in.
+      //
+      //     |---o--    Enter on stack.
+      //     ____===    Reload before first use.
+      //
+      //     |   o--    Defined in block.
+      //         ===    Use MainIntv from def.
+      //
+      if (!RegIn)
+        From = SE->enterIntvBefore(BI.FirstUse);
 
-    // Block has interference.
-    DEBUG(dbgs() << ", interference to " << Intf.last());
+      // Block exit. Handle cases where MainIntv is not live-out.
+      if (!BI.LiveOut)
+        //
+        //     --x   |    Killed in block.
+        //     ===        Use MainIntv up to kill.
+        //
+        To = SE->leaveIntvAfter(BI.LastUse);
+      else if (!RegOut) {
+        //
+        //     --o---|    Live-out on stack.
+        //     ===____    Use MainIntv up to last use, switch to stack.
+        //
+        //     -----o|    Live-out on stack, last use after last split point.
+        //     ======     Extend MainIntv to last use, overlapping.
+        //       \____    Copy to stack interval before last split point.
+        //
+        if (BI.LastUse < LastSplitPoint)
+          To = SE->leaveIntvAfter(BI.LastUse);
+        else {
+          // The last use is after the last split point, it is probably an
+          // indirect branch.
+          To = SE->leaveIntvBefore(LastSplitPoint);
+          // Run a double interval from the split to the last use.  This makes
+          // it possible to spill the complement without affecting the indirect
+          // branch.
+          SE->overlapIntv(To, BI.LastUse);
+        }
+      }
 
-    if (!BI.LiveThrough && Intf.last() <= BI.FirstUse) {
-      // The interference doesn't reach the outgoing segment.
-      DEBUG(dbgs() << " doesn't affect def from " << BI.FirstUse << '\n');
-      SE->useIntv(BI.FirstUse, Stop);
+      // Paint in MainIntv liveness for this block.
+      SE->useIntv(From, To);
       continue;
     }
 
-    SlotIndex LastSplitPoint = SA->getLastSplitPoint(BI.MBB->getNumber());
-    if (Intf.last().getBoundaryIndex() < BI.LastUse) {
-      // There are interference-free uses at the end of the block.
-      // Find the first use that can get the live-out register.
-      SmallVectorImpl<SlotIndex>::const_iterator UI =
-        std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(),
-                         Intf.last().getBoundaryIndex());
-      assert(UI != SA->UseSlots.end() && "Couldn't find last use");
-      SlotIndex Use = *UI;
-      assert(Use <= BI.LastUse && "Couldn't find last use");
-      // Only attempt a split befroe the last split point.
-      if (Use.getBaseIndex() <= LastSplitPoint) {
-        DEBUG(dbgs() << ", free use at " << Use << ".\n");
-        SlotIndex SegStart = SE->enterIntvBefore(Use);
-        assert(SegStart >= Intf.last() && "Couldn't avoid interference");
-        assert(SegStart < LastSplitPoint && "Impossible split point");
-        SE->useIntv(SegStart, Stop);
-        continue;
-      }
-    }
+    // We are now looking at a block with interference, and we know that either
+    // RegIn or RegOut is set.
+    assert(Intf.hasInterference() && (RegIn || RegOut) && "Bad invariant");
 
-    // Interference is after the last use.
-    DEBUG(dbgs() << " after last use.\n");
-    SlotIndex SegStart = SE->enterIntvAtEnd(*BI.MBB);
-    assert(SegStart >= Intf.last() && "Couldn't avoid interference");
-  }
+    // If the live range is not live through the block, it is possible that the
+    // interference doesn't even overlap.  Deal with those cases first.  Since
+    // no copy instructions are required, we can tolerate interference starting
+    // or ending at the same instruction that kills or defines our live range.
 
-  // Now all defs leading to live bundles are handled, do everything else.
-  for (unsigned i = 0; i != UseBlocks.size(); ++i) {
-    const SplitAnalysis::BlockInfo &BI = UseBlocks[i];
-    bool RegIn  = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
-    bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
+    // Live-in, killed before interference.
+    //
+    //               ~~~    Interference after kill.
+    //     |---o---x   |    Killed in block.
+    //     =========        Use MainIntv everywhere.
+    //
+    if (RegIn && !BI.LiveOut && BI.LastUse <= Intf.first()) {
+      DEBUG(dbgs() << ", live-in, killed before interference.\n");
+      SE->selectIntv(MainIntv);
+      SlotIndex To = SE->leaveIntvAfter(BI.LastUse);
+      SE->useIntv(Start, To);
+      continue;
+    }
 
-    // Is the register live-in?
-    if (!BI.LiveIn || !RegIn)
+    // Live-out, defined after interference.
+    //
+    //     ~~~              Interference before def.
+    //     |   o---o---|    Defined in block.
+    //         =========    Use MainIntv everywhere.
+    //
+    if (RegOut && !BI.LiveIn && BI.FirstUse >= Intf.last()) {
+      DEBUG(dbgs() << ", live-out, defined after interference.\n");
+      SE->selectIntv(MainIntv);
+      SlotIndex From = SE->enterIntvBefore(BI.FirstUse);
+      SE->useIntv(From, Stop);
       continue;
+    }
 
-    // We have an incoming register. Check for interference.
-    SlotIndex Start, Stop;
-    tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
-    Intf.moveToBlock(BI.MBB->getNumber());
-    DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0)
-                 << " -> BB#" << BI.MBB->getNumber() << " [" << Start << ';'
-                 << SA->getLastSplitPoint(BI.MBB->getNumber()) << '-' << Stop
-                 << ')');
+    // The interference is now known to overlap the live range, but it may
+    // still be easy to avoid if all the interference is on one side of the
+    // uses, and we enter or leave on the stack.
 
-    // Check interference entering the block.
-    if (!Intf.hasInterference()) {
-      // Block is interference-free.
-      DEBUG(dbgs() << ", no interference");
-      if (!BI.LiveThrough) {
-        DEBUG(dbgs() << ", killed in block.\n");
-        SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
-        continue;
-      }
-      if (!RegOut) {
-        SlotIndex LastSplitPoint = SA->getLastSplitPoint(BI.MBB->getNumber());
-        // Block is live-through, but exit bundle is on the stack.
-        // Spill immediately after the last use.
-        if (BI.LastUse < LastSplitPoint) {
-          DEBUG(dbgs() << ", uses, stack-out.\n");
-          SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
-          continue;
-        }
-        // The last use is after the last split point, it is probably an
-        // indirect jump.
-        DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point "
-                     << LastSplitPoint << ", stack-out.\n");
-        SlotIndex SegEnd = SE->leaveIntvBefore(LastSplitPoint);
-        SE->useIntv(Start, SegEnd);
-        // Run a double interval from the split to the last use.
-        // This makes it possible to spill the complement without affecting the
-        // indirect branch.
-        SE->overlapIntv(SegEnd, BI.LastUse);
-        continue;
+    // Live-out on stack, interference after last use.
+    //
+    //               ~~~    Interference after last use.
+    //     |---o---o---|    Live-out on stack.
+    //     =========____    Leave MainIntv after last use.
+    //
+    //                 ~    Interference after last use.
+    //     |---o---o--o|    Live-out on stack, late last use.
+    //     =========____    Copy to stack after LSP, overlap MainIntv.
+    //
+    if (!RegOut && Intf.first() > BI.LastUse.getBoundaryIndex()) {
+      assert(RegIn && "Stack-in, stack-out should already be handled");
+      if (BI.LastUse < LastSplitPoint) {
+        DEBUG(dbgs() << ", live-in, stack-out, interference after last use.\n");
+        SE->selectIntv(MainIntv);
+        SlotIndex To = SE->leaveIntvAfter(BI.LastUse);
+        assert(To <= Intf.first() && "Expected to avoid interference");
+        SE->useIntv(Start, To);
+      } else {
+        DEBUG(dbgs() << ", live-in, stack-out, avoid last split point\n");
+        SE->selectIntv(MainIntv);
+        SlotIndex To = SE->leaveIntvBefore(LastSplitPoint);
+        assert(To <= Intf.first() && "Expected to avoid interference");
+        SE->overlapIntv(To, BI.LastUse);
+        SE->useIntv(Start, To);
       }
-      // Register is live-through.
-      DEBUG(dbgs() << ", uses, live-through.\n");
-      SE->useIntv(Start, Stop);
       continue;
     }
 
-    // Block has interference.
-    DEBUG(dbgs() << ", interference from " << Intf.first());
-
-    if (!BI.LiveThrough && Intf.first() >= BI.LastUse) {
-      // The interference doesn't reach the outgoing segment.
-      DEBUG(dbgs() << " doesn't affect kill at " << BI.LastUse << '\n');
-      SE->useIntv(Start, BI.LastUse);
+    // Live-in on stack, interference before first use.
+    //
+    //     ~~~              Interference before first use.
+    //     |---o---o---|    Live-in on stack.
+    //     ____=========    Enter MainIntv before first use.
+    //
+    if (!RegIn && Intf.last() < BI.FirstUse.getBaseIndex()) {
+      assert(RegOut && "Stack-in, stack-out should already be handled");
+      DEBUG(dbgs() << ", stack-in, interference before first use.\n");
+      SE->selectIntv(MainIntv);
+      SlotIndex From = SE->enterIntvBefore(BI.FirstUse);
+      assert(From >= Intf.last() && "Expected to avoid interference");
+      SE->useIntv(From, Stop);
       continue;
     }
 
-    if (Intf.first().getBaseIndex() > BI.FirstUse) {
-      // There are interference-free uses at the beginning of the block.
-      // Find the last use that can get the register.
-      SmallVectorImpl<SlotIndex>::const_iterator UI =
-        std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(),
-                         Intf.first().getBaseIndex());
-      assert(UI != SA->UseSlots.begin() && "Couldn't find first use");
-      SlotIndex Use = (--UI)->getBoundaryIndex();
-      DEBUG(dbgs() << ", free use at " << *UI << ".\n");
-      SlotIndex SegEnd = SE->leaveIntvAfter(Use);
-      assert(SegEnd <= Intf.first() && "Couldn't avoid interference");
-      SE->useIntv(Start, SegEnd);
-      continue;
+    // The interference is overlapping somewhere we wanted to use MainIntv. That
+    // means we need to create a local interval that can be allocated a
+    // different register.
+    DEBUG(dbgs() << ", creating local interval.\n");
+    unsigned LocalIntv = SE->openIntv();
+
+    // We may be creating copies directly between MainIntv and LocalIntv,
+    // bypassing the stack interval. When we do that, we should never use the
+    // leaveIntv* methods as they define values in the stack interval. By
+    // starting from the end of the block and working our way backwards, we can
+    // get by with only enterIntv* methods.
+    //
+    // When selecting split points, we generally try to maximize the stack
+    // interval as long at it contains no uses, maximize the main interval as
+    // long as it doesn't overlap interference, and minimize the local interval
+    // that we don't know how to allocate yet.
+
+    // Handle the block exit, set Pos to the first handled slot.
+    SlotIndex Pos = BI.LastUse;
+    if (RegOut) {
+      assert(Intf.last() < LastSplitPoint && "Cannot be live-out in register");
+      // Create a snippet of MainIntv that is live-out.
+      //
+      //     ~~~        Interference overlapping uses.
+      //     --o---|    Live-out in MainIntv.
+      //     ----===    Switch from LocalIntv to MainIntv after interference.
+      //
+      SE->selectIntv(MainIntv);
+      Pos = SE->enterIntvAfter(Intf.last());
+      assert(Pos >= Intf.last() && "Expected to avoid interference");
+      SE->useIntv(Pos, Stop);
+      SE->selectIntv(LocalIntv);
+    } else if (BI.LiveOut) {
+      if (BI.LastUse < LastSplitPoint) {
+        // Live-out on the stack.
+        //
+        //     ~~~        Interference overlapping uses.
+        //     --o---|    Live-out on stack.
+        //     ---____    Switch from LocalIntv to stack after last use.
+        //
+        Pos = SE->leaveIntvAfter(BI.LastUse);
+      } else {
+        // Live-out on the stack, last use after last split point.
+        //
+        //     ~~~        Interference overlapping uses.
+        //     --o--o|    Live-out on stack, late use.
+        //     ------     Copy to stack before LSP, overlap LocalIntv.
+        //         \__
+        //
+        Pos = SE->leaveIntvBefore(LastSplitPoint);
+        // We need to overlap LocalIntv so it can reach LastUse.
+        SE->overlapIntv(Pos, BI.LastUse);
+      }
     }
 
-    // Interference is before the first use.
-    DEBUG(dbgs() << " before first use.\n");
-    SlotIndex SegEnd = SE->leaveIntvAtTop(*BI.MBB);
-    assert(SegEnd <= Intf.first() && "Couldn't avoid interference");
+    // When not live-out, leave Pos at LastUse. We have handled everything from
+    // Pos to Stop. Find the starting point for LocalIntv.
+    assert(SE->currentIntv() == LocalIntv && "Expecting local interval");
+
+    if (RegIn) {
+      assert(Start < Intf.first() && "Cannot be live-in with interference");
+      // Live-in in MainIntv, only use LocalIntv for interference.
+      //
+      //         ~~~    Interference overlapping uses.
+      //     |---o--    Live-in in MainIntv.
+      //     ====---    Switch to LocalIntv before interference.
+      //
+      SlotIndex Switch = SE->enterIntvBefore(Intf.first());
+      assert(Switch <= Intf.first() && "Expected to avoid interference");
+      SE->useIntv(Switch, Pos);
+      SE->selectIntv(MainIntv);
+      SE->useIntv(Start, Switch);
+    } else {
+      // Live-in on stack, enter LocalIntv before first use.
+      //
+      //         ~~~    Interference overlapping uses.
+      //     |---o--    Live-in in MainIntv.
+      //     ____---    Reload to LocalIntv before interference.
+      //
+      // Defined in block.
+      //
+      //         ~~~    Interference overlapping uses.
+      //     |   o--    Defined in block.
+      //         ---    Begin LocalIntv at first use.
+      //
+      SlotIndex Switch = SE->enterIntvBefore(BI.FirstUse);
+      SE->useIntv(Switch, Pos);
+    }
   }
 
   // Handle live-through blocks.
+  SE->selectIntv(MainIntv);
   for (unsigned i = 0, e = Cand.ActiveBlocks.size(); i != e; ++i) {
     unsigned Number = Cand.ActiveBlocks[i];
     bool RegIn  = LiveBundles[Bundles->getBundle(Number, 0)];

Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=134047&r1=134046&r2=134047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.cpp Tue Jun 28 19:24:24 2011
@@ -636,6 +636,7 @@
 void SplitEditor::selectIntv(unsigned Idx) {
   assert(Idx != 0 && "Cannot select the complement interval");
   assert(Idx < Edit->size() && "Can only select previously opened interval");
+  DEBUG(dbgs() << "    selectIntv " << OpenIdx << " -> " << Idx << '\n');
   OpenIdx = Idx;
 }
 
@@ -656,6 +657,24 @@
   return VNI->def;
 }
 
+SlotIndex SplitEditor::enterIntvAfter(SlotIndex Idx) {
+  assert(OpenIdx && "openIntv not called before enterIntvAfter");
+  DEBUG(dbgs() << "    enterIntvAfter " << Idx);
+  Idx = Idx.getBoundaryIndex();
+  VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx);
+  if (!ParentVNI) {
+    DEBUG(dbgs() << ": not live\n");
+    return Idx;
+  }
+  DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n');
+  MachineInstr *MI = LIS.getInstructionFromIndex(Idx);
+  assert(MI && "enterIntvAfter called with invalid index");
+
+  VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(),
+                              llvm::next(MachineBasicBlock::iterator(MI)));
+  return VNI->def;
+}
+
 SlotIndex SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
   assert(OpenIdx && "openIntv not called before enterIntvAtEnd");
   SlotIndex End = LIS.getMBBEndIdx(&MBB);
@@ -1007,12 +1026,6 @@
         markComplexMapped(i, ParentVNI);
   }
 
-#ifndef NDEBUG
-  // Every new interval must have a def by now, otherwise the split is bogus.
-  for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I)
-    assert((*I)->hasAtLeastOneValue() && "Split interval has no value");
-#endif
-
   // Transfer the simply mapped values, check if any are skipped.
   bool Skipped = transferValues();
   if (Skipped)

Modified: llvm/trunk/lib/CodeGen/SplitKit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.h?rev=134047&r1=134046&r2=134047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.h (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.h Tue Jun 28 19:24:24 2011
@@ -81,6 +81,12 @@
     bool LiveThrough;     ///< Live in whole block (Templ 5. above).
     bool LiveIn;          ///< Current reg is live in.
     bool LiveOut;         ///< Current reg is live out.
+
+    /// isOneInstr - Returns true when this BlockInfo describes a single
+    /// instruction.
+    bool isOneInstr() const {
+      return SlotIndex::isSameInstr(FirstUse, LastUse);
+    }
   };
 
 private:
@@ -360,6 +366,10 @@
   /// Return the beginning of the new live range.
   SlotIndex enterIntvBefore(SlotIndex Idx);
 
+  /// enterIntvAfter - Enter the open interval after the instruction at Idx.
+  /// Return the beginning of the new live range.
+  SlotIndex enterIntvAfter(SlotIndex Idx);
+
   /// enterIntvAtEnd - Enter the open interval at the end of MBB.
   /// Use the open interval from he inserted copy to the MBB end.
   /// Return the beginning of the new live range.





More information about the llvm-commits mailing list