From ede626799301430e6afe26b5638d0875206fd00e Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 3 Feb 2011 06:18:29 +0000 Subject: [PATCH] Reapply this. llvm-svn: 124779 --- llvm/include/llvm/CodeGen/LiveInterval.h | 2 +- llvm/lib/CodeGen/LiveRangeEdit.h | 1 + llvm/lib/CodeGen/RegAllocGreedy.cpp | 15 +- llvm/lib/CodeGen/SplitKit.cpp | 334 ++++++++++------------- llvm/lib/CodeGen/SplitKit.h | 63 +++-- 5 files changed, 186 insertions(+), 229 deletions(-) diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h index b2915cee97d4..88131fbc40ff 100644 --- a/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/llvm/include/llvm/CodeGen/LiveInterval.h @@ -560,7 +560,7 @@ namespace llvm { /// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// the equivalence class assigned the VNI. - unsigned getEqClass(const VNInfo *VNI) { return eqClass_[VNI->id]; } + 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 diff --git a/llvm/lib/CodeGen/LiveRangeEdit.h b/llvm/lib/CodeGen/LiveRangeEdit.h index 37b58279b1bb..73f69ed63983 100644 --- a/llvm/lib/CodeGen/LiveRangeEdit.h +++ b/llvm/lib/CodeGen/LiveRangeEdit.h @@ -78,6 +78,7 @@ public: iterator begin() const { return newRegs_.begin()+firstNew_; } iterator end() const { return newRegs_.end(); } unsigned size() const { return newRegs_.size()-firstNew_; } + bool empty() const { return size() == 0; } LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } /// create - Create a new register with the same class and stack slot as diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 2b30c316f15a..d970c7d16a7a 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -645,9 +645,6 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs); SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit); - // Ranges to add to the register interval after all defs are in place. - SmallVector UseRanges; - // Create the main cross-block interval. SE.openIntv(); @@ -684,7 +681,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.LiveThrough) { DEBUG(dbgs() << ", not live-through.\n"); SE.enterIntvBefore(BI.Def); - UseRanges.push_back(IndexPair(BI.Def, Stop)); + SE.useIntv(BI.Def, Stop); continue; } if (!RegIn) { @@ -692,7 +689,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, // Reload just before the first use. DEBUG(dbgs() << ", not live-in, enter before first use.\n"); SE.enterIntvBefore(BI.FirstUse); - UseRanges.push_back(IndexPair(BI.FirstUse, Stop)); + SE.useIntv(BI.FirstUse, Stop); continue; } DEBUG(dbgs() << ", live-through.\n"); @@ -717,7 +714,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, DEBUG(dbgs() << ", free use at " << Use << ".\n"); assert(Use <= BI.LastUse && "Couldn't find last use"); SE.enterIntvBefore(Use); - UseRanges.push_back(IndexPair(Use, Stop)); + SE.useIntv(Use, Stop); continue; } @@ -726,12 +723,6 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, SE.enterIntvAtEnd(*BI.MBB); } - // Add the live-out ranges following the defs. - // We must wait until all defs have been inserted, otherwise SplitKit gets - // confused about the value mapping. - for (unsigned i = 0, e = UseRanges.size(); i != e; ++i) - SE.useIntv(UseRanges[i].first, UseRanges[i].second); - // Now all defs leading to live bundles are handled, do everything else. for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) { BlockInfo &BI = LiveBlocks[i]; diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index daa3140c1538..0ec983ec13f6 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -449,7 +449,6 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx, // VNInfo. Insert phi-def VNInfos along the path back to IdxMBB. DEBUG(dbgs() << "\n Reaching defs for BB#" << IdxMBB->getNumber() << " at " << Idx << " in " << *LI << '\n'); - DEBUG(dumpCache()); // Blocks where LI should be live-in. SmallVector LiveIn; @@ -587,7 +586,6 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx, assert(IdxVNI && "Didn't find value for Idx"); #ifndef NDEBUG - DEBUG(dumpCache()); // Check the LiveOutCache invariants. for (LiveOutMap::iterator I = LiveOutCache.begin(), E = LiveOutCache.end(); I != E; ++I) { @@ -729,69 +727,86 @@ SplitEditor::SplitEditor(SplitAnalysis &sa, LiveRangeEdit &edit) : sa_(sa), LIS(lis), VRM(vrm), MRI(vrm.getMachineFunction().getRegInfo()), + MDT(mdt), TII(*vrm.getMachineFunction().getTarget().getInstrInfo()), TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()), Edit(edit), - DupLI(LIS, mdt, edit.getParent()), - OpenLI(LIS, mdt, edit.getParent()) + OpenIdx(0), + RegAssign(Allocator) { // We don't need an AliasAnalysis since we will only be performing // cheap-as-a-copy remats anyway. Edit.anyRematerializable(LIS, TII, 0); } -bool SplitEditor::intervalsLiveAt(SlotIndex Idx) const { - for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I) - if (*I != DupLI.getLI() && (*I)->liveAt(Idx)) - return true; - return false; +void SplitEditor::dump() const { + if (RegAssign.empty()) { + dbgs() << " empty\n"; + return; + } + + for (RegAssignMap::const_iterator I = RegAssign.begin(); I.valid(); ++I) + dbgs() << " [" << I.start() << ';' << I.stop() << "):" << I.value(); + dbgs() << '\n'; } -VNInfo *SplitEditor::defFromParent(LiveIntervalMap &Reg, +VNInfo *SplitEditor::defFromParent(unsigned RegIdx, VNInfo *ParentVNI, SlotIndex UseIdx, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) { - VNInfo *VNI = 0; MachineInstr *CopyMI = 0; SlotIndex Def; + LiveInterval *LI = Edit.get(RegIdx); // Attempt cheap-as-a-copy rematerialization. LiveRangeEdit::Remat RM(ParentVNI); if (Edit.canRematerializeAt(RM, UseIdx, true, LIS)) { - Def = Edit.rematerializeAt(MBB, I, Reg.getLI()->reg, RM, - LIS, TII, TRI); + Def = Edit.rematerializeAt(MBB, I, LI->reg, RM, LIS, TII, TRI); } else { // Can't remat, just insert a copy from parent. - CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), - Reg.getLI()->reg).addReg(Edit.getReg()); + CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), LI->reg) + .addReg(Edit.getReg()); Def = LIS.InsertMachineInstrInMaps(CopyMI).getDefIndex(); } // Define the value in Reg. - VNI = Reg.defValue(ParentVNI, Def); + VNInfo *VNI = LIMappers[RegIdx].defValue(ParentVNI, Def); VNI->setCopy(CopyMI); // Add minimal liveness for the new value. - if (UseIdx < Def) - UseIdx = Def; - Reg.getLI()->addRange(LiveRange(Def, UseIdx.getNextSlot(), VNI)); + Edit.get(RegIdx)->addRange(LiveRange(Def, Def.getNextSlot(), VNI)); + + if (RegIdx) { + if (UseIdx < Def) + UseIdx = Def; + RegAssign.insert(Def, UseIdx.getNextSlot(), RegIdx); + } return VNI; } /// Create a new virtual register and live interval. void SplitEditor::openIntv() { - assert(!OpenLI.getLI() && "Previous LI not closed before openIntv"); - if (!DupLI.getLI()) - DupLI.reset(&Edit.create(MRI, LIS, VRM)); + assert(!OpenIdx && "Previous LI not closed before openIntv"); - OpenLI.reset(&Edit.create(MRI, LIS, VRM)); + // Create the complement as index 0. + if (Edit.empty()) { + Edit.create(MRI, LIS, VRM); + LIMappers.push_back(LiveIntervalMap(LIS, MDT, Edit.getParent())); + LIMappers.back().reset(Edit.get(0)); + } + + // Create the open interval. + OpenIdx = Edit.size(); + Edit.create(MRI, LIS, VRM); + LIMappers.push_back(LiveIntervalMap(LIS, MDT, Edit.getParent())); + LIMappers[OpenIdx].reset(Edit.get(OpenIdx)); } /// enterIntvBefore - Enter OpenLI before the instruction at Idx. If CurLI is /// not live before Idx, a COPY is not inserted. void SplitEditor::enterIntvBefore(SlotIndex Idx) { - assert(OpenLI.getLI() && "openIntv not called before enterIntvBefore"); + assert(OpenIdx && "openIntv not called before enterIntvBefore"); Idx = Idx.getUseIndex(); DEBUG(dbgs() << " enterIntvBefore " << Idx); VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx); @@ -800,18 +815,16 @@ void SplitEditor::enterIntvBefore(SlotIndex Idx) { return; } DEBUG(dbgs() << ": valno " << ParentVNI->id); - truncatedValues.insert(ParentVNI); MachineInstr *MI = LIS.getInstructionFromIndex(Idx); assert(MI && "enterIntvBefore called with invalid index"); - defFromParent(OpenLI, ParentVNI, Idx, *MI->getParent(), MI); - - DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); + defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(), MI); + DEBUG(dump()); } /// enterIntvAtEnd - Enter OpenLI at the end of MBB. void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) { - assert(OpenLI.getLI() && "openIntv not called before enterIntvAtEnd"); + assert(OpenIdx && "openIntv not called before enterIntvAtEnd"); SlotIndex End = LIS.getMBBEndIdx(&MBB).getPrevSlot(); DEBUG(dbgs() << " enterIntvAtEnd BB#" << MBB.getNumber() << ", " << End); VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(End); @@ -820,9 +833,8 @@ void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) { return; } DEBUG(dbgs() << ": valno " << ParentVNI->id); - truncatedValues.insert(ParentVNI); - defFromParent(OpenLI, ParentVNI, End, MBB, MBB.getFirstTerminator()); - DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); + defFromParent(OpenIdx, ParentVNI, End, MBB, MBB.getFirstTerminator()); + DEBUG(dump()); } /// useIntv - indicate that all instructions in MBB should use OpenLI. @@ -831,15 +843,15 @@ void SplitEditor::useIntv(const MachineBasicBlock &MBB) { } void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) { - assert(OpenLI.getLI() && "openIntv not called before useIntv"); - OpenLI.addRange(Start, End); - DEBUG(dbgs() << " use [" << Start << ';' << End << "): " - << *OpenLI.getLI() << '\n'); + assert(OpenIdx && "openIntv not called before useIntv"); + DEBUG(dbgs() << " useIntv [" << Start << ';' << End << "):"); + RegAssign.insert(Start, End, OpenIdx); + DEBUG(dump()); } /// leaveIntvAfter - Leave OpenLI after the instruction at Idx. void SplitEditor::leaveIntvAfter(SlotIndex Idx) { - assert(OpenLI.getLI() && "openIntv not called before leaveIntvAfter"); + assert(OpenIdx && "openIntv not called before leaveIntvAfter"); DEBUG(dbgs() << " leaveIntvAfter " << Idx); // The interval must be live beyond the instruction at Idx. @@ -852,20 +864,17 @@ void SplitEditor::leaveIntvAfter(SlotIndex Idx) { DEBUG(dbgs() << ": valno " << ParentVNI->id); MachineBasicBlock::iterator MII = LIS.getInstructionFromIndex(Idx); - VNInfo *VNI = defFromParent(DupLI, ParentVNI, Idx, + VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MII->getParent(), llvm::next(MII)); - // Make sure that OpenLI is properly extended from Idx to the new copy. - // FIXME: This shouldn't be necessary for remats. - OpenLI.addSimpleRange(Idx, VNI->def, ParentVNI); - - DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); + RegAssign.insert(Idx, VNI->def, OpenIdx); + DEBUG(dump()); } /// leaveIntvAtTop - Leave the interval at the top of MBB. /// Currently, only one value can leave the interval. void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { - assert(OpenLI.getLI() && "openIntv not called before leaveIntvAtTop"); + assert(OpenIdx && "openIntv not called before leaveIntvAtTop"); SlotIndex Start = LIS.getMBBStartIdx(&MBB); DEBUG(dbgs() << " leaveIntvAtTop BB#" << MBB.getNumber() << ", " << Start); @@ -875,179 +884,130 @@ void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { return; } - VNInfo *VNI = defFromParent(DupLI, ParentVNI, Start, MBB, + VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB, MBB.SkipPHIsAndLabels(MBB.begin())); - - // Finally we must make sure that OpenLI is properly extended from Start to - // the new copy. - OpenLI.addSimpleRange(Start, VNI->def, ParentVNI); - DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); + RegAssign.insert(Start, VNI->def, OpenIdx); + DEBUG(dump()); } /// closeIntv - Indicate that we are done editing the currently open /// LiveInterval, and ranges can be trimmed. void SplitEditor::closeIntv() { - assert(OpenLI.getLI() && "openIntv not called before closeIntv"); - DEBUG(dbgs() << " closeIntv " << *OpenLI.getLI() << '\n'); - OpenLI.reset(0); + assert(OpenIdx && "openIntv not called before closeIntv"); + OpenIdx = 0; } -/// rewrite - Rewrite all uses of reg to use the new registers. -void SplitEditor::rewrite(unsigned reg) { - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(reg), +/// rewriteAssigned - Rewrite all uses of Edit.getReg(). +void SplitEditor::rewriteAssigned() { + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit.getReg()), RE = MRI.reg_end(); RI != RE;) { MachineOperand &MO = RI.getOperand(); - unsigned OpNum = RI.getOperandNo(); MachineInstr *MI = MO.getParent(); ++RI; + // LiveDebugVariables should have handled all DBG_VALUE instructions. if (MI->isDebugValue()) { DEBUG(dbgs() << "Zapping " << *MI); - // FIXME: We can do much better with debug values. MO.setReg(0); continue; } SlotIndex Idx = LIS.getInstructionIndex(MI); Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); - LiveInterval *LI = 0; - for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; - ++I) { - LiveInterval *testli = *I; - if (testli->liveAt(Idx)) { - LI = testli; - break; - } - } - DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'<< Idx); - assert(LI && "No register was live at use"); - MO.setReg(LI->reg); - if (MO.isUse() && !MI->isRegTiedToDefOperand(OpNum)) - MO.setIsKill(LI->killedAt(Idx.getDefIndex())); - DEBUG(dbgs() << '\t' << *MI); + + // Rewrite to the mapped register at Idx. + unsigned RegIdx = RegAssign.lookup(Idx); + MO.setReg(Edit.get(RegIdx)->reg); + DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' + << Idx << ':' << RegIdx << '\t' << *MI); + + // Extend liveness to Idx. + const VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx); + LIMappers[RegIdx].mapValue(ParentVNI, Idx); } } -void -SplitEditor::addTruncSimpleRange(SlotIndex Start, SlotIndex End, VNInfo *VNI) { - // Build vector of iterator pairs from the intervals. - typedef std::pair IIPair; - SmallVector Iters; - for (LiveRangeEdit::iterator LI = Edit.begin(), LE = Edit.end(); LI != LE; - ++LI) { - if (*LI == DupLI.getLI()) +/// rewriteSplit - Rewrite uses of Intvs[0] according to the ConEQ mapping. +void SplitEditor::rewriteComponents(const SmallVectorImpl &Intvs, + const ConnectedVNInfoEqClasses &ConEq) { + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Intvs[0]->reg), + RE = MRI.reg_end(); RI != RE;) { + MachineOperand &MO = RI.getOperand(); + MachineInstr *MI = MO.getParent(); + ++RI; + if (MO.isUse() && MO.isUndef()) continue; - LiveInterval::const_iterator I = (*LI)->find(Start); - LiveInterval::const_iterator E = (*LI)->end(); - if (I != E) - Iters.push_back(std::make_pair(I, E)); + // DBG_VALUE instructions should have been eliminated earlier. + SlotIndex Idx = LIS.getInstructionIndex(MI); + Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); + DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' + << Idx << ':'); + const VNInfo *VNI = Intvs[0]->getVNInfoAt(Idx); + assert(VNI && "Interval not live at use."); + MO.setReg(Intvs[ConEq.getEqClass(VNI)]->reg); + DEBUG(dbgs() << VNI->id << '\t' << *MI); } - - SlotIndex sidx = Start; - // Break [Start;End) into segments that don't overlap any intervals. - for (;;) { - SlotIndex next = sidx, eidx = End; - // Find overlapping intervals. - for (unsigned i = 0; i != Iters.size() && sidx < eidx; ++i) { - LiveInterval::const_iterator I = Iters[i].first; - // Interval I is overlapping [sidx;eidx). Trim sidx. - if (I->start <= sidx) { - sidx = I->end; - // Move to the next run, remove iters when all are consumed. - I = ++Iters[i].first; - if (I == Iters[i].second) { - Iters.erase(Iters.begin() + i); - --i; - continue; - } - } - // Trim eidx too if needed. - if (I->start >= eidx) - continue; - eidx = I->start; - next = I->end; - } - // Now, [sidx;eidx) doesn't overlap anything in intervals_. - if (sidx < eidx) - DupLI.addSimpleRange(sidx, eidx, VNI); - // If the interval end was truncated, we can try again from next. - if (next <= sidx) - break; - sidx = next; - } -} - -void SplitEditor::computeRemainder() { - // First we need to fill in the live ranges in dupli. - // If values were redefined, we need a full recoloring with SSA update. - // If values were truncated, we only need to truncate the ranges. - // If values were partially rematted, we should shrink to uses. - // If values were fully rematted, they should be omitted. - // FIXME: If a single value is redefined, just move the def and truncate. - LiveInterval &parent = Edit.getParent(); - - DEBUG(dbgs() << "computeRemainder from " << parent << '\n'); - - // Values that are fully contained in the split intervals. - SmallPtrSet deadValues; - // Map all CurLI values that should have live defs in dupli. - for (LiveInterval::const_vni_iterator I = parent.vni_begin(), - E = parent.vni_end(); I != E; ++I) { - const VNInfo *VNI = *I; - // Don't transfer unused values to the new intervals. - if (VNI->isUnused()) - continue; - // Original def is contained in the split intervals. - if (intervalsLiveAt(VNI->def)) { - // Did this value escape? - if (DupLI.isMapped(VNI)) - truncatedValues.insert(VNI); - else - deadValues.insert(VNI); - continue; - } - // Add minimal live range at the definition. - VNInfo *DVNI = DupLI.defValue(VNI, VNI->def); - DupLI.getLI()->addRange(LiveRange(VNI->def, VNI->def.getNextSlot(), DVNI)); - } - - // Add all ranges to dupli. - for (LiveInterval::const_iterator I = parent.begin(), E = parent.end(); - I != E; ++I) { - const LiveRange &LR = *I; - if (truncatedValues.count(LR.valno)) { - // recolor after removing intervals_. - addTruncSimpleRange(LR.start, LR.end, LR.valno); - } else if (!deadValues.count(LR.valno)) { - // recolor without truncation. - DupLI.addSimpleRange(LR.start, LR.end, LR.valno); - } - } - - // Extend DupLI to be live out of any critical loop predecessors. - // This means we have multiple registers live out of those blocks. - // The alternative would be to split the critical edges. - if (criticalPreds_.empty()) - return; - for (SplitAnalysis::BlockPtrSet::iterator I = criticalPreds_.begin(), - E = criticalPreds_.end(); I != E; ++I) - DupLI.extendTo(*I, LIS.getMBBEndIdx(*I).getPrevSlot()); - criticalPreds_.clear(); } void SplitEditor::finish() { - assert(!OpenLI.getLI() && "Previous LI not closed before rewrite"); - assert(DupLI.getLI() && "No dupli for rewrite. Noop spilt?"); + assert(OpenIdx == 0 && "Previous LI not closed before rewrite"); - // Complete dupli liveness. - computeRemainder(); + // At this point, the live intervals in Edit contain VNInfos corresponding to + // the inserted copies. + + // Add the original defs from the parent interval. + for (LiveInterval::const_vni_iterator I = Edit.getParent().vni_begin(), + E = Edit.getParent().vni_end(); I != E; ++I) { + const VNInfo *ParentVNI = *I; + LiveIntervalMap &LIM = LIMappers[RegAssign.lookup(ParentVNI->def)]; + VNInfo *VNI = LIM.defValue(ParentVNI, ParentVNI->def); + LIM.getLI()->addRange(LiveRange(ParentVNI->def, + ParentVNI->def.getNextSlot(), VNI)); + // Mark all values as complex to force liveness computation. + // This should really only be necessary for remat victims, but we are lazy. + LIM.markComplexMapped(ParentVNI); + } + +#ifndef NDEBUG + // Every new interval must have a def by now, otherwise the split is bogus. + for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I) + assert((*I)->hasAtLeastOneValue() && "Split interval has no value"); +#endif + + // FIXME: Don't recompute the liveness of all values, infer it from the + // overlaps between the parent live interval and RegAssign. + // The mapValue algorithm is only necessary when: + // - The parent value maps to multiple defs, and new phis are needed, or + // - The value has been rematerialized before some uses, and we want to + // minimize the live range so it only reaches the remaining uses. + // All other values have simple liveness that can be computed from RegAssign + // and the parent live interval. + + // Extend live ranges to be live-out for successor PHI values. + for (LiveInterval::const_vni_iterator I = Edit.getParent().vni_begin(), + E = Edit.getParent().vni_end(); I != E; ++I) { + const VNInfo *PHIVNI = *I; + if (!PHIVNI->isPHIDef()) + continue; + LiveIntervalMap &LIM = LIMappers[RegAssign.lookup(PHIVNI->def)]; + MachineBasicBlock *MBB = LIS.getMBBFromIndex(PHIVNI->def); + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + SlotIndex End = LIS.getMBBEndIdx(*PI).getPrevSlot(); + // The predecessor may not have a live-out value. That is OK, like an + // undef PHI operand. + if (VNInfo *VNI = Edit.getParent().getVNInfoAt(End)) + LIM.mapValue(VNI, End); + } + } + + // Rewrite instructions. + rewriteAssigned(); + + // FIXME: Delete defs that were rematted everywhere. // Get rid of unused values and set phi-kill flags. for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I) (*I)->RenumberValues(LIS); - // Rewrite instructions. - rewrite(Edit.getReg()); - // Now check if any registers were separated into multiple components. ConnectedVNInfoEqClasses ConEQ(LIS); for (unsigned i = 0, e = Edit.size(); i != e; ++i) { @@ -1061,9 +1021,8 @@ void SplitEditor::finish() { dups.push_back(li); for (unsigned i = 1; i != NumComp; ++i) dups.push_back(&Edit.create(MRI, LIS, VRM)); + rewriteComponents(dups, ConEQ); ConEQ.Distribute(&dups[0]); - // Rewrite uses to the new regs. - rewrite(li->reg); } // Calculate spill weight and allocation hints for new intervals. @@ -1095,9 +1054,6 @@ void SplitEditor::splitAroundLoop(const MachineLoop *Loop) { sa_.getCriticalExits(Blocks, CriticalExits); assert(CriticalExits.empty() && "Cannot break critical exits yet"); - // Get critical predecessors so computeRemainder can deal with them. - sa_.getCriticalPreds(Blocks, criticalPreds_); - // Create new live interval for the loop. openIntv(); diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index bb4fca9084b4..5e9b96b62906 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -13,11 +13,13 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/SlotIndexes.h" namespace llvm { +class ConnectedVNInfoEqClasses; class LiveInterval; class LiveIntervals; class LiveRangeEdit; @@ -263,6 +265,10 @@ public: /// with defValue. bool isComplexMapped(const VNInfo *ParentVNI) const; + /// markComplexMapped - Mark ParentVNI as complex mapped regardless of the + /// number of definitions. + void markComplexMapped(const VNInfo *ParentVNI) { Values[ParentVNI] = 0; } + // addSimpleRange - Add a simple range from ParentLI to LI. // ParentVNI must be live in the [Start;End) interval. void addSimpleRange(SlotIndex Start, SlotIndex End, const VNInfo *ParentVNI); @@ -290,49 +296,49 @@ class SplitEditor { LiveIntervals &LIS; VirtRegMap &VRM; MachineRegisterInfo &MRI; + MachineDominatorTree &MDT; const TargetInstrInfo &TII; const TargetRegisterInfo &TRI; /// Edit - The current parent register and new intervals created. LiveRangeEdit &Edit; - /// DupLI - Created as a copy of CurLI, ranges are carved out as new - /// intervals get added through openIntv / closeIntv. This is used to avoid - /// editing CurLI. - LiveIntervalMap DupLI; + /// Index into Edit of the currently open interval. + /// The index 0 is used for the complement, so the first interval started by + /// openIntv will be 1. + unsigned OpenIdx; - /// Currently open LiveInterval. - LiveIntervalMap OpenLI; + typedef IntervalMap RegAssignMap; + + /// Allocator for the interval map. This will eventually be shared with + /// SlotIndexes and LiveIntervals. + RegAssignMap::Allocator Allocator; + + /// RegAssign - Map of the assigned register indexes. + /// Edit.get(RegAssign.lookup(Idx)) is the register that should be live at + /// Idx. + RegAssignMap RegAssign; + + /// LIMappers - One LiveIntervalMap or each interval in Edit. + SmallVector LIMappers; /// defFromParent - Define Reg from ParentVNI at UseIdx using either /// rematerialization or a COPY from parent. Return the new value. - VNInfo *defFromParent(LiveIntervalMap &Reg, + VNInfo *defFromParent(unsigned RegIdx, VNInfo *ParentVNI, SlotIndex UseIdx, MachineBasicBlock &MBB, MachineBasicBlock::iterator I); - /// intervalsLiveAt - Return true if any member of intervals_ is live at Idx. - bool intervalsLiveAt(SlotIndex Idx) const; + /// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers. + void rewriteAssigned(); - /// Values in CurLI whose live range has been truncated when entering an open - /// li. - SmallPtrSet truncatedValues; - - /// addTruncSimpleRange - Add the given simple range to DupLI after - /// truncating any overlap with intervals_. - void addTruncSimpleRange(SlotIndex Start, SlotIndex End, VNInfo *VNI); - - /// criticalPreds_ - Set of basic blocks where both dupli and OpenLI should be - /// live out because of a critical edge. - SplitAnalysis::BlockPtrSet criticalPreds_; - - /// computeRemainder - Compute the dupli liveness as the complement of all the - /// new intervals. - void computeRemainder(); - - /// rewrite - Rewrite all uses of reg to use the new registers. - void rewrite(unsigned reg); + /// rewriteComponents - Rewrite all uses of Intv[0] according to the eq + /// classes in ConEQ. + /// This must be done when Intvs[0] is styill live at all uses, before calling + /// ConEq.Distribute(). + void rewriteComponents(const SmallVectorImpl &Intvs, + const ConnectedVNInfoEqClasses &ConEq); public: /// Create a new SplitEditor for editing the LiveInterval analyzed by SA. @@ -374,6 +380,9 @@ public: /// remaining live range, and rewrite instructions to use the new registers. void finish(); + /// dump - print the current interval maping to dbgs(). + void dump() const; + // ===--- High level methods ---=== /// splitAroundLoop - Split CurLI into a separate live interval inside