diff options
Diffstat (limited to 'lib/CodeGen/InterferenceCache.cpp')
| -rw-r--r-- | lib/CodeGen/InterferenceCache.cpp | 93 | 
1 files changed, 64 insertions, 29 deletions
diff --git a/lib/CodeGen/InterferenceCache.cpp b/lib/CodeGen/InterferenceCache.cpp index 8368b58880a3..1541bf0c8512 100644 --- a/lib/CodeGen/InterferenceCache.cpp +++ b/lib/CodeGen/InterferenceCache.cpp @@ -39,7 +39,7 @@ InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) {    unsigned E = PhysRegEntries[PhysReg];    if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) {      if (!Entries[E].valid(LIUArray, TRI)) -      Entries[E].revalidate(); +      Entries[E].revalidate(LIUArray, TRI);      return &Entries[E];    }    // No valid entry exists, pick the next round-robin entry. @@ -61,13 +61,15 @@ InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) {  }  /// revalidate - LIU contents have changed, update tags. -void InterferenceCache::Entry::revalidate() { +void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray, +                                          const TargetRegisterInfo *TRI) {    // Invalidate all block entries.    ++Tag;    // Invalidate all iterators.    PrevPos = SlotIndex(); -  for (unsigned i = 0, e = Aliases.size(); i != e; ++i) -    Aliases[i].second = Aliases[i].first->getTag(); +  unsigned i = 0; +  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i) +    RegUnits[i].VirtTag = LIUArray[*Units].getTag();  }  void InterferenceCache::Entry::reset(unsigned physReg, @@ -79,28 +81,23 @@ void InterferenceCache::Entry::reset(unsigned physReg,    ++Tag;    PhysReg = physReg;    Blocks.resize(MF->getNumBlockIDs()); -  Aliases.clear(); -  for (const uint16_t *AS = TRI->getOverlaps(PhysReg); *AS; ++AS) { -    LiveIntervalUnion *LIU = LIUArray + *AS; -    Aliases.push_back(std::make_pair(LIU, LIU->getTag())); -  }    // Reset iterators.    PrevPos = SlotIndex(); -  unsigned e = Aliases.size(); -  Iters.resize(e); -  for (unsigned i = 0; i != e; ++i) -    Iters[i].setMap(Aliases[i].first->getMap()); +  RegUnits.clear(); +  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { +    RegUnits.push_back(LIUArray[*Units]); +    RegUnits.back().Fixed = &LIS->getRegUnit(*Units); +  }  }  bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray,                                       const TargetRegisterInfo *TRI) { -  unsigned i = 0, e = Aliases.size(); -  for (const uint16_t *AS = TRI->getOverlaps(PhysReg); *AS; ++AS, ++i) { -    LiveIntervalUnion *LIU = LIUArray + *AS; -    if (i == e ||  Aliases[i].first != LIU) +  unsigned i = 0, e = RegUnits.size(); +  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i) { +    if (i == e)        return false; -    if (LIU->changedSince(Aliases[i].second)) +    if (LIUArray[*Units].changedSince(RegUnits[i].VirtTag))        return false;    }    return i == e; @@ -112,12 +109,20 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {    // Use advanceTo only when possible.    if (PrevPos != Start) { -    if (!PrevPos.isValid() || Start < PrevPos) -      for (unsigned i = 0, e = Iters.size(); i != e; ++i) -        Iters[i].find(Start); -    else -      for (unsigned i = 0, e = Iters.size(); i != e; ++i) -        Iters[i].advanceTo(Start); +    if (!PrevPos.isValid() || Start < PrevPos) { +      for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +        RegUnitInfo &RUI = RegUnits[i]; +        RUI.VirtI.find(Start); +        RUI.FixedI = RUI.Fixed->find(Start); +      } +    } else { +      for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +        RegUnitInfo &RUI = RegUnits[i]; +        RUI.VirtI.advanceTo(Start); +        if (RUI.FixedI != RUI.Fixed->end()) +          RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start); +      } +    }      PrevPos = Start;    } @@ -129,9 +134,9 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {      BI->Tag = Tag;      BI->First = BI->Last = SlotIndex(); -    // Check for first interference. -    for (unsigned i = 0, e = Iters.size(); i != e; ++i) { -      Iter &I = Iters[i]; +    // Check for first interference from virtregs. +    for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +      LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;        if (!I.valid())          continue;        SlotIndex StartI = I.start(); @@ -141,6 +146,19 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {          BI->First = StartI;      } +    // Same thing for fixed interference. +    for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +      LiveInterval::const_iterator I = RegUnits[i].FixedI; +      LiveInterval::const_iterator E = RegUnits[i].Fixed->end(); +      if (I == E) +        continue; +      SlotIndex StartI = I->start; +      if (StartI >= Stop) +        continue; +      if (!BI->First.isValid() || StartI < BI->First) +        BI->First = StartI; +    } +      // Also check for register mask interference.      RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum);      RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum); @@ -168,8 +186,8 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {    }    // Check for last interference in block. -  for (unsigned i = 0, e = Iters.size(); i != e; ++i) { -    Iter &I = Iters[i]; +  for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +    LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;      if (!I.valid() || I.start() >= Stop)        continue;      I.advanceTo(Stop); @@ -183,6 +201,23 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {        ++I;    } +  // Fixed interference. +  for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { +    LiveInterval::iterator &I = RegUnits[i].FixedI; +    LiveInterval *LI = RegUnits[i].Fixed; +    if (I == LI->end() || I->start >= Stop) +      continue; +    I = LI->advanceTo(I, Stop); +    bool Backup = I == LI->end() || I->start >= Stop; +    if (Backup) +      --I; +    SlotIndex StopI = I->end; +    if (!BI->Last.isValid() || StopI > BI->Last) +      BI->Last = StopI; +    if (Backup) +      ++I; +  } +    // Also check for register mask interference.    SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start;    for (unsigned i = RegMaskSlots.size();  | 
