diff options
Diffstat (limited to 'lib/CodeGen/SplitKit.cpp')
| -rw-r--r-- | lib/CodeGen/SplitKit.cpp | 96 | 
1 files changed, 57 insertions, 39 deletions
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index ac9d72bf62c9..bf27cc86574f 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -30,6 +30,9 @@ using namespace llvm;  STATISTIC(NumFinished, "Number of splits finished");  STATISTIC(NumSimple,   "Number of splits that were simple"); +STATISTIC(NumCopies,   "Number of copies inserted for splitting"); +STATISTIC(NumRemats,   "Number of rematerialized defs for splitting"); +STATISTIC(NumRepairs,  "Number of invalid live ranges repaired");  //===----------------------------------------------------------------------===//  //                                 Split Analysis @@ -51,6 +54,7 @@ void SplitAnalysis::clear() {    UseBlocks.clear();    ThroughBlocks.clear();    CurLI = 0; +  DidRepairRange = false;  }  SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) { @@ -119,6 +123,8 @@ void SplitAnalysis::analyzeUses() {    if (!calcLiveBlockInfo()) {      // FIXME: calcLiveBlockInfo found inconsistencies in the live range.      // I am looking at you, SimpleRegisterCoalescing! +    DidRepairRange = true; +    ++NumRepairs;      DEBUG(dbgs() << "*** Fixing inconsistent live interval! ***\n");      const_cast<LiveIntervals&>(LIS)        .shrinkToUses(const_cast<LiveInterval*>(CurLI)); @@ -139,7 +145,7 @@ void SplitAnalysis::analyzeUses() {  /// where CurLI is live.  bool SplitAnalysis::calcLiveBlockInfo() {    ThroughBlocks.resize(MF.getNumBlockIDs()); -  NumThroughBlocks = 0; +  NumThroughBlocks = NumGapBlocks = 0;    if (CurLI->empty())      return true; @@ -158,55 +164,63 @@ bool SplitAnalysis::calcLiveBlockInfo() {      SlotIndex Start, Stop;      tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); -    // LVI is the first live segment overlapping MBB. -    BI.LiveIn = LVI->start <= Start; -    if (!BI.LiveIn) -      BI.Def = LVI->start; - -    // Find the first and last uses in the block. -    bool Uses = UseI != UseE && *UseI < Stop; -    if (Uses) { +    // If the block contains no uses, the range must be live through. At one +    // point, SimpleRegisterCoalescing could create dangling ranges that ended +    // mid-block. +    if (UseI == UseE || *UseI >= Stop) { +      ++NumThroughBlocks; +      ThroughBlocks.set(BI.MBB->getNumber()); +      // The range shouldn't end mid-block if there are no uses. This shouldn't +      // happen. +      if (LVI->end < Stop) +        return false; +    } else { +      // This block has uses. Find the first and last uses in the block.        BI.FirstUse = *UseI;        assert(BI.FirstUse >= Start);        do ++UseI;        while (UseI != UseE && *UseI < Stop);        BI.LastUse = UseI[-1];        assert(BI.LastUse < Stop); -    } -    // Look for gaps in the live range. -    bool hasGap = false; -    BI.LiveOut = true; -    while (LVI->end < Stop) { -      SlotIndex LastStop = LVI->end; -      if (++LVI == LVE || LVI->start >= Stop) { -        BI.Kill = LastStop; -        BI.LiveOut = false; -        break; -      } -      if (LastStop < LVI->start) { -        hasGap = true; -        BI.Kill = LastStop; -        BI.Def = LVI->start; +      // LVI is the first live segment overlapping MBB. +      BI.LiveIn = LVI->start <= Start; + +      // Look for gaps in the live range. +      BI.LiveOut = true; +      while (LVI->end < Stop) { +        SlotIndex LastStop = LVI->end; +        if (++LVI == LVE || LVI->start >= Stop) { +          BI.LiveOut = false; +          BI.LastUse = LastStop; +          break; +        } +        if (LastStop < LVI->start) { +          // There is a gap in the live range. Create duplicate entries for the +          // live-in snippet and the live-out snippet. +          ++NumGapBlocks; + +          // Push the Live-in part. +          BI.LiveThrough = false; +          BI.LiveOut = false; +          UseBlocks.push_back(BI); +          UseBlocks.back().LastUse = LastStop; + +          // Set up BI for the live-out part. +          BI.LiveIn = false; +          BI.LiveOut = true; +          BI.FirstUse = LVI->start; +        }        } -    } -    // Don't set LiveThrough when the block has a gap. -    BI.LiveThrough = !hasGap && BI.LiveIn && BI.LiveOut; -    if (Uses) +      // Don't set LiveThrough when the block has a gap. +      BI.LiveThrough = BI.LiveIn && BI.LiveOut;        UseBlocks.push_back(BI); -    else { -      ++NumThroughBlocks; -      ThroughBlocks.set(BI.MBB->getNumber()); -    } -    // FIXME: This should never happen. The live range stops or starts without a -    // corresponding use. An earlier pass did something wrong. -    if (!BI.LiveThrough && !Uses) -      return false; -    // LVI is now at LVE or LVI->end >= Stop. -    if (LVI == LVE) -      break; +      // LVI is now at LVE or LVI->end >= Stop. +      if (LVI == LVE) +        break; +    }      // Live segment ends exactly at Stop. Move to the next segment.      if (LVI->end == Stop && ++LVI == LVE) @@ -218,6 +232,8 @@ bool SplitAnalysis::calcLiveBlockInfo() {      else        MFI = LIS.getMBBFromIndex(LVI->start);    } + +  assert(getNumLiveBlocks() == countLiveBlocks(CurLI) && "Bad block count");    return true;  } @@ -587,12 +603,14 @@ VNInfo *SplitEditor::defFromParent(unsigned RegIdx,    LiveRangeEdit::Remat RM(ParentVNI);    if (Edit->canRematerializeAt(RM, UseIdx, true, LIS)) {      Def = Edit->rematerializeAt(MBB, I, LI->reg, RM, LIS, TII, TRI, Late); +    ++NumRemats;    } else {      // Can't remat, just insert a copy from parent.      CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), LI->reg)                 .addReg(Edit->getReg());      Def = LIS.getSlotIndexes()->insertMachineInstrInMaps(CopyMI, Late)              .getDefIndex(); +    ++NumCopies;    }    // Define the value in Reg.  | 
