| //===- SplitKit.cpp - Toolkit for splitting live ranges -------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file contains the SplitAnalysis class as well as mutator functions for | |
| // live range splitting. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "SplitKit.h" | |
| #include "LiveRangeCalc.h" | |
| #include "llvm/ADT/ArrayRef.h" | |
| #include "llvm/ADT/DenseSet.h" | |
| #include "llvm/ADT/None.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/ADT/SmallPtrSet.h" | |
| #include "llvm/ADT/SmallVector.h" | |
| #include "llvm/ADT/Statistic.h" | |
| #include "llvm/CodeGen/LiveInterval.h" | |
| #include "llvm/CodeGen/LiveIntervals.h" | |
| #include "llvm/CodeGen/LiveRangeEdit.h" | |
| #include "llvm/CodeGen/MachineBasicBlock.h" | |
| #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" | |
| #include "llvm/CodeGen/MachineDominators.h" | |
| #include "llvm/CodeGen/MachineFunction.h" | |
| #include "llvm/CodeGen/MachineInstr.h" | |
| #include "llvm/CodeGen/MachineInstrBuilder.h" | |
| #include "llvm/CodeGen/MachineLoopInfo.h" | |
| #include "llvm/CodeGen/MachineOperand.h" | |
| #include "llvm/CodeGen/MachineRegisterInfo.h" | |
| #include "llvm/CodeGen/SlotIndexes.h" | |
| #include "llvm/CodeGen/TargetInstrInfo.h" | |
| #include "llvm/CodeGen/TargetOpcodes.h" | |
| #include "llvm/CodeGen/TargetRegisterInfo.h" | |
| #include "llvm/CodeGen/TargetSubtargetInfo.h" | |
| #include "llvm/CodeGen/VirtRegMap.h" | |
| #include "llvm/Config/llvm-config.h" | |
| #include "llvm/IR/DebugLoc.h" | |
| #include "llvm/MC/LaneBitmask.h" | |
| #include "llvm/Support/Allocator.h" | |
| #include "llvm/Support/BlockFrequency.h" | |
| #include "llvm/Support/Compiler.h" | |
| #include "llvm/Support/Debug.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include <algorithm> | |
| #include <cassert> | |
| #include <iterator> | |
| #include <limits> | |
| #include <tuple> | |
| #include <utility> | |
| using namespace llvm; | |
| #define DEBUG_TYPE "regalloc" | |
| STATISTIC(NumFinished, "Number of splits finished"); | |
| STATISTIC(NumSimple, "Number of splits that were simple"); | |
| STATISTIC(NumCopies, "Number of copies inserted for splitting"); | |
| STATISTIC(NumRemats, "Number of rematerialized defs for splitting"); | |
| STATISTIC(NumRepairs, "Number of invalid live ranges repaired"); | |
| //===----------------------------------------------------------------------===// | |
| // Last Insert Point Analysis | |
| //===----------------------------------------------------------------------===// | |
| InsertPointAnalysis::InsertPointAnalysis(const LiveIntervals &lis, | |
| unsigned BBNum) | |
| : LIS(lis), LastInsertPoint(BBNum) {} | |
| SlotIndex | |
| InsertPointAnalysis::computeLastInsertPoint(const LiveInterval &CurLI, | |
| const MachineBasicBlock &MBB) { | |
| unsigned Num = MBB.getNumber(); | |
| std::pair<SlotIndex, SlotIndex> &LIP = LastInsertPoint[Num]; | |
| SlotIndex MBBEnd = LIS.getMBBEndIdx(&MBB); | |
| SmallVector<const MachineBasicBlock *, 1> EHPadSuccessors; | |
| for (const MachineBasicBlock *SMBB : MBB.successors()) | |
| if (SMBB->isEHPad()) | |
| EHPadSuccessors.push_back(SMBB); | |
| // Compute insert points on the first call. The pair is independent of the | |
| // current live interval. | |
| if (!LIP.first.isValid()) { | |
| MachineBasicBlock::const_iterator FirstTerm = MBB.getFirstTerminator(); | |
| if (FirstTerm == MBB.end()) | |
| LIP.first = MBBEnd; | |
| else | |
| LIP.first = LIS.getInstructionIndex(*FirstTerm); | |
| // If there is a landing pad successor, also find the call instruction. | |
| if (EHPadSuccessors.empty()) | |
| return LIP.first; | |
| // There may not be a call instruction (?) in which case we ignore LPad. | |
| LIP.second = LIP.first; | |
| for (MachineBasicBlock::const_iterator I = MBB.end(), E = MBB.begin(); | |
| I != E;) { | |
| --I; | |
| if (I->isCall()) { | |
| LIP.second = LIS.getInstructionIndex(*I); | |
| break; | |
| } | |
| } | |
| } | |
| // If CurLI is live into a landing pad successor, move the last insert point | |
| // back to the call that may throw. | |
| if (!LIP.second) | |
| return LIP.first; | |
| if (none_of(EHPadSuccessors, [&](const MachineBasicBlock *EHPad) { | |
| return LIS.isLiveInToMBB(CurLI, EHPad); | |
| })) | |
| return LIP.first; | |
| // Find the value leaving MBB. | |
| const VNInfo *VNI = CurLI.getVNInfoBefore(MBBEnd); | |
| if (!VNI) | |
| return LIP.first; | |
| // If the value leaving MBB was defined after the call in MBB, it can't | |
| // really be live-in to the landing pad. This can happen if the landing pad | |
| // has a PHI, and this register is undef on the exceptional edge. | |
| // <rdar://problem/10664933> | |
| if (!SlotIndex::isEarlierInstr(VNI->def, LIP.second) && VNI->def < MBBEnd) | |
| return LIP.first; | |
| // Value is properly live-in to the landing pad. | |
| // Only allow inserts before the call. | |
| return LIP.second; | |
| } | |
| MachineBasicBlock::iterator | |
| InsertPointAnalysis::getLastInsertPointIter(const LiveInterval &CurLI, | |
| MachineBasicBlock &MBB) { | |
| SlotIndex LIP = getLastInsertPoint(CurLI, MBB); | |
| if (LIP == LIS.getMBBEndIdx(&MBB)) | |
| return MBB.end(); | |
| return LIS.getInstructionFromIndex(LIP); | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Split Analysis | |
| //===----------------------------------------------------------------------===// | |
| SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis, | |
| const MachineLoopInfo &mli) | |
| : MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), Loops(mli), | |
| TII(*MF.getSubtarget().getInstrInfo()), IPA(lis, MF.getNumBlockIDs()) {} | |
| void SplitAnalysis::clear() { | |
| UseSlots.clear(); | |
| UseBlocks.clear(); | |
| ThroughBlocks.clear(); | |
| CurLI = nullptr; | |
| DidRepairRange = false; | |
| } | |
| /// analyzeUses - Count instructions, basic blocks, and loops using CurLI. | |
| void SplitAnalysis::analyzeUses() { | |
| assert(UseSlots.empty() && "Call clear first"); | |
| // First get all the defs from the interval values. This provides the correct | |
| // slots for early clobbers. | |
| for (const VNInfo *VNI : CurLI->valnos) | |
| if (!VNI->isPHIDef() && !VNI->isUnused()) | |
| UseSlots.push_back(VNI->def); | |
| // Get use slots form the use-def chain. | |
| const MachineRegisterInfo &MRI = MF.getRegInfo(); | |
| for (MachineOperand &MO : MRI.use_nodbg_operands(CurLI->reg)) | |
| if (!MO.isUndef()) | |
| UseSlots.push_back(LIS.getInstructionIndex(*MO.getParent()).getRegSlot()); | |
| array_pod_sort(UseSlots.begin(), UseSlots.end()); | |
| // Remove duplicates, keeping the smaller slot for each instruction. | |
| // That is what we want for early clobbers. | |
| UseSlots.erase(std::unique(UseSlots.begin(), UseSlots.end(), | |
| SlotIndex::isSameInstr), | |
| UseSlots.end()); | |
| // Compute per-live block info. | |
| if (!calcLiveBlockInfo()) { | |
| // FIXME: calcLiveBlockInfo found inconsistencies in the live range. | |
| // I am looking at you, RegisterCoalescer! | |
| DidRepairRange = true; | |
| ++NumRepairs; | |
| LLVM_DEBUG(dbgs() << "*** Fixing inconsistent live interval! ***\n"); | |
| const_cast<LiveIntervals&>(LIS) | |
| .shrinkToUses(const_cast<LiveInterval*>(CurLI)); | |
| UseBlocks.clear(); | |
| ThroughBlocks.clear(); | |
| bool fixed = calcLiveBlockInfo(); | |
| (void)fixed; | |
| assert(fixed && "Couldn't fix broken live interval"); | |
| } | |
| LLVM_DEBUG(dbgs() << "Analyze counted " << UseSlots.size() << " instrs in " | |
| << UseBlocks.size() << " blocks, through " | |
| << NumThroughBlocks << " blocks.\n"); | |
| } | |
| /// calcLiveBlockInfo - Fill the LiveBlocks array with information about blocks | |
| /// where CurLI is live. | |
| bool SplitAnalysis::calcLiveBlockInfo() { | |
| ThroughBlocks.resize(MF.getNumBlockIDs()); | |
| NumThroughBlocks = NumGapBlocks = 0; | |
| if (CurLI->empty()) | |
| return true; | |
| LiveInterval::const_iterator LVI = CurLI->begin(); | |
| LiveInterval::const_iterator LVE = CurLI->end(); | |
| SmallVectorImpl<SlotIndex>::const_iterator UseI, UseE; | |
| UseI = UseSlots.begin(); | |
| UseE = UseSlots.end(); | |
| // Loop over basic blocks where CurLI is live. | |
| MachineFunction::iterator MFI = | |
| LIS.getMBBFromIndex(LVI->start)->getIterator(); | |
| while (true) { | |
| BlockInfo BI; | |
| BI.MBB = &*MFI; | |
| SlotIndex Start, Stop; | |
| std::tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); | |
| // If the block contains no uses, the range must be live through. At one | |
| // point, RegisterCoalescer could create dangling ranges that ended | |
| // mid-block. | |
| if (UseI == UseE || *UseI >= Stop) { | |
| ++NumThroughBlocks; | |
| ThroughBlocks.set(BI.MBB->getNumber()); | |
| // The range shouldn't end mid-block if there are no uses. This shouldn't | |
| // happen. | |
| if (LVI->end < Stop) | |
| return false; | |
| } else { | |
| // This block has uses. Find the first and last uses in the block. | |
| BI.FirstInstr = *UseI; | |
| assert(BI.FirstInstr >= Start); | |
| do ++UseI; | |
| while (UseI != UseE && *UseI < Stop); | |
| BI.LastInstr = UseI[-1]; | |
| assert(BI.LastInstr < Stop); | |
| // LVI is the first live segment overlapping MBB. | |
| BI.LiveIn = LVI->start <= Start; | |
| // When not live in, the first use should be a def. | |
| if (!BI.LiveIn) { | |
| assert(LVI->start == LVI->valno->def && "Dangling Segment start"); | |
| assert(LVI->start == BI.FirstInstr && "First instr should be a def"); | |
| BI.FirstDef = BI.FirstInstr; | |
| } | |
| // Look for gaps in the live range. | |
| BI.LiveOut = true; | |
| while (LVI->end < Stop) { | |
| SlotIndex LastStop = LVI->end; | |
| if (++LVI == LVE || LVI->start >= Stop) { | |
| BI.LiveOut = false; | |
| BI.LastInstr = LastStop; | |
| break; | |
| } | |
| if (LastStop < LVI->start) { | |
| // There is a gap in the live range. Create duplicate entries for the | |
| // live-in snippet and the live-out snippet. | |
| ++NumGapBlocks; | |
| // Push the Live-in part. | |
| BI.LiveOut = false; | |
| UseBlocks.push_back(BI); | |
| UseBlocks.back().LastInstr = LastStop; | |
| // Set up BI for the live-out part. | |
| BI.LiveIn = false; | |
| BI.LiveOut = true; | |
| BI.FirstInstr = BI.FirstDef = LVI->start; | |
| } | |
| // A Segment that starts in the middle of the block must be a def. | |
| assert(LVI->start == LVI->valno->def && "Dangling Segment start"); | |
| if (!BI.FirstDef) | |
| BI.FirstDef = LVI->start; | |
| } | |
| UseBlocks.push_back(BI); | |
| // LVI is now at LVE or LVI->end >= Stop. | |
| if (LVI == LVE) | |
| break; | |
| } | |
| // Live segment ends exactly at Stop. Move to the next segment. | |
| if (LVI->end == Stop && ++LVI == LVE) | |
| break; | |
| // Pick the next basic block. | |
| if (LVI->start < Stop) | |
| ++MFI; | |
| else | |
| MFI = LIS.getMBBFromIndex(LVI->start)->getIterator(); | |
| } | |
| assert(getNumLiveBlocks() == countLiveBlocks(CurLI) && "Bad block count"); | |
| return true; | |
| } | |
| unsigned SplitAnalysis::countLiveBlocks(const LiveInterval *cli) const { | |
| if (cli->empty()) | |
| return 0; | |
| LiveInterval *li = const_cast<LiveInterval*>(cli); | |
| LiveInterval::iterator LVI = li->begin(); | |
| LiveInterval::iterator LVE = li->end(); | |
| unsigned Count = 0; | |
| // Loop over basic blocks where li is live. | |
| MachineFunction::const_iterator MFI = | |
| LIS.getMBBFromIndex(LVI->start)->getIterator(); | |
| SlotIndex Stop = LIS.getMBBEndIdx(&*MFI); | |
| while (true) { | |
| ++Count; | |
| LVI = li->advanceTo(LVI, Stop); | |
| if (LVI == LVE) | |
| return Count; | |
| do { | |
| ++MFI; | |
| Stop = LIS.getMBBEndIdx(&*MFI); | |
| } while (Stop <= LVI->start); | |
| } | |
| } | |
| bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const { | |
| unsigned OrigReg = VRM.getOriginal(CurLI->reg); | |
| const LiveInterval &Orig = LIS.getInterval(OrigReg); | |
| assert(!Orig.empty() && "Splitting empty interval?"); | |
| LiveInterval::const_iterator I = Orig.find(Idx); | |
| // Range containing Idx should begin at Idx. | |
| if (I != Orig.end() && I->start <= Idx) | |
| return I->start == Idx; | |
| // Range does not contain Idx, previous must end at Idx. | |
| return I != Orig.begin() && (--I)->end == Idx; | |
| } | |
| void SplitAnalysis::analyze(const LiveInterval *li) { | |
| clear(); | |
| CurLI = li; | |
| analyzeUses(); | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Split Editor | |
| //===----------------------------------------------------------------------===// | |
| /// Create a new SplitEditor for editing the LiveInterval analyzed by SA. | |
| SplitEditor::SplitEditor(SplitAnalysis &sa, AliasAnalysis &aa, | |
| LiveIntervals &lis, VirtRegMap &vrm, | |
| MachineDominatorTree &mdt, | |
| MachineBlockFrequencyInfo &mbfi) | |
| : SA(sa), AA(aa), LIS(lis), VRM(vrm), | |
| MRI(vrm.getMachineFunction().getRegInfo()), MDT(mdt), | |
| TII(*vrm.getMachineFunction().getSubtarget().getInstrInfo()), | |
| TRI(*vrm.getMachineFunction().getSubtarget().getRegisterInfo()), | |
| MBFI(mbfi), RegAssign(Allocator) {} | |
| void SplitEditor::reset(LiveRangeEdit &LRE, ComplementSpillMode SM) { | |
| Edit = &LRE; | |
| SpillMode = SM; | |
| OpenIdx = 0; | |
| RegAssign.clear(); | |
| Values.clear(); | |
| // Reset the LiveRangeCalc instances needed for this spill mode. | |
| LRCalc[0].reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, | |
| &LIS.getVNInfoAllocator()); | |
| if (SpillMode) | |
| LRCalc[1].reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, | |
| &LIS.getVNInfoAllocator()); | |
| // We don't need an AliasAnalysis since we will only be performing | |
| // cheap-as-a-copy remats anyway. | |
| Edit->anyRematerializable(nullptr); | |
| } | |
| #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |
| LLVM_DUMP_METHOD 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'; | |
| } | |
| #endif | |
| LiveInterval::SubRange &SplitEditor::getSubRangeForMask(LaneBitmask LM, | |
| LiveInterval &LI) { | |
| for (LiveInterval::SubRange &S : LI.subranges()) | |
| if (S.LaneMask == LM) | |
| return S; | |
| llvm_unreachable("SubRange for this mask not found"); | |
| } | |
| void SplitEditor::addDeadDef(LiveInterval &LI, VNInfo *VNI, bool Original) { | |
| if (!LI.hasSubRanges()) { | |
| LI.createDeadDef(VNI); | |
| return; | |
| } | |
| SlotIndex Def = VNI->def; | |
| if (Original) { | |
| // If we are transferring a def from the original interval, make sure | |
| // to only update the subranges for which the original subranges had | |
| // a def at this location. | |
| for (LiveInterval::SubRange &S : LI.subranges()) { | |
| auto &PS = getSubRangeForMask(S.LaneMask, Edit->getParent()); | |
| VNInfo *PV = PS.getVNInfoAt(Def); | |
| if (PV != nullptr && PV->def == Def) | |
| S.createDeadDef(Def, LIS.getVNInfoAllocator()); | |
| } | |
| } else { | |
| // This is a new def: either from rematerialization, or from an inserted | |
| // copy. Since rematerialization can regenerate a definition of a sub- | |
| // register, we need to check which subranges need to be updated. | |
| const MachineInstr *DefMI = LIS.getInstructionFromIndex(Def); | |
| assert(DefMI != nullptr); | |
| LaneBitmask LM; | |
| for (const MachineOperand &DefOp : DefMI->defs()) { | |
| unsigned R = DefOp.getReg(); | |
| if (R != LI.reg) | |
| continue; | |
| if (unsigned SR = DefOp.getSubReg()) | |
| LM |= TRI.getSubRegIndexLaneMask(SR); | |
| else { | |
| LM = MRI.getMaxLaneMaskForVReg(R); | |
| break; | |
| } | |
| } | |
| for (LiveInterval::SubRange &S : LI.subranges()) | |
| if ((S.LaneMask & LM).any()) | |
| S.createDeadDef(Def, LIS.getVNInfoAllocator()); | |
| } | |
| } | |
| VNInfo *SplitEditor::defValue(unsigned RegIdx, | |
| const VNInfo *ParentVNI, | |
| SlotIndex Idx, | |
| bool Original) { | |
| assert(ParentVNI && "Mapping NULL value"); | |
| assert(Idx.isValid() && "Invalid SlotIndex"); | |
| assert(Edit->getParent().getVNInfoAt(Idx) == ParentVNI && "Bad Parent VNI"); | |
| LiveInterval *LI = &LIS.getInterval(Edit->get(RegIdx)); | |
| // Create a new value. | |
| VNInfo *VNI = LI->getNextValue(Idx, LIS.getVNInfoAllocator()); | |
| bool Force = LI->hasSubRanges(); | |
| ValueForcePair FP(Force ? nullptr : VNI, Force); | |
| // Use insert for lookup, so we can add missing values with a second lookup. | |
| std::pair<ValueMap::iterator, bool> InsP = | |
| Values.insert(std::make_pair(std::make_pair(RegIdx, ParentVNI->id), FP)); | |
| // This was the first time (RegIdx, ParentVNI) was mapped, and it is not | |
| // forced. Keep it as a simple def without any liveness. | |
| if (!Force && InsP.second) | |
| return VNI; | |
| // If the previous value was a simple mapping, add liveness for it now. | |
| if (VNInfo *OldVNI = InsP.first->second.getPointer()) { | |
| addDeadDef(*LI, OldVNI, Original); | |
| // No longer a simple mapping. Switch to a complex mapping. If the | |
| // interval has subranges, make it a forced mapping. | |
| InsP.first->second = ValueForcePair(nullptr, Force); | |
| } | |
| // This is a complex mapping, add liveness for VNI | |
| addDeadDef(*LI, VNI, Original); | |
| return VNI; | |
| } | |
| void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo &ParentVNI) { | |
| ValueForcePair &VFP = Values[std::make_pair(RegIdx, ParentVNI.id)]; | |
| VNInfo *VNI = VFP.getPointer(); | |
| // ParentVNI was either unmapped or already complex mapped. Either way, just | |
| // set the force bit. | |
| if (!VNI) { | |
| VFP.setInt(true); | |
| return; | |
| } | |
| // This was previously a single mapping. Make sure the old def is represented | |
| // by a trivial live range. | |
| addDeadDef(LIS.getInterval(Edit->get(RegIdx)), VNI, false); | |
| // Mark as complex mapped, forced. | |
| VFP = ValueForcePair(nullptr, true); | |
| } | |
| SlotIndex SplitEditor::buildSingleSubRegCopy(unsigned FromReg, unsigned ToReg, | |
| MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, | |
| unsigned SubIdx, LiveInterval &DestLI, bool Late, SlotIndex Def) { | |
| const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); | |
| bool FirstCopy = !Def.isValid(); | |
| MachineInstr *CopyMI = BuildMI(MBB, InsertBefore, DebugLoc(), Desc) | |
| .addReg(ToReg, RegState::Define | getUndefRegState(FirstCopy) | |
| | getInternalReadRegState(!FirstCopy), SubIdx) | |
| .addReg(FromReg, 0, SubIdx); | |
| BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator(); | |
| if (FirstCopy) { | |
| SlotIndexes &Indexes = *LIS.getSlotIndexes(); | |
| Def = Indexes.insertMachineInstrInMaps(*CopyMI, Late).getRegSlot(); | |
| } else { | |
| CopyMI->bundleWithPred(); | |
| } | |
| LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubIdx); | |
| DestLI.refineSubRanges(Allocator, LaneMask, | |
| [Def, &Allocator](LiveInterval::SubRange& SR) { | |
| SR.createDeadDef(Def, Allocator); | |
| }); | |
| return Def; | |
| } | |
| SlotIndex SplitEditor::buildCopy(unsigned FromReg, unsigned ToReg, | |
| LaneBitmask LaneMask, MachineBasicBlock &MBB, | |
| MachineBasicBlock::iterator InsertBefore, bool Late, unsigned RegIdx) { | |
| const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); | |
| if (LaneMask.all() || LaneMask == MRI.getMaxLaneMaskForVReg(FromReg)) { | |
| // The full vreg is copied. | |
| MachineInstr *CopyMI = | |
| BuildMI(MBB, InsertBefore, DebugLoc(), Desc, ToReg).addReg(FromReg); | |
| SlotIndexes &Indexes = *LIS.getSlotIndexes(); | |
| return Indexes.insertMachineInstrInMaps(*CopyMI, Late).getRegSlot(); | |
| } | |
| // Only a subset of lanes needs to be copied. The following is a simple | |
| // heuristic to construct a sequence of COPYs. We could add a target | |
| // specific callback if this turns out to be suboptimal. | |
| LiveInterval &DestLI = LIS.getInterval(Edit->get(RegIdx)); | |
| // First pass: Try to find a perfectly matching subregister index. If none | |
| // exists find the one covering the most lanemask bits. | |
| SmallVector<unsigned, 8> PossibleIndexes; | |
| unsigned BestIdx = 0; | |
| unsigned BestCover = 0; | |
| const TargetRegisterClass *RC = MRI.getRegClass(FromReg); | |
| assert(RC == MRI.getRegClass(ToReg) && "Should have same reg class"); | |
| for (unsigned Idx = 1, E = TRI.getNumSubRegIndices(); Idx < E; ++Idx) { | |
| // Is this index even compatible with the given class? | |
| if (TRI.getSubClassWithSubReg(RC, Idx) != RC) | |
| continue; | |
| LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(Idx); | |
| // Early exit if we found a perfect match. | |
| if (SubRegMask == LaneMask) { | |
| BestIdx = Idx; | |
| break; | |
| } | |
| // The index must not cover any lanes outside \p LaneMask. | |
| if ((SubRegMask & ~LaneMask).any()) | |
| continue; | |
| unsigned PopCount = SubRegMask.getNumLanes(); | |
| PossibleIndexes.push_back(Idx); | |
| if (PopCount > BestCover) { | |
| BestCover = PopCount; | |
| BestIdx = Idx; | |
| } | |
| } | |
| // Abort if we cannot possibly implement the COPY with the given indexes. | |
| if (BestIdx == 0) | |
| report_fatal_error("Impossible to implement partial COPY"); | |
| SlotIndex Def = buildSingleSubRegCopy(FromReg, ToReg, MBB, InsertBefore, | |
| BestIdx, DestLI, Late, SlotIndex()); | |
| // Greedy heuristic: Keep iterating keeping the best covering subreg index | |
| // each time. | |
| LaneBitmask LanesLeft = LaneMask & ~(TRI.getSubRegIndexLaneMask(BestIdx)); | |
| while (LanesLeft.any()) { | |
| unsigned BestIdx = 0; | |
| int BestCover = std::numeric_limits<int>::min(); | |
| for (unsigned Idx : PossibleIndexes) { | |
| LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(Idx); | |
| // Early exit if we found a perfect match. | |
| if (SubRegMask == LanesLeft) { | |
| BestIdx = Idx; | |
| break; | |
| } | |
| // Try to cover as much of the remaining lanes as possible but | |
| // as few of the already covered lanes as possible. | |
| int Cover = (SubRegMask & LanesLeft).getNumLanes() | |
| - (SubRegMask & ~LanesLeft).getNumLanes(); | |
| if (Cover > BestCover) { | |
| BestCover = Cover; | |
| BestIdx = Idx; | |
| } | |
| } | |
| if (BestIdx == 0) | |
| report_fatal_error("Impossible to implement partial COPY"); | |
| buildSingleSubRegCopy(FromReg, ToReg, MBB, InsertBefore, BestIdx, | |
| DestLI, Late, Def); | |
| LanesLeft &= ~TRI.getSubRegIndexLaneMask(BestIdx); | |
| } | |
| return Def; | |
| } | |
| VNInfo *SplitEditor::defFromParent(unsigned RegIdx, | |
| VNInfo *ParentVNI, | |
| SlotIndex UseIdx, | |
| MachineBasicBlock &MBB, | |
| MachineBasicBlock::iterator I) { | |
| SlotIndex Def; | |
| LiveInterval *LI = &LIS.getInterval(Edit->get(RegIdx)); | |
| // We may be trying to avoid interference that ends at a deleted instruction, | |
| // so always begin RegIdx 0 early and all others late. | |
| bool Late = RegIdx != 0; | |
| // Attempt cheap-as-a-copy rematerialization. | |
| unsigned Original = VRM.getOriginal(Edit->get(RegIdx)); | |
| LiveInterval &OrigLI = LIS.getInterval(Original); | |
| VNInfo *OrigVNI = OrigLI.getVNInfoAt(UseIdx); | |
| unsigned Reg = LI->reg; | |
| bool DidRemat = false; | |
| if (OrigVNI) { | |
| LiveRangeEdit::Remat RM(ParentVNI); | |
| RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->def); | |
| if (Edit->canRematerializeAt(RM, OrigVNI, UseIdx, true)) { | |
| Def = Edit->rematerializeAt(MBB, I, Reg, RM, TRI, Late); | |
| ++NumRemats; | |
| DidRemat = true; | |
| } | |
| } | |
| if (!DidRemat) { | |
| LaneBitmask LaneMask; | |
| if (LI->hasSubRanges()) { | |
| LaneMask = LaneBitmask::getNone(); | |
| for (LiveInterval::SubRange &S : LI->subranges()) | |
| LaneMask |= S.LaneMask; | |
| } else { | |
| LaneMask = LaneBitmask::getAll(); | |
| } | |
| ++NumCopies; | |
| Def = buildCopy(Edit->getReg(), Reg, LaneMask, MBB, I, Late, RegIdx); | |
| } | |
| // Define the value in Reg. | |
| return defValue(RegIdx, ParentVNI, Def, false); | |
| } | |
| /// Create a new virtual register and live interval. | |
| unsigned SplitEditor::openIntv() { | |
| // Create the complement as index 0. | |
| if (Edit->empty()) | |
| Edit->createEmptyInterval(); | |
| // Create the open interval. | |
| OpenIdx = Edit->size(); | |
| Edit->createEmptyInterval(); | |
| return OpenIdx; | |
| } | |
| void SplitEditor::selectIntv(unsigned Idx) { | |
| assert(Idx != 0 && "Cannot select the complement interval"); | |
| assert(Idx < Edit->size() && "Can only select previously opened interval"); | |
| LLVM_DEBUG(dbgs() << " selectIntv " << OpenIdx << " -> " << Idx << '\n'); | |
| OpenIdx = Idx; | |
| } | |
| SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) { | |
| assert(OpenIdx && "openIntv not called before enterIntvBefore"); | |
| LLVM_DEBUG(dbgs() << " enterIntvBefore " << Idx); | |
| Idx = Idx.getBaseIndex(); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return Idx; | |
| } | |
| LLVM_DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); | |
| MachineInstr *MI = LIS.getInstructionFromIndex(Idx); | |
| assert(MI && "enterIntvBefore called with invalid index"); | |
| VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(), MI); | |
| return VNI->def; | |
| } | |
| SlotIndex SplitEditor::enterIntvAfter(SlotIndex Idx) { | |
| assert(OpenIdx && "openIntv not called before enterIntvAfter"); | |
| LLVM_DEBUG(dbgs() << " enterIntvAfter " << Idx); | |
| Idx = Idx.getBoundaryIndex(); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return Idx; | |
| } | |
| LLVM_DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); | |
| MachineInstr *MI = LIS.getInstructionFromIndex(Idx); | |
| assert(MI && "enterIntvAfter called with invalid index"); | |
| VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(), | |
| std::next(MachineBasicBlock::iterator(MI))); | |
| return VNI->def; | |
| } | |
| SlotIndex SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) { | |
| assert(OpenIdx && "openIntv not called before enterIntvAtEnd"); | |
| SlotIndex End = LIS.getMBBEndIdx(&MBB); | |
| SlotIndex Last = End.getPrevSlot(); | |
| LLVM_DEBUG(dbgs() << " enterIntvAtEnd " << printMBBReference(MBB) << ", " | |
| << Last); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Last); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return End; | |
| } | |
| LLVM_DEBUG(dbgs() << ": valno " << ParentVNI->id); | |
| VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Last, MBB, | |
| SA.getLastSplitPointIter(&MBB)); | |
| RegAssign.insert(VNI->def, End, OpenIdx); | |
| LLVM_DEBUG(dump()); | |
| return VNI->def; | |
| } | |
| /// useIntv - indicate that all instructions in MBB should use OpenLI. | |
| void SplitEditor::useIntv(const MachineBasicBlock &MBB) { | |
| useIntv(LIS.getMBBStartIdx(&MBB), LIS.getMBBEndIdx(&MBB)); | |
| } | |
| void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) { | |
| assert(OpenIdx && "openIntv not called before useIntv"); | |
| LLVM_DEBUG(dbgs() << " useIntv [" << Start << ';' << End << "):"); | |
| RegAssign.insert(Start, End, OpenIdx); | |
| LLVM_DEBUG(dump()); | |
| } | |
| SlotIndex SplitEditor::leaveIntvAfter(SlotIndex Idx) { | |
| assert(OpenIdx && "openIntv not called before leaveIntvAfter"); | |
| LLVM_DEBUG(dbgs() << " leaveIntvAfter " << Idx); | |
| // The interval must be live beyond the instruction at Idx. | |
| SlotIndex Boundary = Idx.getBoundaryIndex(); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Boundary); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return Boundary.getNextSlot(); | |
| } | |
| LLVM_DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); | |
| MachineInstr *MI = LIS.getInstructionFromIndex(Boundary); | |
| assert(MI && "No instruction at index"); | |
| // In spill mode, make live ranges as short as possible by inserting the copy | |
| // before MI. This is only possible if that instruction doesn't redefine the | |
| // value. The inserted COPY is not a kill, and we don't need to recompute | |
| // the source live range. The spiller also won't try to hoist this copy. | |
| if (SpillMode && !SlotIndex::isSameInstr(ParentVNI->def, Idx) && | |
| MI->readsVirtualRegister(Edit->getReg())) { | |
| forceRecompute(0, *ParentVNI); | |
| defFromParent(0, ParentVNI, Idx, *MI->getParent(), MI); | |
| return Idx; | |
| } | |
| VNInfo *VNI = defFromParent(0, ParentVNI, Boundary, *MI->getParent(), | |
| std::next(MachineBasicBlock::iterator(MI))); | |
| return VNI->def; | |
| } | |
| SlotIndex SplitEditor::leaveIntvBefore(SlotIndex Idx) { | |
| assert(OpenIdx && "openIntv not called before leaveIntvBefore"); | |
| LLVM_DEBUG(dbgs() << " leaveIntvBefore " << Idx); | |
| // The interval must be live into the instruction at Idx. | |
| Idx = Idx.getBaseIndex(); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return Idx.getNextSlot(); | |
| } | |
| LLVM_DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); | |
| MachineInstr *MI = LIS.getInstructionFromIndex(Idx); | |
| assert(MI && "No instruction at index"); | |
| VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MI->getParent(), MI); | |
| return VNI->def; | |
| } | |
| SlotIndex SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { | |
| assert(OpenIdx && "openIntv not called before leaveIntvAtTop"); | |
| SlotIndex Start = LIS.getMBBStartIdx(&MBB); | |
| LLVM_DEBUG(dbgs() << " leaveIntvAtTop " << printMBBReference(MBB) << ", " | |
| << Start); | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Start); | |
| if (!ParentVNI) { | |
| LLVM_DEBUG(dbgs() << ": not live\n"); | |
| return Start; | |
| } | |
| VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB, | |
| MBB.SkipPHIsLabelsAndDebug(MBB.begin())); | |
| RegAssign.insert(Start, VNI->def, OpenIdx); | |
| LLVM_DEBUG(dump()); | |
| return VNI->def; | |
| } | |
| void SplitEditor::overlapIntv(SlotIndex Start, SlotIndex End) { | |
| assert(OpenIdx && "openIntv not called before overlapIntv"); | |
| const VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Start); | |
| assert(ParentVNI == Edit->getParent().getVNInfoBefore(End) && | |
| "Parent changes value in extended range"); | |
| assert(LIS.getMBBFromIndex(Start) == LIS.getMBBFromIndex(End) && | |
| "Range cannot span basic blocks"); | |
| // The complement interval will be extended as needed by LRCalc.extend(). | |
| if (ParentVNI) | |
| forceRecompute(0, *ParentVNI); | |
| LLVM_DEBUG(dbgs() << " overlapIntv [" << Start << ';' << End << "):"); | |
| RegAssign.insert(Start, End, OpenIdx); | |
| LLVM_DEBUG(dump()); | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Spill modes | |
| //===----------------------------------------------------------------------===// | |
| void SplitEditor::removeBackCopies(SmallVectorImpl<VNInfo*> &Copies) { | |
| LiveInterval *LI = &LIS.getInterval(Edit->get(0)); | |
| LLVM_DEBUG(dbgs() << "Removing " << Copies.size() << " back-copies.\n"); | |
| RegAssignMap::iterator AssignI; | |
| AssignI.setMap(RegAssign); | |
| for (unsigned i = 0, e = Copies.size(); i != e; ++i) { | |
| SlotIndex Def = Copies[i]->def; | |
| MachineInstr *MI = LIS.getInstructionFromIndex(Def); | |
| assert(MI && "No instruction for back-copy"); | |
| MachineBasicBlock *MBB = MI->getParent(); | |
| MachineBasicBlock::iterator MBBI(MI); | |
| bool AtBegin; | |
| do AtBegin = MBBI == MBB->begin(); | |
| while (!AtBegin && (--MBBI)->isDebugInstr()); | |
| LLVM_DEBUG(dbgs() << "Removing " << Def << '\t' << *MI); | |
| LIS.removeVRegDefAt(*LI, Def); | |
| LIS.RemoveMachineInstrFromMaps(*MI); | |
| MI->eraseFromParent(); | |
| // Adjust RegAssign if a register assignment is killed at Def. We want to | |
| // avoid calculating the live range of the source register if possible. | |
| AssignI.find(Def.getPrevSlot()); | |
| if (!AssignI.valid() || AssignI.start() >= Def) | |
| continue; | |
| // If MI doesn't kill the assigned register, just leave it. | |
| if (AssignI.stop() != Def) | |
| continue; | |
| unsigned RegIdx = AssignI.value(); | |
| if (AtBegin || !MBBI->readsVirtualRegister(Edit->getReg())) { | |
| LLVM_DEBUG(dbgs() << " cannot find simple kill of RegIdx " << RegIdx | |
| << '\n'); | |
| forceRecompute(RegIdx, *Edit->getParent().getVNInfoAt(Def)); | |
| } else { | |
| SlotIndex Kill = LIS.getInstructionIndex(*MBBI).getRegSlot(); | |
| LLVM_DEBUG(dbgs() << " move kill to " << Kill << '\t' << *MBBI); | |
| AssignI.setStop(Kill); | |
| } | |
| } | |
| } | |
| MachineBasicBlock* | |
| SplitEditor::findShallowDominator(MachineBasicBlock *MBB, | |
| MachineBasicBlock *DefMBB) { | |
| if (MBB == DefMBB) | |
| return MBB; | |
| assert(MDT.dominates(DefMBB, MBB) && "MBB must be dominated by the def."); | |
| const MachineLoopInfo &Loops = SA.Loops; | |
| const MachineLoop *DefLoop = Loops.getLoopFor(DefMBB); | |
| MachineDomTreeNode *DefDomNode = MDT[DefMBB]; | |
| // Best candidate so far. | |
| MachineBasicBlock *BestMBB = MBB; | |
| unsigned BestDepth = std::numeric_limits<unsigned>::max(); | |
| while (true) { | |
| const MachineLoop *Loop = Loops.getLoopFor(MBB); | |
| // MBB isn't in a loop, it doesn't get any better. All dominators have a | |
| // higher frequency by definition. | |
| if (!Loop) { | |
| LLVM_DEBUG(dbgs() << "Def in " << printMBBReference(*DefMBB) | |
| << " dominates " << printMBBReference(*MBB) | |
| << " at depth 0\n"); | |
| return MBB; | |
| } | |
| // We'll never be able to exit the DefLoop. | |
| if (Loop == DefLoop) { | |
| LLVM_DEBUG(dbgs() << "Def in " << printMBBReference(*DefMBB) | |
| << " dominates " << printMBBReference(*MBB) | |
| << " in the same loop\n"); | |
| return MBB; | |
| } | |
| // Least busy dominator seen so far. | |
| unsigned Depth = Loop->getLoopDepth(); | |
| if (Depth < BestDepth) { | |
| BestMBB = MBB; | |
| BestDepth = Depth; | |
| LLVM_DEBUG(dbgs() << "Def in " << printMBBReference(*DefMBB) | |
| << " dominates " << printMBBReference(*MBB) | |
| << " at depth " << Depth << '\n'); | |
| } | |
| // Leave loop by going to the immediate dominator of the loop header. | |
| // This is a bigger stride than simply walking up the dominator tree. | |
| MachineDomTreeNode *IDom = MDT[Loop->getHeader()]->getIDom(); | |
| // Too far up the dominator tree? | |
| if (!IDom || !MDT.dominates(DefDomNode, IDom)) | |
| return BestMBB; | |
| MBB = IDom->getBlock(); | |
| } | |
| } | |
| void SplitEditor::computeRedundantBackCopies( | |
| DenseSet<unsigned> &NotToHoistSet, SmallVectorImpl<VNInfo *> &BackCopies) { | |
| LiveInterval *LI = &LIS.getInterval(Edit->get(0)); | |
| LiveInterval *Parent = &Edit->getParent(); | |
| SmallVector<SmallPtrSet<VNInfo *, 8>, 8> EqualVNs(Parent->getNumValNums()); | |
| SmallPtrSet<VNInfo *, 8> DominatedVNIs; | |
| // Aggregate VNIs having the same value as ParentVNI. | |
| for (VNInfo *VNI : LI->valnos) { | |
| if (VNI->isUnused()) | |
| continue; | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(VNI->def); | |
| EqualVNs[ParentVNI->id].insert(VNI); | |
| } | |
| // For VNI aggregation of each ParentVNI, collect dominated, i.e., | |
| // redundant VNIs to BackCopies. | |
| for (unsigned i = 0, e = Parent->getNumValNums(); i != e; ++i) { | |
| VNInfo *ParentVNI = Parent->getValNumInfo(i); | |
| if (!NotToHoistSet.count(ParentVNI->id)) | |
| continue; | |
| SmallPtrSetIterator<VNInfo *> It1 = EqualVNs[ParentVNI->id].begin(); | |
| SmallPtrSetIterator<VNInfo *> It2 = It1; | |
| for (; It1 != EqualVNs[ParentVNI->id].end(); ++It1) { | |
| It2 = It1; | |
| for (++It2; It2 != EqualVNs[ParentVNI->id].end(); ++It2) { | |
| if (DominatedVNIs.count(*It1) || DominatedVNIs.count(*It2)) | |
| continue; | |
| MachineBasicBlock *MBB1 = LIS.getMBBFromIndex((*It1)->def); | |
| MachineBasicBlock *MBB2 = LIS.getMBBFromIndex((*It2)->def); | |
| if (MBB1 == MBB2) { | |
| DominatedVNIs.insert((*It1)->def < (*It2)->def ? (*It2) : (*It1)); | |
| } else if (MDT.dominates(MBB1, MBB2)) { | |
| DominatedVNIs.insert(*It2); | |
| } else if (MDT.dominates(MBB2, MBB1)) { | |
| DominatedVNIs.insert(*It1); | |
| } | |
| } | |
| } | |
| if (!DominatedVNIs.empty()) { | |
| forceRecompute(0, *ParentVNI); | |
| for (auto VNI : DominatedVNIs) { | |
| BackCopies.push_back(VNI); | |
| } | |
| DominatedVNIs.clear(); | |
| } | |
| } | |
| } | |
| /// For SM_Size mode, find a common dominator for all the back-copies for | |
| /// the same ParentVNI and hoist the backcopies to the dominator BB. | |
| /// For SM_Speed mode, if the common dominator is hot and it is not beneficial | |
| /// to do the hoisting, simply remove the dominated backcopies for the same | |
| /// ParentVNI. | |
| void SplitEditor::hoistCopies() { | |
| // Get the complement interval, always RegIdx 0. | |
| LiveInterval *LI = &LIS.getInterval(Edit->get(0)); | |
| LiveInterval *Parent = &Edit->getParent(); | |
| // Track the nearest common dominator for all back-copies for each ParentVNI, | |
| // indexed by ParentVNI->id. | |
| using DomPair = std::pair<MachineBasicBlock *, SlotIndex>; | |
| SmallVector<DomPair, 8> NearestDom(Parent->getNumValNums()); | |
| // The total cost of all the back-copies for each ParentVNI. | |
| SmallVector<BlockFrequency, 8> Costs(Parent->getNumValNums()); | |
| // The ParentVNI->id set for which hoisting back-copies are not beneficial | |
| // for Speed. | |
| DenseSet<unsigned> NotToHoistSet; | |
| // Find the nearest common dominator for parent values with multiple | |
| // back-copies. If a single back-copy dominates, put it in DomPair.second. | |
| for (VNInfo *VNI : LI->valnos) { | |
| if (VNI->isUnused()) | |
| continue; | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(VNI->def); | |
| assert(ParentVNI && "Parent not live at complement def"); | |
| // Don't hoist remats. The complement is probably going to disappear | |
| // completely anyway. | |
| if (Edit->didRematerialize(ParentVNI)) | |
| continue; | |
| MachineBasicBlock *ValMBB = LIS.getMBBFromIndex(VNI->def); | |
| DomPair &Dom = NearestDom[ParentVNI->id]; | |
| // Keep directly defined parent values. This is either a PHI or an | |
| // instruction in the complement range. All other copies of ParentVNI | |
| // should be eliminated. | |
| if (VNI->def == ParentVNI->def) { | |
| LLVM_DEBUG(dbgs() << "Direct complement def at " << VNI->def << '\n'); | |
| Dom = DomPair(ValMBB, VNI->def); | |
| continue; | |
| } | |
| // Skip the singly mapped values. There is nothing to gain from hoisting a | |
| // single back-copy. | |
| if (Values.lookup(std::make_pair(0, ParentVNI->id)).getPointer()) { | |
| LLVM_DEBUG(dbgs() << "Single complement def at " << VNI->def << '\n'); | |
| continue; | |
| } | |
| if (!Dom.first) { | |
| // First time we see ParentVNI. VNI dominates itself. | |
| Dom = DomPair(ValMBB, VNI->def); | |
| } else if (Dom.first == ValMBB) { | |
| // Two defs in the same block. Pick the earlier def. | |
| if (!Dom.second.isValid() || VNI->def < Dom.second) | |
| Dom.second = VNI->def; | |
| } else { | |
| // Different basic blocks. Check if one dominates. | |
| MachineBasicBlock *Near = | |
| MDT.findNearestCommonDominator(Dom.first, ValMBB); | |
| if (Near == ValMBB) | |
| // Def ValMBB dominates. | |
| Dom = DomPair(ValMBB, VNI->def); | |
| else if (Near != Dom.first) | |
| // None dominate. Hoist to common dominator, need new def. | |
| Dom = DomPair(Near, SlotIndex()); | |
| Costs[ParentVNI->id] += MBFI.getBlockFreq(ValMBB); | |
| } | |
| LLVM_DEBUG(dbgs() << "Multi-mapped complement " << VNI->id << '@' | |
| << VNI->def << " for parent " << ParentVNI->id << '@' | |
| << ParentVNI->def << " hoist to " | |
| << printMBBReference(*Dom.first) << ' ' << Dom.second | |
| << '\n'); | |
| } | |
| // Insert the hoisted copies. | |
| for (unsigned i = 0, e = Parent->getNumValNums(); i != e; ++i) { | |
| DomPair &Dom = NearestDom[i]; | |
| if (!Dom.first || Dom.second.isValid()) | |
| continue; | |
| // This value needs a hoisted copy inserted at the end of Dom.first. | |
| VNInfo *ParentVNI = Parent->getValNumInfo(i); | |
| MachineBasicBlock *DefMBB = LIS.getMBBFromIndex(ParentVNI->def); | |
| // Get a less loopy dominator than Dom.first. | |
| Dom.first = findShallowDominator(Dom.first, DefMBB); | |
| if (SpillMode == SM_Speed && | |
| MBFI.getBlockFreq(Dom.first) > Costs[ParentVNI->id]) { | |
| NotToHoistSet.insert(ParentVNI->id); | |
| continue; | |
| } | |
| SlotIndex Last = LIS.getMBBEndIdx(Dom.first).getPrevSlot(); | |
| Dom.second = | |
| defFromParent(0, ParentVNI, Last, *Dom.first, | |
| SA.getLastSplitPointIter(Dom.first))->def; | |
| } | |
| // Remove redundant back-copies that are now known to be dominated by another | |
| // def with the same value. | |
| SmallVector<VNInfo*, 8> BackCopies; | |
| for (VNInfo *VNI : LI->valnos) { | |
| if (VNI->isUnused()) | |
| continue; | |
| VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(VNI->def); | |
| const DomPair &Dom = NearestDom[ParentVNI->id]; | |
| if (!Dom.first || Dom.second == VNI->def || | |
| NotToHoistSet.count(ParentVNI->id)) | |
| continue; | |
| BackCopies.push_back(VNI); | |
| forceRecompute(0, *ParentVNI); | |
| } | |
| // If it is not beneficial to hoist all the BackCopies, simply remove | |
| // redundant BackCopies in speed mode. | |
| if (SpillMode == SM_Speed && !NotToHoistSet.empty()) | |
| computeRedundantBackCopies(NotToHoistSet, BackCopies); | |
| removeBackCopies(BackCopies); | |
| } | |
| /// transferValues - Transfer all possible values to the new live ranges. | |
| /// Values that were rematerialized are left alone, they need LRCalc.extend(). | |
| bool SplitEditor::transferValues() { | |
| bool Skipped = false; | |
| RegAssignMap::const_iterator AssignI = RegAssign.begin(); | |
| for (const LiveRange::Segment &S : Edit->getParent()) { | |
| LLVM_DEBUG(dbgs() << " blit " << S << ':'); | |
| VNInfo *ParentVNI = S.valno; | |
| // RegAssign has holes where RegIdx 0 should be used. | |
| SlotIndex Start = S.start; | |
| AssignI.advanceTo(Start); | |
| do { | |
| unsigned RegIdx; | |
| SlotIndex End = S.end; | |
| if (!AssignI.valid()) { | |
| RegIdx = 0; | |
| } else if (AssignI.start() <= Start) { | |
| RegIdx = AssignI.value(); | |
| if (AssignI.stop() < End) { | |
| End = AssignI.stop(); | |
| ++AssignI; | |
| } | |
| } else { | |
| RegIdx = 0; | |
| End = std::min(End, AssignI.start()); | |
| } | |
| // The interval [Start;End) is continuously mapped to RegIdx, ParentVNI. | |
| LLVM_DEBUG(dbgs() << " [" << Start << ';' << End << ")=" << RegIdx << '(' | |
| << printReg(Edit->get(RegIdx)) << ')'); | |
| LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx)); | |
| // Check for a simply defined value that can be blitted directly. | |
| ValueForcePair VFP = Values.lookup(std::make_pair(RegIdx, ParentVNI->id)); | |
| if (VNInfo *VNI = VFP.getPointer()) { | |
| LLVM_DEBUG(dbgs() << ':' << VNI->id); | |
| LI.addSegment(LiveInterval::Segment(Start, End, VNI)); | |
| Start = End; | |
| continue; | |
| } | |
| // Skip values with forced recomputation. | |
| if (VFP.getInt()) { | |
| LLVM_DEBUG(dbgs() << "(recalc)"); | |
| Skipped = true; | |
| Start = End; | |
| continue; | |
| } | |
| LiveRangeCalc &LRC = getLRCalc(RegIdx); | |
| // This value has multiple defs in RegIdx, but it wasn't rematerialized, | |
| // so the live range is accurate. Add live-in blocks in [Start;End) to the | |
| // LiveInBlocks. | |
| MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start)->getIterator(); | |
| SlotIndex BlockStart, BlockEnd; | |
| std::tie(BlockStart, BlockEnd) = LIS.getSlotIndexes()->getMBBRange(&*MBB); | |
| // The first block may be live-in, or it may have its own def. | |
| if (Start != BlockStart) { | |
| VNInfo *VNI = LI.extendInBlock(BlockStart, std::min(BlockEnd, End)); | |
| assert(VNI && "Missing def for complex mapped value"); | |
| LLVM_DEBUG(dbgs() << ':' << VNI->id << "*" << printMBBReference(*MBB)); | |
| // MBB has its own def. Is it also live-out? | |
| if (BlockEnd <= End) | |
| LRC.setLiveOutValue(&*MBB, VNI); | |
| // Skip to the next block for live-in. | |
| ++MBB; | |
| BlockStart = BlockEnd; | |
| } | |
| // Handle the live-in blocks covered by [Start;End). | |
| assert(Start <= BlockStart && "Expected live-in block"); | |
| while (BlockStart < End) { | |
| LLVM_DEBUG(dbgs() << ">" << printMBBReference(*MBB)); | |
| BlockEnd = LIS.getMBBEndIdx(&*MBB); | |
| 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?"); | |
| 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. | |
| } else { | |
| // This block needs a live-in value. The last block covered may not | |
| // be live-out. | |
| if (End < BlockEnd) | |
| LRC.addLiveInBlock(LI, MDT[&*MBB], End); | |
| else { | |
| // Live-through, and we don't know the value. | |
| LRC.addLiveInBlock(LI, MDT[&*MBB]); | |
| LRC.setLiveOutValue(&*MBB, nullptr); | |
| } | |
| } | |
| BlockStart = BlockEnd; | |
| ++MBB; | |
| } | |
| Start = End; | |
| } while (Start != S.end); | |
| LLVM_DEBUG(dbgs() << '\n'); | |
| } | |
| LRCalc[0].calculateValues(); | |
| if (SpillMode) | |
| LRCalc[1].calculateValues(); | |
| return Skipped; | |
| } | |
| static bool removeDeadSegment(SlotIndex Def, LiveRange &LR) { | |
| const LiveRange::Segment *Seg = LR.getSegmentContaining(Def); | |
| if (Seg == nullptr) | |
| return true; | |
| if (Seg->end != Def.getDeadSlot()) | |
| return false; | |
| // This is a dead PHI. Remove it. | |
| LR.removeSegment(*Seg, true); | |
| return true; | |
| } | |
| void SplitEditor::extendPHIRange(MachineBasicBlock &B, LiveRangeCalc &LRC, | |
| LiveRange &LR, LaneBitmask LM, | |
| ArrayRef<SlotIndex> Undefs) { | |
| 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. | |
| LiveInterval &PLI = Edit->getParent(); | |
| // Need the cast because the inputs to ?: would otherwise be deemed | |
| // "incompatible": SubRange vs LiveInterval. | |
| LiveRange &PSR = !LM.all() ? getSubRangeForMask(LM, PLI) | |
| : static_cast<LiveRange&>(PLI); | |
| if (PSR.liveAt(LastUse)) | |
| LRC.extend(LR, End, /*PhysReg=*/0, Undefs); | |
| } | |
| } | |
| void SplitEditor::extendPHIKillRanges() { | |
| // Extend live ranges to be live-out for successor PHI values. | |
| // Visit each PHI def slot in the parent live interval. If the def is dead, | |
| // remove it. Otherwise, extend the live interval to reach the end indexes | |
| // of all predecessor blocks. | |
| LiveInterval &ParentLI = Edit->getParent(); | |
| for (const VNInfo *V : ParentLI.valnos) { | |
| if (V->isUnused() || !V->isPHIDef()) | |
| continue; | |
| unsigned RegIdx = RegAssign.lookup(V->def); | |
| LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx)); | |
| LiveRangeCalc &LRC = getLRCalc(RegIdx); | |
| MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def); | |
| if (!removeDeadSegment(V->def, LI)) | |
| extendPHIRange(B, LRC, LI, LaneBitmask::getAll(), /*Undefs=*/{}); | |
| } | |
| SmallVector<SlotIndex, 4> Undefs; | |
| LiveRangeCalc SubLRC; | |
| for (LiveInterval::SubRange &PS : ParentLI.subranges()) { | |
| for (const VNInfo *V : PS.valnos) { | |
| if (V->isUnused() || !V->isPHIDef()) | |
| continue; | |
| unsigned RegIdx = RegAssign.lookup(V->def); | |
| LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx)); | |
| LiveInterval::SubRange &S = getSubRangeForMask(PS.LaneMask, LI); | |
| if (removeDeadSegment(V->def, S)) | |
| continue; | |
| MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def); | |
| SubLRC.reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, | |
| &LIS.getVNInfoAllocator()); | |
| Undefs.clear(); | |
| LI.computeSubRangeUndefs(Undefs, PS.LaneMask, MRI, *LIS.getSlotIndexes()); | |
| extendPHIRange(B, SubLRC, S, PS.LaneMask, Undefs); | |
| } | |
| } | |
| } | |
| /// rewriteAssigned - Rewrite all uses of Edit->getReg(). | |
| void SplitEditor::rewriteAssigned(bool ExtendRanges) { | |
| struct ExtPoint { | |
| ExtPoint(const MachineOperand &O, unsigned R, SlotIndex N) | |
| : MO(O), RegIdx(R), Next(N) {} | |
| MachineOperand MO; | |
| unsigned RegIdx; | |
| SlotIndex Next; | |
| }; | |
| SmallVector<ExtPoint,4> ExtPoints; | |
| for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg()), | |
| RE = MRI.reg_end(); RI != RE;) { | |
| MachineOperand &MO = *RI; | |
| MachineInstr *MI = MO.getParent(); | |
| ++RI; | |
| // LiveDebugVariables should have handled all DBG_VALUE instructions. | |
| if (MI->isDebugValue()) { | |
| LLVM_DEBUG(dbgs() << "Zapping " << *MI); | |
| MO.setReg(0); | |
| continue; | |
| } | |
| // <undef> operands don't really read the register, so it doesn't matter | |
| // which register we choose. When the use operand is tied to a def, we must | |
| // use the same register as the def, so just do that always. | |
| SlotIndex Idx = LIS.getInstructionIndex(*MI); | |
| if (MO.isDef() || MO.isUndef()) | |
| Idx = Idx.getRegSlot(MO.isEarlyClobber()); | |
| // Rewrite to the mapped register at Idx. | |
| unsigned RegIdx = RegAssign.lookup(Idx); | |
| LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx)); | |
| MO.setReg(LI.reg); | |
| LLVM_DEBUG(dbgs() << " rewr " << printMBBReference(*MI->getParent()) | |
| << '\t' << Idx << ':' << RegIdx << '\t' << *MI); | |
| // Extend liveness to Idx if the instruction reads reg. | |
| if (!ExtendRanges || MO.isUndef()) | |
| continue; | |
| // Skip instructions that don't read Reg. | |
| if (MO.isDef()) { | |
| if (!MO.getSubReg() && !MO.isEarlyClobber()) | |
| continue; | |
| // We may want to extend a live range for a partial redef, or for a use | |
| // tied to an early clobber. | |
| Idx = Idx.getPrevSlot(); | |
| if (!Edit->getParent().liveAt(Idx)) | |
| continue; | |
| } else | |
| Idx = Idx.getRegSlot(true); | |
| SlotIndex Next = Idx.getNextSlot(); | |
| if (LI.hasSubRanges()) { | |
| // We have to delay extending subranges until we have seen all operands | |
| // defining the register. This is because a <def,read-undef> operand | |
| // will create an "undef" point, and we cannot extend any subranges | |
| // until all of them have been accounted for. | |
| if (MO.isUse()) | |
| ExtPoints.push_back(ExtPoint(MO, RegIdx, Next)); | |
| } else { | |
| LiveRangeCalc &LRC = getLRCalc(RegIdx); | |
| LRC.extend(LI, Next, 0, ArrayRef<SlotIndex>()); | |
| } | |
| } | |
| for (ExtPoint &EP : ExtPoints) { | |
| LiveInterval &LI = LIS.getInterval(Edit->get(EP.RegIdx)); | |
| assert(LI.hasSubRanges()); | |
| LiveRangeCalc SubLRC; | |
| unsigned Reg = EP.MO.getReg(), Sub = EP.MO.getSubReg(); | |
| LaneBitmask LM = Sub != 0 ? TRI.getSubRegIndexLaneMask(Sub) | |
| : MRI.getMaxLaneMaskForVReg(Reg); | |
| for (LiveInterval::SubRange &S : LI.subranges()) { | |
| if ((S.LaneMask & LM).none()) | |
| continue; | |
| // The problem here can be that the new register may have been created | |
| // for a partially defined original register. For example: | |
| // %0:subreg_hireg<def,read-undef> = ... | |
| // ... | |
| // %1 = COPY %0 | |
| if (S.empty()) | |
| continue; | |
| SubLRC.reset(&VRM.getMachineFunction(), LIS.getSlotIndexes(), &MDT, | |
| &LIS.getVNInfoAllocator()); | |
| SmallVector<SlotIndex, 4> Undefs; | |
| LI.computeSubRangeUndefs(Undefs, S.LaneMask, MRI, *LIS.getSlotIndexes()); | |
| SubLRC.extend(S, EP.Next, 0, Undefs); | |
| } | |
| } | |
| for (unsigned R : *Edit) { | |
| LiveInterval &LI = LIS.getInterval(R); | |
| if (!LI.hasSubRanges()) | |
| continue; | |
| LI.clear(); | |
| LI.removeEmptySubRanges(); | |
| LIS.constructMainRangeFromSubranges(LI); | |
| } | |
| } | |
| void SplitEditor::deleteRematVictims() { | |
| SmallVector<MachineInstr*, 8> Dead; | |
| for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){ | |
| LiveInterval *LI = &LIS.getInterval(*I); | |
| for (const LiveRange::Segment &S : LI->segments) { | |
| // Dead defs end at the dead slot. | |
| if (S.end != S.valno->def.getDeadSlot()) | |
| continue; | |
| if (S.valno->isPHIDef()) | |
| continue; | |
| MachineInstr *MI = LIS.getInstructionFromIndex(S.valno->def); | |
| assert(MI && "Missing instruction for dead def"); | |
| MI->addRegisterDead(LI->reg, &TRI); | |
| if (!MI->allDefsAreDead()) | |
| continue; | |
| LLVM_DEBUG(dbgs() << "All defs dead: " << *MI); | |
| Dead.push_back(MI); | |
| } | |
| } | |
| if (Dead.empty()) | |
| return; | |
| Edit->eliminateDeadDefs(Dead, None, &AA); | |
| } | |
| void SplitEditor::forceRecomputeVNI(const VNInfo &ParentVNI) { | |
| // Fast-path for common case. | |
| if (!ParentVNI.isPHIDef()) { | |
| for (unsigned I = 0, E = Edit->size(); I != E; ++I) | |
| forceRecompute(I, ParentVNI); | |
| return; | |
| } | |
| // Trace value through phis. | |
| SmallPtrSet<const VNInfo *, 8> Visited; ///< whether VNI was/is in worklist. | |
| SmallVector<const VNInfo *, 4> WorkList; | |
| Visited.insert(&ParentVNI); | |
| WorkList.push_back(&ParentVNI); | |
| const LiveInterval &ParentLI = Edit->getParent(); | |
| const SlotIndexes &Indexes = *LIS.getSlotIndexes(); | |
| do { | |
| const VNInfo &VNI = *WorkList.back(); | |
| WorkList.pop_back(); | |
| for (unsigned I = 0, E = Edit->size(); I != E; ++I) | |
| forceRecompute(I, VNI); | |
| if (!VNI.isPHIDef()) | |
| continue; | |
| MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(VNI.def); | |
| for (const MachineBasicBlock *Pred : MBB.predecessors()) { | |
| SlotIndex PredEnd = Indexes.getMBBEndIdx(Pred); | |
| VNInfo *PredVNI = ParentLI.getVNInfoBefore(PredEnd); | |
| assert(PredVNI && "Value available in PhiVNI predecessor"); | |
| if (Visited.insert(PredVNI).second) | |
| WorkList.push_back(PredVNI); | |
| } | |
| } while(!WorkList.empty()); | |
| } | |
| void SplitEditor::finish(SmallVectorImpl<unsigned> *LRMap) { | |
| ++NumFinished; | |
| // At this point, the live intervals in Edit contain VNInfos corresponding to | |
| // the inserted copies. | |
| // Add the original defs from the parent interval. | |
| for (const VNInfo *ParentVNI : Edit->getParent().valnos) { | |
| if (ParentVNI->isUnused()) | |
| continue; | |
| unsigned RegIdx = RegAssign.lookup(ParentVNI->def); | |
| defValue(RegIdx, ParentVNI, ParentVNI->def, true); | |
| // Force rematted values to be recomputed everywhere. | |
| // The new live ranges may be truncated. | |
| if (Edit->didRematerialize(ParentVNI)) | |
| forceRecomputeVNI(*ParentVNI); | |
| } | |
| // Hoist back-copies to the complement interval when in spill mode. | |
| switch (SpillMode) { | |
| case SM_Partition: | |
| // Leave all back-copies as is. | |
| break; | |
| case SM_Size: | |
| case SM_Speed: | |
| // hoistCopies will behave differently between size and speed. | |
| hoistCopies(); | |
| } | |
| // Transfer the simply mapped values, check if any are skipped. | |
| bool Skipped = transferValues(); | |
| // Rewrite virtual registers, possibly extending ranges. | |
| rewriteAssigned(Skipped); | |
| if (Skipped) | |
| extendPHIKillRanges(); | |
| else | |
| ++NumSimple; | |
| // Delete defs that were rematted everywhere. | |
| if (Skipped) | |
| deleteRematVictims(); | |
| // Get rid of unused values and set phi-kill flags. | |
| for (unsigned Reg : *Edit) { | |
| LiveInterval &LI = LIS.getInterval(Reg); | |
| LI.removeEmptySubRanges(); | |
| LI.RenumberValues(); | |
| } | |
| // Provide a reverse mapping from original indices to Edit ranges. | |
| if (LRMap) { | |
| LRMap->clear(); | |
| for (unsigned i = 0, e = Edit->size(); i != e; ++i) | |
| LRMap->push_back(i); | |
| } | |
| // Now check if any registers were separated into multiple components. | |
| ConnectedVNInfoEqClasses ConEQ(LIS); | |
| for (unsigned i = 0, e = Edit->size(); i != e; ++i) { | |
| // Don't use iterators, they are invalidated by create() below. | |
| unsigned VReg = Edit->get(i); | |
| LiveInterval &LI = LIS.getInterval(VReg); | |
| SmallVector<LiveInterval*, 8> 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); | |
| } | |
| // Calculate spill weight and allocation hints for new intervals. | |
| Edit->calculateRegClassAndHint(VRM.getMachineFunction(), SA.Loops, MBFI); | |
| assert(!LRMap || LRMap->size() == Edit->size()); | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Single Block Splitting | |
| //===----------------------------------------------------------------------===// | |
| bool SplitAnalysis::shouldSplitSingleBlock(const BlockInfo &BI, | |
| bool SingleInstrs) const { | |
| // Always split for multiple instructions. | |
| if (!BI.isOneInstr()) | |
| return true; | |
| // Don't split for single instructions unless explicitly requested. | |
| if (!SingleInstrs) | |
| return false; | |
| // Splitting a live-through range always makes progress. | |
| if (BI.LiveIn && BI.LiveOut) | |
| return true; | |
| // No point in isolating a copy. It has no register class constraints. | |
| if (LIS.getInstructionFromIndex(BI.FirstInstr)->isCopyLike()) | |
| return false; | |
| // Finally, don't isolate an end point that was created by earlier splits. | |
| return isOriginalEndpoint(BI.FirstInstr); | |
| } | |
| void SplitEditor::splitSingleBlock(const SplitAnalysis::BlockInfo &BI) { | |
| openIntv(); | |
| SlotIndex LastSplitPoint = SA.getLastSplitPoint(BI.MBB->getNumber()); | |
| SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstInstr, | |
| LastSplitPoint)); | |
| if (!BI.LiveOut || BI.LastInstr < LastSplitPoint) { | |
| useIntv(SegStart, leaveIntvAfter(BI.LastInstr)); | |
| } else { | |
| // The last use is after the last valid split point. | |
| SlotIndex SegStop = leaveIntvBefore(LastSplitPoint); | |
| useIntv(SegStart, SegStop); | |
| overlapIntv(SegStop, BI.LastInstr); | |
| } | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // Global Live Range Splitting Support | |
| //===----------------------------------------------------------------------===// | |
| // These methods support a method of global live range splitting that uses a | |
| // global algorithm to decide intervals for CFG edges. They will insert split | |
| // points and color intervals in basic blocks while avoiding interference. | |
| // | |
| // Note that splitSingleBlock is also useful for blocks where both CFG edges | |
| // are on the stack. | |
| void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, | |
| unsigned IntvIn, SlotIndex LeaveBefore, | |
| unsigned IntvOut, SlotIndex EnterAfter){ | |
| SlotIndex Start, Stop; | |
| std::tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(MBBNum); | |
| LLVM_DEBUG(dbgs() << "%bb." << MBBNum << " [" << Start << ';' << Stop | |
| << ") intf " << LeaveBefore << '-' << EnterAfter | |
| << ", live-through " << IntvIn << " -> " << IntvOut); | |
| assert((IntvIn || IntvOut) && "Use splitSingleBlock for isolated blocks"); | |
| assert((!LeaveBefore || LeaveBefore < Stop) && "Interference after block"); | |
| assert((!IntvIn || !LeaveBefore || LeaveBefore > Start) && "Impossible intf"); | |
| assert((!EnterAfter || EnterAfter >= Start) && "Interference before block"); | |
| MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum); | |
| if (!IntvOut) { | |
| LLVM_DEBUG(dbgs() << ", spill on entry.\n"); | |
| // | |
| // <<<<<<<<< Possible LeaveBefore interference. | |
| // |-----------| Live through. | |
| // -____________ Spill on entry. | |
| // | |
| selectIntv(IntvIn); | |
| SlotIndex Idx = leaveIntvAtTop(*MBB); | |
| assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); | |
| (void)Idx; | |
| return; | |
| } | |
| if (!IntvIn) { | |
| LLVM_DEBUG(dbgs() << ", reload on exit.\n"); | |
| // | |
| // >>>>>>> Possible EnterAfter interference. | |
| // |-----------| Live through. | |
| // ___________-- Reload on exit. | |
| // | |
| selectIntv(IntvOut); | |
| SlotIndex Idx = enterIntvAtEnd(*MBB); | |
| assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); | |
| (void)Idx; | |
| return; | |
| } | |
| if (IntvIn == IntvOut && !LeaveBefore && !EnterAfter) { | |
| LLVM_DEBUG(dbgs() << ", straight through.\n"); | |
| // | |
| // |-----------| Live through. | |
| // ------------- Straight through, same intv, no interference. | |
| // | |
| selectIntv(IntvOut); | |
| useIntv(Start, Stop); | |
| return; | |
| } | |
| // We cannot legally insert splits after LSP. | |
| SlotIndex LSP = SA.getLastSplitPoint(MBBNum); | |
| assert((!IntvOut || !EnterAfter || EnterAfter < LSP) && "Impossible intf"); | |
| if (IntvIn != IntvOut && (!LeaveBefore || !EnterAfter || | |
| LeaveBefore.getBaseIndex() > EnterAfter.getBoundaryIndex())) { | |
| LLVM_DEBUG(dbgs() << ", switch avoiding interference.\n"); | |
| // | |
| // >>>> <<<< Non-overlapping EnterAfter/LeaveBefore interference. | |
| // |-----------| Live through. | |
| // ------======= Switch intervals between interference. | |
| // | |
| selectIntv(IntvOut); | |
| SlotIndex Idx; | |
| if (LeaveBefore && LeaveBefore < LSP) { | |
| Idx = enterIntvBefore(LeaveBefore); | |
| useIntv(Idx, Stop); | |
| } else { | |
| Idx = enterIntvAtEnd(*MBB); | |
| } | |
| selectIntv(IntvIn); | |
| useIntv(Start, Idx); | |
| assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); | |
| assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); | |
| return; | |
| } | |
| LLVM_DEBUG(dbgs() << ", create local intv for interference.\n"); | |
| // | |
| // >>><><><><<<< Overlapping EnterAfter/LeaveBefore interference. | |
| // |-----------| Live through. | |
| // ==---------== Switch intervals before/after interference. | |
| // | |
| assert(LeaveBefore <= EnterAfter && "Missed case"); | |
| selectIntv(IntvOut); | |
| SlotIndex Idx = enterIntvAfter(EnterAfter); | |
| useIntv(Idx, Stop); | |
| assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); | |
| selectIntv(IntvIn); | |
| Idx = leaveIntvBefore(LeaveBefore); | |
| useIntv(Start, Idx); | |
| assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); | |
| } | |
| void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, | |
| unsigned IntvIn, SlotIndex LeaveBefore) { | |
| SlotIndex Start, Stop; | |
| std::tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); | |
| LLVM_DEBUG(dbgs() << printMBBReference(*BI.MBB) << " [" << Start << ';' | |
| << Stop << "), uses " << BI.FirstInstr << '-' | |
| << BI.LastInstr << ", reg-in " << IntvIn | |
| << ", leave before " << LeaveBefore | |
| << (BI.LiveOut ? ", stack-out" : ", killed in block")); | |
| assert(IntvIn && "Must have register in"); | |
| assert(BI.LiveIn && "Must be live-in"); | |
| assert((!LeaveBefore || LeaveBefore > Start) && "Bad interference"); | |
| if (!BI.LiveOut && (!LeaveBefore || LeaveBefore >= BI.LastInstr)) { | |
| LLVM_DEBUG(dbgs() << " before interference.\n"); | |
| // | |
| // <<< Interference after kill. | |
| // |---o---x | Killed in block. | |
| // ========= Use IntvIn everywhere. | |
| // | |
| selectIntv(IntvIn); | |
| useIntv(Start, BI.LastInstr); | |
| return; | |
| } | |
| SlotIndex LSP = SA.getLastSplitPoint(BI.MBB->getNumber()); | |
| if (!LeaveBefore || LeaveBefore > BI.LastInstr.getBoundaryIndex()) { | |
| // | |
| // <<< Possible interference after last use. | |
| // |---o---o---| Live-out on stack. | |
| // =========____ Leave IntvIn after last use. | |
| // | |
| // < Interference after last use. | |
| // |---o---o--o| Live-out on stack, late last use. | |
| // ============ Copy to stack after LSP, overlap IntvIn. | |
| // \_____ Stack interval is live-out. | |
| // | |
| if (BI.LastInstr < LSP) { | |
| LLVM_DEBUG(dbgs() << ", spill after last use before interference.\n"); | |
| selectIntv(IntvIn); | |
| SlotIndex Idx = leaveIntvAfter(BI.LastInstr); | |
| useIntv(Start, Idx); | |
| assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); | |
| } else { | |
| LLVM_DEBUG(dbgs() << ", spill before last split point.\n"); | |
| selectIntv(IntvIn); | |
| SlotIndex Idx = leaveIntvBefore(LSP); | |
| overlapIntv(Idx, BI.LastInstr); | |
| useIntv(Start, Idx); | |
| assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); | |
| } | |
| return; | |
| } | |
| // The interference is overlapping somewhere we wanted to use IntvIn. That | |
| // means we need to create a local interval that can be allocated a | |
| // different register. | |
| unsigned LocalIntv = openIntv(); | |
| (void)LocalIntv; | |
| LLVM_DEBUG(dbgs() << ", creating local interval " << LocalIntv << ".\n"); | |
| if (!BI.LiveOut || BI.LastInstr < LSP) { | |
| // | |
| // <<<<<<< Interference overlapping uses. | |
| // |---o---o---| Live-out on stack. | |
| // =====----____ Leave IntvIn before interference, then spill. | |
| // | |
| SlotIndex To = leaveIntvAfter(BI.LastInstr); | |
| SlotIndex From = enterIntvBefore(LeaveBefore); | |
| useIntv(From, To); | |
| selectIntv(IntvIn); | |
| useIntv(Start, From); | |
| assert((!LeaveBefore || From <= LeaveBefore) && "Interference"); | |
| return; | |
| } | |
| // <<<<<<< Interference overlapping uses. | |
| // |---o---o--o| Live-out on stack, late last use. | |
| // =====------- Copy to stack before LSP, overlap LocalIntv. | |
| // \_____ Stack interval is live-out. | |
| // | |
| SlotIndex To = leaveIntvBefore(LSP); | |
| overlapIntv(To, BI.LastInstr); | |
| SlotIndex From = enterIntvBefore(std::min(To, LeaveBefore)); | |
| useIntv(From, To); | |
| selectIntv(IntvIn); | |
| useIntv(Start, From); | |
| assert((!LeaveBefore || From <= LeaveBefore) && "Interference"); | |
| } | |
| void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, | |
| unsigned IntvOut, SlotIndex EnterAfter) { | |
| SlotIndex Start, Stop; | |
| std::tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); | |
| LLVM_DEBUG(dbgs() << printMBBReference(*BI.MBB) << " [" << Start << ';' | |
| << Stop << "), uses " << BI.FirstInstr << '-' | |
| << BI.LastInstr << ", reg-out " << IntvOut | |
| << ", enter after " << EnterAfter | |
| << (BI.LiveIn ? ", stack-in" : ", defined in block")); | |
| SlotIndex LSP = SA.getLastSplitPoint(BI.MBB->getNumber()); | |
| assert(IntvOut && "Must have register out"); | |
| assert(BI.LiveOut && "Must be live-out"); | |
| assert((!EnterAfter || EnterAfter < LSP) && "Bad interference"); | |
| if (!BI.LiveIn && (!EnterAfter || EnterAfter <= BI.FirstInstr)) { | |
| LLVM_DEBUG(dbgs() << " after interference.\n"); | |
| // | |
| // >>>> Interference before def. | |
| // | o---o---| Defined in block. | |
| // ========= Use IntvOut everywhere. | |
| // | |
| selectIntv(IntvOut); | |
| useIntv(BI.FirstInstr, Stop); | |
| return; | |
| } | |
| if (!EnterAfter || EnterAfter < BI.FirstInstr.getBaseIndex()) { | |
| LLVM_DEBUG(dbgs() << ", reload after interference.\n"); | |
| // | |
| // >>>> Interference before def. | |
| // |---o---o---| Live-through, stack-in. | |
| // ____========= Enter IntvOut before first use. | |
| // | |
| selectIntv(IntvOut); | |
| SlotIndex Idx = enterIntvBefore(std::min(LSP, BI.FirstInstr)); | |
| useIntv(Idx, Stop); | |
| assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); | |
| return; | |
| } | |
| // The interference is overlapping somewhere we wanted to use IntvOut. That | |
| // means we need to create a local interval that can be allocated a | |
| // different register. | |
| LLVM_DEBUG(dbgs() << ", interference overlaps uses.\n"); | |
| // | |
| // >>>>>>> Interference overlapping uses. | |
| // |---o---o---| Live-through, stack-in. | |
| // ____---====== Create local interval for interference range. | |
| // | |
| selectIntv(IntvOut); | |
| SlotIndex Idx = enterIntvAfter(EnterAfter); | |
| useIntv(Idx, Stop); | |
| assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); | |
| openIntv(); | |
| SlotIndex From = enterIntvBefore(std::min(Idx, BI.FirstInstr)); | |
| useIntv(From, Idx); | |
| } |