X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLiveInterval.cpp;h=2ed4d124972ebdcb5b61a1bc1eb2457d41280df6;hb=0253df9a897ce541d56146699cedd79c464bda5e;hp=32399ef2fc7ec097f4891be54b5be08e1ea92172;hpb=a141cfe5b2beb16599b5bab8c73333b31cc7a548;p=oota-llvm.git diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 32399ef2fc7..2ed4d124972 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -2,15 +2,15 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the LiveRange and LiveInterval classes. Given some // numbering of each the machine instructions an interval [i, j) is said to be a // live interval for register v if there is no instruction with number j' > j -// such that v is live at j' abd there is no instruction with number i' < i such +// such that v is live at j' and there is no instruction with number i' < i such // that v is live at i'. In this implementation intervals can have holes, // i.e. an interval might look like [1,20), [50,65), [1000,1001). Each // individual range is represented as an instance of LiveRange, and the whole @@ -19,29 +19,45 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Streams.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetRegisterInfo.h" #include -#include -#include using namespace llvm; -// An example for liveAt(): -// -// this = [1,4), liveAt(0) will return false. The instruction defining this -// spans slots [0,3]. The interval belongs to an spilled definition of the -// variable it represents. This is because slot 1 is used (def slot) and spans -// up to slot 3 (store slot). -// -bool LiveInterval::liveAt(unsigned I) const { - Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); +// CompEnd - Compare LiveRange ends. +namespace { +struct CompEnd { + bool operator()(const LiveRange &A, const LiveRange &B) const { + return A.end < B.end; + } +}; +} + +LiveInterval::iterator LiveInterval::find(SlotIndex Pos) { + assert(Pos.isValid() && "Cannot search for an invalid index"); + return std::upper_bound(begin(), end(), LiveRange(SlotIndex(), Pos, 0), + CompEnd()); +} +/// killedInRange - Return true if the interval has kills in [Start,End). +bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const { + Ranges::const_iterator r = + std::lower_bound(ranges.begin(), ranges.end(), End); + + // Now r points to the first interval with start >= End, or ranges.end(). if (r == ranges.begin()) return false; --r; - return r->contains(I); + // Now r points to the last interval with end <= End. + // r->end is the kill point. + return r->end >= Start && r->end < End; } // overlaps - Return true if the intersection of the two live intervals is @@ -64,6 +80,7 @@ bool LiveInterval::liveAt(unsigned I) const { // bool LiveInterval::overlapsFrom(const LiveInterval& other, const_iterator StartPos) const { + assert(!empty() && "empty interval"); const_iterator i = begin(); const_iterator ie = end(); const_iterator j = StartPos; @@ -102,30 +119,88 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other, return false; } +/// overlaps - Return true if the live interval overlaps a range specified +/// by [Start, End). +bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const { + assert(Start < End && "Invalid range"); + const_iterator I = std::lower_bound(begin(), end(), End); + return I != begin() && (--I)->end > Start; +} + + +/// ValNo is dead, remove it. If it is the largest value number, just nuke it +/// (and any other deleted values neighboring it), otherwise mark it as ~1U so +/// it can be nuked later. +void LiveInterval::markValNoForDeletion(VNInfo *ValNo) { + if (ValNo->id == getNumValNums()-1) { + do { + valnos.pop_back(); + } while (!valnos.empty() && valnos.back()->isUnused()); + } else { + ValNo->setIsUnused(true); + } +} + +/// RenumberValues - Renumber all values in order of appearance and delete the +/// remaining unused values. +void LiveInterval::RenumberValues(LiveIntervals &lis) { + SmallPtrSet Seen; + bool seenPHIDef = false; + valnos.clear(); + for (const_iterator I = begin(), E = end(); I != E; ++I) { + VNInfo *VNI = I->valno; + if (!Seen.insert(VNI)) + continue; + assert(!VNI->isUnused() && "Unused valno used by live range"); + VNI->id = (unsigned)valnos.size(); + valnos.push_back(VNI); + VNI->setHasPHIKill(false); + if (VNI->isPHIDef()) + seenPHIDef = true; + } + + // Recompute phi kill flags. + if (!seenPHIDef) + return; + for (const_vni_iterator I = vni_begin(), E = vni_end(); I != E; ++I) { + VNInfo *VNI = *I; + if (!VNI->isPHIDef()) + continue; + const MachineBasicBlock *PHIBB = lis.getMBBFromIndex(VNI->def); + assert(PHIBB && "No basic block for phi-def"); + for (MachineBasicBlock::const_pred_iterator PI = PHIBB->pred_begin(), + PE = PHIBB->pred_end(); PI != PE; ++PI) { + VNInfo *KVNI = getVNInfoAt(lis.getMBBEndIdx(*PI).getPrevSlot()); + if (KVNI) + KVNI->setHasPHIKill(true); + } + } +} + /// extendIntervalEndTo - This method is used when we want to extend the range /// specified by I to end at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. The iterator is /// not invalidated. -void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) { +void LiveInterval::extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd) { assert(I != ranges.end() && "Not a valid interval!"); - unsigned ValId = I->ValId; + VNInfo *ValNo = I->valno; // Search for the first interval that we can't merge with. - Ranges::iterator MergeTo = next(I); + Ranges::iterator MergeTo = llvm::next(I); for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) { - assert(MergeTo->ValId == ValId && "Cannot merge with differing values!"); + assert(MergeTo->valno == ValNo && "Cannot merge with differing values!"); } // If NewEnd was in the middle of an interval, make sure to get its endpoint. I->end = std::max(NewEnd, prior(MergeTo)->end); // Erase any dead ranges. - ranges.erase(next(I), MergeTo); - + ranges.erase(llvm::next(I), MergeTo); + // If the newly formed range now touches the range after it and if they have // the same value number, merge the two ranges into one range. - Ranges::iterator Next = next(I); - if (Next != ranges.end() && Next->start <= I->end && Next->ValId == ValId) { + Ranges::iterator Next = llvm::next(I); + if (Next != ranges.end() && Next->start <= I->end && Next->valno == ValNo) { I->end = Next->end; ranges.erase(Next); } @@ -136,9 +211,9 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) { /// specified by I to start at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. LiveInterval::Ranges::iterator -LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) { +LiveInterval::extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStart) { assert(I != ranges.end() && "Not a valid interval!"); - unsigned ValId = I->ValId; + VNInfo *ValNo = I->valno; // Search for the first interval that we can't merge with. Ranges::iterator MergeTo = I; @@ -148,13 +223,13 @@ LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) { ranges.erase(MergeTo, I); return I; } - assert(MergeTo->ValId == ValId && "Cannot merge with differing values!"); + assert(MergeTo->valno == ValNo && "Cannot merge with differing values!"); --MergeTo; } while (NewStart <= MergeTo->start); // If we start in the middle of another interval, just delete a range and // extend that interval. - if (MergeTo->end >= NewStart && MergeTo->ValId == ValId) { + if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) { MergeTo->end = I->end; } else { // Otherwise, extend the interval right after. @@ -163,27 +238,27 @@ LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) { MergeTo->end = I->end; } - ranges.erase(next(MergeTo), next(I)); + ranges.erase(llvm::next(MergeTo), llvm::next(I)); return MergeTo; } LiveInterval::iterator LiveInterval::addRangeFrom(LiveRange LR, iterator From) { - unsigned Start = LR.start, End = LR.end; + SlotIndex Start = LR.start, End = LR.end; iterator it = std::upper_bound(From, ranges.end(), Start); // If the inserted interval starts in the middle or right at the end of // another interval, just extend that interval to contain the range of LR. if (it != ranges.begin()) { iterator B = prior(it); - if (LR.ValId == B->ValId) { + if (LR.valno == B->valno) { if (B->start <= Start && B->end >= Start) { extendIntervalEndTo(B, End); return B; } } else { // Check to make sure that we are not overlapping two live ranges with - // different ValId's. + // different valno's. assert(B->end <= Start && "Cannot overlap two LiveRanges with differing ValID's" " (did you def the same reg twice in a MachineInstr?)"); @@ -192,8 +267,8 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { // Otherwise, if this range ends in the middle of, or right next to, another // interval, merge it into that interval. - if (it != ranges.end()) - if (LR.ValId == it->ValId) { + if (it != ranges.end()) { + if (LR.valno == it->valno) { if (it->start <= End) { it = extendIntervalStartTo(it, Start); @@ -205,10 +280,11 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { } } else { // Check to make sure that we are not overlapping two live ranges with - // different ValId's. + // different valno's. assert(it->start >= End && "Cannot overlap two LiveRanges with differing ValID's"); } + } // Otherwise, this is just a new range that doesn't interact with anything. // Insert it. @@ -217,20 +293,34 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { /// removeRange - Remove the specified range from this interval. Note that -/// the range must already be in this interval in its entirety. -void LiveInterval::removeRange(unsigned Start, unsigned End) { +/// the range must be in a single LiveRange in its entirety. +void LiveInterval::removeRange(SlotIndex Start, SlotIndex End, + bool RemoveDeadValNo) { // Find the LiveRange containing this span. - Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); - assert(I != ranges.begin() && "Range is not in interval!"); - --I; - assert(I->contains(Start) && I->contains(End-1) && - "Range is not entirely in interval!"); + Ranges::iterator I = find(Start); + assert(I != ranges.end() && "Range is not in interval!"); + assert(I->containsRange(Start, End) && "Range is not entirely in interval!"); // If the span we are removing is at the start of the LiveRange, adjust it. + VNInfo *ValNo = I->valno; if (I->start == Start) { - if (I->end == End) + if (I->end == End) { + if (RemoveDeadValNo) { + // Check if val# is dead. + bool isDead = true; + for (const_iterator II = begin(), EE = end(); II != EE; ++II) + if (II != I && II->valno == ValNo) { + isDead = false; + break; + } + if (isDead) { + // Now that ValNo is dead, remove it. + markValNoForDeletion(ValNo); + } + } + ranges.erase(I); // Removed the whole LiveRange. - else + } else I->start = End; return; } @@ -243,171 +333,208 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) { } // Otherwise, we are splitting the LiveRange into two pieces. - unsigned OldEnd = I->end; + SlotIndex OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. - ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId)); + ranges.insert(llvm::next(I), LiveRange(End, OldEnd, ValNo)); } -/// getLiveRangeContaining - Return the live range that contains the -/// specified index, or null if there is none. -LiveInterval::const_iterator -LiveInterval::FindLiveRangeContaining(unsigned Idx) const { - const_iterator It = std::upper_bound(begin(), end(), Idx); - if (It != ranges.begin()) { - --It; - if (It->contains(Idx)) - return It; - } - - return end(); +/// removeValNo - Remove all the ranges defined by the specified value#. +/// Also remove the value# from value# list. +void LiveInterval::removeValNo(VNInfo *ValNo) { + if (empty()) return; + Ranges::iterator I = ranges.end(); + Ranges::iterator E = ranges.begin(); + do { + --I; + if (I->valno == ValNo) + ranges.erase(I); + } while (I != E); + // Now that ValNo is dead, remove it. + markValNoForDeletion(ValNo); } -LiveInterval::iterator -LiveInterval::FindLiveRangeContaining(unsigned Idx) { - iterator It = std::upper_bound(begin(), end(), Idx); - if (It != begin()) { - --It; - if (It->contains(Idx)) - return It; +/// findDefinedVNInfo - Find the VNInfo defined by the specified +/// index (register interval). +VNInfo *LiveInterval::findDefinedVNInfoForRegInt(SlotIndex Idx) const { + for (LiveInterval::const_vni_iterator i = vni_begin(), e = vni_end(); + i != e; ++i) { + if ((*i)->def == Idx) + return *i; } - - return end(); + + return 0; } /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. -void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, - int *RHSValNoAssignments, - SmallVector &NewValueNumberInfo) { - - // Try to do the least amount of work possible. In particular, if there are - // more liverange chunks in the other set than there are in the 'this' set, - // swap sets to merge the fewest chunks in possible. - // - // Also, if one range is a physreg and one is a vreg, we always merge from the - // vreg into the physreg, which leaves the vreg intervals pristine. - if ((Other.ranges.size() > ranges.size() && - MRegisterInfo::isVirtualRegister(reg)) || - MRegisterInfo::isPhysicalRegister(Other.reg)) { - swap(Other); - std::swap(LHSValNoAssignments, RHSValNoAssignments); - } - +void LiveInterval::join(LiveInterval &Other, + const int *LHSValNoAssignments, + const int *RHSValNoAssignments, + SmallVector &NewVNInfo, + MachineRegisterInfo *MRI) { // Determine if any of our live range values are mapped. This is uncommon, so // we want to avoid the interval scan if not. bool MustMapCurValNos = false; - for (unsigned i = 0, e = getNumValNums(); i != e; ++i) { - if (ValueNumberInfo[i].def == ~1U) continue; // tombstone value # - if (i != (unsigned)LHSValNoAssignments[i]) { + unsigned NumVals = getNumValNums(); + unsigned NumNewVals = NewVNInfo.size(); + for (unsigned i = 0; i != NumVals; ++i) { + unsigned LHSValID = LHSValNoAssignments[i]; + if (i != LHSValID || + (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) MustMapCurValNos = true; - break; - } } - + // If we have to apply a mapping to our base interval assignment, rewrite it // now. if (MustMapCurValNos) { // Map the first live range. iterator OutIt = begin(); - OutIt->ValId = LHSValNoAssignments[OutIt->ValId]; + OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]]; ++OutIt; for (iterator I = OutIt, E = end(); I != E; ++I) { - OutIt->ValId = LHSValNoAssignments[I->ValId]; - + OutIt->valno = NewVNInfo[LHSValNoAssignments[I->valno->id]]; + // If this live range has the same value # as its immediate predecessor, // and if they are neighbors, remove one LiveRange. This happens when we // have [0,3:0)[4,7:1) and map 0/1 onto the same value #. - if (OutIt->ValId == (OutIt-1)->ValId && (OutIt-1)->end == OutIt->start) { + if (OutIt->valno == (OutIt-1)->valno && (OutIt-1)->end == OutIt->start) { (OutIt-1)->end = OutIt->end; } else { if (I != OutIt) { OutIt->start = I->start; OutIt->end = I->end; } - + // Didn't merge, on to the next one. ++OutIt; } } - + // If we merge some live ranges, chop off the end. ranges.erase(OutIt, end()); } - + + // Remember assignements because val# ids are changing. + SmallVector OtherAssignments; + for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) + OtherAssignments.push_back(RHSValNoAssignments[I->valno->id]); + + // Update val# info. Renumber them and make sure they all belong to this + // LiveInterval now. Also remove dead val#'s. + unsigned NumValNos = 0; + for (unsigned i = 0; i < NumNewVals; ++i) { + VNInfo *VNI = NewVNInfo[i]; + if (VNI) { + if (NumValNos >= NumVals) + valnos.push_back(VNI); + else + valnos[NumValNos] = VNI; + VNI->id = NumValNos++; // Renumber val#. + } + } + if (NumNewVals < NumVals) + valnos.resize(NumNewVals); // shrinkify + // Okay, now insert the RHS live ranges into the LHS. iterator InsertPos = begin(); - for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) { - // Map the ValId in the other live range to the current live range. - I->ValId = RHSValNoAssignments[I->ValId]; + unsigned RangeNo = 0; + for (iterator I = Other.begin(), E = Other.end(); I != E; ++I, ++RangeNo) { + // Map the valno in the other live range to the current live range. + I->valno = NewVNInfo[OtherAssignments[RangeNo]]; + assert(I->valno && "Adding a dead range?"); InsertPos = addRangeFrom(*I, InsertPos); } - ValueNumberInfo.clear(); - ValueNumberInfo.append(NewValueNumberInfo.begin(), NewValueNumberInfo.end()); - weight += Other.weight; - if (Other.preference && !preference) - preference = Other.preference; + ComputeJoinedWeight(Other); } /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live /// interval as the specified value number. The LiveRanges in RHS are /// allowed to overlap with LiveRanges in the current interval, but only if /// the overlapping LiveRanges have the specified value number. -void LiveInterval::MergeRangesInAsValue(const LiveInterval &RHS, - unsigned LHSValNo) { +void LiveInterval::MergeRangesInAsValue(const LiveInterval &RHS, + VNInfo *LHSValNo) { // TODO: Make this more efficient. iterator InsertPos = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { - // Map the ValId in the other live range to the current live range. + // Map the valno in the other live range to the current live range. LiveRange Tmp = *I; - Tmp.ValId = LHSValNo; + Tmp.valno = LHSValNo; InsertPos = addRangeFrom(Tmp, InsertPos); } } -/// MergeInClobberRanges - For any live ranges that are not defined in the -/// current interval, but are defined in the Clobbers interval, mark them -/// used with an unknown definition value. -void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers) { - if (Clobbers.begin() == Clobbers.end()) return; - - // Find a value # to use for the clobber ranges. If there is already a value# - // for unknown values, use it. - // FIXME: Use a single sentinal number for these! - unsigned ClobberValNo = getNextValue(~0U, 0); - +/// MergeValueInAsValue - Merge all of the live ranges of a specific val# +/// in RHS into this live interval as the specified value number. +/// The LiveRanges in RHS are allowed to overlap with LiveRanges in the +/// current interval, it will replace the value numbers of the overlaped +/// live ranges with the specified value number. +void LiveInterval::MergeValueInAsValue( + const LiveInterval &RHS, + const VNInfo *RHSValNo, VNInfo *LHSValNo) { + SmallVector ReplacedValNos; iterator IP = begin(); - for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) { - unsigned Start = I->start, End = I->end; + for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { + assert(I->valno == RHS.getValNumInfo(I->valno->id) && "Bad VNInfo"); + if (I->valno != RHSValNo) + continue; + SlotIndex Start = I->start, End = I->end; IP = std::upper_bound(IP, end(), Start); - // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > Start) { + if (IP[-1].valno != LHSValNo) { + ReplacedValNos.push_back(IP[-1].valno); + IP[-1].valno = LHSValNo; // Update val#. + } Start = IP[-1].end; // Trimmed away the whole range? if (Start >= End) continue; } // If the end of this range overlaps with an existing liverange, trim it. if (IP != end() && End > IP->start) { + if (IP->valno != LHSValNo) { + ReplacedValNos.push_back(IP->valno); + IP->valno = LHSValNo; // Update val#. + } End = IP->start; // If this trimmed away the whole range, ignore it. if (Start == End) continue; } - - // Insert the clobber interval. - IP = addRangeFrom(LiveRange(Start, End, ClobberValNo), IP); + + // Map the valno in the other live range to the current live range. + IP = addRangeFrom(LiveRange(Start, End, LHSValNo), IP); + } + + + SmallSet Seen; + for (unsigned i = 0, e = ReplacedValNos.size(); i != e; ++i) { + VNInfo *V1 = ReplacedValNos[i]; + if (Seen.insert(V1)) { + bool isDead = true; + for (const_iterator I = begin(), E = end(); I != E; ++I) + if (I->valno == V1) { + isDead = false; + break; + } + if (isDead) { + // Now that V1 is dead, remove it. + markValNoForDeletion(V1); + } + } } } + + /// MergeValueNumberInto - This method is called when two value nubmers /// are found to be equivalent. This eliminates V1, replacing all /// LiveRanges with the V1 value number with the V2 value number. This can /// cause merging of V1/V2 values numbers and compaction of the value space. -void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) { +VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { assert(V1 != V2 && "Identical value#'s are always equivalent!"); // This code actually merges the (numerically) larger value number into the @@ -416,21 +543,21 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) { // instruction that defines the result value. // Make sure V2 is smaller than V1. - if (V1 < V2) { - setValueNumberInfo(V1, getValNumInfo(V2)); + if (V1->id < V2->id) { + V1->copyFrom(*V2); std::swap(V1, V2); } // Merge V1 live ranges into V2. for (iterator I = begin(); I != end(); ) { iterator LR = I++; - if (LR->ValId != V1) continue; // Not a V1 LiveRange. - + if (LR->valno != V1) continue; // Not a V1 LiveRange. + // Okay, we found a V1 live range. If it had a previous, touching, V2 live // range, extend it. if (LR != begin()) { iterator Prev = LR-1; - if (Prev->ValId == V2 && Prev->end == LR->start) { + if (Prev->valno == V2 && Prev->end == LR->start) { Prev->end = LR->end; // Erase this live-range. @@ -439,89 +566,249 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) { LR = Prev; } } - + // Okay, now we have a V1 or V2 live range that is maximally merged forward. // Ensure that it is a V2 live-range. - LR->ValId = V2; - + LR->valno = V2; + // If we can merge it into later V2 live ranges, do so now. We ignore any // following V1 live ranges, as they will be merged in subsequent iterations // of the loop. if (I != end()) { - if (I->start == LR->end && I->ValId == V2) { + if (I->start == LR->end && I->valno == V2) { LR->end = I->end; ranges.erase(I); I = LR+1; } } } - - // Now that V1 is dead, remove it. If it is the largest value number, just - // nuke it (and any other deleted values neighboring it), otherwise mark it as - // ~1U so it can be nuked later. - if (V1 == getNumValNums()-1) { - do { - ValueNumberInfo.pop_back(); - } while (ValueNumberInfo.back().def == ~1U); - } else { - ValueNumberInfo[V1].def = ~1U; + + // Merge the relevant flags. + V2->mergeFlags(V1); + + // Now that V1 is dead, remove it. + markValNoForDeletion(V1); + + return V2; +} + +void LiveInterval::Copy(const LiveInterval &RHS, + MachineRegisterInfo *MRI, + VNInfo::Allocator &VNInfoAllocator) { + ranges.clear(); + valnos.clear(); + std::pair Hint = MRI->getRegAllocationHint(RHS.reg); + MRI->setRegAllocationHint(reg, Hint.first, Hint.second); + + weight = RHS.weight; + for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) { + const VNInfo *VNI = RHS.getValNumInfo(i); + createValueCopy(VNI, VNInfoAllocator); + } + for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) { + const LiveRange &LR = RHS.ranges[i]; + addRange(LiveRange(LR.start, LR.end, getValNumInfo(LR.valno->id))); } } unsigned LiveInterval::getSize() const { unsigned Sum = 0; for (const_iterator I = begin(), E = end(); I != E; ++I) - Sum += I->end - I->start; + Sum += I->start.distance(I->end); return Sum; } -std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) { - return os << '[' << LR.start << ',' << LR.end << ':' << LR.ValId << ")"; +/// ComputeJoinedWeight - Set the weight of a live interval Joined +/// after Other has been merged into it. +void LiveInterval::ComputeJoinedWeight(const LiveInterval &Other) { + // If either of these intervals was spilled, the weight is the + // weight of the non-spilled interval. This can only happen with + // iterative coalescers. + + if (Other.weight != HUGE_VALF) { + weight += Other.weight; + } + else if (weight == HUGE_VALF && + !TargetRegisterInfo::isPhysicalRegister(reg)) { + // Remove this assert if you have an iterative coalescer + assert(0 && "Joining to spilled interval"); + weight = Other.weight; + } + else { + // Otherwise the weight stays the same + // Remove this assert if you have an iterative coalescer + assert(0 && "Joining from spilled interval"); + } +} + +raw_ostream& llvm::operator<<(raw_ostream& os, const LiveRange &LR) { + return os << '[' << LR.start << ',' << LR.end << ':' << LR.valno->id << ")"; } void LiveRange::dump() const { - cerr << *this << "\n"; + dbgs() << *this << "\n"; } -void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const { - if (MRI && MRegisterInfo::isPhysicalRegister(reg)) - OS << MRI->getName(reg); +void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const { + if (isStackSlot()) + OS << "SS#" << getStackSlotIndex(); + else if (TRI && TargetRegisterInfo::isPhysicalRegister(reg)) + OS << TRI->getName(reg); else OS << "%reg" << reg; OS << ',' << weight; if (empty()) - OS << "EMPTY"; + OS << " EMPTY"; else { OS << " = "; for (LiveInterval::Ranges::const_iterator I = ranges.begin(), - E = ranges.end(); I != E; ++I) - OS << *I; + E = ranges.end(); I != E; ++I) { + OS << *I; + assert(I->valno == getValNumInfo(I->valno->id) && "Bad VNInfo"); + } } - + // Print value number info. if (getNumValNums()) { OS << " "; - for (unsigned i = 0; i != getNumValNums(); ++i) { - if (i) OS << " "; - OS << i << "@"; - if (ValueNumberInfo[i].def == ~0U) { - OS << "?"; - } else if (ValueNumberInfo[i].def == ~1U) { + unsigned vnum = 0; + for (const_vni_iterator i = vni_begin(), e = vni_end(); i != e; + ++i, ++vnum) { + const VNInfo *vni = *i; + if (vnum) OS << " "; + OS << vnum << "@"; + if (vni->isUnused()) { OS << "x"; } else { - OS << ValueNumberInfo[i].def; + OS << vni->def; + if (vni->isPHIDef()) + OS << "-phidef"; + if (vni->hasPHIKill()) + OS << "-phikill"; + if (vni->hasRedefByEC()) + OS << "-ec"; } } } } void LiveInterval::dump() const { - cerr << *this << "\n"; + dbgs() << *this << "\n"; } -void LiveRange::print(std::ostream &os) const { +void LiveRange::print(raw_ostream &os) const { os << *this; } + +/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a +/// LiveInterval into equivalence clases of connected components. A +/// LiveInterval that has multiple connected components can be broken into +/// multiple LiveIntervals. + +void ConnectedVNInfoEqClasses::Connect(unsigned a, unsigned b) { + // Add new eq classes as needed. + for (unsigned i = eqClass_.size(), m = std::max(a, b); i <= m; ++i) + eqClass_.push_back(i); + + unsigned eqa = eqClass_[a]; + unsigned eqb = eqClass_[b]; + if (eqa == eqb) + return; + if (eqa > eqb) + std::swap(eqa, eqb); + // Now, eqa < eqb. Switch all eqb members over to eqa. + for (unsigned i = eqb, e = eqClass_.size(); i != e; ++i) + if (eqClass_[i] == eqb) + eqClass_[i] = eqa; +} + +unsigned ConnectedVNInfoEqClasses::Renumber() { + // No values at all. + if (eqClass_.empty()) + return 0; + + // Common case: A single connected component. + if (eqClass_.back() == 0) + return 1; + + // Renumber classes. We use the fact that eqClass_[i] == i for class leaders. + unsigned count = 0; + for (unsigned i = 0, e = eqClass_.size(); i != e; ++i) { + unsigned q = eqClass_[i]; + if (q == i) + eqClass_[i] = count++; + else + eqClass_[i] = eqClass_[q]; + } + + return count; +} + +unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { + // Determine connections. + eqClass_.clear(); + for (LiveInterval::const_vni_iterator I = LI->vni_begin(), E = LI->vni_end(); + I != E; ++I) { + const VNInfo *VNI = *I; + if (VNI->id == eqClass_.size()) + eqClass_.push_back(VNI->id); + assert(!VNI->isUnused() && "Cannot handle unused values"); + if (VNI->isPHIDef()) { + const MachineBasicBlock *MBB = lis_.getMBBFromIndex(VNI->def); + assert(MBB && "Phi-def has no defining MBB"); + // Connect to values live out of predecessors. + for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) + if (const VNInfo *PVNI = + LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot())) + Connect(VNI->id, PVNI->id); + } else { + // Normal value defined by an instruction. Check for two-addr redef. + // FIXME: This could be coincidental. Should we really check for a tied + // operand constraint? + if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getUseIndex())) + Connect(VNI->id, UVNI->id); + } + } + return Renumber(); +} + +void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) { + assert(LIV[0] && "LIV[0] must be set"); + LiveInterval &LI = *LIV[0]; + // Check that they likely ran Classify() on LIV[0] first. + assert(eqClass_.size() == LI.getNumValNums() && "Bad classification data"); + + // First move runs to new intervals. + LiveInterval::iterator J = LI.begin(), E = LI.end(); + while (J != E && eqClass_[J->valno->id] == 0) + ++J; + for (LiveInterval::iterator I = J; I != E; ++I) { + if (unsigned eq = eqClass_[I->valno->id]) { + assert(LIV[eq]->empty() || LIV[eq]->expiredAt(I->start) && + "New intervals should be empty"); + LIV[eq]->ranges.push_back(*I); + } else + *J++ = *I; + } + LI.ranges.erase(J, E); + + // Transfer VNInfos to their new owners and renumber them. + unsigned j = 0, e = LI.getNumValNums(); + while (j != e && eqClass_[j] == 0) + ++j; + for (unsigned i = j; i != e; ++i) { + VNInfo *VNI = LI.getValNumInfo(i); + if (unsigned eq = eqClass_[i]) { + VNI->id = LIV[eq]->getNumValNums(); + LIV[eq]->valnos.push_back(VNI); + } else { + VNI->id = j; + LI.valnos[j++] = VNI; + } + } + LI.valnos.resize(j); +}