From 463a2977b1d9e6679f859db9f32e9e783b075c10 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 3 Feb 2011 05:40:54 +0000 Subject: [PATCH] Temporarily revert 124765 in an attempt to find the cycle breaking bootstrap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124778 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveInterval.h | 2 +- lib/CodeGen/LiveRangeEdit.h | 1 - lib/CodeGen/RegAllocGreedy.cpp | 15 +- lib/CodeGen/SplitKit.cpp | 322 ++++++++++++++++------------ lib/CodeGen/SplitKit.h | 63 +++--- 5 files changed, 223 insertions(+), 180 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 88131fbc40f..b2915cee97d 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/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) const { return eqClass_[VNI->id]; } + unsigned getEqClass(const VNInfo *VNI) { 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/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h index 73f69ed6398..37b58279b1b 100644 --- a/lib/CodeGen/LiveRangeEdit.h +++ b/lib/CodeGen/LiveRangeEdit.h @@ -78,7 +78,6 @@ 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/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index d970c7d16a7..2b30c316f15 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -645,6 +645,9 @@ 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(); @@ -681,7 +684,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.LiveThrough) { DEBUG(dbgs() << ", not live-through.\n"); SE.enterIntvBefore(BI.Def); - SE.useIntv(BI.Def, Stop); + UseRanges.push_back(IndexPair(BI.Def, Stop)); continue; } if (!RegIn) { @@ -689,7 +692,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); - SE.useIntv(BI.FirstUse, Stop); + UseRanges.push_back(IndexPair(BI.FirstUse, Stop)); continue; } DEBUG(dbgs() << ", live-through.\n"); @@ -714,7 +717,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); - SE.useIntv(Use, Stop); + UseRanges.push_back(IndexPair(Use, Stop)); continue; } @@ -723,6 +726,12 @@ 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/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index 0ec983ec13f..daa3140c153 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -449,6 +449,7 @@ 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; @@ -586,6 +587,7 @@ 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) { @@ -727,86 +729,69 @@ 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), - OpenIdx(0), - RegAssign(Allocator) + DupLI(LIS, mdt, edit.getParent()), + OpenLI(LIS, mdt, edit.getParent()) { // We don't need an AliasAnalysis since we will only be performing // cheap-as-a-copy remats anyway. Edit.anyRematerializable(LIS, TII, 0); } -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'; +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; } -VNInfo *SplitEditor::defFromParent(unsigned RegIdx, +VNInfo *SplitEditor::defFromParent(LiveIntervalMap &Reg, 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, LI->reg, RM, LIS, TII, TRI); + Def = Edit.rematerializeAt(MBB, I, Reg.getLI()->reg, RM, + LIS, TII, TRI); } else { // Can't remat, just insert a copy from parent. - CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), LI->reg) - .addReg(Edit.getReg()); + CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), + Reg.getLI()->reg).addReg(Edit.getReg()); Def = LIS.InsertMachineInstrInMaps(CopyMI).getDefIndex(); } // Define the value in Reg. - VNInfo *VNI = LIMappers[RegIdx].defValue(ParentVNI, Def); + VNI = Reg.defValue(ParentVNI, Def); VNI->setCopy(CopyMI); // Add minimal liveness for the new value. - Edit.get(RegIdx)->addRange(LiveRange(Def, Def.getNextSlot(), VNI)); - - if (RegIdx) { - if (UseIdx < Def) - UseIdx = Def; - RegAssign.insert(Def, UseIdx.getNextSlot(), RegIdx); - } + if (UseIdx < Def) + UseIdx = Def; + Reg.getLI()->addRange(LiveRange(Def, UseIdx.getNextSlot(), VNI)); return VNI; } /// Create a new virtual register and live interval. void SplitEditor::openIntv() { - assert(!OpenIdx && "Previous LI not closed before openIntv"); + assert(!OpenLI.getLI() && "Previous LI not closed before openIntv"); + if (!DupLI.getLI()) + DupLI.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)); + OpenLI.reset(&Edit.create(MRI, LIS, VRM)); } /// 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(OpenIdx && "openIntv not called before enterIntvBefore"); + assert(OpenLI.getLI() && "openIntv not called before enterIntvBefore"); Idx = Idx.getUseIndex(); DEBUG(dbgs() << " enterIntvBefore " << Idx); VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx); @@ -815,16 +800,18 @@ 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(OpenIdx, ParentVNI, Idx, *MI->getParent(), MI); - DEBUG(dump()); + defFromParent(OpenLI, ParentVNI, Idx, *MI->getParent(), MI); + + DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); } /// enterIntvAtEnd - Enter OpenLI at the end of MBB. void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) { - assert(OpenIdx && "openIntv not called before enterIntvAtEnd"); + assert(OpenLI.getLI() && "openIntv not called before enterIntvAtEnd"); SlotIndex End = LIS.getMBBEndIdx(&MBB).getPrevSlot(); DEBUG(dbgs() << " enterIntvAtEnd BB#" << MBB.getNumber() << ", " << End); VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(End); @@ -833,8 +820,9 @@ void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) { return; } DEBUG(dbgs() << ": valno " << ParentVNI->id); - defFromParent(OpenIdx, ParentVNI, End, MBB, MBB.getFirstTerminator()); - DEBUG(dump()); + truncatedValues.insert(ParentVNI); + defFromParent(OpenLI, ParentVNI, End, MBB, MBB.getFirstTerminator()); + DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n'); } /// useIntv - indicate that all instructions in MBB should use OpenLI. @@ -843,15 +831,15 @@ void SplitEditor::useIntv(const MachineBasicBlock &MBB) { } void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) { - assert(OpenIdx && "openIntv not called before useIntv"); - DEBUG(dbgs() << " useIntv [" << Start << ';' << End << "):"); - RegAssign.insert(Start, End, OpenIdx); - DEBUG(dump()); + assert(OpenLI.getLI() && "openIntv not called before useIntv"); + OpenLI.addRange(Start, End); + DEBUG(dbgs() << " use [" << Start << ';' << End << "): " + << *OpenLI.getLI() << '\n'); } /// leaveIntvAfter - Leave OpenLI after the instruction at Idx. void SplitEditor::leaveIntvAfter(SlotIndex Idx) { - assert(OpenIdx && "openIntv not called before leaveIntvAfter"); + assert(OpenLI.getLI() && "openIntv not called before leaveIntvAfter"); DEBUG(dbgs() << " leaveIntvAfter " << Idx); // The interval must be live beyond the instruction at Idx. @@ -864,17 +852,20 @@ void SplitEditor::leaveIntvAfter(SlotIndex Idx) { DEBUG(dbgs() << ": valno " << ParentVNI->id); MachineBasicBlock::iterator MII = LIS.getInstructionFromIndex(Idx); - VNInfo *VNI = defFromParent(0, ParentVNI, Idx, + VNInfo *VNI = defFromParent(DupLI, ParentVNI, Idx, *MII->getParent(), llvm::next(MII)); - RegAssign.insert(Idx, VNI->def, OpenIdx); - DEBUG(dump()); + // 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'); } /// leaveIntvAtTop - Leave the interval at the top of MBB. /// Currently, only one value can leave the interval. void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { - assert(OpenIdx && "openIntv not called before leaveIntvAtTop"); + assert(OpenLI.getLI() && "openIntv not called before leaveIntvAtTop"); SlotIndex Start = LIS.getMBBStartIdx(&MBB); DEBUG(dbgs() << " leaveIntvAtTop BB#" << MBB.getNumber() << ", " << Start); @@ -884,130 +875,179 @@ void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { return; } - VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB, + VNInfo *VNI = defFromParent(DupLI, ParentVNI, Start, MBB, MBB.SkipPHIsAndLabels(MBB.begin())); - RegAssign.insert(Start, VNI->def, OpenIdx); - DEBUG(dump()); + + // 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'); } /// closeIntv - Indicate that we are done editing the currently open /// LiveInterval, and ranges can be trimmed. void SplitEditor::closeIntv() { - assert(OpenIdx && "openIntv not called before closeIntv"); - OpenIdx = 0; + assert(OpenLI.getLI() && "openIntv not called before closeIntv"); + DEBUG(dbgs() << " closeIntv " << *OpenLI.getLI() << '\n'); + OpenLI.reset(0); } -/// rewriteAssigned - Rewrite all uses of Edit.getReg(). -void SplitEditor::rewriteAssigned() { - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit.getReg()), +/// 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), 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(); - - // 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); + 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); } } -/// 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()) +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()) continue; - // 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); + LiveInterval::const_iterator I = (*LI)->find(Start); + LiveInterval::const_iterator E = (*LI)->end(); + if (I != E) + Iters.push_back(std::make_pair(I, E)); + } + + 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::finish() { - assert(OpenIdx == 0 && "Previous LI not closed before rewrite"); +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(); - // At this point, the live intervals in Edit contain VNInfos corresponding to - // the inserted copies. + DEBUG(dbgs() << "computeRemainder from " << parent << '\n'); - // 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); + // 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)); } -#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); + // 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); } } - // Rewrite instructions. - rewriteAssigned(); + // 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(); +} - // FIXME: Delete defs that were rematted everywhere. +void SplitEditor::finish() { + assert(!OpenLI.getLI() && "Previous LI not closed before rewrite"); + assert(DupLI.getLI() && "No dupli for rewrite. Noop spilt?"); + + // Complete dupli liveness. + computeRemainder(); // 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) { @@ -1021,8 +1061,9 @@ 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. @@ -1054,6 +1095,9 @@ 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/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index 5e9b96b6290..bb4fca9084b 100644 --- a/lib/CodeGen/SplitKit.h +++ b/lib/CodeGen/SplitKit.h @@ -13,13 +13,11 @@ //===----------------------------------------------------------------------===// #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; @@ -265,10 +263,6 @@ 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); @@ -296,49 +290,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; - /// 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; + /// 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; - 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; + /// Currently open LiveInterval. + LiveIntervalMap OpenLI; /// defFromParent - Define Reg from ParentVNI at UseIdx using either /// rematerialization or a COPY from parent. Return the new value. - VNInfo *defFromParent(unsigned RegIdx, + VNInfo *defFromParent(LiveIntervalMap &Reg, VNInfo *ParentVNI, SlotIndex UseIdx, MachineBasicBlock &MBB, MachineBasicBlock::iterator I); - /// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers. - void rewriteAssigned(); + /// intervalsLiveAt - Return true if any member of intervals_ is live at Idx. + bool intervalsLiveAt(SlotIndex Idx) const; - /// 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); + /// 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); public: /// Create a new SplitEditor for editing the LiveInterval analyzed by SA. @@ -380,9 +374,6 @@ 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