Work around a coalescer bug.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 5 Mar 2011 18:33:49 +0000 (18:33 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 5 Mar 2011 18:33:49 +0000 (18:33 +0000)
The coalescer can in very rare cases leave too large live intervals around after
rematerializing cheap-as-a-move instructions.

Linear scan doesn't really care, but live range splitting gets very confused
when a live range is killed by a ghost instruction.

I will fix this properly in the coalescer after 2.9 branches.

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

lib/CodeGen/SplitKit.cpp
lib/CodeGen/SplitKit.h

index 4adf8f7f9492a0fba882810dcc73994bb973b88e..c4ae8c474c5fdf0e824999ad77ea7da93874bae5 100644 (file)
@@ -81,7 +81,20 @@ void SplitAnalysis::analyzeUses() {
     UsingBlocks[MBB]++;
   }
   array_pod_sort(UseSlots.begin(), UseSlots.end());
-  calcLiveBlockInfo();
+
+  // Compute per-live block info.
+  if (!calcLiveBlockInfo()) {
+    // FIXME: calcLiveBlockInfo found inconsistencies in the live range.
+    // I am looking at you, SimpleRegisterCoalescing!
+    DEBUG(dbgs() << "*** Fixing inconsistent live interval! ***\n");
+    const_cast<LiveIntervals&>(LIS)
+      .shrinkToUses(const_cast<LiveInterval*>(CurLI));
+    LiveBlocks.clear();
+    bool fixed = calcLiveBlockInfo();
+    (void)fixed;
+    assert(fixed && "Couldn't fix broken live interval");
+  }
+
   DEBUG(dbgs() << "  counted "
                << UsingInstrs.size() << " instrs, "
                << UsingBlocks.size() << " blocks.\n");
@@ -89,9 +102,9 @@ void SplitAnalysis::analyzeUses() {
 
 /// calcLiveBlockInfo - Fill the LiveBlocks array with information about blocks
 /// where CurLI is live.
-void SplitAnalysis::calcLiveBlockInfo() {
+bool SplitAnalysis::calcLiveBlockInfo() {
   if (CurLI->empty())
-    return;
+    return true;
 
   LiveInterval::const_iterator LVI = CurLI->begin();
   LiveInterval::const_iterator LVE = CurLI->end();
@@ -154,6 +167,11 @@ void SplitAnalysis::calcLiveBlockInfo() {
     BI.LiveThrough = !hasGap && BI.LiveIn && BI.LiveOut;
     LiveBlocks.push_back(BI);
 
+    // FIXME: This should never happen. The live range stops or starts without a
+    // corresponding use. An earlier pass did something wrong.
+    if (!BI.LiveThrough && !BI.Uses)
+      return false;
+
     // LVI is now at LVE or LVI->end >= Stop.
     if (LVI == LVE)
       break;
@@ -168,6 +186,7 @@ void SplitAnalysis::calcLiveBlockInfo() {
     else
       MFI = LIS.getMBBFromIndex(LVI->start);
   }
+  return true;
 }
 
 bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
index 29c0afc76ca224b152614228ab6f645bec328be3..0e35df0ed6cff8c54fcba6644e52d109550d7840 100644 (file)
@@ -103,7 +103,7 @@ private:
   void analyzeUses();
 
   /// calcLiveBlockInfo - Compute per-block information about CurLI.
-  void calcLiveBlockInfo();
+  bool calcLiveBlockInfo();
 
   /// canAnalyzeBranch - Return true if MBB ends in a branch that can be
   /// analyzed.