From da24989368e50787a06329a7876f7e14ee3545a2 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 13 Feb 2008 02:48:26 +0000 Subject: [PATCH] - Added removeValNo() to remove all live ranges of a particular value#. - removeRange() can now update value# information. llvm-svn: 47044 --- include/llvm/CodeGen/LiveInterval.h | 16 +++---- lib/CodeGen/LiveInterval.cpp | 68 ++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 52bbf78e3b2..e7ebb5157df 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -299,12 +299,6 @@ namespace llvm { /// contains the specified index, or end() if there is none. iterator FindLiveRangeContaining(unsigned Idx); - /// getOverlapingRanges - Given another live interval which is defined as a - /// copy from this one, return a list of all of the live ranges where the - /// two overlap and have different value numbers. - void getOverlapingRanges(const LiveInterval &Other, unsigned CopyIdx, - std::vector &Ranges); - /// overlaps - Return true if the intersection of the two live intervals is /// not empty. bool overlaps(const LiveInterval& other) const { @@ -332,12 +326,16 @@ namespace llvm { /// removeRange - Remove the specified range from this interval. Note that /// the range must already be in this interval in its entirety. - void removeRange(unsigned Start, unsigned End); + void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false); - void removeRange(LiveRange LR) { - removeRange(LR.start, LR.end); + void removeRange(LiveRange LR, bool RemoveDeadValNo = false) { + removeRange(LR.start, LR.end, RemoveDeadValNo); } + /// removeValNo - Remove all the ranges defined by the specified value#. + /// Also remove the value# from value# list. + void removeValNo(VNInfo *ValNo); + /// getSize - Returns the sum of sizes of all the LiveRange's. /// unsigned getSize() const; diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 22ebf3b41d4..b09ffd48e64 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -225,7 +225,8 @@ 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) { +void LiveInterval::removeRange(unsigned Start, unsigned 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!"); @@ -234,9 +235,34 @@ void LiveInterval::removeRange(unsigned Start, unsigned 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) { removeKills(I->valno, Start, 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. 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 (ValNo->id == getNumValNums()-1) { + do { + VNInfo *VNI = valnos.back(); + valnos.pop_back(); + VNI->~VNInfo(); + } while (!valnos.empty() && valnos.back()->def == ~1U); + } else { + ValNo->def = ~1U; + } + } + } + ranges.erase(I); // Removed the whole LiveRange. } else I->start = End; @@ -246,7 +272,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(ValNo, Start, End); I->end = Start; return; } @@ -256,9 +282,34 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) { I->end = Start; // Trim the old interval. // Insert the new one. - ranges.insert(next(I), LiveRange(End, OldEnd, I->valno)); + ranges.insert(next(I), LiveRange(End, OldEnd, ValNo)); } +/// 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. 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 (ValNo->id == getNumValNums()-1) { + do { + VNInfo *VNI = valnos.back(); + valnos.pop_back(); + VNI->~VNInfo(); + } while (!valnos.empty() && valnos.back()->def == ~1U); + } else { + ValNo->def = ~1U; + } +} + /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. LiveInterval::const_iterator @@ -445,7 +496,7 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); - } while (valnos.back()->def == ~1U); + } while (!valnos.empty() && valnos.back()->def == ~1U); } else { V1->def = ~1U; } @@ -624,15 +675,18 @@ void LiveInterval::print(std::ostream &OS, else OS << vni->def; unsigned ee = vni->kills.size(); - if (ee) { + if (ee || vni->hasPHIKill) { OS << "-("; for (unsigned j = 0; j != ee; ++j) { OS << vni->kills[j]; if (j != ee-1) OS << " "; } - if (vni->hasPHIKill) - OS << " phi"; + if (vni->hasPHIKill) { + if (ee) + OS << " "; + OS << "phi"; + } OS << ")"; } }