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; } }
bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg) { if (VirtReg.empty()) return false; CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { const LiveRange &UnitRange = LIS->getRegUnit(*Units); if (VirtReg.overlaps(UnitRange, CP, *LIS->getSlotIndexes())) return true; } return false; }
bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg) { if (VirtReg.empty()) return false; CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) { const LiveRange &UnitRange = LIS->getRegUnit(Unit); return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes()); }); return Result; }
// 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); } }
void RegAllocPBQP::findVRegIntervalsToAlloc() { // Iterate over all live ranges. for (unsigned i = 0, e = mri->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (mri->reg_nodbg_empty(Reg)) continue; LiveInterval *li = &lis->getInterval(Reg); // If this live interval is non-empty we will use pbqp to allocate it. // Empty intervals we allocate in a simple post-processing stage in // finalizeAlloc. if (!li->empty()) { vregsToAlloc.insert(li->reg); } else { emptyIntervalVRegs.insert(li->reg); } } }
void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const { assert(!LI.empty()); assert(LI.hasSubRanges()); using SubRangeIteratorPair = std::pair<const LiveInterval::SubRange *, LiveInterval::const_iterator>; SmallVector<SubRangeIteratorPair, 4> SubRanges; SlotIndex First; SlotIndex Last; for (const LiveInterval::SubRange &SR : LI.subranges()) { SubRanges.push_back(std::make_pair(&SR, SR.begin())); if (!First.isValid() || SR.segments.front().start < First) First = SR.segments.front().start; if (!Last.isValid() || SR.segments.back().end > Last) Last = SR.segments.back().end; } // Check all mbb start positions between First and Last while // simulatenously advancing an iterator for each subrange. for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First); MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) { SlotIndex MBBBegin = MBBI->first; // Advance all subrange iterators so that their end position is just // behind MBBBegin (or the iterator is at the end). LaneBitmask LaneMask; for (auto &RangeIterPair : SubRanges) { const LiveInterval::SubRange *SR = RangeIterPair.first; LiveInterval::const_iterator &SRI = RangeIterPair.second; while (SRI != SR->end() && SRI->end <= MBBBegin) ++SRI; if (SRI == SR->end()) continue; if (SRI->start <= MBBBegin) LaneMask |= SR->LaneMask; } if (LaneMask.none()) continue; MachineBasicBlock *MBB = MBBI->second; MBB->addLiveIn(PhysReg, LaneMask); } }
LiveRegMatrix::InterferenceKind LiveRegMatrix::checkInterference(LiveInterval &VirtReg, unsigned PhysReg) { if (VirtReg.empty()) return IK_Free; // Regmask interference is the fastest check. if (checkRegMaskInterference(VirtReg, PhysReg)) return IK_RegMask; // Check for fixed interference. if (checkRegUnitInterference(VirtReg, PhysReg)) return IK_RegUnit; // Check the matrix for virtual register interference. for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) if (query(VirtReg, *Units).checkInterference()) return IK_VirtReg; return IK_Free; }
bool LiveInterval::overlaps(const LiveInterval &Other, const CoalescerPair &CP, const SlotIndexes &Indexes) const { assert(!empty() && "empty interval"); if (Other.empty()) return false; // Use binary searches to find initial positions. const_iterator I = find(Other.beginIndex()); const_iterator IE = end(); if (I == IE) return false; const_iterator J = Other.find(I->start); const_iterator JE = Other.end(); if (J == JE) return false; for (;;) { // J has just been advanced to satisfy: assert(J->end >= I->start); // Check for an overlap. if (J->start < I->end) { // I and J are overlapping. Find the later start. SlotIndex Def = std::max(I->start, J->start); // Allow the overlap if Def is a coalescable copy. if (Def.isBlock() || !CP.isCoalescable(Indexes.getInstructionFromIndex(Def))) return true; } // Advance the iterator that ends first to check for more overlaps. if (J->end > I->end) { std::swap(I, J); std::swap(IE, JE); } // Advance J until J->end >= I->start. do if (++J == JE) return false; while (J->end < I->start); } }
void RegAllocPBQP::findVRegIntervalsToAlloc() { // Iterate over all live ranges. for (LiveIntervals::iterator itr = lis->begin(), end = lis->end(); itr != end; ++itr) { // Ignore physical ones. if (TargetRegisterInfo::isPhysicalRegister(itr->first)) continue; LiveInterval *li = itr->second; // If this live interval is non-empty we will use pbqp to allocate it. // Empty intervals we allocate in a simple post-processing stage in // finalizeAlloc. if (!li->empty()) { vregsToAlloc.insert(li->reg); } else { emptyIntervalVRegs.insert(li->reg); } } }
// 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); } }
bool StackColoring::runOnMachineFunction(MachineFunction &Func) { DEBUG(dbgs() << "********** Stack Coloring **********\n" << "********** Function: " << ((const Value*)Func.getFunction())->getName() << '\n'); MF = &Func; MFI = MF->getFrameInfo(); Indexes = &getAnalysis<SlotIndexes>(); BlockLiveness.clear(); BasicBlocks.clear(); BasicBlockNumbering.clear(); Markers.clear(); Intervals.clear(); VNInfoAllocator.Reset(); unsigned NumSlots = MFI->getObjectIndexEnd(); // If there are no stack slots then there are no markers to remove. if (!NumSlots) return false; SmallVector<int, 8> SortedSlots; SortedSlots.reserve(NumSlots); Intervals.reserve(NumSlots); unsigned NumMarkers = collectMarkers(NumSlots); unsigned TotalSize = 0; DEBUG(dbgs()<<"Found "<<NumMarkers<<" markers and "<<NumSlots<<" slots\n"); DEBUG(dbgs()<<"Slot structure:\n"); for (int i=0; i < MFI->getObjectIndexEnd(); ++i) { DEBUG(dbgs()<<"Slot #"<<i<<" - "<<MFI->getObjectSize(i)<<" bytes.\n"); TotalSize += MFI->getObjectSize(i); } DEBUG(dbgs()<<"Total Stack size: "<<TotalSize<<" bytes\n\n"); // Don't continue because there are not enough lifetime markers, or the // stack is too small, or we are told not to optimize the slots. if (NumMarkers < 2 || TotalSize < 16 || DisableColoring) { DEBUG(dbgs()<<"Will not try to merge slots.\n"); return removeAllMarkers(); } for (unsigned i=0; i < NumSlots; ++i) { LiveInterval *LI = new LiveInterval(i, 0); Intervals.push_back(LI); LI->getNextValue(Indexes->getZeroIndex(), VNInfoAllocator); SortedSlots.push_back(i); } // Calculate the liveness of each block. calculateLocalLiveness(); // Propagate the liveness information. calculateLiveIntervals(NumSlots); // Search for allocas which are used outside of the declared lifetime // markers. if (ProtectFromEscapedAllocas) removeInvalidSlotRanges(); // Maps old slots to new slots. DenseMap<int, int> SlotRemap; unsigned RemovedSlots = 0; unsigned ReducedSize = 0; // Do not bother looking at empty intervals. for (unsigned I = 0; I < NumSlots; ++I) { if (Intervals[SortedSlots[I]]->empty()) SortedSlots[I] = -1; } // This is a simple greedy algorithm for merging allocas. First, sort the // slots, placing the largest slots first. Next, perform an n^2 scan and look // for disjoint slots. When you find disjoint slots, merge the samller one // into the bigger one and update the live interval. Remove the small alloca // and continue. // Sort the slots according to their size. Place unused slots at the end. // Use stable sort to guarantee deterministic code generation. std::stable_sort(SortedSlots.begin(), SortedSlots.end(), SlotSizeSorter(MFI)); bool Changed = true; while (Changed) { Changed = false; for (unsigned I = 0; I < NumSlots; ++I) { if (SortedSlots[I] == -1) continue; for (unsigned J=I+1; J < NumSlots; ++J) { if (SortedSlots[J] == -1) continue; int FirstSlot = SortedSlots[I]; int SecondSlot = SortedSlots[J]; LiveInterval *First = Intervals[FirstSlot]; LiveInterval *Second = Intervals[SecondSlot]; assert (!First->empty() && !Second->empty() && "Found an empty range"); // Merge disjoint slots. if (!First->overlaps(*Second)) { Changed = true; First->MergeSegmentsInAsValue(*Second, First->getValNumInfo(0)); SlotRemap[SecondSlot] = FirstSlot; SortedSlots[J] = -1; DEBUG(dbgs()<<"Merging #"<<FirstSlot<<" and slots #"<< SecondSlot<<" together.\n"); unsigned MaxAlignment = std::max(MFI->getObjectAlignment(FirstSlot), MFI->getObjectAlignment(SecondSlot)); assert(MFI->getObjectSize(FirstSlot) >= MFI->getObjectSize(SecondSlot) && "Merging a small object into a larger one"); RemovedSlots+=1; ReducedSize += MFI->getObjectSize(SecondSlot); MFI->setObjectAlignment(FirstSlot, MaxAlignment); MFI->RemoveStackObject(SecondSlot); } } } }// While changed. // Record statistics. StackSpaceSaved += ReducedSize; StackSlotMerged += RemovedSlots; DEBUG(dbgs()<<"Merge "<<RemovedSlots<<" slots. Saved "<< ReducedSize<<" bytes\n"); // Scan the entire function and update all machine operands that use frame // indices to use the remapped frame index. expungeSlotMap(SlotRemap, NumSlots); remapInstructions(SlotRemap); // Release the intervals. for (unsigned I = 0; I < NumSlots; ++I) { delete Intervals[I]; } return removeAllMarkers(); }
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); } } }
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval &interval) { DEBUG(dbgs() << "\t\tregister: " << PrintReg(interval.reg, tri_)); // Virtual registers may be defined multiple times (due to phi // elimination and 2-addr elimination). Much of what we do only has to be // done once for the vreg. We use an empty interval to detect the first // time we see a vreg. LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); if (interval.empty()) { // Get the Idx of the defining instructions. SlotIndex defIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); // Make sure the first definition is not a partial redefinition. Add an // <imp-def> of the full register. // FIXME: LiveIntervals shouldn't modify the code like this. Whoever // created the machine instruction should annotate it with <undef> flags // as needed. Then we can simply assert here. The REG_SEQUENCE lowering // is the main suspect. if (MO.getSubReg()) { mi->addRegisterDefined(interval.reg); // Mark all defs of interval.reg on this instruction as reading <undef>. for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) { MachineOperand &MO2 = mi->getOperand(i); if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg()) MO2.setIsUndef(); } } MachineInstr *CopyMI = NULL; if (mi->isCopyLike()) { CopyMI = mi; } VNInfo *ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator); assert(ValNo->id == 0 && "First value in interval is not 0?"); // Loop over all of the blocks that the vreg is defined in. There are // two cases we have to handle here. The most common case is a vreg // whose lifetime is contained within a basic block. In this case there // will be a single kill, in MBB, which comes after the definition. if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { // FIXME: what about dead vars? SlotIndex killIdx; if (vi.Kills[0] != mi) killIdx = getInstructionIndex(vi.Kills[0]).getRegSlot(); else killIdx = defIndex.getDeadSlot(); // If the kill happens after the definition, we have an intra-block // live range. if (killIdx > defIndex) { assert(vi.AliveBlocks.empty() && "Shouldn't be alive across any blocks!"); LiveRange LR(defIndex, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR << "\n"); return; } } // The other case we handle is when a virtual register lives to the end // of the defining block, potentially live across some blocks, then is // live into some number of blocks, but gets killed. Start by adding a // range that goes from this definition to the end of the defining block. LiveRange NewLR(defIndex, getMBBEndIdx(mbb), ValNo); DEBUG(dbgs() << " +" << NewLR); interval.addRange(NewLR); bool PHIJoin = lv_->isPHIJoin(interval.reg); if (PHIJoin) { // A phi join register is killed at the end of the MBB and revived as a new // valno in the killing blocks. assert(vi.AliveBlocks.empty() && "Phi join can't pass through blocks"); DEBUG(dbgs() << " phi-join"); ValNo->setHasPHIKill(true); } else { // Iterate over all of the blocks that the variable is completely // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the // live interval. for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(), E = vi.AliveBlocks.end(); I != E; ++I) { MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I); LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } // Finally, this virtual register is live from the start of any killing // block to the 'use' slot of the killing instruction. for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { MachineInstr *Kill = vi.Kills[i]; SlotIndex Start = getMBBStartIdx(Kill->getParent()); SlotIndex killIdx = getInstructionIndex(Kill).getRegSlot(); // Create interval with one of a NEW value number. Note that this value // number isn't actually defined by an instruction, weird huh? :) if (PHIJoin) { assert(getInstructionFromIndex(Start) == 0 && "PHI def index points at actual instruction."); ValNo = interval.getNextValue(Start, 0, VNInfoAllocator); ValNo->setIsPHIDef(true); } LiveRange LR(Start, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } else { if (MultipleDefsBySameMI(*mi, MOIdx)) // Multiple defs of the same virtual register by the same instruction. // e.g. %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... // This is likely due to elimination of REG_SEQUENCE instructions. Return // here since there is nothing to do. return; // If this is the second time we see a virtual register definition, it // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the // def-and-use register operand. // It may also be partial redef like this: // 80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0 // 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0 bool PartReDef = isPartialRedef(MIIdx, MO, interval); if (PartReDef || mi->isRegTiedToUseOperand(MOIdx)) { // If this is a two-address definition, then we have already processed // the live range. The only problem is that we didn't realize there // are actually two values in the live interval. Because of this we // need to take the LiveRegion that defines this register and split it // into two values. SlotIndex RedefIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex.getRegSlot(true)); VNInfo *OldValNo = OldLR->valno; SlotIndex DefIndex = OldValNo->def.getRegSlot(); // Delete the previous value, which should be short and continuous, // because the 2-addr copy must be in the same MBB as the redef. interval.removeRange(DefIndex, RedefIndex); // The new value number (#1) is defined by the instruction we claimed // defined value #0. VNInfo *ValNo = interval.createValueCopy(OldValNo, VNInfoAllocator); // Value#0 is now defined by the 2-addr instruction. OldValNo->def = RedefIndex; OldValNo->setCopy(0); // A re-def may be a copy. e.g. %reg1030:6<def> = VMOVD %reg1026, ... if (PartReDef && mi->isCopyLike()) OldValNo->setCopy(&*mi); // Add the new live interval which replaces the range for the input copy. LiveRange LR(DefIndex, RedefIndex, ValNo); DEBUG(dbgs() << " replace range with " << LR); interval.addRange(LR); // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. if (MO.isDead()) interval.addRange(LiveRange(RedefIndex, RedefIndex.getDeadSlot(), OldValNo)); DEBUG({ dbgs() << " RESULT: "; interval.print(dbgs(), tri_); }); } else if (lv_->isPHIJoin(interval.reg)) {
/// 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(); } }
void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) { assert(MRI && Indexes && "call reset() first"); // Step 1: Create minimal live segments for every definition of Reg. // Visit all def operands. If the same instruction has multiple defs of Reg, // createDeadDef() will deduplicate. const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); unsigned Reg = LI.reg; for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { if (!MO.isDef() && !MO.readsReg()) continue; unsigned SubReg = MO.getSubReg(); if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) { LaneBitmask Mask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg) : MRI->getMaxLaneMaskForVReg(Reg); // If this is the first time we see a subregister def, initialize // subranges by creating a copy of the main range. if (!LI.hasSubRanges() && !LI.empty()) { LaneBitmask ClassMask = MRI->getMaxLaneMaskForVReg(Reg); LI.createSubRangeFrom(*Alloc, ClassMask, LI); } for (LiveInterval::SubRange &S : LI.subranges()) { // A Mask for subregs common to the existing subrange and current def. LaneBitmask Common = S.LaneMask & Mask; if (Common == 0) continue; // A Mask for subregs covered by the subrange but not the current def. LaneBitmask LRest = S.LaneMask & ~Mask; LiveInterval::SubRange *CommonRange; if (LRest != 0) { // Split current subrange into Common and LRest ranges. S.LaneMask = LRest; CommonRange = LI.createSubRangeFrom(*Alloc, Common, S); } else { assert(Common == S.LaneMask); CommonRange = &S; } if (MO.isDef()) createDeadDef(*Indexes, *Alloc, *CommonRange, MO); Mask &= ~Common; } // Create a new SubRange for subregs we did not cover yet. if (Mask != 0) { LiveInterval::SubRange *NewRange = LI.createSubRange(*Alloc, Mask); if (MO.isDef()) createDeadDef(*Indexes, *Alloc, *NewRange, MO); } } // Create the def in the main liverange. We do not have to do this if // subranges are tracked as we recreate the main range later in this case. if (MO.isDef() && !LI.hasSubRanges()) createDeadDef(*Indexes, *Alloc, LI, MO); } // We may have created empty live ranges for partially undefined uses, we // can't keep them because we won't find defs in them later. LI.removeEmptySubRanges(); // Step 2: Extend live segments to all uses, constructing SSA form as // necessary. if (LI.hasSubRanges()) { for (LiveInterval::SubRange &S : LI.subranges()) { resetLiveOutMap(); extendToUses(S, Reg, S.LaneMask); } LI.clear(); constructMainRangeFromSubranges(LI); } else { resetLiveOutMap(); extendToUses(LI, Reg, ~0u); } }