Index: include/llvm/CodeGen/LiveInterval.h =================================================================== --- include/llvm/CodeGen/LiveInterval.h +++ include/llvm/CodeGen/LiveInterval.h @@ -192,11 +192,9 @@ typedef SmallVector Segments; typedef SmallVector VNInfoList; - typedef SmallVector SlotList; Segments segments; // the liveness segments VNInfoList valnos; // value#'s - SlotList undefs; // explicit "undefs" via // The segment set is used temporarily to accelerate initial computation // of live ranges of physical registers in computeRegUnitRange. @@ -278,7 +276,6 @@ void clear() { valnos.clear(); segments.clear(); - undefs.clear(); } size_t size() const { @@ -458,6 +455,8 @@ /// may have grown since it was inserted). iterator addSegment(Segment S); + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); + /// Attempt to extend a value defined after @p StartIdx to include @p Use. /// Both @p StartIdx and @p Use should be in the same basic block. In case /// of subranges, an extension could be prevented by an explicit "undef" @@ -471,7 +470,8 @@ /// segment before @p Use and there is no "undef" between @p StartIdx and /// @p Use, return {nullptr, false}. If there is an "undef" before @p Use, /// return {nullptr, true}. - std::pair extendInBlock(SlotIndex StartIdx, SlotIndex Use); + std::pair extendInBlock(ArrayRef Undefs, + SlotIndex StartIdx, SlotIndex Use); /// join - Join two live ranges (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS ranges as specified. If @@ -574,8 +574,9 @@ /// Returns true if there is an explicit "undef" between @p Begin /// @p End. - bool isUndefIn(SlotIndex Begin, SlotIndex End) const { - return std::any_of(undefs.begin(), undefs.end(), + bool isUndefIn(ArrayRef Undefs, SlotIndex Begin, + SlotIndex End) const { + return std::any_of(Undefs.begin(), Undefs.end(), [Begin,End] (SlotIndex Idx) -> bool { return Begin <= Idx && Idx < End; }); @@ -587,8 +588,6 @@ /// activated in the constructor of the live range. void flushSegmentSet(); - void clearUndefs() { undefs.clear(); } - void print(raw_ostream &OS) const; void dump() const; @@ -757,17 +756,6 @@ weight = llvm::huge_valf; } - void clearSubRangeUndefs() { - super::clearUndefs(); - for (SubRange &S : subranges()) - S.clearUndefs(); - } - - /// Recalculate explicit "undefs" for all subranges: if a subrange is - /// defined at Idx, any subranges that are not defined at Idx and are - /// not live at Idx will be considered explicitly undefined. - void recalculateSubRangeUndefs(); - bool operator<(const LiveInterval& other) const { const SlotIndex &thisIndex = beginIndex(); const SlotIndex &otherIndex = other.beginIndex(); Index: include/llvm/CodeGen/LiveIntervalAnalysis.h =================================================================== --- include/llvm/CodeGen/LiveIntervalAnalysis.h +++ include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -175,8 +175,7 @@ /// will be extended to be live out of the basic block. /// /// See also LiveRangeCalc::extend(). - void extendToIndices(LiveRange &LR, ArrayRef Indices, - bool AllowUndef = false); + void extendToIndices(LiveRange &LR, ArrayRef Indices); /// If @p LR has a live value at @p Kill, prune its live range by removing Index: lib/CodeGen/LiveInterval.cpp =================================================================== --- lib/CodeGen/LiveInterval.cpp +++ lib/CodeGen/LiveInterval.cpp @@ -94,18 +94,34 @@ return VNI; } - std::pair extendInBlock(SlotIndex StartIdx, SlotIndex Use) { + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Use) { + if (segments().empty()) + return nullptr; + iterator I = + impl().findInsertPos(Segment(Use.getPrevSlot(), Use, nullptr)); + if (I == segments().begin()) + return nullptr; + --I; + if (I->end <= StartIdx) + return nullptr; + if (I->end < Use) + extendSegmentEndTo(I, Use); + return I->valno; + } + + std::pair extendInBlock(ArrayRef Undefs, + SlotIndex StartIdx, SlotIndex Use) { if (segments().empty()) return std::make_pair(nullptr, false); SlotIndex BeforeUse = Use.getPrevSlot(); iterator I = impl().findInsertPos(Segment(BeforeUse, Use, nullptr)); if (I == segments().begin()) - return std::make_pair(nullptr, LR->isUndefIn(StartIdx, BeforeUse)); + return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse)); --I; if (I->end <= StartIdx) - return std::make_pair(nullptr, LR->isUndefIn(StartIdx, BeforeUse)); + return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse)); if (I->end < Use) { - if (LR->isUndefIn(I->end, BeforeUse)) + if (LR->isUndefIn(Undefs, I->end, BeforeUse)) return std::make_pair(nullptr, true); extendSegmentEndTo(I, Use); } @@ -514,7 +530,6 @@ } // Otherwise use the segment vector. LiveRange::iterator I = CalcLiveRangeUtilVector(this).addSegment(S); - pruneUndefs(); return I; } @@ -522,14 +537,21 @@ // Check that the segment belongs to the back of the list. assert(segments.empty() || segments.back().end <= S.start); segments.push_back(S); - pruneUndefs(); } /// extendInBlock - If this range is live before Kill in the basic /// block that starts at StartIdx, extend it to be live up to Kill and return /// the value. If there is no live range before Kill, return NULL. -std::pair LiveRange::extendInBlock(SlotIndex StartIdx, - SlotIndex Kill) { +std::pair LiveRange::extendInBlock(ArrayRef Undefs, + SlotIndex StartIdx, SlotIndex Kill) { + // Use the segment set, if it is available. + if (segmentSet != nullptr) + return CalcLiveRangeUtilSet(this).extendInBlock(Undefs, StartIdx, Kill); + // Otherwise use the segment vector. + return CalcLiveRangeUtilVector(this).extendInBlock(Undefs, StartIdx, Kill); +} + +VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) { // Use the segment set, if it is available. if (segmentSet != nullptr) return CalcLiveRangeUtilSet(this).extendInBlock(StartIdx, Kill); @@ -767,7 +789,6 @@ "segment set can be used only initially before switching to the array"); segments.append(segmentSet->begin(), segmentSet->end()); segmentSet = nullptr; - pruneUndefs(); verify(); } @@ -805,12 +826,6 @@ return false; } -void LiveRange::pruneUndefs() { - for (unsigned i = undefs.size(); i > 0; --i) - if (getSegmentContaining(undefs[i-1])) - undefs.erase(undefs.begin()+i-1); -} - void LiveInterval::freeSubRange(SubRange *S) { S->~SubRange(); // Memory was allocated with BumpPtr allocator and is not freed here. @@ -843,27 +858,6 @@ SubRanges = nullptr; } -void LiveInterval::recalculateSubRangeUndefs() { - clearSubRangeUndefs(); - // Go over the main range and visit all register defs. For each subrange - // that is not live immediately after the point of the def, add "undef" - // to it. An exception is a subrange with a dead def at that position--- - // it should not receive an undef. - for (Segment &Seg : *this) { - if (!Seg.start.isRegister()) - continue; - SlotIndex After = Seg.start.getDeadSlot(); - for (SubRange &S : subranges()) { - // If S has a def at Seg.start, skip it. - iterator I = S.find(Seg.start); - if (I != S.end() && I->start == Seg.start) - continue; - if (I == S.end() || I->start >= After) - S.undefs.push_back(Seg.start); - } - } -} - unsigned LiveInterval::getSize() const { unsigned Sum = 0; for (const Segment &S : segments) @@ -909,15 +903,6 @@ } } } - - if (!undefs.empty()) { - OS << " undef@"; - for (unsigned i = 0, n = undefs.size(); i != n; ++i) { - OS << undefs[i]; - if (i != n-1) - OS << ','; - } - } } void LiveInterval::SubRange::print(raw_ostream &OS) const { @@ -962,8 +947,6 @@ assert(I->valno != std::next(I)->valno); } } - for (SlotIndex U : undefs) - assert(getSegmentContaining(U) == nullptr); } void LiveInterval::verify(const MachineRegisterInfo *MRI) const { @@ -1176,7 +1159,6 @@ // Nothing to merge? if (Spills.empty()) { LR->segments.erase(WriteI, ReadI); - LR->pruneUndefs(); LR->verify(); return; } @@ -1195,7 +1177,6 @@ } ReadI = WriteI + Spills.size(); mergeSpills(); - LR->pruneUndefs(); LR->verify(); } Index: lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- lib/CodeGen/LiveIntervalAnalysis.cpp +++ lib/CodeGen/LiveIntervalAnalysis.cpp @@ -352,7 +352,7 @@ static void extendSegmentsToUses(LiveRange &LR, const SlotIndexes &Indexes, ShrinkToUsesWorkList &WorkList, - const LiveRange &OldRange, bool AllowUndef) { + const LiveRange &OldRange) { // Keep track of the PHIs that are in use. SmallPtrSet UsedPHIs; // Blocks that have already been added to WorkList as live-out. @@ -367,7 +367,7 @@ SlotIndex BlockStart = Indexes.getMBBStartIdx(MBB); // Extend the live range for VNI to be live at Idx. - if (VNInfo *ExtVNI = LR.extendInBlock(BlockStart, Idx).first) { + if (VNInfo *ExtVNI = LR.extendInBlock(BlockStart, Idx)) { assert(ExtVNI == VNI && "Unexpected existing value number"); (void)ExtVNI; // Is this a PHIDef we haven't seen before? @@ -395,8 +395,6 @@ if (!LiveOut.insert(Pred).second) continue; SlotIndex Stop = Indexes.getMBBEndIdx(Pred); - if (AllowUndef && OldRange.getVNInfoBefore(Stop) == nullptr) - continue; assert(OldRange.getVNInfoBefore(Stop) == VNI && "Wrong value out of predecessor"); WorkList.push_back(std::make_pair(Stop, VNI)); @@ -453,7 +451,7 @@ // Create new live ranges with only minimal live segments per def. LiveRange NewLR; createSegmentsForValues(NewLR, make_range(li->vni_begin(), li->vni_end())); - extendSegmentsToUses(NewLR, *Indexes, WorkList, *li, false); + extendSegmentsToUses(NewLR, *Indexes, WorkList, *li); // Move the trimmed segments back. li->segments.swap(NewLR.segments); @@ -552,7 +550,7 @@ // Create a new live ranges with only minimal live segments per def. LiveRange NewLR; createSegmentsForValues(NewLR, make_range(SR.vni_begin(), SR.vni_end())); - extendSegmentsToUses(NewLR, *Indexes, WorkList, SR, true); + extendSegmentsToUses(NewLR, *Indexes, WorkList, SR); // Move the trimmed ranges back. SR.segments.swap(NewLR.segments); @@ -577,12 +575,12 @@ } void LiveIntervals::extendToIndices(LiveRange &LR, - ArrayRef Indices, - bool AllowUndef) { + ArrayRef Indices) { assert(LRCalc && "LRCalc not initialized."); LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator()); + SmallVector Undefs; for (unsigned i = 0, e = Indices.size(); i != e; ++i) - LRCalc->extend(LR, Indices[i], /*PhysReg=*/0, AllowUndef); + LRCalc->extend(LR, Indices[i], /*PhysReg=*/0, Undefs); } void LiveIntervals::pruneValue(LiveRange &LR, SlotIndex Kill, @@ -957,7 +955,6 @@ if (TargetRegisterInfo::isVirtualRegister(Reg)) { LiveInterval &LI = LIS.getInterval(Reg); if (LI.hasSubRanges()) { - LI.clearSubRangeUndefs(); unsigned SubReg = MO.getSubReg(); LaneBitmask LaneMask = SubReg ? TRI.getSubRegIndexLaneMask(SubReg) : MRI.getMaxLaneMaskForVReg(Reg); @@ -986,7 +983,6 @@ unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; - LIS.getInterval(Reg).recalculateSubRangeUndefs(); } } Index: lib/CodeGen/LiveRangeCalc.h =================================================================== --- lib/CodeGen/LiveRangeCalc.h +++ lib/CodeGen/LiveRangeCalc.h @@ -117,8 +117,9 @@ /// Check if the entry to block @p MBB can be reached by any of the defs /// in @p LR. Return true if none of the defs reach the entry to @p MBB. - bool isDefOnEntry(LiveRange &LR, MachineBasicBlock &MBB, - BitVector &DefOnEntry, BitVector &UndefOnEntry); + bool isDefOnEntry(LiveRange &LR, ArrayRef Undefs, + MachineBasicBlock &MBB, BitVector &DefOnEntry, + BitVector &UndefOnEntry); /// Find the set of defs that can reach @p Kill. @p Kill must belong to /// @p UseMBB. @@ -140,7 +141,8 @@ /// /// PhysReg, when set, is used to verify live-in lists on basic blocks. bool findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, - SlotIndex Kill, unsigned PhysReg, bool AllowUndef); + SlotIndex Kill, unsigned PhysReg, + ArrayRef Undefs); /// updateSSA - Compute the values that will be live in to all requested /// blocks in LiveIn. Create PHI-def values as required to preserve SSA form. @@ -170,7 +172,7 @@ /// location of the second def into the @p LiveAt set informs this /// function that Reg is live at that location. void extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask, - bool AllowUndef = false); + LiveInterval *LI = nullptr); /// Reset Map and Seen fields. void resetLiveOutMap(); @@ -203,6 +205,9 @@ // Modify existing live ranges. // + void computeSubRangeUndefs(SmallVectorImpl &Undefs, + LiveInterval &LI, LaneBitmask LaneMask) const; + /// Extend the live range of @p LR to reach @p Use. /// /// The existing values in @p LR must be live so they jointly dominate @p Use. @@ -210,8 +215,8 @@ /// inserted as required to preserve SSA form. /// /// PhysReg, when set, is used to verify live-in lists on basic blocks. - void extend(LiveRange &LR, SlotIndex Use, unsigned PhysReg = 0, - bool AllowUndef = false); + void extend(LiveRange &LR, SlotIndex Use, unsigned PhysReg, + ArrayRef Undefs); /// createDeadDefs - Create a dead def in LI for every def operand of Reg. /// Each instruction defining Reg gets a new VNInfo with a corresponding Index: lib/CodeGen/LiveRangeCalc.cpp =================================================================== --- lib/CodeGen/LiveRangeCalc.cpp +++ lib/CodeGen/LiveRangeCalc.cpp @@ -77,10 +77,6 @@ if (!MO.isDef() && !MO.readsReg()) continue; - const MachineInstr &MI = *MO.getParent(); - bool IsEC = MO.isEarlyClobber(); - SlotIndex Idx = Indexes->getInstructionIndex(MI).getRegSlot(IsEC); - unsigned SubReg = MO.getSubReg(); if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) { LaneBitmask WholeMask = MRI->getMaxLaneMaskForVReg(Reg); @@ -110,21 +106,6 @@ if (MO.isDef()) createDeadDef(*Indexes, *Alloc, *NewRange, MO); } - - if (MO.isDef() && MO.isUndef() && SubReg != 0) { - LaneBitmask UndefMask = WholeMask & ~SubMask; - // Add undefs to the subranges covered by UndefMask. Create new - // subranges if necessary. - for (LiveInterval::SubRange &S : LI.subranges()) { - LaneBitmask Common = S.LaneMask & UndefMask; - if (Common == 0) - continue; - getCommonRange(S, UndefMask)->undefs.push_back(Idx); - UndefMask &= ~Common; - } - if (UndefMask != 0) - LI.createSubRange(*Alloc, UndefMask)->undefs.push_back(Idx); - } } // Create the def in the main liverange. We do not have to do this if @@ -143,7 +124,7 @@ for (LiveInterval::SubRange &S : LI.subranges()) { LiveRangeCalc SubLRC; SubLRC.reset(MF, Indexes, DomTree, Alloc); - SubLRC.extendToUses(S, Reg, S.LaneMask, true); + SubLRC.extendToUses(S, Reg, S.LaneMask, &LI); } LI.clear(); constructMainRangeFromSubranges(LI); @@ -166,7 +147,7 @@ } } resetLiveOutMap(); - extendToUses(MainRange, LI.reg, ~0U, true); + extendToUses(MainRange, LI.reg, ~0U, &LI); } void LiveRangeCalc::createDeadDefs(LiveRange &LR, unsigned Reg) { @@ -180,7 +161,11 @@ void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask, - bool AllowUndef) { + LiveInterval *LI) { + SmallVector Undefs; + if (LI != nullptr) + computeSubRangeUndefs(Undefs, *LI, Mask); + // Visit all operands that read Reg. This may include partial defs. const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { @@ -226,7 +211,7 @@ // MI is reading Reg. We may have visited MI before if it happens to be // reading Reg multiple times. That is OK, extend() is idempotent. - extend(LR, UseIdx, Reg, AllowUndef); + extend(LR, UseIdx, Reg, Undefs); } } @@ -256,9 +241,32 @@ LiveIn.clear(); } +void LiveRangeCalc::computeSubRangeUndefs(SmallVectorImpl &Undefs, + LiveInterval &LI, + LaneBitmask LaneMask) const { + unsigned Reg = LI.reg; + assert(TargetRegisterInfo::isVirtualRegister(Reg)); + unsigned VRegMask = MRI->getMaxLaneMaskForVReg(Reg); + assert((VRegMask & LaneMask) != 0); + const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); + for (const MachineOperand &MO : MRI->def_operands(Reg)) { + if (!MO.isUndef()) + continue; + unsigned SubReg = MO.getSubReg(); + assert(SubReg != 0 && "Undef should only be set on subreg defs"); + LaneBitmask DefMask = TRI.getSubRegIndexLaneMask(SubReg); + LaneBitmask UndefMask = VRegMask & ~DefMask; + if ((UndefMask & LaneMask) != 0) { + const MachineInstr &MI = *MO.getParent(); + bool EarlyClobber = MO.isEarlyClobber(); + SlotIndex Pos = Indexes->getInstructionIndex(MI).getRegSlot(EarlyClobber); + Undefs.push_back(Pos); + } + } +} void LiveRangeCalc::extend(LiveRange &LR, SlotIndex Use, unsigned PhysReg, - bool AllowUndef) { + ArrayRef Undefs) { assert(Use.isValid() && "Invalid SlotIndex"); assert(Indexes && "Missing SlotIndexes"); assert(DomTree && "Missing dominator tree"); @@ -267,7 +275,7 @@ assert(UseMBB && "No MBB at Use"); // Is there a def in the same MBB we can extend? - auto EP = LR.extendInBlock(Indexes->getMBBStartIdx(UseMBB), Use); + auto EP = LR.extendInBlock(Undefs, Indexes->getMBBStartIdx(UseMBB), Use); if (EP.first != nullptr || EP.second) return; @@ -275,7 +283,7 @@ // multiple values, and we may need to create even more phi-defs to preserve // VNInfo SSA form. Perform a search for all predecessor blocks where we // know the dominating VNInfo. - if (findReachingDefs(LR, *UseMBB, Use, PhysReg, AllowUndef)) + if (findReachingDefs(LR, *UseMBB, Use, PhysReg, Undefs)) return; // When there were multiple different values, we may need new PHIs. @@ -294,8 +302,9 @@ } -bool LiveRangeCalc::isDefOnEntry(LiveRange &LR, MachineBasicBlock &MBB, - BitVector &DefOnEntry, BitVector &UndefOnEntry) { +bool LiveRangeCalc::isDefOnEntry(LiveRange &LR, ArrayRef Undefs, + MachineBasicBlock &MBB, BitVector &DefOnEntry, + BitVector &UndefOnEntry) { unsigned BN = MBB.getNumber(); if (DefOnEntry[BN]) return true; @@ -332,7 +341,7 @@ // undefined between the end of the segment and the end of the block, // treat the block as defined on exit. If it is, go to the next block // on the work list. - if (LR.isUndefIn(Seg.end, End)) + if (LR.isUndefIn(Undefs, Seg.end, End)) continue; return MarkDefined(B); } @@ -340,7 +349,7 @@ // No segment overlaps with this block. If this block is not defined on // entry, or it undefines the range, do not process its predecessors. - if (UndefOnEntry[N] || LR.isUndefIn(Begin, End)) { + if (UndefOnEntry[N] || LR.isUndefIn(Undefs, Begin, End)) { UndefOnEntry[N] = true; continue; } @@ -358,7 +367,7 @@ bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, SlotIndex Use, unsigned PhysReg, - bool AllowUndef) { + ArrayRef Undefs) { unsigned UseMBBNum = UseMBB.getNumber(); // Block numbers where LR should be live-in. @@ -375,7 +384,7 @@ MachineBasicBlock *MBB = MF->getBlockNumbered(WorkList[i]); #ifndef NDEBUG - if (!AllowUndef && MBB->pred_empty()) { + if (Undefs.size() > 0 && MBB->pred_empty()) { MBB->getParent()->verify(); errs() << "Use of " << PrintReg(PhysReg) << " does not have a corresponding definition on every path:\n"; @@ -415,7 +424,7 @@ // First time we see Pred. Try to determine the live-out value, but set // it as null if Pred is live-through with an unknown value. - auto EP = LR.extendInBlock(Start, End); + auto EP = LR.extendInBlock(Undefs, Start, End); VNInfo *VNI = EP.first; FoundUndef |= EP.second; setLiveOutValue(Pred, VNI); @@ -438,7 +447,7 @@ LiveIn.clear(); FoundUndef |= (TheVNI == nullptr); - if (AllowUndef && FoundUndef) + if (Undefs.size() > 0 && FoundUndef) UniqueVNI = false; // Both updateSSA() and LiveRangeUpdater benefit from ordered blocks, but @@ -478,7 +487,7 @@ LiveIn.reserve(WorkList.size()); for (unsigned BN : WorkList) { MachineBasicBlock *MBB = MF->getBlockNumbered(BN); - if (AllowUndef && !isDefOnEntry(LR, *MBB, DefOnEntry, UndefOnEntry)) + if (Undefs.size() > 0 && !isDefOnEntry(LR, Undefs, *MBB, DefOnEntry, UndefOnEntry)) continue; addLiveInBlock(LR, DomTree->getNode(MBB)); if (MBB == &UseMBB) Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -1330,9 +1330,6 @@ dbgs() << *UseMI; }); } - - if (DstInt && DstInt->hasSubRanges()) - DstInt->recalculateSubRangeUndefs(); } bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) { @@ -2781,7 +2778,6 @@ } // The merging process may cause the undef information to become invalid // and fail verification. Clear it here, it will be recalculated later. - LHS.clearSubRangeUndefs(); DEBUG(dbgs() << "\t\tLHST = " << PrintReg(CP.getDstReg()) << ' ' << LHS << '\n'); Index: lib/CodeGen/RenameIndependentSubregs.cpp =================================================================== --- lib/CodeGen/RenameIndependentSubregs.cpp +++ lib/CodeGen/RenameIndependentSubregs.cpp @@ -74,14 +74,6 @@ : ConEQ(LIS), SR(&SR), Index(Index) {} }; - struct UndefInfo { - UndefInfo() : Reg(0), SubIdx(0), At() {} - UndefInfo(unsigned R, unsigned S, SlotIndex P) - : Reg(R), SubIdx(S), At(P) {} - unsigned Reg, SubIdx; - SlotIndex At; - }; - /// Split unrelated subregister components and rename them to new vregs. bool renameComponents(LiveInterval &LI) const; @@ -96,8 +88,7 @@ /// belonging to their class. void distribute(const IntEqClasses &Classes, const SmallVectorImpl &SubRangeInfos, - const SmallVectorImpl &Intervals, - const SmallVectorImpl &UndefInfos) const; + const SmallVectorImpl &Intervals) const; /// \brief Constructs main liverange and add missing undef+dead flags. void computeMainRangesFixFlags(const IntEqClasses &Classes, @@ -107,8 +98,7 @@ /// Rewrite Machine Operands to use the new vreg belonging to their class. void rewriteOperands(const IntEqClasses &Classes, const SmallVectorImpl &SubRangeInfos, - const SmallVectorImpl &Intervals, - SmallVectorImpl &UndefInfos) const; + const SmallVectorImpl &Intervals) const; LiveIntervals *LIS; @@ -156,9 +146,8 @@ } DEBUG(dbgs() << '\n'); - SmallVector UndefInfos; - rewriteOperands(Classes, SubRangeInfos, Intervals, UndefInfos); - distribute(Classes, SubRangeInfos, Intervals, UndefInfos); + rewriteOperands(Classes, SubRangeInfos, Intervals); + distribute(Classes, SubRangeInfos, Intervals); computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals); return true; } @@ -221,8 +210,7 @@ void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes, const SmallVectorImpl &SubRangeInfos, - const SmallVectorImpl &Intervals, - SmallVectorImpl &UndefInfos) const { + const SmallVectorImpl &Intervals) const { const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); unsigned Reg = Intervals[0]->reg;; for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg), @@ -255,8 +243,6 @@ unsigned VReg = Intervals[ID]->reg; MO.setReg(VReg); - if (SubRegIdx && MO.isUndef()) - UndefInfos.push_back(UndefInfo(VReg, SubRegIdx, Pos)); } // TODO: We could attempt to recompute new register classes while visiting // the operands: Some of the split register may be fine with less constraint @@ -265,8 +251,7 @@ void RenameIndependentSubregs::distribute(const IntEqClasses &Classes, const SmallVectorImpl &SubRangeInfos, - const SmallVectorImpl &Intervals, - const SmallVectorImpl &UndefInfos) const { + const SmallVectorImpl &Intervals) const { unsigned NumClasses = Classes.getNumClasses(); SmallVector VNIMapping; SmallVector SubRanges; @@ -288,15 +273,6 @@ } DistributeRange(SR, SubRanges.data(), VNIMapping); } - - const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); - for (const UndefInfo &U : UndefInfos) { - LiveInterval &LI = LIS->getInterval(U.Reg); - LaneBitmask LM = TRI.getSubRegIndexLaneMask(U.SubIdx); - for (LiveInterval::SubRange &SR : LI.subranges()) - if ((SR.LaneMask & LM) == 0) - SR.undefs.push_back(U.At); - } } static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) { @@ -382,7 +358,6 @@ // and may cause the recorded live range to be larger than the actual // liveness in the program IR. LIS->shrinkToUses(&LI); - LI.recalculateSubRangeUndefs(); } } Index: lib/CodeGen/SplitKit.cpp =================================================================== --- lib/CodeGen/SplitKit.cpp +++ lib/CodeGen/SplitKit.cpp @@ -1014,8 +1014,7 @@ // The first block may be live-in, or it may have its own def. if (Start != BlockStart) { - auto EP = LI.extendInBlock(BlockStart, std::min(BlockEnd, End)); - VNInfo *VNI = EP.first; + VNInfo *VNI = LI.extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped value"); DEBUG(dbgs() << ':' << VNI->id << "*BB#" << MBB->getNumber()); // MBB has its own def. Is it also live-out? @@ -1035,8 +1034,7 @@ if (BlockStart == ParentVNI->def) { // This block has the def of a parent PHI, so it isn't live-in. assert(ParentVNI->isPHIDef() && "Non-phi defined at block start?"); - auto EP = LI.extendInBlock(BlockStart, std::min(BlockEnd, End)); - VNInfo *VNI = EP.first; + VNInfo *VNI = LI.extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped parent PHI"); if (End >= BlockEnd) LRC.setLiveOutValue(&*MBB, VNI); // Live-out as well. @@ -1079,14 +1077,15 @@ }; auto ExtendPHIRange = [this] (MachineBasicBlock &B, LiveRangeCalc &LRC, - LiveRange &LR, bool AllowUndef) -> void { + LiveRange &LR, + ArrayRef Undefs) -> void { for (MachineBasicBlock *P : B.predecessors()) { SlotIndex End = LIS.getMBBEndIdx(P); SlotIndex LastUse = End.getPrevSlot(); // The predecessor may not have a live-out value. That is OK, like an // undef PHI operand. if (Edit->getParent().liveAt(LastUse)) - LRC.extend(LR, End, 0, AllowUndef); + LRC.extend(LR, End, 0, Undefs); } }; @@ -1095,6 +1094,7 @@ // of all predecessor blocks. LiveInterval &ParentLI = Edit->getParent(); + SmallVector Undefs; for (const VNInfo *V : ParentLI.valnos) { if (V->isUnused() || !V->isPHIDef()) continue; @@ -1104,7 +1104,7 @@ LiveRangeCalc &LRC = getLRCalc(RegIdx); MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def); if (!RemoveDeadSegment(V->def, LI)) - ExtendPHIRange(B, LRC, LI, false); + ExtendPHIRange(B, LRC, LI, Undefs); } LiveRangeCalc SubLRC; @@ -1122,7 +1122,9 @@ MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def); SubLRC.reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, &LIS.getVNInfoAllocator()); - ExtendPHIRange(B, SubLRC, S, true); + Undefs.clear(); + SubLRC.computeSubRangeUndefs(Undefs, ParentLI, PS.LaneMask); + ExtendPHIRange(B, SubLRC, S, Undefs); } } } @@ -1169,16 +1171,6 @@ unsigned RegIdx = RegAssign.lookup(Idx); LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx)); MO.setReg(LI.reg); - if (LI.hasSubRanges()) { - // If this is a read-undef def of a subregister, add undefs to the - // undefined subranges. - if (MO.getSubReg() && MO.isUndef()) { - LaneBitmask LM = getMaskForOp(MO); - for (LiveInterval::SubRange &S : LI.subranges()) - if (!(S.LaneMask & LM)) - S.undefs.push_back(Idx); - } - } DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' << Idx << ':' << RegIdx << '\t' << *MI); @@ -1207,7 +1199,7 @@ ExtPoints.push_back(ExtPoint(MO, RegIdx, Next)); } else { LiveRangeCalc &LRC = getLRCalc(RegIdx); - LRC.extend(LI, Next); + LRC.extend(LI, Next, 0, ArrayRef()); } } @@ -1234,7 +1226,9 @@ continue; SubLRC.reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, &LIS.getVNInfoAllocator()); - SubLRC.extend(S, EP.Next, 0, true); + SmallVector Undefs; + SubLRC.computeSubRangeUndefs(Undefs, LI, S.LaneMask); + SubLRC.extend(S, EP.Next, 0, Undefs); } }