X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLiveInterval.cpp;h=26722a3ca11a4c8bccbe9dc4467a5e0f3470f541;hb=626742231863db0e9aeef1be1fd48e9f4b7e22f8;hp=3f8714085aef64b6d0b7a8936fad286c1586ed5a;hpb=97121ba2afb8d566ff1bf5c4e8fc5d4077940a7f;p=oota-llvm.git diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 3f8714085ae..26722a3ca11 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -19,6 +19,8 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.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" @@ -123,6 +125,22 @@ 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(unsigned Start, unsigned End) const { + assert(Start < End && "Invalid range"); + const_iterator I = begin(); + const_iterator E = end(); + const_iterator si = std::upper_bound(I, E, Start); + const_iterator ei = std::upper_bound(I, E, End); + if (si != ei) + return true; + if (si == I) + return false; + --si; + return si->contains(Start); +} + /// 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 @@ -288,9 +306,9 @@ void LiveInterval::removeRange(unsigned Start, unsigned End, VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); - } while (!valnos.empty() && valnos.back()->def == ~1U); + } while (!valnos.empty() && valnos.back()->isUnused()); } else { - ValNo->def = ~1U; + ValNo->setIsUnused(true); } } } @@ -336,12 +354,35 @@ void LiveInterval::removeValNo(VNInfo *ValNo) { VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); - } while (!valnos.empty() && valnos.back()->def == ~1U); + } while (!valnos.empty() && valnos.back()->isUnused()); } else { - ValNo->def = ~1U; + ValNo->setIsUnused(true); } } +/// scaleNumbering - Renumber VNI and ranges to provide gaps for new +/// instructions. +void LiveInterval::scaleNumbering(unsigned factor) { + // Scale ranges. + for (iterator RI = begin(), RE = end(); RI != RE; ++RI) { + RI->start = InstrSlots::scale(RI->start, factor); + RI->end = InstrSlots::scale(RI->end, factor); + } + + // Scale VNI info. + for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) { + VNInfo *vni = *VNI; + + if (vni->isDefAccurate()) + vni->def = InstrSlots::scale(vni->def, factor); + + for (unsigned i = 0; i < vni->kills.size(); ++i) { + if (vni->kills[i] != 0) + vni->kills[i] = InstrSlots::scale(vni->kills[i], factor); + } + } +} + /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. LiveInterval::const_iterator @@ -381,13 +422,13 @@ VNInfo *LiveInterval::findDefinedVNInfo(unsigned DefIdxOrReg) const { return VNI; } - /// 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, const int *LHSValNoAssignments, const int *RHSValNoAssignments, - SmallVector &NewVNInfo) { + 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; @@ -441,7 +482,7 @@ void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments, for (unsigned i = 0; i < NumNewVals; ++i) { VNInfo *VNI = NewVNInfo[i]; if (VNI) { - if (i >= NumVals) + if (NumValNos >= NumVals) valnos.push_back(VNI); else valnos[NumValNos] = VNI; @@ -462,8 +503,18 @@ void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments, } weight += Other.weight; - if (Other.preference && !preference) - preference = Other.preference; + + // Update regalloc hint if currently there isn't one. + if (TargetRegisterInfo::isVirtualRegister(reg) && + TargetRegisterInfo::isVirtualRegister(Other.reg)) { + std::pair Hint = MRI->getRegAllocationHint(reg); + if (Hint.first == 0 && Hint.second == 0) { + std::pair OtherHint = + MRI->getRegAllocationHint(Other.reg); + if (OtherHint.first || OtherHint.second) + MRI->setRegAllocationHint(reg, OtherHint.first, OtherHint.second); + } + } } /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live @@ -542,29 +593,15 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); - } while (!valnos.empty() && valnos.back()->def == ~1U); + } while (!valnos.empty() && valnos.back()->isUnused()); } else { - V1->def = ~1U; + V1->setIsUnused(true); } } } } } -VNInfo *LiveInterval::getUnknownValNo(BumpPtrAllocator &VNInfoAllocator) { - unsigned i = getNumValNums(); - if (i) { - do { - --i; - VNInfo *VNI = getValNumInfo(i); - if (VNI->def == ~0U && !VNI->copy && - !VNI->hasPHIKill && !VNI->redefByEC && VNI->kills.empty()) - return VNI; - } while (i != 0); - } - return getNextValue(~0U, 0, VNInfoAllocator); -} - /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them @@ -573,12 +610,22 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator) { if (Clobbers.empty()) return; - // Find a value # to use for the clobber ranges. If there is already a value# - // for unknown values, use it. - VNInfo *ClobberValNo = getUnknownValNo(VNInfoAllocator); - + DenseMap ValNoMaps; + VNInfo *UnusedValNo = 0; iterator IP = begin(); for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) { + // For every val# in the Clobbers interval, create a new "unknown" val#. + VNInfo *ClobberValNo = 0; + DenseMap::iterator VI = ValNoMaps.find(I->valno); + if (VI != ValNoMaps.end()) + ClobberValNo = VI->second; + else if (UnusedValNo) + ClobberValNo = UnusedValNo; + else { + UnusedValNo = ClobberValNo = getNextValue(0, 0, false, VNInfoAllocator); + ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo)); + } + bool Done = false; unsigned Start = I->start, End = I->end; // If a clobber range starts before an existing range and ends after @@ -613,15 +660,22 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, // Insert the clobber interval. IP = addRangeFrom(LiveRange(SubRangeStart, SubRangeEnd, ClobberValNo), IP); + UnusedValNo = 0; } } + + if (UnusedValNo) { + // Delete the last unused val#. + valnos.pop_back(); + UnusedValNo->~VNInfo(); + } } void LiveInterval::MergeInClobberRange(unsigned Start, unsigned End, BumpPtrAllocator &VNInfoAllocator) { // Find a value # to use for the clobber ranges. If there is already a value# // for unknown values, use it. - VNInfo *ClobberValNo = getUnknownValNo(VNInfoAllocator); + VNInfo *ClobberValNo = getNextValue(0, 0, false, VNInfoAllocator); iterator IP = begin(); IP = std::upper_bound(IP, end(), Start); @@ -704,24 +758,26 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); - } while (valnos.back()->def == ~1U); + } while (valnos.back()->isUnused()); } else { - V1->def = ~1U; + V1->setIsUnused(true); } return V2; } void LiveInterval::Copy(const LiveInterval &RHS, + MachineRegisterInfo *MRI, BumpPtrAllocator &VNInfoAllocator) { ranges.clear(); valnos.clear(); - preference = RHS.preference; + 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); - VNInfo *NewVNI = getNextValue(~0U, 0, VNInfoAllocator); - copyValNumInfo(NewVNI, VNI); + createValueCopy(VNI, VNInfoAllocator); } for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) { const LiveRange &LR = RHS.ranges[i]; @@ -773,22 +829,22 @@ void LiveInterval::print(std::ostream &OS, const VNInfo *vni = *i; if (vnum) OS << " "; OS << vnum << "@"; - if (vni->def == ~1U) { + if (vni->isUnused()) { OS << "x"; } else { - if (vni->def == ~0U) + if (!vni->isDefAccurate()) OS << "?"; else OS << vni->def; unsigned ee = vni->kills.size(); - if (ee || vni->hasPHIKill) { + if (ee || vni->hasPHIKill()) { OS << "-("; for (unsigned j = 0; j != ee; ++j) { OS << vni->kills[j]; if (j != ee-1) OS << " "; } - if (vni->hasPHIKill) { + if (vni->hasPHIKill()) { if (ee) OS << " "; OS << "phi";