diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h index a80df8f8b8ff..b5b6b2e0c64b 100644 --- a/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/llvm/include/llvm/CodeGen/LiveInterval.h @@ -22,6 +22,7 @@ #define LLVM_CODEGEN_LIVEINTERVAL_H #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Streams.h" #include #include @@ -35,20 +36,18 @@ namespace llvm { /// VNInfo - If the value number definition is undefined (e.g. phi /// merge point), it contains ~0u,x. If the value number is not in use, it /// contains ~1u,x to indicate that the value # is not used. - /// parent- LiveInterval parent. /// def - Instruction # of the definition. /// reg - Source reg iff val# is defined by a copy; zero otherwise. /// kills - Instruction # of the kills. If a kill is an odd #, it means /// the kill is a phi join point. struct VNInfo { - LiveInterval *parent; unsigned id; unsigned def; unsigned reg; SmallVector kills; - VNInfo() : parent(0), id(~1U), def(~1U), reg(0) {} - VNInfo(LiveInterval *p, unsigned i, unsigned d, unsigned r) - : parent(p), id(i), def(d), reg(r) {} + VNInfo() : id(~1U), def(~1U), reg(0) {} + VNInfo(unsigned i, unsigned d, unsigned r) + : id(i), def(d), reg(r) {} }; /// LiveRange structure - This represents a simple register range in the @@ -129,15 +128,6 @@ namespace llvm { const_vni_iterator vni_begin() const { return valnos.begin(); } const_vni_iterator vni_end() const { return valnos.end(); } - ~LiveInterval() { - for (vni_iterator i = vni_begin(), e = vni_end(); i != e; ++i) { - VNInfo *VNI = *i; - if (VNI->parent == this) - delete VNI; - } - valnos.clear(); - } - /// advanceTo - Advance the specified iterator to point to the LiveRange /// containing the specified position, or end() if the position is past the /// end of the interval. If no LiveRange contains this position, but the @@ -154,35 +144,43 @@ namespace llvm { unsigned getNumValNums() const { return valnos.size(); } - /// getFirstValNumInfo - Returns pointer to the first val#. + /// getValNumInfo - Returns pointer to the specified val#. /// - inline VNInfo *getFirstValNumInfo() { - return valnos.front(); + inline VNInfo *getValNumInfo(unsigned ValNo) { + return valnos[ValNo]; } - inline const VNInfo *getFirstValNumInfo() const { - return valnos.front(); + inline const VNInfo *getValNumInfo(unsigned ValNo) const { + return valnos[ValNo]; } /// copyValNumInfo - Copy the value number info for one value number to /// another. - void copyValNumInfo(VNInfo &DstValNo, VNInfo &SrcValNo) { - DstValNo.def = SrcValNo.def; - DstValNo.reg = SrcValNo.reg; - DstValNo.kills = SrcValNo.kills; + void copyValNumInfo(VNInfo *DstValNo, VNInfo *SrcValNo) { + DstValNo->def = SrcValNo->def; + DstValNo->reg = SrcValNo->reg; + DstValNo->kills = SrcValNo->kills; } /// getNextValue - Create a new value number and return it. MIIdx specifies /// the instruction that defines the value number. VNInfo *getNextValue(unsigned MIIdx, unsigned SrcReg) { - VNInfo *VNI = new VNInfo(this, valnos.size(), MIIdx, SrcReg); +#ifdef __GNUC__ + unsigned Alignment = __alignof__(VNInfo); +#else + // FIXME: ugly. + unsigned Alignment = 8; +#endif + VNInfo *VNI= static_cast(VNInfoAllocator.Allocate(sizeof(VNInfo), + Alignment)); + new (VNI) VNInfo(valnos.size(), MIIdx, SrcReg); valnos.push_back(VNI); return VNI; } /// addKillForValNum - Add a kill instruction index to the specified value /// number. - static void addKill(VNInfo &VNI, unsigned KillIdx) { - SmallVector &kills = VNI.kills; + static void addKill(VNInfo *VNI, unsigned KillIdx) { + SmallVector &kills = VNI->kills; if (kills.empty()) { kills.push_back(KillIdx); } else { @@ -194,21 +192,21 @@ namespace llvm { /// addKills - Add a number of kills into the VNInfo kill vector. If this /// interval is live at a kill point, then the kill is not added. - void addKills(VNInfo &VNI, const SmallVector &kills) { + void addKills(VNInfo *VNI, const SmallVector &kills) { for (unsigned i = 0, e = kills.size(); i != e; ++i) { unsigned KillIdx = kills[i]; if (!liveAt(KillIdx)) { SmallVector::iterator - I = std::lower_bound(VNI.kills.begin(), VNI.kills.end(), KillIdx); - VNI.kills.insert(I, KillIdx); + I = std::lower_bound(VNI->kills.begin(), VNI->kills.end(), KillIdx); + VNI->kills.insert(I, KillIdx); } } } /// removeKill - Remove the specified kill from the list of kills of /// the specified val#. - static bool removeKill(VNInfo &VNI, unsigned KillIdx) { - SmallVector &kills = VNI.kills; + static bool removeKill(VNInfo *VNI, unsigned KillIdx) { + SmallVector &kills = VNI->kills; SmallVector::iterator I = std::lower_bound(kills.begin(), kills.end(), KillIdx); if (I != kills.end() && *I == KillIdx) { @@ -220,8 +218,8 @@ namespace llvm { /// removeKills - Remove all the kills in specified range /// [Start, End] of the specified val#. - void removeKills(VNInfo &VNI, unsigned Start, unsigned End) { - SmallVector &kills = VNI.kills; + void removeKills(VNInfo *VNI, unsigned Start, unsigned End) { + SmallVector &kills = VNI->kills; SmallVector::iterator I = std::lower_bound(kills.begin(), kills.end(), Start); SmallVector::iterator @@ -237,10 +235,11 @@ namespace llvm { /// 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 MergeInClobberRanges(const LiveInterval &Clobbers); + /// used with an unknown definition value. Caller must pass in reference to + /// VNInfoAllocator since it will create a new val#. + void MergeInClobberRanges(const LiveInterval &Clobbers, + BumpPtrAllocator &VNInfoAllocator); - /// 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 diff --git a/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h index bf78475a01f1..671de02eeeb6 100644 --- a/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -27,6 +27,7 @@ #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" namespace llvm { @@ -43,6 +44,10 @@ namespace llvm { const TargetInstrInfo* tii_; LiveVariables* lv_; + /// Special pool allocator for VNInfo's (LiveInterval val#). + /// + BumpPtrAllocator VNInfoAllocator; + /// MBB2IdxMap - The indexes of the first and last instructions in the /// specified basic block. std::vector > MBB2IdxMap; @@ -194,6 +199,8 @@ namespace llvm { } } + BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; } + virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual void releaseMemory(); diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp index 53ffbe3fca45..4d38f0adcfa2 100644 --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -124,7 +124,7 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) { ranges.erase(next(I), MergeTo); // Update kill info. - removeKills(*ValNo, OldEnd, I->end-1); + removeKills(ValNo, OldEnd, I->end-1); // 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. @@ -233,7 +233,7 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) { // If the span we are removing is at the start of the LiveRange, adjust it. if (I->start == Start) { if (I->end == End) { - removeKills(*I->valno, Start, End); + removeKills(I->valno, Start, End); ranges.erase(I); // Removed the whole LiveRange. } else I->start = End; @@ -243,7 +243,7 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) { // Otherwise if the span we are removing is at the end of the LiveRange, // adjust the other way. if (I->end == End) { - removeKills(*I->valno, Start, End); + removeKills(I->valno, Start, End); I->end = Start; return; } @@ -296,17 +296,8 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, for (unsigned i = 0; i != NumVals; ++i) { unsigned LHSValID = LHSValNoAssignments[i]; if (i != LHSValID || - (NewVNInfo[LHSValID] && NewVNInfo[LHSValID]->parent != this)) + (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) MustMapCurValNos = true; - - // There might be some dead val#, create VNInfo for them. - if (i < NumNewVals) { - VNInfo *VNI = NewVNInfo[i]; - if (!VNI) { - VNI = new VNInfo(this, i, ~1U, 0); - NewVNInfo[i] = VNI; - } - } } // If we have to apply a mapping to our base interval assignment, rewrite it @@ -345,27 +336,18 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, OtherAssignments.push_back(RHSValNoAssignments[I->valno->id]); // Update val# info. Renumber them and make sure they all belong to this - // LiveInterval now. - for (unsigned i = 0; i != NumVals; ++i) { - if (i == NumNewVals) - break; + // LiveInterval now. Also remove dead val#'s. + unsigned NumValNos = 0; + for (unsigned i = 0; i < NumNewVals; ++i) { VNInfo *VNI = NewVNInfo[i]; - if (VNI->parent != this || VNI->id != i) { - VNI->parent = this; - VNI->id = i; // Renumber val#. - valnos[i] = VNI; + if (VNI) { + if (i >= NumVals) + valnos.push_back(VNI); + else + valnos[NumValNos] = VNI; + VNI->id = NumValNos++; // Renumber val#. } } - for (unsigned i = NumVals; i < NumNewVals; ++i) { - VNInfo *VNI = NewVNInfo[i]; - if (!VNI) - VNI = new VNInfo(this, i, ~1U, 0); - else { - VNI->parent = this; - VNI->id = i; // Renumber val#. - } - valnos.push_back(VNI); - } if (NumNewVals < NumVals) valnos.resize(NumNewVals); // shrinkify @@ -375,6 +357,7 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, 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); } @@ -403,13 +386,14 @@ void LiveInterval::MergeRangesInAsValue(const LiveInterval &RHS, /// 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) { +void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, + BumpPtrAllocator &VNInfoAllocator) { 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! - VNInfo *ClobberValNo = getNextValue(~0U, 0); + VNInfo *ClobberValNo = getNextValue(~0U, 0, VNInfoAllocator); iterator IP = begin(); for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) { @@ -448,7 +432,7 @@ void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { // Make sure V2 is smaller than V1. if (V1->id < V2->id) { - copyValNumInfo(*V1, *V2); + copyValNumInfo(V1, V2); std::swap(V1, V2); } @@ -492,9 +476,7 @@ void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { // ~1U so it can be nuked later. if (V1->id == getNumValNums()-1) { do { - VNInfo *VNI = valnos.back(); valnos.pop_back(); - delete VNI; } while (valnos.back()->def == ~1U); } else { V1->def = ~1U; diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 25de7c3ae381..2f93b7694854 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -62,6 +62,7 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { } void LiveIntervals::releaseMemory() { + VNInfoAllocator.Reset(); mi2iMap_.clear(); i2miMap_.clear(); r2iMap_.clear(); @@ -448,13 +449,13 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, unsigned reg) { if (HasUse) { LiveRange LR(getLoadIndex(index), getUseIndex(index), - nI.getNextValue(~0U, 0)); + nI.getNextValue(~0U, 0, VNInfoAllocator)); DOUT << " +" << LR; nI.addRange(LR); } if (HasDef) { LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(~0U, 0)); + nI.getNextValue(~0U, 0, VNInfoAllocator)); DOUT << " +" << LR; nI.addRange(LR); } @@ -500,9 +501,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, VNInfo *ValNo; unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNo = interval.getNextValue(defIndex, 0); + ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); else - ValNo = interval.getNextValue(defIndex, SrcReg); + ValNo = interval.getNextValue(defIndex, SrcReg, VNInfoAllocator); assert(ValNo->id == 0 && "First value in interval is not 0?"); @@ -526,7 +527,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, LiveRange LR(defIndex, killIdx, ValNo); interval.addRange(LR); DOUT << " +" << LR << "\n"; - interval.addKill(*ValNo, killIdx); + interval.addKill(ValNo, killIdx); return; } } @@ -565,7 +566,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo); interval.addRange(LR); - interval.addKill(*ValNo, killIdx); + interval.addKill(ValNo, killIdx); DOUT << " +" << LR; } @@ -597,8 +598,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // The new value number (#1) is defined by the instruction we claimed // defined value #0. - VNInfo *ValNo = interval.getNextValue(0, 0); - interval.copyValNumInfo(*ValNo, *OldValNo); + VNInfo *ValNo = interval.getNextValue(0, 0, VNInfoAllocator); + interval.copyValNumInfo(ValNo, OldValNo); // Value#0 is now defined by the 2-addr instruction. OldValNo->def = RedefIndex; @@ -608,8 +609,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, LiveRange LR(DefIndex, RedefIndex, ValNo); DOUT << " replace range with " << LR; interval.addRange(LR); - interval.addKill(*ValNo, RedefIndex); - interval.removeKills(*ValNo, RedefIndex, OldEnd); + interval.addKill(ValNo, RedefIndex); + interval.removeKills(ValNo, RedefIndex, OldEnd); // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. @@ -628,22 +629,22 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, "PHI elimination vreg should have one kill, the PHI itself!"); // Remove the old range that we now know has an incorrect number. - VNInfo *VNI = interval.getFirstValNumInfo(); + VNInfo *VNI = interval.getValNumInfo(0); MachineInstr *Killer = vi.Kills[0]; unsigned Start = getMBBStartIdx(Killer->getParent()); unsigned End = getUseIndex(getInstructionIndex(Killer))+1; DOUT << " Removing [" << Start << "," << End << "] from: "; interval.print(DOUT, mri_); DOUT << "\n"; interval.removeRange(Start, End); - interval.addKill(*VNI, Start+1); // odd # means phi node + interval.addKill(VNI, Start+1); // odd # means phi node DOUT << " RESULT: "; interval.print(DOUT, mri_); // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) - LiveRange LR(Start, End, interval.getNextValue(~0, 0)); + LiveRange LR(Start, End, interval.getNextValue(~0, 0, VNInfoAllocator)); DOUT << " replace range with " << LR; interval.addRange(LR); - interval.addKill(*LR.valno, End); + interval.addKill(LR.valno, End); DOUT << " RESULT: "; interval.print(DOUT, mri_); } @@ -655,14 +656,14 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, VNInfo *ValNo; unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNo = interval.getNextValue(defIndex, 0); + ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); else - ValNo = interval.getNextValue(defIndex, SrcReg); + ValNo = interval.getNextValue(defIndex, SrcReg, VNInfoAllocator); unsigned killIndex = getInstructionIndex(&mbb->back()) + InstrSlots::NUM; LiveRange LR(defIndex, killIndex, ValNo); interval.addRange(LR); - interval.addKill(*ValNo, killIndex-1); // odd # means phi node + interval.addKill(ValNo, killIndex-1); // odd # means phi node DOUT << " +" << LR; } } @@ -724,10 +725,10 @@ exit: // Already exists? Extend old live interval. LiveInterval::iterator OldLR = interval.FindLiveRangeContaining(start); VNInfo *ValNo = (OldLR != interval.end()) - ? OldLR->valno : interval.getNextValue(start, SrcReg); + ? OldLR->valno : interval.getNextValue(start, SrcReg, VNInfoAllocator); LiveRange LR(start, end, ValNo); interval.addRange(LR); - interval.addKill(*LR.valno, end); + interval.addKill(LR.valno, end); DOUT << " +" << LR << '\n'; } @@ -792,9 +793,9 @@ exit: } } - LiveRange LR(start, end, interval.getNextValue(start, 0)); + LiveRange LR(start, end, interval.getNextValue(start, 0, VNInfoAllocator)); interval.addRange(LR); - interval.addKill(*LR.valno, end); + interval.addKill(LR.valno, end); DOUT << " +" << LR << '\n'; } diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index 03e416b26064..4d5c0819ad07 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -158,7 +158,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte for (const unsigned *AS = mri_->getSubRegisters(IntB.reg); *AS; ++AS) { LiveInterval &AliasLI = li_->getInterval(*AS); AliasLI.addRange(LiveRange(FillerStart, FillerEnd, - AliasLI.getNextValue(FillerStart, 0))); + AliasLI.getNextValue(FillerStart, 0, li_->getVNInfoAllocator()))); } } @@ -366,7 +366,8 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, // Update the liveintervals of sub-registers. for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS) - li_->getInterval(*AS).MergeInClobberRanges(*ResSrcInt); + li_->getInterval(*AS).MergeInClobberRanges(*ResSrcInt, + li_->getVNInfoAllocator()); } else { // Merge use info if the destination is a virtual register. LiveVariables::VarInfo& dVI = lv_->getVarInfo(repDstReg); @@ -564,13 +565,13 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS) // Okay, now that there is a single LHS value number that we're merging the // RHS into, update the value number info for the LHS to indicate that the // value number is defined where the RHS value number was. - const VNInfo *VNI = RHS.getFirstValNumInfo(); + const VNInfo *VNI = RHS.getValNumInfo(0); LHSValNo->def = VNI->def; LHSValNo->reg = VNI->reg; // Okay, the final step is to loop over the RHS live intervals, adding them to // the LHS. - LHS.addKills(*LHSValNo, VNI->kills); + LHS.addKills(LHSValNo, VNI->kills); LHS.MergeRangesInAsValue(RHS, LHSValNo); LHS.weight += RHS.weight; if (RHS.preference && !LHS.preference) @@ -625,7 +626,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, int RHSVal0DefinedFromLHS = -1; int RHSValID = -1; VNInfo *RHSValNoInfo = NULL; - VNInfo *RHSValNoInfo0 = RHS.getFirstValNumInfo(); + VNInfo *RHSValNoInfo0 = RHS.getValNumInfo(0); unsigned RHSSrcReg = RHSValNoInfo0->reg; if ((RHSSrcReg == 0 || rep(RHSSrcReg) != LHS.reg)) { // If RHS is not defined as a copy from the LHS, we can use simpler and @@ -809,8 +810,8 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, E = LHSValsDefinedFromRHS.end(); I != E; ++I) { VNInfo *VNI = I->first; unsigned LHSValID = LHSValNoAssignments[VNI->id]; - LiveInterval::removeKill(*NewVNInfo[LHSValID], VNI->def); - RHS.addKills(*NewVNInfo[LHSValID], VNI->kills); + LiveInterval::removeKill(NewVNInfo[LHSValID], VNI->def); + RHS.addKills(NewVNInfo[LHSValID], VNI->kills); } RHS.join(LHS, &RHSValNoAssignments[0], &LHSValNoAssignments[0], NewVNInfo); @@ -821,8 +822,8 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, E = RHSValsDefinedFromLHS.end(); I != E; ++I) { VNInfo *VNI = I->first; unsigned RHSValID = RHSValNoAssignments[VNI->id]; - LiveInterval::removeKill(*NewVNInfo[RHSValID], VNI->def); - LHS.addKills(*NewVNInfo[RHSValID], VNI->kills); + LiveInterval::removeKill(NewVNInfo[RHSValID], VNI->def); + LHS.addKills(NewVNInfo[RHSValID], VNI->kills); } LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0], NewVNInfo);