// Merge a LiveInterval's segments. Guarantee no overlaps. void LiveIntervalUnion::unify(LiveInterval &VirtReg) { if (VirtReg.empty()) return; ++Tag; // Insert each of the virtual register's live segments into the map. LiveInterval::iterator RegPos = VirtReg.begin(); LiveInterval::iterator RegEnd = VirtReg.end(); SegmentIter SegPos = Segments.find(RegPos->start); while (SegPos.valid()) { SegPos.insert(RegPos->start, RegPos->end, &VirtReg); if (++RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } // We have reached the end of Segments, so it is no longer necessary to search // for the insertion position. // It is faster to insert the end first. --RegEnd; SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg); for (; RegPos != RegEnd; ++RegPos, ++SegPos) SegPos.insert(RegPos->start, RegPos->end, &VirtReg); }
/// When adding a new instruction to liveness, the newly added definition /// will start a new live segment. This may happen at a position that falls /// within an existing live segment. In such case that live segment needs to /// be truncated to make room for the new segment. Ultimately, the truncation /// will occur at the last use, but for now the segment can be terminated /// right at the place where the new segment will start. The segments will be /// shrunk-to-uses later. void HexagonExpandCondsets::terminateSegment(LiveInterval::iterator LT, SlotIndex S, LiveInterval &LI) { // Terminate the live segment pointed to by LT within a live interval LI. if (LT == LI.end()) return; VNInfo *OldVN = LT->valno; SlotIndex EX = LT->end; LT->end = S; // If LT does not end at a block boundary, the termination is done. if (!EX.isBlock()) return; // If LT ended at a block boundary, it's possible that its value number // is picked up at the beginning other blocks. Create a new value number // and change such blocks to use it instead. VNInfo *NewVN = 0; for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { if (!I->start.isBlock() || I->valno != OldVN) continue; // Generate on-demand a new value number that is defined by the // block beginning (i.e. -phi). if (!NewVN) NewVN = LI.getNextValue(I->start, LIS->getVNInfoAllocator()); I->valno = NewVN; } }
void SplitEditor::deleteRematVictims() { SmallVector<MachineInstr*, 8> Dead; for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){ LiveInterval *LI = *I; for (LiveInterval::const_iterator LII = LI->begin(), LIE = LI->end(); LII != LIE; ++LII) { // Dead defs end at the store slot. if (LII->end != LII->valno->def.getNextSlot()) continue; MachineInstr *MI = LIS.getInstructionFromIndex(LII->valno->def); assert(MI && "Missing instruction for dead def"); MI->addRegisterDead(LI->reg, &TRI); if (!MI->allDefsAreDead()) continue; DEBUG(dbgs() << "All defs dead: " << *MI); Dead.push_back(MI); } } if (Dead.empty()) return; Edit->eliminateDeadDefs(Dead, LIS, VRM, TII); }
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI) { // Rewrite instructions. for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), RE = MRI.reg_end(); RI != RE;) { MachineOperand &MO = *RI; MachineInstr *MI = RI->getParent(); ++RI; // DBG_VALUE instructions don't have slot indexes, so get the index of the // instruction before them. // Normally, DBG_VALUE instructions are removed before this function is // called, but it is not a requirement. SlotIndex Idx; if (MI->isDebugValue()) Idx = LIS.getSlotIndexes()->getIndexBefore(MI); else Idx = LIS.getInstructionIndex(MI); LiveQueryResult LRQ = LI.Query(Idx); const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined(); // In the case of an <undef> use that isn't tied to any def, VNI will be // NULL. If the use is tied to a def, VNI will be the defined value. if (!VNI) continue; if (unsigned EqClass = getEqClass(VNI)) MO.setReg(LIV[EqClass-1]->reg); } // 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-1]->empty() || LIV[eq-1]->expiredAt(I->start)) && "New intervals should be empty"); LIV[eq-1]->segments.push_back(*I); } else *J++ = *I; } // TODO: do not cheat anymore by simply cleaning all subranges LI.clearSubRanges(); LI.segments.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-1]->getNumValNums(); LIV[eq-1]->valnos.push_back(VNI); } else { VNI->id = j; LI.valnos[j++] = VNI; } } LI.valnos.resize(j); }
LiveInterval::iterator HexagonExpandCondsets::nextSegment(LiveInterval &LI, SlotIndex S) { for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { if (I->start >= S) return I; } return LI.end(); }
/// 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) { LiveRangeUpdater Updater(this); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) if (I->valno == RHSValNo) Updater.add(I->start, I->end, LHSValNo); }
LiveInterval::iterator HexagonExpandCondsets::prevSegment(LiveInterval &LI, SlotIndex S) { LiveInterval::iterator P = LI.end(); for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { if (I->end > S) return P; P = I; } return P; }
static void determineMissingVNIs(const SlotIndexes &Indexes, LiveInterval &LI) { SmallPtrSet<const MachineBasicBlock*, 5> Visited; LiveRange::iterator OutIt; VNInfo *PrevValNo = nullptr; for (LiveRange::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { LiveRange::Segment &S = *I; // Determine final VNI if necessary. if (S.valno == nullptr) { // This can only happen at the begin of a basic block. assert(S.start.isBlock() && "valno should only be missing at block begin"); Visited.clear(); const MachineBasicBlock *MBB = Indexes.getMBBFromIndex(S.start); for (const MachineBasicBlock *Pred : MBB->predecessors()) { VNInfo *VNI = searchForVNI(Indexes, LI, Pred, Visited); if (VNI != nullptr) { S.valno = VNI; break; } } assert(S.valno != nullptr && "could not determine valno"); } // Merge with previous segment if it has the same VNI. if (PrevValNo == S.valno && OutIt->end == S.start) { OutIt->end = S.end; } else { // Didn't merge. Move OutIt to next segment. if (PrevValNo == nullptr) OutIt = LI.begin(); else ++OutIt; if (OutIt != I) *OutIt = *I; PrevValNo = S.valno; } } // If we merged some segments chop off the end. ++OutIt; LI.segments.erase(OutIt, LI.end()); }
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI, BitVector &UsableRegs) { if (LI.empty()) return false; LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); // Use a smaller arrays for local live ranges. ArrayRef<SlotIndex> Slots; ArrayRef<const uint32_t*> Bits; if (MachineBasicBlock *MBB = intervalIsInOneMBB(LI)) { Slots = getRegMaskSlotsInBlock(MBB->getNumber()); Bits = getRegMaskBitsInBlock(MBB->getNumber()); } else { Slots = getRegMaskSlots(); Bits = getRegMaskBits(); } // We are going to enumerate all the register mask slots contained in LI. // Start with a binary search of RegMaskSlots to find a starting point. ArrayRef<SlotIndex>::iterator SlotI = std::lower_bound(Slots.begin(), Slots.end(), LiveI->start); ArrayRef<SlotIndex>::iterator SlotE = Slots.end(); // No slots in range, LI begins after the last call. if (SlotI == SlotE) return false; bool Found = false; for (;;) { assert(*SlotI >= LiveI->start); // Loop over all slots overlapping this segment. while (*SlotI < LiveI->end) { // *SlotI overlaps LI. Collect mask bits. if (!Found) { // This is the first overlap. Initialize UsableRegs to all ones. UsableRegs.clear(); UsableRegs.resize(TRI->getNumRegs(), true); Found = true; } // Remove usable registers clobbered by this mask. UsableRegs.clearBitsNotInMask(Bits[SlotI-Slots.begin()]); if (++SlotI == SlotE) return Found; } // *SlotI is beyond the current LI segment. LiveI = LI.advanceTo(LiveI, *SlotI); if (LiveI == LiveE) return Found; // Advance SlotI until it overlaps. while (*SlotI < LiveI->start) if (++SlotI == SlotE) return Found; } }
/// 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<VNInfo*, 4> ReplacedValNos; iterator IP = begin(); 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; } // Map the valno in the other live range to the current live range. IP = addRangeFrom(LiveRange(Start, End, LHSValNo), IP); } SmallSet<VNInfo*, 4> 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); } } } }
/// 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, VNInfo *LHSValNo) { // TODO: Make this more efficient. iterator InsertPos = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { // Map the valno in the other live range to the current live range. LiveRange Tmp = *I; Tmp.valno = LHSValNo; InsertPos = addRangeFrom(Tmp, InsertPos); } }
bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) { for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { LiveRange::Segment &LR = *I; // Range must start at a register... if (!LR.start.isRegister()) return false; // ...and end in a register or in a dead slot. if (!LR.end.isRegister() && !LR.end.isDead()) return false; } return true; }
// Merge a LiveInterval's segments. Guarantee no overlaps. void LiveIntervalUnion::unify(LiveInterval &VirtReg) { if (VirtReg.empty()) return; // Insert each of the virtual register's live segments into the map. LiveInterval::iterator RegPos = VirtReg.begin(); LiveInterval::iterator RegEnd = VirtReg.end(); SegmentIter SegPos = Segments.find(RegPos->start); for (;;) { SegPos.insert(RegPos->start, RegPos->end, &VirtReg); if (++RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } }
/// Given an updated live interval LI for register Reg, update the kill flags /// in instructions using Reg to reflect the liveness changes. void HexagonExpandCondsets::updateKillFlags(unsigned Reg, LiveInterval &LI) { MRI->clearKillFlags(Reg); for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { SlotIndex EX = I->end; if (!EX.isRegister()) continue; MachineInstr *MI = LIS->getInstructionFromIndex(EX); for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isUse() || Op.getReg() != Reg) continue; // Only set the kill flag on the first encountered use of Reg in this // instruction. Op.setIsKill(true); break; } } }
bool LiveIntervals::computeDeadValues(LiveInterval &LI, SmallVectorImpl<MachineInstr*> *dead) { bool PHIRemoved = false; for (auto VNI : LI.valnos) { if (VNI->isUnused()) continue; SlotIndex Def = VNI->def; LiveRange::iterator I = LI.FindSegmentContaining(Def); assert(I != LI.end() && "Missing segment for VNI"); // Is the register live before? Otherwise we may have to add a read-undef // flag for subregister defs. if (MRI->tracksSubRegLiveness()) { if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) { MachineInstr *MI = getInstructionFromIndex(Def); MI->addRegisterDefReadUndef(LI.reg); } } if (I->end != Def.getDeadSlot()) continue; if (VNI->isPHIDef()) { // This is a dead PHI. Remove it. VNI->markUnused(); LI.removeSegment(I); DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n"); PHIRemoved = true; } else { // This is a dead def. Make sure the instruction knows. MachineInstr *MI = getInstructionFromIndex(Def); assert(MI && "No instruction defining live value"); MI->addRegisterDead(LI.reg, TRI); if (dead && MI->allDefsAreDead()) { DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI); dead->push_back(MI); } } } return PHIRemoved; }
// overlaps - Return true if the intersection of the two live intervals is // not empty. // // An example for overlaps(): // // 0: A = ... // 4: B = ... // 8: C = A + B ;; last use of A // // The live intervals should look like: // // A = [3, 11) // B = [7, x) // C = [11, y) // // A->overlaps(C) should return false since we want to be able to join // A and C. // 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; const_iterator je = other.end(); assert((StartPos->start <= i->start || StartPos == other.begin()) && StartPos != other.end() && "Bogus start position hint!"); if (i->start < j->start) { i = std::upper_bound(i, ie, j->start); if (i != ranges.begin()) --i; } else if (j->start < i->start) { ++StartPos; if (StartPos != other.end() && StartPos->start <= i->start) { assert(StartPos < other.end() && i < end()); j = std::upper_bound(j, je, i->start); if (j != other.ranges.begin()) --j; } } else { return true; } if (j == je) return false; while (i != ie) { if (i->start > j->start) { std::swap(i, j); std::swap(ie, je); } if (i->end > j->start) return true; ++i; } return false; }
unsigned SplitAnalysis::countLiveBlocks(const LiveInterval *cli) const { if (cli->empty()) return 0; LiveInterval *li = const_cast<LiveInterval*>(cli); LiveInterval::iterator LVI = li->begin(); LiveInterval::iterator LVE = li->end(); unsigned Count = 0; // Loop over basic blocks where li is live. MachineFunction::const_iterator MFI = LIS.getMBBFromIndex(LVI->start); SlotIndex Stop = LIS.getMBBEndIdx(MFI); for (;;) { ++Count; LVI = li->advanceTo(LVI, Stop); if (LVI == LVE) return Count; do { ++MFI; Stop = LIS.getMBBEndIdx(MFI); } while (Stop <= LVI->start); } }
// Remove a live virtual register's segments from this union. void LiveIntervalUnion::extract(LiveInterval &VirtReg) { if (VirtReg.empty()) return; // Remove each of the virtual register's live segments from the map. LiveInterval::iterator RegPos = VirtReg.begin(); LiveInterval::iterator RegEnd = VirtReg.end(); SegmentIter SegPos = Segments.find(RegPos->start); for (;;) { assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval"); SegPos.erase(); if (!SegPos.valid()) return; // Skip all segments that may have been coalesced. RegPos = VirtReg.advanceTo(RegPos, SegPos.start()); if (RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } }
/// 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<VNInfo*, 16> &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; 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; } // 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->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]]; ++OutIt; for (iterator I = OutIt, E = end(); I != E; ++I) { 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->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<unsigned, 16> 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(); 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); } ComputeJoinedWeight(Other); }
void LiveIntervals::addKillFlags(const VirtRegMap *VRM) { // Keep track of regunit ranges. SmallVector<std::pair<LiveInterval*, LiveInterval::iterator>, 8> RU; for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (MRI->reg_nodbg_empty(Reg)) continue; LiveInterval *LI = &getInterval(Reg); if (LI->empty()) continue; // Find the regunit intervals for the assigned register. They may overlap // the virtual register live range, cancelling any kills. RU.clear(); for (MCRegUnitIterator Units(VRM->getPhys(Reg), TRI); Units.isValid(); ++Units) { LiveInterval *RUInt = &getRegUnit(*Units); if (RUInt->empty()) continue; RU.push_back(std::make_pair(RUInt, RUInt->find(LI->begin()->end))); } // Every instruction that kills Reg corresponds to a live range end point. for (LiveInterval::iterator RI = LI->begin(), RE = LI->end(); RI != RE; ++RI) { // A block index indicates an MBB edge. if (RI->end.isBlock()) continue; MachineInstr *MI = getInstructionFromIndex(RI->end); if (!MI) continue; // Check if any of the regunits are live beyond the end of RI. That could // happen when a physreg is defined as a copy of a virtreg: // // %EAX = COPY %vreg5 // FOO %vreg5 <--- MI, cancel kill because %EAX is live. // BAR %EAX<kill> // // There should be no kill flag on FOO when %vreg5 is rewritten as %EAX. bool CancelKill = false; for (unsigned u = 0, e = RU.size(); u != e; ++u) { LiveInterval *RInt = RU[u].first; LiveInterval::iterator &I = RU[u].second; if (I == RInt->end()) continue; I = RInt->advanceTo(I, RI->end); if (I == RInt->end() || I->start >= RI->end) continue; // I is overlapping RI. CancelKill = true; break; } if (CancelKill) MI->clearRegisterKills(Reg, NULL); else MI->addRegisterKilled(Reg, NULL); } } }
/// 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<VNInfo*, 4> ReplacedValNos; iterator IP = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { 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; } // Map the valno in the other live range to the current live range. IP = addRangeFrom(LiveRange(Start, End, LHSValNo), IP); } SmallSet<VNInfo*, 4> 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. 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->id == getNumValNums()-1) { do { valnos.pop_back(); } while (!valnos.empty() && valnos.back()->isUnused()); } else { V1->setIsUnused(true); } } } } }
/// 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(LiveIntervals &li_, const LiveInterval &Clobbers, VNInfo::Allocator &VNInfoAllocator) { if (Clobbers.empty()) return; DenseMap<VNInfo*, VNInfo*> 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<VNInfo*, VNInfo*>::iterator VI = ValNoMaps.find(I->valno); if (VI != ValNoMaps.end()) ClobberValNo = VI->second; else if (UnusedValNo) ClobberValNo = UnusedValNo; else { UnusedValNo = ClobberValNo = getNextValue(li_.getInvalidIndex(), 0, false, VNInfoAllocator); ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo)); } bool Done = false; SlotIndex Start = I->start, End = I->end; // If a clobber range starts before an existing range and ends after // it, the clobber range will need to be split into multiple ranges. // Loop until the entire clobber range is handled. while (!Done) { Done = true; IP = std::upper_bound(IP, end(), Start); SlotIndex SubRangeStart = Start; SlotIndex SubRangeEnd = End; // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > SubRangeStart) { SubRangeStart = IP[-1].end; // Trimmed away the whole range? if (SubRangeStart >= SubRangeEnd) continue; } // If the end of this range overlaps with an existing liverange, trim it. if (IP != end() && SubRangeEnd > IP->start) { // If the clobber live range extends beyond the existing live range, // it'll need at least another live range, so set the flag to keep // iterating. if (SubRangeEnd > IP->end) { Start = IP->end; Done = false; } SubRangeEnd = IP->start; // If this trimmed away the whole range, ignore it. if (SubRangeStart == SubRangeEnd) continue; } // Insert the clobber interval. IP = addRangeFrom(LiveRange(SubRangeStart, SubRangeEnd, ClobberValNo), IP); UnusedValNo = 0; } } if (UnusedValNo) { // Delete the last unused val#. valnos.pop_back(); } }
/// 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<VNInfo*, 16> &NewVNInfo, MachineRegisterInfo *MRI) { verify(); // 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; 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 && !empty()) { // Map the first live range. iterator OutIt = begin(); OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]]; for (iterator I = llvm::next(OutIt), E = end(); I != E; ++I) { VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]]; assert(nextValNo != 0 && "Huh?"); // 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,4:0)[4,7:1) and map 0/1 onto the same value #. if (OutIt->valno == nextValNo && OutIt->end == I->start) { OutIt->end = I->end; } else { // Didn't merge. Move OutIt to the next interval, ++OutIt; OutIt->valno = nextValNo; if (OutIt != I) { OutIt->start = I->start; OutIt->end = I->end; } } } // If we merge some live ranges, chop off the end. ++OutIt; ranges.erase(OutIt, end()); } // Rewrite Other values before changing the VNInfo ids. // This can leave Other in an invalid state because we're not coalescing // touching segments that now have identical values. That's OK since Other is // not supposed to be valid after calling join(); for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) I->valno = NewVNInfo[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. LiveRangeUpdater Updater(this); for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) Updater.add(*I); }