From 95e05ddf7446f406801aa0c6c710bb6872e26493 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 22 Sep 2015 03:44:41 +0000 Subject: [PATCH] LiveIntervalAnalysis: Factor common code into splitSeparateComponents; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248241 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveInterval.h | 12 ++++---- include/llvm/CodeGen/LiveIntervalAnalysis.h | 4 +++ lib/CodeGen/LiveInterval.cpp | 16 +++++----- lib/CodeGen/LiveIntervalAnalysis.cpp | 17 +++++++++++ lib/CodeGen/LiveRangeEdit.cpp | 33 ++++++++------------- lib/CodeGen/RegisterCoalescer.cpp | 25 ++++------------ lib/CodeGen/SplitKit.cpp | 18 +++++------ 7 files changed, 61 insertions(+), 64 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index cadd219dc69..bec4c6bd0f2 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -853,12 +853,12 @@ namespace llvm { /// the equivalence class assigned the VNI. unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } - /// Distribute - Distribute values in LIV[0] into a separate LiveInterval - /// for each connected component. LIV must have a LiveInterval for each - /// connected component. The LiveIntervals in Liv[1..] must be empty. - /// Instructions using LIV[0] are rewritten. - void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); - + /// Distribute values in \p LI into a separate LiveIntervals + /// for each connected component. LIV must have an empty LiveInterval for + /// each additional connected component. The first connected component is + /// left in \p LI. + void Distribute(LiveInterval &LI, LiveInterval *LIV[], + MachineRegisterInfo &MRI); }; } diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 5996f8dd334..137e9658750 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -402,6 +402,10 @@ extern cl::opt UseSegmentSetForPhysRegs; /// that start at position @p Pos. void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos); + /// Split separate components in LiveInterval \p LI into separate intervals. + void splitSeparateComponents(LiveInterval &LI, + SmallVectorImpl &SplitLIs); + private: /// Compute live intervals for all virtual registers. void computeVirtRegs(); diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 3dc4113c639..5c2dba4531a 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -1372,11 +1372,8 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { return EqClass.getNumClasses(); } -void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], +void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI) { - assert(LIV[0] && "LIV[0] must be set"); - LiveInterval &LI = *LIV[0]; - // Rewrite instructions. for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), RE = MRI.reg_end(); RI != RE;) { @@ -1398,7 +1395,8 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], // NULL. If the use is tied to a def, VNI will be the defined value. if (!VNI) continue; - MO.setReg(LIV[getEqClass(VNI)]->reg); + if (unsigned EqClass = getEqClass(VNI)) + MO.setReg(LIV[EqClass-1]->reg); } // Move runs to new intervals. @@ -1407,9 +1405,9 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], ++J; for (LiveInterval::iterator I = J; I != E; ++I) { if (unsigned eq = EqClass[I->valno->id]) { - assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) && + assert((LIV[eq-1]->empty() || LIV[eq-1]->expiredAt(I->start)) && "New intervals should be empty"); - LIV[eq]->segments.push_back(*I); + LIV[eq-1]->segments.push_back(*I); } else *J++ = *I; } @@ -1424,8 +1422,8 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], for (unsigned i = j; i != e; ++i) { VNInfo *VNI = LI.getValNumInfo(i); if (unsigned eq = EqClass[i]) { - VNI->id = LIV[eq]->getNumValNums(); - LIV[eq]->valnos.push_back(VNI); + VNI->id = LIV[eq-1]->getNumValNums(); + LIV[eq-1]->valnos.push_back(VNI); } else { VNI->id = j; LI.valnos[j++] = VNI; diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 53a241203fd..1160dcf4121 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1413,3 +1413,20 @@ void LiveIntervals::removeVRegDefAt(LiveInterval &LI, SlotIndex Pos) { } LI.removeEmptySubRanges(); } + +void LiveIntervals::splitSeparateComponents(LiveInterval &LI, + SmallVectorImpl &SplitLIs) { + ConnectedVNInfoEqClasses ConEQ(*this); + unsigned NumComp = ConEQ.Classify(&LI); + if (NumComp <= 1) + return; + DEBUG(dbgs() << " Split " << NumComp << " components: " << LI << '\n'); + unsigned Reg = LI.reg; + const TargetRegisterClass *RegClass = MRI->getRegClass(Reg); + for (unsigned I = 1; I < NumComp; ++I) { + unsigned NewVReg = MRI->createVirtualRegister(RegClass); + LiveInterval &NewLI = createEmptyInterval(NewVReg); + SplitLIs.push_back(&NewLI); + } + ConEQ.Distribute(LI, SplitLIs.data(), *MRI); +} diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 78961138b63..be2225514ff 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -349,8 +349,9 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, ToShrink.pop_back(); if (foldAsLoad(LI, Dead)) continue; + unsigned VReg = LI->reg; if (TheDelegate) - TheDelegate->LRE_WillShrinkVirtReg(LI->reg); + TheDelegate->LRE_WillShrinkVirtReg(VReg); if (!LIS.shrinkToUses(LI, &Dead)) continue; @@ -360,7 +361,7 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, // them results in incorrect code. bool BeingSpilled = false; for (unsigned i = 0, e = RegsBeingSpilled.size(); i != e; ++i) { - if (LI->reg == RegsBeingSpilled[i]) { + if (VReg == RegsBeingSpilled[i]) { BeingSpilled = true; break; } @@ -370,29 +371,21 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, // LI may have been separated, create new intervals. LI->RenumberValues(); - ConnectedVNInfoEqClasses ConEQ(LIS); - unsigned NumComp = ConEQ.Classify(LI); - if (NumComp <= 1) - continue; - ++NumFracRanges; - bool IsOriginal = VRM && VRM->getOriginal(LI->reg) == LI->reg; - DEBUG(dbgs() << NumComp << " components: " << *LI << '\n'); - SmallVector Dups(1, LI); - for (unsigned i = 1; i != NumComp; ++i) { - Dups.push_back(&createEmptyIntervalFrom(LI->reg)); + SmallVector SplitLIs; + LIS.splitSeparateComponents(*LI, SplitLIs); + if (!SplitLIs.empty()) + ++NumFracRanges; + + unsigned Original = VRM ? VRM->getOriginal(VReg) : 0; + for (const LiveInterval *SplitLI : SplitLIs) { // If LI is an original interval that hasn't been split yet, make the new // intervals their own originals instead of referring to LI. The original // interval must contain all the split products, and LI doesn't. - if (IsOriginal) - VRM->setIsSplitFromReg(Dups.back()->reg, 0); + if (Original != VReg && Original != 0) + VRM->setIsSplitFromReg(SplitLI->reg, Original); if (TheDelegate) - TheDelegate->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg); + TheDelegate->LRE_DidCloneVirtReg(SplitLI->reg, VReg); } - ConEQ.Distribute(&Dups[0], MRI); - DEBUG({ - for (unsigned i = 0; i != NumComp; ++i) - dbgs() << '\t' << *Dups[i] << '\n'; - }); } } diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index 581f6e414b7..3222377a17a 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -224,30 +224,17 @@ namespace { /// Dst, we can drop \p Copy. bool applyTerminalRule(const MachineInstr &Copy) const; - /// Check whether or not \p LI is composed by multiple connected - /// components and if that is the case, fix that. - void splitNewRanges(LiveInterval *LI) { - ConnectedVNInfoEqClasses ConEQ(*LIS); - unsigned NumComps = ConEQ.Classify(LI); - if (NumComps <= 1) - return; - SmallVector NewComps(1, LI); - for (unsigned i = 1; i != NumComps; ++i) { - unsigned VReg = MRI->createVirtualRegister(MRI->getRegClass(LI->reg)); - NewComps.push_back(&LIS->createEmptyInterval(VReg)); - } - - ConEQ.Distribute(&NewComps[0], *MRI); - } - /// Wrapper method for \see LiveIntervals::shrinkToUses. /// This method does the proper fixing of the live-ranges when the afore /// mentioned method returns true. void shrinkToUses(LiveInterval *LI, SmallVectorImpl *Dead = nullptr) { - if (LIS->shrinkToUses(LI, Dead)) - // We may have created multiple connected components, split them. - splitNewRanges(LI); + if (LIS->shrinkToUses(LI, Dead)) { + /// Check whether or not \p LI is composed by multiple connected + /// components and if that is the case, fix that. + SmallVector SplitLIs; + LIS->splitSeparateComponents(*LI, SplitLIs); + } } public: diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index d06a316ba6c..665ed3b0d23 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -1082,16 +1082,14 @@ void SplitEditor::finish(SmallVectorImpl *LRMap) { ConnectedVNInfoEqClasses ConEQ(LIS); for (unsigned i = 0, e = Edit->size(); i != e; ++i) { // Don't use iterators, they are invalidated by create() below. - LiveInterval *li = &LIS.getInterval(Edit->get(i)); - unsigned NumComp = ConEQ.Classify(li); - if (NumComp <= 1) - continue; - DEBUG(dbgs() << " " << NumComp << " components: " << *li << '\n'); - SmallVector dups; - dups.push_back(li); - for (unsigned j = 1; j != NumComp; ++j) - dups.push_back(&Edit->createEmptyInterval()); - ConEQ.Distribute(&dups[0], MRI); + unsigned VReg = Edit->get(i); + LiveInterval &LI = LIS.getInterval(VReg); + SmallVector SplitLIs; + LIS.splitSeparateComponents(LI, SplitLIs); + unsigned Original = VRM.getOriginal(VReg); + for (LiveInterval *SplitLI : SplitLIs) + VRM.setIsSplitFromReg(SplitLI->reg, Original); + // The new intervals all map back to i. if (LRMap) LRMap->resize(Edit->size(), i); -- 2.34.1