10b57cec5SDimitry Andric //===- RegAllocGreedy.cpp - greedy register allocator ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the RAGreedy function pass for register allocation in
100b57cec5SDimitry Andric // optimized builds.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
1404eeddc0SDimitry Andric #include "RegAllocGreedy.h"
150b57cec5SDimitry Andric #include "AllocationOrder.h"
160b57cec5SDimitry Andric #include "InterferenceCache.h"
170b57cec5SDimitry Andric #include "RegAllocBase.h"
18349cc55cSDimitry Andric #include "RegAllocEvictionAdvisor.h"
19bdd1243dSDimitry Andric #include "RegAllocPriorityAdvisor.h"
200b57cec5SDimitry Andric #include "SpillPlacement.h"
210b57cec5SDimitry Andric #include "SplitKit.h"
220b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
230b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
240b57cec5SDimitry Andric #include "llvm/ADT/IndexedMap.h"
250b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
260b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
270b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
280b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
290b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
300b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/CalcSpillWeights.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/EdgeBundles.h"
33*0fca6ea1SDimitry Andric #include "llvm/CodeGen/LiveDebugVariables.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervalUnion.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRangeEdit.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRegMatrix.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
440b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
450b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
460b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
470b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
480b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
490b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
500b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
510b57cec5SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
520b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h"
530b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
545ffd83dbSDimitry Andric #include "llvm/CodeGen/Spiller.h"
550b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
560b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
570b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
580b57cec5SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
59349cc55cSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
600b57cec5SDimitry Andric #include "llvm/IR/Function.h"
610b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
6281ad6265SDimitry Andric #include "llvm/InitializePasses.h"
630b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
640b57cec5SDimitry Andric #include "llvm/Pass.h"
650b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h"
660b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
670b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
680b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
690b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
700b57cec5SDimitry Andric #include "llvm/Support/Timer.h"
710b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
720b57cec5SDimitry Andric #include <algorithm>
730b57cec5SDimitry Andric #include <cassert>
740b57cec5SDimitry Andric #include <cstdint>
750b57cec5SDimitry Andric #include <utility>
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric using namespace llvm;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric #define DEBUG_TYPE "regalloc"
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric STATISTIC(NumGlobalSplits, "Number of split global live ranges");
820b57cec5SDimitry Andric STATISTIC(NumLocalSplits, "Number of split local live ranges");
830b57cec5SDimitry Andric STATISTIC(NumEvicted, "Number of interferences evicted");
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric static cl::opt<SplitEditor::ComplementSpillMode> SplitSpillMode(
860b57cec5SDimitry Andric "split-spill-mode", cl::Hidden,
870b57cec5SDimitry Andric cl::desc("Spill mode for splitting live ranges"),
880b57cec5SDimitry Andric cl::values(clEnumValN(SplitEditor::SM_Partition, "default", "Default"),
890b57cec5SDimitry Andric clEnumValN(SplitEditor::SM_Size, "size", "Optimize for size"),
900b57cec5SDimitry Andric clEnumValN(SplitEditor::SM_Speed, "speed", "Optimize for speed")),
910b57cec5SDimitry Andric cl::init(SplitEditor::SM_Speed));
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric static cl::opt<unsigned>
940b57cec5SDimitry Andric LastChanceRecoloringMaxDepth("lcr-max-depth", cl::Hidden,
950b57cec5SDimitry Andric cl::desc("Last chance recoloring max depth"),
960b57cec5SDimitry Andric cl::init(5));
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric static cl::opt<unsigned> LastChanceRecoloringMaxInterference(
990b57cec5SDimitry Andric "lcr-max-interf", cl::Hidden,
1000b57cec5SDimitry Andric cl::desc("Last chance recoloring maximum number of considered"
1010b57cec5SDimitry Andric " interference at a time"),
1020b57cec5SDimitry Andric cl::init(8));
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric static cl::opt<bool> ExhaustiveSearch(
1050b57cec5SDimitry Andric "exhaustive-register-search", cl::NotHidden,
1060b57cec5SDimitry Andric cl::desc("Exhaustive Search for registers bypassing the depth "
1070b57cec5SDimitry Andric "and interference cutoffs of last chance recoloring"),
1080b57cec5SDimitry Andric cl::Hidden);
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric static cl::opt<bool> EnableDeferredSpilling(
1110b57cec5SDimitry Andric "enable-deferred-spilling", cl::Hidden,
1120b57cec5SDimitry Andric cl::desc("Instead of spilling a variable right away, defer the actual "
1130b57cec5SDimitry Andric "code insertion to the end of the allocation. That way the "
1140b57cec5SDimitry Andric "allocator might still find a suitable coloring for this "
1150b57cec5SDimitry Andric "variable because of other evicted variables."),
1160b57cec5SDimitry Andric cl::init(false));
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric // FIXME: Find a good default for this flag and remove the flag.
1190b57cec5SDimitry Andric static cl::opt<unsigned>
1200b57cec5SDimitry Andric CSRFirstTimeCost("regalloc-csr-first-time-cost",
1210b57cec5SDimitry Andric cl::desc("Cost for first time use of callee-saved register."),
1220b57cec5SDimitry Andric cl::init(0), cl::Hidden);
1230b57cec5SDimitry Andric
12481ad6265SDimitry Andric static cl::opt<unsigned long> GrowRegionComplexityBudget(
12581ad6265SDimitry Andric "grow-region-complexity-budget",
12681ad6265SDimitry Andric cl::desc("growRegion() does not scale with the number of BB edges, so "
12781ad6265SDimitry Andric "limit its budget and bail out once we reach the limit."),
12881ad6265SDimitry Andric cl::init(10000), cl::Hidden);
12981ad6265SDimitry Andric
13081ad6265SDimitry Andric static cl::opt<bool> GreedyRegClassPriorityTrumpsGlobalness(
13181ad6265SDimitry Andric "greedy-regclass-priority-trumps-globalness",
13281ad6265SDimitry Andric cl::desc("Change the greedy register allocator's live range priority "
13381ad6265SDimitry Andric "calculation to make the AllocationPriority of the register class "
13481ad6265SDimitry Andric "more important then whether the range is global"),
13581ad6265SDimitry Andric cl::Hidden);
1360b57cec5SDimitry Andric
137972a253aSDimitry Andric static cl::opt<bool> GreedyReverseLocalAssignment(
138972a253aSDimitry Andric "greedy-reverse-local-assignment",
139972a253aSDimitry Andric cl::desc("Reverse allocation order of local live ranges, such that "
140972a253aSDimitry Andric "shorter local live ranges will tend to be allocated first"),
141972a253aSDimitry Andric cl::Hidden);
142972a253aSDimitry Andric
1435f757f3fSDimitry Andric static cl::opt<unsigned> SplitThresholdForRegWithHint(
1445f757f3fSDimitry Andric "split-threshold-for-reg-with-hint",
1455f757f3fSDimitry Andric cl::desc("The threshold for splitting a virtual register with a hint, in "
1465f757f3fSDimitry Andric "percentate"),
1475f757f3fSDimitry Andric cl::init(75), cl::Hidden);
1485f757f3fSDimitry Andric
1490b57cec5SDimitry Andric static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
1500b57cec5SDimitry Andric createGreedyRegisterAllocator);
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric char RAGreedy::ID = 0;
1530b57cec5SDimitry Andric char &llvm::RAGreedyID = RAGreedy::ID;
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RAGreedy, "greedy",
1560b57cec5SDimitry Andric "Greedy Register Allocator", false, false)
1570b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
158*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
159*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
1600b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
1610b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
1620b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveStacks)
163*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
164*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
1650b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
1660b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
1670b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(EdgeBundles)
1680b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SpillPlacement)
1690b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
1700eae32dcSDimitry Andric INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysis)
171bdd1243dSDimitry Andric INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysis)
1720b57cec5SDimitry Andric INITIALIZE_PASS_END(RAGreedy, "greedy",
1730b57cec5SDimitry Andric "Greedy Register Allocator", false, false)
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric #ifndef NDEBUG
1760b57cec5SDimitry Andric const char *const RAGreedy::StageName[] = {
1770b57cec5SDimitry Andric "RS_New",
1780b57cec5SDimitry Andric "RS_Assign",
1790b57cec5SDimitry Andric "RS_Split",
1800b57cec5SDimitry Andric "RS_Split2",
1810b57cec5SDimitry Andric "RS_Spill",
1820b57cec5SDimitry Andric "RS_Memory",
1830b57cec5SDimitry Andric "RS_Done"
1840b57cec5SDimitry Andric };
1850b57cec5SDimitry Andric #endif
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric // Hysteresis to use when comparing floats.
1880b57cec5SDimitry Andric // This helps stabilize decisions based on float comparisons.
1890b57cec5SDimitry Andric const float Hysteresis = (2007 / 2048.0f); // 0.97998046875
1900b57cec5SDimitry Andric
createGreedyRegisterAllocator()1910b57cec5SDimitry Andric FunctionPass* llvm::createGreedyRegisterAllocator() {
1920b57cec5SDimitry Andric return new RAGreedy();
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric
createGreedyRegisterAllocator(RegAllocFilterFunc Ftor)195*0fca6ea1SDimitry Andric FunctionPass *llvm::createGreedyRegisterAllocator(RegAllocFilterFunc Ftor) {
196fe6060f1SDimitry Andric return new RAGreedy(Ftor);
197fe6060f1SDimitry Andric }
198fe6060f1SDimitry Andric
RAGreedy(RegAllocFilterFunc F)199*0fca6ea1SDimitry Andric RAGreedy::RAGreedy(RegAllocFilterFunc F)
200*0fca6ea1SDimitry Andric : MachineFunctionPass(ID), RegAllocBase(F) {}
2010b57cec5SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const2020b57cec5SDimitry Andric void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
2030b57cec5SDimitry Andric AU.setPreservesCFG();
204*0fca6ea1SDimitry Andric AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
205*0fca6ea1SDimitry Andric AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();
206*0fca6ea1SDimitry Andric AU.addRequired<LiveIntervalsWrapperPass>();
207*0fca6ea1SDimitry Andric AU.addPreserved<LiveIntervalsWrapperPass>();
208*0fca6ea1SDimitry Andric AU.addRequired<SlotIndexesWrapperPass>();
209*0fca6ea1SDimitry Andric AU.addPreserved<SlotIndexesWrapperPass>();
2100b57cec5SDimitry Andric AU.addRequired<LiveDebugVariables>();
2110b57cec5SDimitry Andric AU.addPreserved<LiveDebugVariables>();
2120b57cec5SDimitry Andric AU.addRequired<LiveStacks>();
2130b57cec5SDimitry Andric AU.addPreserved<LiveStacks>();
214*0fca6ea1SDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>();
215*0fca6ea1SDimitry Andric AU.addPreserved<MachineDominatorTreeWrapperPass>();
216*0fca6ea1SDimitry Andric AU.addRequired<MachineLoopInfoWrapperPass>();
217*0fca6ea1SDimitry Andric AU.addPreserved<MachineLoopInfoWrapperPass>();
2180b57cec5SDimitry Andric AU.addRequired<VirtRegMap>();
2190b57cec5SDimitry Andric AU.addPreserved<VirtRegMap>();
2200b57cec5SDimitry Andric AU.addRequired<LiveRegMatrix>();
2210b57cec5SDimitry Andric AU.addPreserved<LiveRegMatrix>();
2220b57cec5SDimitry Andric AU.addRequired<EdgeBundles>();
2230b57cec5SDimitry Andric AU.addRequired<SpillPlacement>();
2240b57cec5SDimitry Andric AU.addRequired<MachineOptimizationRemarkEmitterPass>();
2250eae32dcSDimitry Andric AU.addRequired<RegAllocEvictionAdvisorAnalysis>();
226bdd1243dSDimitry Andric AU.addRequired<RegAllocPriorityAdvisorAnalysis>();
2270b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2310b57cec5SDimitry Andric // LiveRangeEdit delegate methods
2320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2330b57cec5SDimitry Andric
LRE_CanEraseVirtReg(Register VirtReg)234e8d8bef9SDimitry Andric bool RAGreedy::LRE_CanEraseVirtReg(Register VirtReg) {
2350b57cec5SDimitry Andric LiveInterval &LI = LIS->getInterval(VirtReg);
2360b57cec5SDimitry Andric if (VRM->hasPhys(VirtReg)) {
2370b57cec5SDimitry Andric Matrix->unassign(LI);
2380b57cec5SDimitry Andric aboutToRemoveInterval(LI);
2390b57cec5SDimitry Andric return true;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric // Unassigned virtreg is probably in the priority queue.
2420b57cec5SDimitry Andric // RegAllocBase will erase it after dequeueing.
2430b57cec5SDimitry Andric // Nonetheless, clear the live-range so that the debug
2440b57cec5SDimitry Andric // dump will show the right state for that VirtReg.
2450b57cec5SDimitry Andric LI.clear();
2460b57cec5SDimitry Andric return false;
2470b57cec5SDimitry Andric }
2480b57cec5SDimitry Andric
LRE_WillShrinkVirtReg(Register VirtReg)249e8d8bef9SDimitry Andric void RAGreedy::LRE_WillShrinkVirtReg(Register VirtReg) {
2500b57cec5SDimitry Andric if (!VRM->hasPhys(VirtReg))
2510b57cec5SDimitry Andric return;
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric // Register is assigned, put it back on the queue for reassignment.
2540b57cec5SDimitry Andric LiveInterval &LI = LIS->getInterval(VirtReg);
2550b57cec5SDimitry Andric Matrix->unassign(LI);
256fe6060f1SDimitry Andric RegAllocBase::enqueue(&LI);
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric
LRE_DidCloneVirtReg(Register New,Register Old)259e8d8bef9SDimitry Andric void RAGreedy::LRE_DidCloneVirtReg(Register New, Register Old) {
2600eae32dcSDimitry Andric ExtraInfo->LRE_DidCloneVirtReg(New, Old);
2610eae32dcSDimitry Andric }
2620eae32dcSDimitry Andric
LRE_DidCloneVirtReg(Register New,Register Old)26304eeddc0SDimitry Andric void RAGreedy::ExtraRegInfo::LRE_DidCloneVirtReg(Register New, Register Old) {
2640b57cec5SDimitry Andric // Cloning a register we haven't even heard about yet? Just ignore it.
2650eae32dcSDimitry Andric if (!Info.inBounds(Old))
2660b57cec5SDimitry Andric return;
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric // LRE may clone a virtual register because dead code elimination causes it to
2690b57cec5SDimitry Andric // be split into connected components. The new components are much smaller
2700b57cec5SDimitry Andric // than the original, so they should get a new chance at being assigned.
2710b57cec5SDimitry Andric // same stage as the parent.
2720eae32dcSDimitry Andric Info[Old].Stage = RS_Assign;
2730eae32dcSDimitry Andric Info.grow(New.id());
2740eae32dcSDimitry Andric Info[New] = Info[Old];
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric
releaseMemory()2770b57cec5SDimitry Andric void RAGreedy::releaseMemory() {
2780b57cec5SDimitry Andric SpillerInstance.reset();
2790b57cec5SDimitry Andric GlobalCand.clear();
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric
enqueueImpl(const LiveInterval * LI)28281ad6265SDimitry Andric void RAGreedy::enqueueImpl(const LiveInterval *LI) { enqueue(Queue, LI); }
2830b57cec5SDimitry Andric
enqueue(PQueue & CurQueue,const LiveInterval * LI)28481ad6265SDimitry Andric void RAGreedy::enqueue(PQueue &CurQueue, const LiveInterval *LI) {
2850b57cec5SDimitry Andric // Prioritize live ranges by size, assigning larger ranges first.
2860b57cec5SDimitry Andric // The queue holds (size, reg) pairs.
287e8d8bef9SDimitry Andric const Register Reg = LI->reg();
288e8d8bef9SDimitry Andric assert(Reg.isVirtual() && "Can only enqueue virtual registers");
2890b57cec5SDimitry Andric
2900eae32dcSDimitry Andric auto Stage = ExtraInfo->getOrInitStage(Reg);
2914824e7fdSDimitry Andric if (Stage == RS_New) {
2924824e7fdSDimitry Andric Stage = RS_Assign;
2930eae32dcSDimitry Andric ExtraInfo->setStage(Reg, Stage);
2944824e7fdSDimitry Andric }
295bdd1243dSDimitry Andric
296bdd1243dSDimitry Andric unsigned Ret = PriorityAdvisor->getPriority(*LI);
297bdd1243dSDimitry Andric
298bdd1243dSDimitry Andric // The virtual register number is a tie breaker for same-sized ranges.
299bdd1243dSDimitry Andric // Give lower vreg numbers higher priority to assign them first.
300bdd1243dSDimitry Andric CurQueue.push(std::make_pair(Ret, ~Reg));
301bdd1243dSDimitry Andric }
302bdd1243dSDimitry Andric
getPriority(const LiveInterval & LI) const303bdd1243dSDimitry Andric unsigned DefaultPriorityAdvisor::getPriority(const LiveInterval &LI) const {
304bdd1243dSDimitry Andric const unsigned Size = LI.getSize();
305bdd1243dSDimitry Andric const Register Reg = LI.reg();
306bdd1243dSDimitry Andric unsigned Prio;
307bdd1243dSDimitry Andric LiveRangeStage Stage = RA.getExtraInfo().getStage(LI);
308bdd1243dSDimitry Andric
3094824e7fdSDimitry Andric if (Stage == RS_Split) {
3100b57cec5SDimitry Andric // Unsplit ranges that couldn't be allocated immediately are deferred until
3110b57cec5SDimitry Andric // everything else has been allocated.
3120b57cec5SDimitry Andric Prio = Size;
3134824e7fdSDimitry Andric } else if (Stage == RS_Memory) {
3140b57cec5SDimitry Andric // Memory operand should be considered last.
3150b57cec5SDimitry Andric // Change the priority such that Memory operand are assigned in
3160b57cec5SDimitry Andric // the reverse order that they came in.
3170b57cec5SDimitry Andric // TODO: Make this a member variable and probably do something about hints.
3180b57cec5SDimitry Andric static unsigned MemOp = 0;
3190b57cec5SDimitry Andric Prio = MemOp++;
3200b57cec5SDimitry Andric } else {
3210b57cec5SDimitry Andric // Giant live ranges fall back to the global assignment heuristic, which
3220b57cec5SDimitry Andric // prevents excessive spilling in pathological cases.
3230b57cec5SDimitry Andric const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
324bdd1243dSDimitry Andric bool ForceGlobal = RC.GlobalPriority ||
325bdd1243dSDimitry Andric (!ReverseLocalAssignment &&
326972a253aSDimitry Andric (Size / SlotIndex::InstrDist) >
327bdd1243dSDimitry Andric (2 * RegClassInfo.getNumAllocatableRegs(&RC)));
32881ad6265SDimitry Andric unsigned GlobalBit = 0;
3290b57cec5SDimitry Andric
330bdd1243dSDimitry Andric if (Stage == RS_Assign && !ForceGlobal && !LI.empty() &&
331bdd1243dSDimitry Andric LIS->intervalIsInOneMBB(LI)) {
3320b57cec5SDimitry Andric // Allocate original local ranges in linear instruction order. Since they
3330b57cec5SDimitry Andric // are singly defined, this produces optimal coloring in the absence of
3340b57cec5SDimitry Andric // global interference and other constraints.
335972a253aSDimitry Andric if (!ReverseLocalAssignment)
336bdd1243dSDimitry Andric Prio = LI.beginIndex().getApproxInstrDistance(Indexes->getLastIndex());
3370b57cec5SDimitry Andric else {
3380b57cec5SDimitry Andric // Allocating bottom up may allow many short LRGs to be assigned first
3390b57cec5SDimitry Andric // to one of the cheap registers. This could be much faster for very
3400b57cec5SDimitry Andric // large blocks on targets with many physical registers.
341bdd1243dSDimitry Andric Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.endIndex());
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric } else {
3440b57cec5SDimitry Andric // Allocate global and split ranges in long->short order. Long ranges that
3450b57cec5SDimitry Andric // don't fit should be spilled (or split) ASAP so they don't create
3460b57cec5SDimitry Andric // interference. Mark a bit to prioritize global above local ranges.
34781ad6265SDimitry Andric Prio = Size;
34881ad6265SDimitry Andric GlobalBit = 1;
3490b57cec5SDimitry Andric }
350bdd1243dSDimitry Andric
351bdd1243dSDimitry Andric // Priority bit layout:
352bdd1243dSDimitry Andric // 31 RS_Assign priority
353bdd1243dSDimitry Andric // 30 Preference priority
354bdd1243dSDimitry Andric // if (RegClassPriorityTrumpsGlobalness)
355bdd1243dSDimitry Andric // 29-25 AllocPriority
356bdd1243dSDimitry Andric // 24 GlobalBit
357bdd1243dSDimitry Andric // else
358bdd1243dSDimitry Andric // 29 Global bit
359bdd1243dSDimitry Andric // 28-24 AllocPriority
360bdd1243dSDimitry Andric // 0-23 Size/Instr distance
361bdd1243dSDimitry Andric
362bdd1243dSDimitry Andric // Clamp the size to fit with the priority masking scheme
363bdd1243dSDimitry Andric Prio = std::min(Prio, (unsigned)maxUIntN(24));
364bdd1243dSDimitry Andric assert(isUInt<5>(RC.AllocationPriority) && "allocation priority overflow");
365bdd1243dSDimitry Andric
36681ad6265SDimitry Andric if (RegClassPriorityTrumpsGlobalness)
36781ad6265SDimitry Andric Prio |= RC.AllocationPriority << 25 | GlobalBit << 24;
36881ad6265SDimitry Andric else
36981ad6265SDimitry Andric Prio |= GlobalBit << 29 | RC.AllocationPriority << 24;
37081ad6265SDimitry Andric
3710b57cec5SDimitry Andric // Mark a higher bit to prioritize global and local above RS_Split.
3720b57cec5SDimitry Andric Prio |= (1u << 31);
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Boost ranges that have a physical register hint.
3750b57cec5SDimitry Andric if (VRM->hasKnownPreference(Reg))
3760b57cec5SDimitry Andric Prio |= (1u << 30);
3770b57cec5SDimitry Andric }
378bdd1243dSDimitry Andric
379bdd1243dSDimitry Andric return Prio;
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric
dequeue()38281ad6265SDimitry Andric const LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); }
3830b57cec5SDimitry Andric
dequeue(PQueue & CurQueue)38481ad6265SDimitry Andric const LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) {
3850b57cec5SDimitry Andric if (CurQueue.empty())
3860b57cec5SDimitry Andric return nullptr;
3870b57cec5SDimitry Andric LiveInterval *LI = &LIS->getInterval(~CurQueue.top().second);
3880b57cec5SDimitry Andric CurQueue.pop();
3890b57cec5SDimitry Andric return LI;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3930b57cec5SDimitry Andric // Direct Assignment
3940b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3950b57cec5SDimitry Andric
3960b57cec5SDimitry Andric /// tryAssign - Try to assign VirtReg to an available register.
tryAssign(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,const SmallVirtRegSet & FixedRegisters)39781ad6265SDimitry Andric MCRegister RAGreedy::tryAssign(const LiveInterval &VirtReg,
3980b57cec5SDimitry Andric AllocationOrder &Order,
3995ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
4000b57cec5SDimitry Andric const SmallVirtRegSet &FixedRegisters) {
401fe6060f1SDimitry Andric MCRegister PhysReg;
402e8d8bef9SDimitry Andric for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
403e8d8bef9SDimitry Andric assert(*I);
404e8d8bef9SDimitry Andric if (!Matrix->checkInterference(VirtReg, *I)) {
405e8d8bef9SDimitry Andric if (I.isHint())
406e8d8bef9SDimitry Andric return *I;
407e8d8bef9SDimitry Andric else
408e8d8bef9SDimitry Andric PhysReg = *I;
409e8d8bef9SDimitry Andric }
410e8d8bef9SDimitry Andric }
411e8d8bef9SDimitry Andric if (!PhysReg.isValid())
4120b57cec5SDimitry Andric return PhysReg;
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric // PhysReg is available, but there may be a better choice.
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric // If we missed a simple hint, try to cheaply evict interference from the
4170b57cec5SDimitry Andric // preferred register.
418e8d8bef9SDimitry Andric if (Register Hint = MRI->getSimpleHint(VirtReg.reg()))
4190b57cec5SDimitry Andric if (Order.isHint(Hint)) {
420e8d8bef9SDimitry Andric MCRegister PhysHint = Hint.asMCReg();
421e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "missed hint " << printReg(PhysHint, TRI) << '\n');
4224824e7fdSDimitry Andric
4230eae32dcSDimitry Andric if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
4240eae32dcSDimitry Andric FixedRegisters)) {
425e8d8bef9SDimitry Andric evictInterference(VirtReg, PhysHint, NewVRegs);
426e8d8bef9SDimitry Andric return PhysHint;
4270b57cec5SDimitry Andric }
4285f757f3fSDimitry Andric
4295f757f3fSDimitry Andric // We can also split the virtual register in cold blocks.
4305f757f3fSDimitry Andric if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
4315f757f3fSDimitry Andric return 0;
4325f757f3fSDimitry Andric
4330b57cec5SDimitry Andric // Record the missed hint, we may be able to recover
4340b57cec5SDimitry Andric // at the end if the surrounding allocation changed.
4350b57cec5SDimitry Andric SetOfBrokenHints.insert(&VirtReg);
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric // Try to evict interference from a cheaper alternative.
439fe6060f1SDimitry Andric uint8_t Cost = RegCosts[PhysReg];
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric // Most registers have 0 additional cost.
4420b57cec5SDimitry Andric if (!Cost)
4430b57cec5SDimitry Andric return PhysReg;
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << " is available at cost "
446349cc55cSDimitry Andric << (unsigned)Cost << '\n');
447fe6060f1SDimitry Andric MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs, Cost, FixedRegisters);
4480b57cec5SDimitry Andric return CheapReg ? CheapReg : PhysReg;
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4520b57cec5SDimitry Andric // Interference eviction
4530b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4540b57cec5SDimitry Andric
canReassign(const LiveInterval & VirtReg,MCRegister FromReg) const45506c3fb27SDimitry Andric bool RegAllocEvictionAdvisor::canReassign(const LiveInterval &VirtReg,
45606c3fb27SDimitry Andric MCRegister FromReg) const {
45706c3fb27SDimitry Andric auto HasRegUnitInterference = [&](MCRegUnit Unit) {
4580b57cec5SDimitry Andric // Instantiate a "subquery", not to be confused with the Queries array.
45906c3fb27SDimitry Andric LiveIntervalUnion::Query SubQ(VirtReg, Matrix->getLiveUnions()[Unit]);
46006c3fb27SDimitry Andric return SubQ.checkInterference();
46106c3fb27SDimitry Andric };
46206c3fb27SDimitry Andric
46306c3fb27SDimitry Andric for (MCRegister Reg :
46406c3fb27SDimitry Andric AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix)) {
46506c3fb27SDimitry Andric if (Reg == FromReg)
46606c3fb27SDimitry Andric continue;
46706c3fb27SDimitry Andric // If no units have interference, reassignment is possible.
46806c3fb27SDimitry Andric if (none_of(TRI->regunits(Reg), HasRegUnitInterference)) {
4690b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "can reassign: " << VirtReg << " from "
47006c3fb27SDimitry Andric << printReg(FromReg, TRI) << " to "
47106c3fb27SDimitry Andric << printReg(Reg, TRI) << '\n');
47206c3fb27SDimitry Andric return true;
47306c3fb27SDimitry Andric }
47406c3fb27SDimitry Andric }
47506c3fb27SDimitry Andric return false;
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andric /// evictInterference - Evict any interferring registers that prevent VirtReg
4790b57cec5SDimitry Andric /// from being assigned to Physreg. This assumes that canEvictInterference
4800b57cec5SDimitry Andric /// returned true.
evictInterference(const LiveInterval & VirtReg,MCRegister PhysReg,SmallVectorImpl<Register> & NewVRegs)48181ad6265SDimitry Andric void RAGreedy::evictInterference(const LiveInterval &VirtReg,
48281ad6265SDimitry Andric MCRegister PhysReg,
4835ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
4840b57cec5SDimitry Andric // Make sure that VirtReg has a cascade number, and assign that cascade
4850b57cec5SDimitry Andric // number to every evicted register. These live ranges than then only be
4860b57cec5SDimitry Andric // evicted by a newer cascade, preventing infinite loops.
4870eae32dcSDimitry Andric unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.reg());
4880b57cec5SDimitry Andric
4890b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "evicting " << printReg(PhysReg, TRI)
4900b57cec5SDimitry Andric << " interference: Cascade " << Cascade << '\n');
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andric // Collect all interfering virtregs first.
49381ad6265SDimitry Andric SmallVector<const LiveInterval *, 8> Intfs;
49406c3fb27SDimitry Andric for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
49506c3fb27SDimitry Andric LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
4960b57cec5SDimitry Andric // We usually have the interfering VRegs cached so collectInterferingVRegs()
4970b57cec5SDimitry Andric // should be fast, we may need to recalculate if when different physregs
4980b57cec5SDimitry Andric // overlap the same register unit so we had different SubRanges queried
4990b57cec5SDimitry Andric // against it.
50081ad6265SDimitry Andric ArrayRef<const LiveInterval *> IVR = Q.interferingVRegs();
5010b57cec5SDimitry Andric Intfs.append(IVR.begin(), IVR.end());
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric // Evict them second. This will invalidate the queries.
50581ad6265SDimitry Andric for (const LiveInterval *Intf : Intfs) {
5060b57cec5SDimitry Andric // The same VirtReg may be present in multiple RegUnits. Skip duplicates.
507e8d8bef9SDimitry Andric if (!VRM->hasPhys(Intf->reg()))
5080b57cec5SDimitry Andric continue;
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric Matrix->unassign(*Intf);
5110eae32dcSDimitry Andric assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
5120b57cec5SDimitry Andric VirtReg.isSpillable() < Intf->isSpillable()) &&
5130b57cec5SDimitry Andric "Cannot decrease cascade number, illegal eviction");
5140eae32dcSDimitry Andric ExtraInfo->setCascade(Intf->reg(), Cascade);
5150b57cec5SDimitry Andric ++NumEvicted;
516e8d8bef9SDimitry Andric NewVRegs.push_back(Intf->reg());
5170b57cec5SDimitry Andric }
5180b57cec5SDimitry Andric }
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andric /// Returns true if the given \p PhysReg is a callee saved register and has not
5210b57cec5SDimitry Andric /// been used for allocation yet.
isUnusedCalleeSavedReg(MCRegister PhysReg) const5220eae32dcSDimitry Andric bool RegAllocEvictionAdvisor::isUnusedCalleeSavedReg(MCRegister PhysReg) const {
5235ffd83dbSDimitry Andric MCRegister CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg);
5245ffd83dbSDimitry Andric if (!CSR)
5250b57cec5SDimitry Andric return false;
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andric return !Matrix->isPhysRegUsed(PhysReg);
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric
530bdd1243dSDimitry Andric std::optional<unsigned>
getOrderLimit(const LiveInterval & VirtReg,const AllocationOrder & Order,unsigned CostPerUseLimit) const53104eeddc0SDimitry Andric RegAllocEvictionAdvisor::getOrderLimit(const LiveInterval &VirtReg,
53204eeddc0SDimitry Andric const AllocationOrder &Order,
53304eeddc0SDimitry Andric unsigned CostPerUseLimit) const {
5340b57cec5SDimitry Andric unsigned OrderLimit = Order.getOrder().size();
5350b57cec5SDimitry Andric
536fe6060f1SDimitry Andric if (CostPerUseLimit < uint8_t(~0u)) {
5370b57cec5SDimitry Andric // Check of any registers in RC are below CostPerUseLimit.
538e8d8bef9SDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg());
539fe6060f1SDimitry Andric uint8_t MinCost = RegClassInfo.getMinCost(RC);
5400b57cec5SDimitry Andric if (MinCost >= CostPerUseLimit) {
5410b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << TRI->getRegClassName(RC) << " minimum cost = "
5420b57cec5SDimitry Andric << MinCost << ", no cheaper registers to be found.\n");
543bdd1243dSDimitry Andric return std::nullopt;
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andric // It is normal for register classes to have a long tail of registers with
5470b57cec5SDimitry Andric // the same cost. We don't need to look at them if they're too expensive.
548fe6060f1SDimitry Andric if (RegCosts[Order.getOrder().back()] >= CostPerUseLimit) {
5490b57cec5SDimitry Andric OrderLimit = RegClassInfo.getLastCostChange(RC);
5500b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Only trying the first " << OrderLimit
5510b57cec5SDimitry Andric << " regs.\n");
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric }
55404eeddc0SDimitry Andric return OrderLimit;
55504eeddc0SDimitry Andric }
5560b57cec5SDimitry Andric
canAllocatePhysReg(unsigned CostPerUseLimit,MCRegister PhysReg) const55704eeddc0SDimitry Andric bool RegAllocEvictionAdvisor::canAllocatePhysReg(unsigned CostPerUseLimit,
55804eeddc0SDimitry Andric MCRegister PhysReg) const {
559fe6060f1SDimitry Andric if (RegCosts[PhysReg] >= CostPerUseLimit)
56004eeddc0SDimitry Andric return false;
5610b57cec5SDimitry Andric // The first use of a callee-saved register in a function has cost 1.
5620b57cec5SDimitry Andric // Don't start using a CSR when the CostPerUseLimit is low.
5630b57cec5SDimitry Andric if (CostPerUseLimit == 1 && isUnusedCalleeSavedReg(PhysReg)) {
5640b57cec5SDimitry Andric LLVM_DEBUG(
5650b57cec5SDimitry Andric dbgs() << printReg(PhysReg, TRI) << " would clobber CSR "
5660b57cec5SDimitry Andric << printReg(RegClassInfo.getLastCalleeSavedAlias(PhysReg), TRI)
5670b57cec5SDimitry Andric << '\n');
56804eeddc0SDimitry Andric return false;
56904eeddc0SDimitry Andric }
57004eeddc0SDimitry Andric return true;
5710b57cec5SDimitry Andric }
5720b57cec5SDimitry Andric
573349cc55cSDimitry Andric /// tryEvict - Try to evict all interferences for a physreg.
574349cc55cSDimitry Andric /// @param VirtReg Currently unassigned virtual register.
575349cc55cSDimitry Andric /// @param Order Physregs to try.
576349cc55cSDimitry Andric /// @return Physreg to assign VirtReg, or 0.
tryEvict(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,uint8_t CostPerUseLimit,const SmallVirtRegSet & FixedRegisters)57781ad6265SDimitry Andric MCRegister RAGreedy::tryEvict(const LiveInterval &VirtReg,
57881ad6265SDimitry Andric AllocationOrder &Order,
579349cc55cSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
580349cc55cSDimitry Andric uint8_t CostPerUseLimit,
581349cc55cSDimitry Andric const SmallVirtRegSet &FixedRegisters) {
582349cc55cSDimitry Andric NamedRegionTimer T("evict", "Evict", TimerGroupName, TimerGroupDescription,
583349cc55cSDimitry Andric TimePassesIsEnabled);
584349cc55cSDimitry Andric
5850eae32dcSDimitry Andric MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
5860eae32dcSDimitry Andric VirtReg, Order, CostPerUseLimit, FixedRegisters);
587fe6060f1SDimitry Andric if (BestPhys.isValid())
5880b57cec5SDimitry Andric evictInterference(VirtReg, BestPhys, NewVRegs);
5890b57cec5SDimitry Andric return BestPhys;
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric
5920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5930b57cec5SDimitry Andric // Region Splitting
5940b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5950b57cec5SDimitry Andric
5960b57cec5SDimitry Andric /// addSplitConstraints - Fill out the SplitConstraints vector based on the
5970b57cec5SDimitry Andric /// interference pattern in Physreg and its aliases. Add the constraints to
5980b57cec5SDimitry Andric /// SpillPlacement and return the static cost of this split in Cost, assuming
5990b57cec5SDimitry Andric /// that all preferences in SplitConstraints are met.
6000b57cec5SDimitry Andric /// Return false if there are no bundles with positive bias.
addSplitConstraints(InterferenceCache::Cursor Intf,BlockFrequency & Cost)6010b57cec5SDimitry Andric bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
6020b57cec5SDimitry Andric BlockFrequency &Cost) {
6030b57cec5SDimitry Andric ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
6040b57cec5SDimitry Andric
6050b57cec5SDimitry Andric // Reset interference dependent info.
6060b57cec5SDimitry Andric SplitConstraints.resize(UseBlocks.size());
6075f757f3fSDimitry Andric BlockFrequency StaticCost = BlockFrequency(0);
608e8d8bef9SDimitry Andric for (unsigned I = 0; I != UseBlocks.size(); ++I) {
609e8d8bef9SDimitry Andric const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
610e8d8bef9SDimitry Andric SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andric BC.Number = BI.MBB->getNumber();
6130b57cec5SDimitry Andric Intf.moveToBlock(BC.Number);
6140b57cec5SDimitry Andric BC.Entry = BI.LiveIn ? SpillPlacement::PrefReg : SpillPlacement::DontCare;
6150b57cec5SDimitry Andric BC.Exit = (BI.LiveOut &&
6160b57cec5SDimitry Andric !LIS->getInstructionFromIndex(BI.LastInstr)->isImplicitDef())
6170b57cec5SDimitry Andric ? SpillPlacement::PrefReg
6180b57cec5SDimitry Andric : SpillPlacement::DontCare;
6190b57cec5SDimitry Andric BC.ChangesValue = BI.FirstDef.isValid();
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric if (!Intf.hasInterference())
6220b57cec5SDimitry Andric continue;
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric // Number of spill code instructions to insert.
6250b57cec5SDimitry Andric unsigned Ins = 0;
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric // Interference for the live-in value.
6280b57cec5SDimitry Andric if (BI.LiveIn) {
6290b57cec5SDimitry Andric if (Intf.first() <= Indexes->getMBBStartIdx(BC.Number)) {
6300b57cec5SDimitry Andric BC.Entry = SpillPlacement::MustSpill;
6310b57cec5SDimitry Andric ++Ins;
6320b57cec5SDimitry Andric } else if (Intf.first() < BI.FirstInstr) {
6330b57cec5SDimitry Andric BC.Entry = SpillPlacement::PrefSpill;
6340b57cec5SDimitry Andric ++Ins;
6350b57cec5SDimitry Andric } else if (Intf.first() < BI.LastInstr) {
6360b57cec5SDimitry Andric ++Ins;
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric
6390b57cec5SDimitry Andric // Abort if the spill cannot be inserted at the MBB' start
6400b57cec5SDimitry Andric if (((BC.Entry == SpillPlacement::MustSpill) ||
6410b57cec5SDimitry Andric (BC.Entry == SpillPlacement::PrefSpill)) &&
6420b57cec5SDimitry Andric SlotIndex::isEarlierInstr(BI.FirstInstr,
6430b57cec5SDimitry Andric SA->getFirstSplitPoint(BC.Number)))
6440b57cec5SDimitry Andric return false;
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric // Interference for the live-out value.
6480b57cec5SDimitry Andric if (BI.LiveOut) {
6490b57cec5SDimitry Andric if (Intf.last() >= SA->getLastSplitPoint(BC.Number)) {
6500b57cec5SDimitry Andric BC.Exit = SpillPlacement::MustSpill;
6510b57cec5SDimitry Andric ++Ins;
6520b57cec5SDimitry Andric } else if (Intf.last() > BI.LastInstr) {
6530b57cec5SDimitry Andric BC.Exit = SpillPlacement::PrefSpill;
6540b57cec5SDimitry Andric ++Ins;
6550b57cec5SDimitry Andric } else if (Intf.last() > BI.FirstInstr) {
6560b57cec5SDimitry Andric ++Ins;
6570b57cec5SDimitry Andric }
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andric // Accumulate the total frequency of inserted spill code.
6610b57cec5SDimitry Andric while (Ins--)
6620b57cec5SDimitry Andric StaticCost += SpillPlacer->getBlockFrequency(BC.Number);
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric Cost = StaticCost;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric // Add constraints for use-blocks. Note that these are the only constraints
6670b57cec5SDimitry Andric // that may add a positive bias, it is downhill from here.
6680b57cec5SDimitry Andric SpillPlacer->addConstraints(SplitConstraints);
6690b57cec5SDimitry Andric return SpillPlacer->scanActiveBundles();
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric
6720b57cec5SDimitry Andric /// addThroughConstraints - Add constraints and links to SpillPlacer from the
6730b57cec5SDimitry Andric /// live-through blocks in Blocks.
addThroughConstraints(InterferenceCache::Cursor Intf,ArrayRef<unsigned> Blocks)6740b57cec5SDimitry Andric bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
6750b57cec5SDimitry Andric ArrayRef<unsigned> Blocks) {
6760b57cec5SDimitry Andric const unsigned GroupSize = 8;
6770b57cec5SDimitry Andric SpillPlacement::BlockConstraint BCS[GroupSize];
6780b57cec5SDimitry Andric unsigned TBS[GroupSize];
6790b57cec5SDimitry Andric unsigned B = 0, T = 0;
6800b57cec5SDimitry Andric
681e8d8bef9SDimitry Andric for (unsigned Number : Blocks) {
6820b57cec5SDimitry Andric Intf.moveToBlock(Number);
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andric if (!Intf.hasInterference()) {
6850b57cec5SDimitry Andric assert(T < GroupSize && "Array overflow");
6860b57cec5SDimitry Andric TBS[T] = Number;
6870b57cec5SDimitry Andric if (++T == GroupSize) {
688bdd1243dSDimitry Andric SpillPlacer->addLinks(ArrayRef(TBS, T));
6890b57cec5SDimitry Andric T = 0;
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric continue;
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andric assert(B < GroupSize && "Array overflow");
6950b57cec5SDimitry Andric BCS[B].Number = Number;
6960b57cec5SDimitry Andric
6970b57cec5SDimitry Andric // Abort if the spill cannot be inserted at the MBB' start
6980b57cec5SDimitry Andric MachineBasicBlock *MBB = MF->getBlockNumbered(Number);
699fe6060f1SDimitry Andric auto FirstNonDebugInstr = MBB->getFirstNonDebugInstr();
700fe6060f1SDimitry Andric if (FirstNonDebugInstr != MBB->end() &&
701fe6060f1SDimitry Andric SlotIndex::isEarlierInstr(LIS->getInstructionIndex(*FirstNonDebugInstr),
7020b57cec5SDimitry Andric SA->getFirstSplitPoint(Number)))
7030b57cec5SDimitry Andric return false;
7040b57cec5SDimitry Andric // Interference for the live-in value.
7050b57cec5SDimitry Andric if (Intf.first() <= Indexes->getMBBStartIdx(Number))
7060b57cec5SDimitry Andric BCS[B].Entry = SpillPlacement::MustSpill;
7070b57cec5SDimitry Andric else
7080b57cec5SDimitry Andric BCS[B].Entry = SpillPlacement::PrefSpill;
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric // Interference for the live-out value.
7110b57cec5SDimitry Andric if (Intf.last() >= SA->getLastSplitPoint(Number))
7120b57cec5SDimitry Andric BCS[B].Exit = SpillPlacement::MustSpill;
7130b57cec5SDimitry Andric else
7140b57cec5SDimitry Andric BCS[B].Exit = SpillPlacement::PrefSpill;
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andric if (++B == GroupSize) {
717bdd1243dSDimitry Andric SpillPlacer->addConstraints(ArrayRef(BCS, B));
7180b57cec5SDimitry Andric B = 0;
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric }
7210b57cec5SDimitry Andric
722bdd1243dSDimitry Andric SpillPlacer->addConstraints(ArrayRef(BCS, B));
723bdd1243dSDimitry Andric SpillPlacer->addLinks(ArrayRef(TBS, T));
7240b57cec5SDimitry Andric return true;
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric
growRegion(GlobalSplitCandidate & Cand)7270b57cec5SDimitry Andric bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
7280b57cec5SDimitry Andric // Keep track of through blocks that have not been added to SpillPlacer.
7290b57cec5SDimitry Andric BitVector Todo = SA->getThroughBlocks();
7300b57cec5SDimitry Andric SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
7310b57cec5SDimitry Andric unsigned AddedTo = 0;
7320b57cec5SDimitry Andric #ifndef NDEBUG
7330b57cec5SDimitry Andric unsigned Visited = 0;
7340b57cec5SDimitry Andric #endif
7350b57cec5SDimitry Andric
73681ad6265SDimitry Andric unsigned long Budget = GrowRegionComplexityBudget;
7370b57cec5SDimitry Andric while (true) {
7380b57cec5SDimitry Andric ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
7390b57cec5SDimitry Andric // Find new through blocks in the periphery of PrefRegBundles.
740e8d8bef9SDimitry Andric for (unsigned Bundle : NewBundles) {
7410b57cec5SDimitry Andric // Look at all blocks connected to Bundle in the full graph.
7420b57cec5SDimitry Andric ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
74381ad6265SDimitry Andric // Limit compilation time by bailing out after we use all our budget.
74481ad6265SDimitry Andric if (Blocks.size() >= Budget)
74581ad6265SDimitry Andric return false;
74681ad6265SDimitry Andric Budget -= Blocks.size();
747fe6060f1SDimitry Andric for (unsigned Block : Blocks) {
7480b57cec5SDimitry Andric if (!Todo.test(Block))
7490b57cec5SDimitry Andric continue;
7500b57cec5SDimitry Andric Todo.reset(Block);
7510b57cec5SDimitry Andric // This is a new through block. Add it to SpillPlacer later.
7520b57cec5SDimitry Andric ActiveBlocks.push_back(Block);
7530b57cec5SDimitry Andric #ifndef NDEBUG
7540b57cec5SDimitry Andric ++Visited;
7550b57cec5SDimitry Andric #endif
7560b57cec5SDimitry Andric }
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric // Any new blocks to add?
7590b57cec5SDimitry Andric if (ActiveBlocks.size() == AddedTo)
7600b57cec5SDimitry Andric break;
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric // Compute through constraints from the interference, or assume that all
7630b57cec5SDimitry Andric // through blocks prefer spilling when forming compact regions.
764bdd1243dSDimitry Andric auto NewBlocks = ArrayRef(ActiveBlocks).slice(AddedTo);
7650b57cec5SDimitry Andric if (Cand.PhysReg) {
7660b57cec5SDimitry Andric if (!addThroughConstraints(Cand.Intf, NewBlocks))
7670b57cec5SDimitry Andric return false;
7685f757f3fSDimitry Andric } else {
7695f757f3fSDimitry Andric // Providing that the variable being spilled does not look like a loop
7705f757f3fSDimitry Andric // induction variable, which is expensive to spill around and better
7715f757f3fSDimitry Andric // pushed into a condition inside the loop if possible, provide a strong
7725f757f3fSDimitry Andric // negative bias on through blocks to prevent unwanted liveness on loop
7735f757f3fSDimitry Andric // backedges.
7745f757f3fSDimitry Andric bool PrefSpill = true;
7755f757f3fSDimitry Andric if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
7765f757f3fSDimitry Andric // Check that the current bundle is adding a Header + start+end of
7775f757f3fSDimitry Andric // loop-internal blocks. If the block is indeed a header, don't make
7785f757f3fSDimitry Andric // the NewBlocks as PrefSpill to allow the variable to be live in
7795f757f3fSDimitry Andric // Header<->Latch.
7805f757f3fSDimitry Andric MachineLoop *L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
7815f757f3fSDimitry Andric if (L && L->getHeader()->getNumber() == (int)NewBlocks[0] &&
7825f757f3fSDimitry Andric all_of(NewBlocks.drop_front(), [&](unsigned Block) {
7835f757f3fSDimitry Andric return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
7845f757f3fSDimitry Andric }))
7855f757f3fSDimitry Andric PrefSpill = false;
7865f757f3fSDimitry Andric }
7875f757f3fSDimitry Andric if (PrefSpill)
7880b57cec5SDimitry Andric SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true);
7895f757f3fSDimitry Andric }
7900b57cec5SDimitry Andric AddedTo = ActiveBlocks.size();
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric // Perhaps iterating can enable more bundles?
7930b57cec5SDimitry Andric SpillPlacer->iterate();
7940b57cec5SDimitry Andric }
7950b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ", v=" << Visited);
7960b57cec5SDimitry Andric return true;
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andric /// calcCompactRegion - Compute the set of edge bundles that should be live
8000b57cec5SDimitry Andric /// when splitting the current live range into compact regions. Compact
8010b57cec5SDimitry Andric /// regions can be computed without looking at interference. They are the
8020b57cec5SDimitry Andric /// regions formed by removing all the live-through blocks from the live range.
8030b57cec5SDimitry Andric ///
8040b57cec5SDimitry Andric /// Returns false if the current live range is already compact, or if the
8050b57cec5SDimitry Andric /// compact regions would form single block regions anyway.
calcCompactRegion(GlobalSplitCandidate & Cand)8060b57cec5SDimitry Andric bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
8070b57cec5SDimitry Andric // Without any through blocks, the live range is already compact.
8080b57cec5SDimitry Andric if (!SA->getNumThroughBlocks())
8090b57cec5SDimitry Andric return false;
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andric // Compact regions don't correspond to any physreg.
812e8d8bef9SDimitry Andric Cand.reset(IntfCache, MCRegister::NoRegister);
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Compact region bundles");
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andric // Use the spill placer to determine the live bundles. GrowRegion pretends
8170b57cec5SDimitry Andric // that all the through blocks have interference when PhysReg is unset.
8180b57cec5SDimitry Andric SpillPlacer->prepare(Cand.LiveBundles);
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric // The static split cost will be zero since Cand.Intf reports no interference.
8210b57cec5SDimitry Andric BlockFrequency Cost;
8220b57cec5SDimitry Andric if (!addSplitConstraints(Cand.Intf, Cost)) {
8230b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ", none.\n");
8240b57cec5SDimitry Andric return false;
8250b57cec5SDimitry Andric }
8260b57cec5SDimitry Andric
8270b57cec5SDimitry Andric if (!growRegion(Cand)) {
8280b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
8290b57cec5SDimitry Andric return false;
8300b57cec5SDimitry Andric }
8310b57cec5SDimitry Andric
8320b57cec5SDimitry Andric SpillPlacer->finish();
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andric if (!Cand.LiveBundles.any()) {
8350b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ", none.\n");
8360b57cec5SDimitry Andric return false;
8370b57cec5SDimitry Andric }
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric LLVM_DEBUG({
840e8d8bef9SDimitry Andric for (int I : Cand.LiveBundles.set_bits())
841e8d8bef9SDimitry Andric dbgs() << " EB#" << I;
8420b57cec5SDimitry Andric dbgs() << ".\n";
8430b57cec5SDimitry Andric });
8440b57cec5SDimitry Andric return true;
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andric /// calcSpillCost - Compute how expensive it would be to split the live range in
8480b57cec5SDimitry Andric /// SA around all use blocks instead of forming bundle regions.
calcSpillCost()8490b57cec5SDimitry Andric BlockFrequency RAGreedy::calcSpillCost() {
8505f757f3fSDimitry Andric BlockFrequency Cost = BlockFrequency(0);
8510b57cec5SDimitry Andric ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
852e8d8bef9SDimitry Andric for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
8530b57cec5SDimitry Andric unsigned Number = BI.MBB->getNumber();
8540b57cec5SDimitry Andric // We normally only need one spill instruction - a load or a store.
8550b57cec5SDimitry Andric Cost += SpillPlacer->getBlockFrequency(Number);
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andric // Unless the value is redefined in the block.
8580b57cec5SDimitry Andric if (BI.LiveIn && BI.LiveOut && BI.FirstDef)
8590b57cec5SDimitry Andric Cost += SpillPlacer->getBlockFrequency(Number);
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric return Cost;
8620b57cec5SDimitry Andric }
8630b57cec5SDimitry Andric
8640b57cec5SDimitry Andric /// calcGlobalSplitCost - Return the global split cost of following the split
8650b57cec5SDimitry Andric /// pattern in LiveBundles. This cost should be added to the local cost of the
8660b57cec5SDimitry Andric /// interference pattern in SplitConstraints.
8670b57cec5SDimitry Andric ///
calcGlobalSplitCost(GlobalSplitCandidate & Cand,const AllocationOrder & Order)8680b57cec5SDimitry Andric BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
86981ad6265SDimitry Andric const AllocationOrder &Order) {
8705f757f3fSDimitry Andric BlockFrequency GlobalCost = BlockFrequency(0);
8710b57cec5SDimitry Andric const BitVector &LiveBundles = Cand.LiveBundles;
8720b57cec5SDimitry Andric ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
873e8d8bef9SDimitry Andric for (unsigned I = 0; I != UseBlocks.size(); ++I) {
874e8d8bef9SDimitry Andric const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
875e8d8bef9SDimitry Andric SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
8760b57cec5SDimitry Andric bool RegIn = LiveBundles[Bundles->getBundle(BC.Number, false)];
8770b57cec5SDimitry Andric bool RegOut = LiveBundles[Bundles->getBundle(BC.Number, true)];
8780b57cec5SDimitry Andric unsigned Ins = 0;
8790b57cec5SDimitry Andric
8800b57cec5SDimitry Andric Cand.Intf.moveToBlock(BC.Number);
8810b57cec5SDimitry Andric
8820b57cec5SDimitry Andric if (BI.LiveIn)
8830b57cec5SDimitry Andric Ins += RegIn != (BC.Entry == SpillPlacement::PrefReg);
8840b57cec5SDimitry Andric if (BI.LiveOut)
8850b57cec5SDimitry Andric Ins += RegOut != (BC.Exit == SpillPlacement::PrefReg);
8860b57cec5SDimitry Andric while (Ins--)
8870b57cec5SDimitry Andric GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric
890e8d8bef9SDimitry Andric for (unsigned Number : Cand.ActiveBlocks) {
8910b57cec5SDimitry Andric bool RegIn = LiveBundles[Bundles->getBundle(Number, false)];
8920b57cec5SDimitry Andric bool RegOut = LiveBundles[Bundles->getBundle(Number, true)];
8930b57cec5SDimitry Andric if (!RegIn && !RegOut)
8940b57cec5SDimitry Andric continue;
8950b57cec5SDimitry Andric if (RegIn && RegOut) {
8960b57cec5SDimitry Andric // We need double spill code if this block has interference.
8970b57cec5SDimitry Andric Cand.Intf.moveToBlock(Number);
8980b57cec5SDimitry Andric if (Cand.Intf.hasInterference()) {
8990b57cec5SDimitry Andric GlobalCost += SpillPlacer->getBlockFrequency(Number);
9000b57cec5SDimitry Andric GlobalCost += SpillPlacer->getBlockFrequency(Number);
9010b57cec5SDimitry Andric }
9020b57cec5SDimitry Andric continue;
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric // live-in / stack-out or stack-in live-out.
9050b57cec5SDimitry Andric GlobalCost += SpillPlacer->getBlockFrequency(Number);
9060b57cec5SDimitry Andric }
9070b57cec5SDimitry Andric return GlobalCost;
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric /// splitAroundRegion - Split the current live range around the regions
9110b57cec5SDimitry Andric /// determined by BundleCand and GlobalCand.
9120b57cec5SDimitry Andric ///
9130b57cec5SDimitry Andric /// Before calling this function, GlobalCand and BundleCand must be initialized
9140b57cec5SDimitry Andric /// so each bundle is assigned to a valid candidate, or NoCand for the
9150b57cec5SDimitry Andric /// stack-bound bundles. The shared SA/SE SplitAnalysis and SplitEditor
9160b57cec5SDimitry Andric /// objects must be initialized for the current live range, and intervals
9170b57cec5SDimitry Andric /// created for the used candidates.
9180b57cec5SDimitry Andric ///
9190b57cec5SDimitry Andric /// @param LREdit The LiveRangeEdit object handling the current split.
9200b57cec5SDimitry Andric /// @param UsedCands List of used GlobalCand entries. Every BundleCand value
9210b57cec5SDimitry Andric /// must appear in this list.
splitAroundRegion(LiveRangeEdit & LREdit,ArrayRef<unsigned> UsedCands)9220b57cec5SDimitry Andric void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
9230b57cec5SDimitry Andric ArrayRef<unsigned> UsedCands) {
9240b57cec5SDimitry Andric // These are the intervals created for new global ranges. We may create more
9250b57cec5SDimitry Andric // intervals for local ranges.
9260b57cec5SDimitry Andric const unsigned NumGlobalIntvs = LREdit.size();
9270b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "splitAroundRegion with " << NumGlobalIntvs
9280b57cec5SDimitry Andric << " globals.\n");
9290b57cec5SDimitry Andric assert(NumGlobalIntvs && "No global intervals configured");
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric // Isolate even single instructions when dealing with a proper sub-class.
9320b57cec5SDimitry Andric // That guarantees register class inflation for the stack interval because it
9330b57cec5SDimitry Andric // is all copies.
934e8d8bef9SDimitry Andric Register Reg = SA->getParent().reg();
9350b57cec5SDimitry Andric bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
9360b57cec5SDimitry Andric
9370b57cec5SDimitry Andric // First handle all the blocks with uses.
9380b57cec5SDimitry Andric ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
939e8d8bef9SDimitry Andric for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
9400b57cec5SDimitry Andric unsigned Number = BI.MBB->getNumber();
9410b57cec5SDimitry Andric unsigned IntvIn = 0, IntvOut = 0;
9420b57cec5SDimitry Andric SlotIndex IntfIn, IntfOut;
9430b57cec5SDimitry Andric if (BI.LiveIn) {
9440b57cec5SDimitry Andric unsigned CandIn = BundleCand[Bundles->getBundle(Number, false)];
9450b57cec5SDimitry Andric if (CandIn != NoCand) {
9460b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[CandIn];
9470b57cec5SDimitry Andric IntvIn = Cand.IntvIdx;
9480b57cec5SDimitry Andric Cand.Intf.moveToBlock(Number);
9490b57cec5SDimitry Andric IntfIn = Cand.Intf.first();
9500b57cec5SDimitry Andric }
9510b57cec5SDimitry Andric }
9520b57cec5SDimitry Andric if (BI.LiveOut) {
9530b57cec5SDimitry Andric unsigned CandOut = BundleCand[Bundles->getBundle(Number, true)];
9540b57cec5SDimitry Andric if (CandOut != NoCand) {
9550b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[CandOut];
9560b57cec5SDimitry Andric IntvOut = Cand.IntvIdx;
9570b57cec5SDimitry Andric Cand.Intf.moveToBlock(Number);
9580b57cec5SDimitry Andric IntfOut = Cand.Intf.last();
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric }
9610b57cec5SDimitry Andric
9620b57cec5SDimitry Andric // Create separate intervals for isolated blocks with multiple uses.
9630b57cec5SDimitry Andric if (!IntvIn && !IntvOut) {
9640b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*BI.MBB) << " isolated.\n");
9650b57cec5SDimitry Andric if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
9660b57cec5SDimitry Andric SE->splitSingleBlock(BI);
9670b57cec5SDimitry Andric continue;
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andric if (IntvIn && IntvOut)
9710b57cec5SDimitry Andric SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut);
9720b57cec5SDimitry Andric else if (IntvIn)
9730b57cec5SDimitry Andric SE->splitRegInBlock(BI, IntvIn, IntfIn);
9740b57cec5SDimitry Andric else
9750b57cec5SDimitry Andric SE->splitRegOutBlock(BI, IntvOut, IntfOut);
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andric // Handle live-through blocks. The relevant live-through blocks are stored in
9790b57cec5SDimitry Andric // the ActiveBlocks list with each candidate. We need to filter out
9800b57cec5SDimitry Andric // duplicates.
9810b57cec5SDimitry Andric BitVector Todo = SA->getThroughBlocks();
9820eae32dcSDimitry Andric for (unsigned UsedCand : UsedCands) {
9830eae32dcSDimitry Andric ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
984e8d8bef9SDimitry Andric for (unsigned Number : Blocks) {
9850b57cec5SDimitry Andric if (!Todo.test(Number))
9860b57cec5SDimitry Andric continue;
9870b57cec5SDimitry Andric Todo.reset(Number);
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andric unsigned IntvIn = 0, IntvOut = 0;
9900b57cec5SDimitry Andric SlotIndex IntfIn, IntfOut;
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andric unsigned CandIn = BundleCand[Bundles->getBundle(Number, false)];
9930b57cec5SDimitry Andric if (CandIn != NoCand) {
9940b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[CandIn];
9950b57cec5SDimitry Andric IntvIn = Cand.IntvIdx;
9960b57cec5SDimitry Andric Cand.Intf.moveToBlock(Number);
9970b57cec5SDimitry Andric IntfIn = Cand.Intf.first();
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andric unsigned CandOut = BundleCand[Bundles->getBundle(Number, true)];
10010b57cec5SDimitry Andric if (CandOut != NoCand) {
10020b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[CandOut];
10030b57cec5SDimitry Andric IntvOut = Cand.IntvIdx;
10040b57cec5SDimitry Andric Cand.Intf.moveToBlock(Number);
10050b57cec5SDimitry Andric IntfOut = Cand.Intf.last();
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric if (!IntvIn && !IntvOut)
10080b57cec5SDimitry Andric continue;
10090b57cec5SDimitry Andric SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut);
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric
10130b57cec5SDimitry Andric ++NumGlobalSplits;
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric SmallVector<unsigned, 8> IntvMap;
10160b57cec5SDimitry Andric SE->finish(&IntvMap);
10170b57cec5SDimitry Andric DebugVars->splitRegister(Reg, LREdit.regs(), *LIS);
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andric unsigned OrigBlocks = SA->getNumLiveBlocks();
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andric // Sort out the new intervals created by splitting. We get four kinds:
10220b57cec5SDimitry Andric // - Remainder intervals should not be split again.
10230b57cec5SDimitry Andric // - Candidate intervals can be assigned to Cand.PhysReg.
10240b57cec5SDimitry Andric // - Block-local splits are candidates for local splitting.
10250b57cec5SDimitry Andric // - DCE leftovers should go back on the queue.
1026e8d8bef9SDimitry Andric for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
10274824e7fdSDimitry Andric const LiveInterval &Reg = LIS->getInterval(LREdit.get(I));
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andric // Ignore old intervals from DCE.
10300eae32dcSDimitry Andric if (ExtraInfo->getOrInitStage(Reg.reg()) != RS_New)
10310b57cec5SDimitry Andric continue;
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andric // Remainder interval. Don't try splitting again, spill if it doesn't
10340b57cec5SDimitry Andric // allocate.
1035e8d8bef9SDimitry Andric if (IntvMap[I] == 0) {
10360eae32dcSDimitry Andric ExtraInfo->setStage(Reg, RS_Spill);
10370b57cec5SDimitry Andric continue;
10380b57cec5SDimitry Andric }
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric // Global intervals. Allow repeated splitting as long as the number of live
10410b57cec5SDimitry Andric // blocks is strictly decreasing.
1042e8d8bef9SDimitry Andric if (IntvMap[I] < NumGlobalIntvs) {
10430b57cec5SDimitry Andric if (SA->countLiveBlocks(&Reg) >= OrigBlocks) {
10440b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Main interval covers the same " << OrigBlocks
10450b57cec5SDimitry Andric << " blocks as original.\n");
10460b57cec5SDimitry Andric // Don't allow repeated splitting as a safe guard against looping.
10470eae32dcSDimitry Andric ExtraInfo->setStage(Reg, RS_Split2);
10480b57cec5SDimitry Andric }
10490b57cec5SDimitry Andric continue;
10500b57cec5SDimitry Andric }
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andric // Other intervals are treated as new. This includes local intervals created
10530b57cec5SDimitry Andric // for blocks with multiple uses, and anything created by DCE.
10540b57cec5SDimitry Andric }
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andric if (VerifyEnabled)
10570b57cec5SDimitry Andric MF->verify(this, "After splitting live range around region");
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric
tryRegionSplit(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)106081ad6265SDimitry Andric MCRegister RAGreedy::tryRegionSplit(const LiveInterval &VirtReg,
1061e8d8bef9SDimitry Andric AllocationOrder &Order,
10625ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
10635ffd83dbSDimitry Andric if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1064e8d8bef9SDimitry Andric return MCRegister::NoRegister;
10650b57cec5SDimitry Andric unsigned NumCands = 0;
10660b57cec5SDimitry Andric BlockFrequency SpillCost = calcSpillCost();
10670b57cec5SDimitry Andric BlockFrequency BestCost;
10680b57cec5SDimitry Andric
10690b57cec5SDimitry Andric // Check if we can split this live range around a compact region.
10700b57cec5SDimitry Andric bool HasCompact = calcCompactRegion(GlobalCand.front());
10710b57cec5SDimitry Andric if (HasCompact) {
10720b57cec5SDimitry Andric // Yes, keep GlobalCand[0] as the compact region candidate.
10730b57cec5SDimitry Andric NumCands = 1;
10745f757f3fSDimitry Andric BestCost = BlockFrequency::max();
10750b57cec5SDimitry Andric } else {
10760b57cec5SDimitry Andric // No benefit from the compact region, our fallback will be per-block
10770b57cec5SDimitry Andric // splitting. Make sure we find a solution that is cheaper than spilling.
10780b57cec5SDimitry Andric BestCost = SpillCost;
10795f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "Cost of isolating all blocks = "
10805f757f3fSDimitry Andric << printBlockFreq(*MBFI, BestCost) << '\n');
10810b57cec5SDimitry Andric }
10820b57cec5SDimitry Andric
108381ad6265SDimitry Andric unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
108481ad6265SDimitry Andric NumCands, false /*IgnoreCSR*/);
10850b57cec5SDimitry Andric
10860b57cec5SDimitry Andric // No solutions found, fall back to single block splitting.
10870b57cec5SDimitry Andric if (!HasCompact && BestCand == NoCand)
1088e8d8bef9SDimitry Andric return MCRegister::NoRegister;
10890b57cec5SDimitry Andric
10900b57cec5SDimitry Andric return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric
10935f757f3fSDimitry Andric unsigned
calculateRegionSplitCostAroundReg(MCPhysReg PhysReg,AllocationOrder & Order,BlockFrequency & BestCost,unsigned & NumCands,unsigned & BestCand)10945f757f3fSDimitry Andric RAGreedy::calculateRegionSplitCostAroundReg(MCPhysReg PhysReg,
10950b57cec5SDimitry Andric AllocationOrder &Order,
10960b57cec5SDimitry Andric BlockFrequency &BestCost,
109781ad6265SDimitry Andric unsigned &NumCands,
10985f757f3fSDimitry Andric unsigned &BestCand) {
10990b57cec5SDimitry Andric // Discard bad candidates before we run out of interference cache cursors.
11000b57cec5SDimitry Andric // This will only affect register classes with a lot of registers (>32).
11010b57cec5SDimitry Andric if (NumCands == IntfCache.getMaxCursors()) {
11020b57cec5SDimitry Andric unsigned WorstCount = ~0u;
11030b57cec5SDimitry Andric unsigned Worst = 0;
1104e8d8bef9SDimitry Andric for (unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1105e8d8bef9SDimitry Andric if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
11060b57cec5SDimitry Andric continue;
1107e8d8bef9SDimitry Andric unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
11080b57cec5SDimitry Andric if (Count < WorstCount) {
1109e8d8bef9SDimitry Andric Worst = CandIndex;
11100b57cec5SDimitry Andric WorstCount = Count;
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric }
11130b57cec5SDimitry Andric --NumCands;
11140b57cec5SDimitry Andric GlobalCand[Worst] = GlobalCand[NumCands];
11150b57cec5SDimitry Andric if (BestCand == NumCands)
11160b57cec5SDimitry Andric BestCand = Worst;
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andric if (GlobalCand.size() <= NumCands)
11200b57cec5SDimitry Andric GlobalCand.resize(NumCands+1);
11210b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[NumCands];
11220b57cec5SDimitry Andric Cand.reset(IntfCache, PhysReg);
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andric SpillPlacer->prepare(Cand.LiveBundles);
11250b57cec5SDimitry Andric BlockFrequency Cost;
11260b57cec5SDimitry Andric if (!addSplitConstraints(Cand.Intf, Cost)) {
11270b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << "\tno positive bundles\n");
11285f757f3fSDimitry Andric return BestCand;
11290b57cec5SDimitry Andric }
11305f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI)
11315f757f3fSDimitry Andric << "\tstatic = " << printBlockFreq(*MBFI, Cost));
11320b57cec5SDimitry Andric if (Cost >= BestCost) {
11330b57cec5SDimitry Andric LLVM_DEBUG({
11340b57cec5SDimitry Andric if (BestCand == NoCand)
11350b57cec5SDimitry Andric dbgs() << " worse than no bundles\n";
11360b57cec5SDimitry Andric else
11370b57cec5SDimitry Andric dbgs() << " worse than "
11380b57cec5SDimitry Andric << printReg(GlobalCand[BestCand].PhysReg, TRI) << '\n';
11390b57cec5SDimitry Andric });
11405f757f3fSDimitry Andric return BestCand;
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric if (!growRegion(Cand)) {
11430b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
11445f757f3fSDimitry Andric return BestCand;
11450b57cec5SDimitry Andric }
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andric SpillPlacer->finish();
11480b57cec5SDimitry Andric
11490b57cec5SDimitry Andric // No live bundles, defer to splitSingleBlocks().
11500b57cec5SDimitry Andric if (!Cand.LiveBundles.any()) {
11510b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " no bundles.\n");
11525f757f3fSDimitry Andric return BestCand;
11530b57cec5SDimitry Andric }
11540b57cec5SDimitry Andric
115581ad6265SDimitry Andric Cost += calcGlobalSplitCost(Cand, Order);
11560b57cec5SDimitry Andric LLVM_DEBUG({
11575f757f3fSDimitry Andric dbgs() << ", total = " << printBlockFreq(*MBFI, Cost) << " with bundles";
1158e8d8bef9SDimitry Andric for (int I : Cand.LiveBundles.set_bits())
1159e8d8bef9SDimitry Andric dbgs() << " EB#" << I;
11600b57cec5SDimitry Andric dbgs() << ".\n";
11610b57cec5SDimitry Andric });
11620b57cec5SDimitry Andric if (Cost < BestCost) {
11630b57cec5SDimitry Andric BestCand = NumCands;
11640b57cec5SDimitry Andric BestCost = Cost;
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric ++NumCands;
11675f757f3fSDimitry Andric
11685f757f3fSDimitry Andric return BestCand;
11695f757f3fSDimitry Andric }
11705f757f3fSDimitry Andric
calculateRegionSplitCost(const LiveInterval & VirtReg,AllocationOrder & Order,BlockFrequency & BestCost,unsigned & NumCands,bool IgnoreCSR)11715f757f3fSDimitry Andric unsigned RAGreedy::calculateRegionSplitCost(const LiveInterval &VirtReg,
11725f757f3fSDimitry Andric AllocationOrder &Order,
11735f757f3fSDimitry Andric BlockFrequency &BestCost,
11745f757f3fSDimitry Andric unsigned &NumCands,
11755f757f3fSDimitry Andric bool IgnoreCSR) {
11765f757f3fSDimitry Andric unsigned BestCand = NoCand;
11775f757f3fSDimitry Andric for (MCPhysReg PhysReg : Order) {
11785f757f3fSDimitry Andric assert(PhysReg);
11795f757f3fSDimitry Andric if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
11805f757f3fSDimitry Andric continue;
11815f757f3fSDimitry Andric
11825f757f3fSDimitry Andric calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
11835f757f3fSDimitry Andric BestCand);
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andric return BestCand;
11870b57cec5SDimitry Andric }
11880b57cec5SDimitry Andric
doRegionSplit(const LiveInterval & VirtReg,unsigned BestCand,bool HasCompact,SmallVectorImpl<Register> & NewVRegs)118981ad6265SDimitry Andric unsigned RAGreedy::doRegionSplit(const LiveInterval &VirtReg, unsigned BestCand,
11900b57cec5SDimitry Andric bool HasCompact,
11915ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
11920b57cec5SDimitry Andric SmallVector<unsigned, 8> UsedCands;
11930b57cec5SDimitry Andric // Prepare split editor.
11940b57cec5SDimitry Andric LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
11950b57cec5SDimitry Andric SE->reset(LREdit, SplitSpillMode);
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andric // Assign all edge bundles to the preferred candidate, or NoCand.
11980b57cec5SDimitry Andric BundleCand.assign(Bundles->getNumBundles(), NoCand);
11990b57cec5SDimitry Andric
12000b57cec5SDimitry Andric // Assign bundles for the best candidate region.
12010b57cec5SDimitry Andric if (BestCand != NoCand) {
12020b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand[BestCand];
12030b57cec5SDimitry Andric if (unsigned B = Cand.getBundles(BundleCand, BestCand)) {
12040b57cec5SDimitry Andric UsedCands.push_back(BestCand);
12050b57cec5SDimitry Andric Cand.IntvIdx = SE->openIntv();
12060b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Split for " << printReg(Cand.PhysReg, TRI) << " in "
12070b57cec5SDimitry Andric << B << " bundles, intv " << Cand.IntvIdx << ".\n");
12080b57cec5SDimitry Andric (void)B;
12090b57cec5SDimitry Andric }
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric
12120b57cec5SDimitry Andric // Assign bundles for the compact region.
12130b57cec5SDimitry Andric if (HasCompact) {
12140b57cec5SDimitry Andric GlobalSplitCandidate &Cand = GlobalCand.front();
12150b57cec5SDimitry Andric assert(!Cand.PhysReg && "Compact region has no physreg");
12160b57cec5SDimitry Andric if (unsigned B = Cand.getBundles(BundleCand, 0)) {
12170b57cec5SDimitry Andric UsedCands.push_back(0);
12180b57cec5SDimitry Andric Cand.IntvIdx = SE->openIntv();
12190b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Split for compact region in " << B
12200b57cec5SDimitry Andric << " bundles, intv " << Cand.IntvIdx << ".\n");
12210b57cec5SDimitry Andric (void)B;
12220b57cec5SDimitry Andric }
12230b57cec5SDimitry Andric }
12240b57cec5SDimitry Andric
12250b57cec5SDimitry Andric splitAroundRegion(LREdit, UsedCands);
12260b57cec5SDimitry Andric return 0;
12270b57cec5SDimitry Andric }
12280b57cec5SDimitry Andric
12295f757f3fSDimitry Andric // VirtReg has a physical Hint, this function tries to split VirtReg around
12305f757f3fSDimitry Andric // Hint if we can place new COPY instructions in cold blocks.
trySplitAroundHintReg(MCPhysReg Hint,const LiveInterval & VirtReg,SmallVectorImpl<Register> & NewVRegs,AllocationOrder & Order)12315f757f3fSDimitry Andric bool RAGreedy::trySplitAroundHintReg(MCPhysReg Hint,
12325f757f3fSDimitry Andric const LiveInterval &VirtReg,
12335f757f3fSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
12345f757f3fSDimitry Andric AllocationOrder &Order) {
12355f757f3fSDimitry Andric // Split the VirtReg may generate COPY instructions in multiple cold basic
12365f757f3fSDimitry Andric // blocks, and increase code size. So we avoid it when the function is
12375f757f3fSDimitry Andric // optimized for size.
12385f757f3fSDimitry Andric if (MF->getFunction().hasOptSize())
12395f757f3fSDimitry Andric return false;
12405f757f3fSDimitry Andric
12415f757f3fSDimitry Andric // Don't allow repeated splitting as a safe guard against looping.
12425f757f3fSDimitry Andric if (ExtraInfo->getStage(VirtReg) >= RS_Split2)
12435f757f3fSDimitry Andric return false;
12445f757f3fSDimitry Andric
12455f757f3fSDimitry Andric BlockFrequency Cost = BlockFrequency(0);
12465f757f3fSDimitry Andric Register Reg = VirtReg.reg();
12475f757f3fSDimitry Andric
12485f757f3fSDimitry Andric // Compute the cost of assigning a non Hint physical register to VirtReg.
12495f757f3fSDimitry Andric // We define it as the total frequency of broken COPY instructions to/from
12505f757f3fSDimitry Andric // Hint register, and after split, they can be deleted.
12515f757f3fSDimitry Andric for (const MachineInstr &Instr : MRI->reg_nodbg_instructions(Reg)) {
12525f757f3fSDimitry Andric if (!TII->isFullCopyInstr(Instr))
12535f757f3fSDimitry Andric continue;
12545f757f3fSDimitry Andric Register OtherReg = Instr.getOperand(1).getReg();
12555f757f3fSDimitry Andric if (OtherReg == Reg) {
12565f757f3fSDimitry Andric OtherReg = Instr.getOperand(0).getReg();
12575f757f3fSDimitry Andric if (OtherReg == Reg)
12585f757f3fSDimitry Andric continue;
12595f757f3fSDimitry Andric // Check if VirtReg interferes with OtherReg after this COPY instruction.
12605f757f3fSDimitry Andric if (VirtReg.liveAt(LIS->getInstructionIndex(Instr).getRegSlot()))
12615f757f3fSDimitry Andric continue;
12625f757f3fSDimitry Andric }
12635f757f3fSDimitry Andric MCRegister OtherPhysReg =
12645f757f3fSDimitry Andric OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
12655f757f3fSDimitry Andric if (OtherPhysReg == Hint)
12665f757f3fSDimitry Andric Cost += MBFI->getBlockFreq(Instr.getParent());
12675f757f3fSDimitry Andric }
12685f757f3fSDimitry Andric
12695f757f3fSDimitry Andric // Decrease the cost so it will be split in colder blocks.
12705f757f3fSDimitry Andric BranchProbability Threshold(SplitThresholdForRegWithHint, 100);
12715f757f3fSDimitry Andric Cost *= Threshold;
12725f757f3fSDimitry Andric if (Cost == BlockFrequency(0))
12735f757f3fSDimitry Andric return false;
12745f757f3fSDimitry Andric
12755f757f3fSDimitry Andric unsigned NumCands = 0;
12765f757f3fSDimitry Andric unsigned BestCand = NoCand;
12775f757f3fSDimitry Andric SA->analyze(&VirtReg);
12785f757f3fSDimitry Andric calculateRegionSplitCostAroundReg(Hint, Order, Cost, NumCands, BestCand);
12795f757f3fSDimitry Andric if (BestCand == NoCand)
12805f757f3fSDimitry Andric return false;
12815f757f3fSDimitry Andric
12825f757f3fSDimitry Andric doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);
12835f757f3fSDimitry Andric return true;
12845f757f3fSDimitry Andric }
12855f757f3fSDimitry Andric
12860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12870b57cec5SDimitry Andric // Per-Block Splitting
12880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12890b57cec5SDimitry Andric
12900b57cec5SDimitry Andric /// tryBlockSplit - Split a global live range around every block with uses. This
12910b57cec5SDimitry Andric /// creates a lot of local live ranges, that will be split by tryLocalSplit if
12920b57cec5SDimitry Andric /// they don't allocate.
tryBlockSplit(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)129381ad6265SDimitry Andric unsigned RAGreedy::tryBlockSplit(const LiveInterval &VirtReg,
129481ad6265SDimitry Andric AllocationOrder &Order,
12955ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
12960b57cec5SDimitry Andric assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed");
1297e8d8bef9SDimitry Andric Register Reg = VirtReg.reg();
12980b57cec5SDimitry Andric bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
12990b57cec5SDimitry Andric LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
13000b57cec5SDimitry Andric SE->reset(LREdit, SplitSpillMode);
13010b57cec5SDimitry Andric ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
1302e8d8bef9SDimitry Andric for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
13030b57cec5SDimitry Andric if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
13040b57cec5SDimitry Andric SE->splitSingleBlock(BI);
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric // No blocks were split.
13070b57cec5SDimitry Andric if (LREdit.empty())
13080b57cec5SDimitry Andric return 0;
13090b57cec5SDimitry Andric
13100b57cec5SDimitry Andric // We did split for some blocks.
13110b57cec5SDimitry Andric SmallVector<unsigned, 8> IntvMap;
13120b57cec5SDimitry Andric SE->finish(&IntvMap);
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andric // Tell LiveDebugVariables about the new ranges.
13150b57cec5SDimitry Andric DebugVars->splitRegister(Reg, LREdit.regs(), *LIS);
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric // Sort out the new intervals created by splitting. The remainder interval
13180b57cec5SDimitry Andric // goes straight to spilling, the new local ranges get to stay RS_New.
1319e8d8bef9SDimitry Andric for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
13204824e7fdSDimitry Andric const LiveInterval &LI = LIS->getInterval(LREdit.get(I));
13210eae32dcSDimitry Andric if (ExtraInfo->getOrInitStage(LI.reg()) == RS_New && IntvMap[I] == 0)
13220eae32dcSDimitry Andric ExtraInfo->setStage(LI, RS_Spill);
13230b57cec5SDimitry Andric }
13240b57cec5SDimitry Andric
13250b57cec5SDimitry Andric if (VerifyEnabled)
13260b57cec5SDimitry Andric MF->verify(this, "After splitting live range around basic blocks");
13270b57cec5SDimitry Andric return 0;
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric
13300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13310b57cec5SDimitry Andric // Per-Instruction Splitting
13320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13330b57cec5SDimitry Andric
13340b57cec5SDimitry Andric /// Get the number of allocatable registers that match the constraints of \p Reg
13350b57cec5SDimitry Andric /// on \p MI and that are also in \p SuperRC.
getNumAllocatableRegsForConstraints(const MachineInstr * MI,Register Reg,const TargetRegisterClass * SuperRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,const RegisterClassInfo & RCI)13360b57cec5SDimitry Andric static unsigned getNumAllocatableRegsForConstraints(
1337e8d8bef9SDimitry Andric const MachineInstr *MI, Register Reg, const TargetRegisterClass *SuperRC,
13380b57cec5SDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
13390b57cec5SDimitry Andric const RegisterClassInfo &RCI) {
13400b57cec5SDimitry Andric assert(SuperRC && "Invalid register class");
13410b57cec5SDimitry Andric
13420b57cec5SDimitry Andric const TargetRegisterClass *ConstrainedRC =
13430b57cec5SDimitry Andric MI->getRegClassConstraintEffectForVReg(Reg, SuperRC, TII, TRI,
13440b57cec5SDimitry Andric /* ExploreBundle */ true);
13450b57cec5SDimitry Andric if (!ConstrainedRC)
13460b57cec5SDimitry Andric return 0;
13470b57cec5SDimitry Andric return RCI.getNumAllocatableRegs(ConstrainedRC);
13480b57cec5SDimitry Andric }
13490b57cec5SDimitry Andric
getInstReadLaneMask(const MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI,const MachineInstr & FirstMI,Register Reg)1350bdd1243dSDimitry Andric static LaneBitmask getInstReadLaneMask(const MachineRegisterInfo &MRI,
1351bdd1243dSDimitry Andric const TargetRegisterInfo &TRI,
13525f757f3fSDimitry Andric const MachineInstr &FirstMI,
13535f757f3fSDimitry Andric Register Reg) {
1354bdd1243dSDimitry Andric LaneBitmask Mask;
13555f757f3fSDimitry Andric SmallVector<std::pair<MachineInstr *, unsigned>, 8> Ops;
13565f757f3fSDimitry Andric (void)AnalyzeVirtRegInBundle(const_cast<MachineInstr &>(FirstMI), Reg, &Ops);
1357bdd1243dSDimitry Andric
13585f757f3fSDimitry Andric for (auto [MI, OpIdx] : Ops) {
13595f757f3fSDimitry Andric const MachineOperand &MO = MI->getOperand(OpIdx);
13605f757f3fSDimitry Andric assert(MO.isReg() && MO.getReg() == Reg);
1361bdd1243dSDimitry Andric unsigned SubReg = MO.getSubReg();
1362bdd1243dSDimitry Andric if (SubReg == 0 && MO.isUse()) {
13635f757f3fSDimitry Andric if (MO.isUndef())
1364bdd1243dSDimitry Andric continue;
13655f757f3fSDimitry Andric return MRI.getMaxLaneMaskForVReg(Reg);
1366bdd1243dSDimitry Andric }
1367bdd1243dSDimitry Andric
1368bdd1243dSDimitry Andric LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg);
1369bdd1243dSDimitry Andric if (MO.isDef()) {
1370bdd1243dSDimitry Andric if (!MO.isUndef())
1371bdd1243dSDimitry Andric Mask |= ~SubRegMask;
1372bdd1243dSDimitry Andric } else
1373bdd1243dSDimitry Andric Mask |= SubRegMask;
1374bdd1243dSDimitry Andric }
1375bdd1243dSDimitry Andric
1376bdd1243dSDimitry Andric return Mask;
1377bdd1243dSDimitry Andric }
1378bdd1243dSDimitry Andric
1379bdd1243dSDimitry Andric /// Return true if \p MI at \P Use reads a subset of the lanes live in \p
1380bdd1243dSDimitry Andric /// VirtReg.
readsLaneSubset(const MachineRegisterInfo & MRI,const MachineInstr * MI,const LiveInterval & VirtReg,const TargetRegisterInfo * TRI,SlotIndex Use,const TargetInstrInfo * TII)1381bdd1243dSDimitry Andric static bool readsLaneSubset(const MachineRegisterInfo &MRI,
1382bdd1243dSDimitry Andric const MachineInstr *MI, const LiveInterval &VirtReg,
13835f757f3fSDimitry Andric const TargetRegisterInfo *TRI, SlotIndex Use,
13845f757f3fSDimitry Andric const TargetInstrInfo *TII) {
13855f757f3fSDimitry Andric // Early check the common case. Beware of the semi-formed bundles SplitKit
13865f757f3fSDimitry Andric // creates by setting the bundle flag on copies without a matching BUNDLE.
13875f757f3fSDimitry Andric
13885f757f3fSDimitry Andric auto DestSrc = TII->isCopyInstr(*MI);
13895f757f3fSDimitry Andric if (DestSrc && !MI->isBundled() &&
13905f757f3fSDimitry Andric DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1391bdd1243dSDimitry Andric return false;
1392bdd1243dSDimitry Andric
1393bdd1243dSDimitry Andric // FIXME: We're only considering uses, but should be consider defs too?
1394bdd1243dSDimitry Andric LaneBitmask ReadMask = getInstReadLaneMask(MRI, *TRI, *MI, VirtReg.reg());
1395bdd1243dSDimitry Andric
1396bdd1243dSDimitry Andric LaneBitmask LiveAtMask;
1397bdd1243dSDimitry Andric for (const LiveInterval::SubRange &S : VirtReg.subranges()) {
1398bdd1243dSDimitry Andric if (S.liveAt(Use))
1399bdd1243dSDimitry Andric LiveAtMask |= S.LaneMask;
1400bdd1243dSDimitry Andric }
1401bdd1243dSDimitry Andric
1402bdd1243dSDimitry Andric // If the live lanes aren't different from the lanes used by the instruction,
1403bdd1243dSDimitry Andric // this doesn't help.
1404bdd1243dSDimitry Andric return (ReadMask & ~(LiveAtMask & TRI->getCoveringLanes())).any();
1405bdd1243dSDimitry Andric }
1406bdd1243dSDimitry Andric
14070b57cec5SDimitry Andric /// tryInstructionSplit - Split a live range around individual instructions.
14080b57cec5SDimitry Andric /// This is normally not worthwhile since the spiller is doing essentially the
14090b57cec5SDimitry Andric /// same thing. However, when the live range is in a constrained register
14100b57cec5SDimitry Andric /// class, it may help to insert copies such that parts of the live range can
14110b57cec5SDimitry Andric /// be moved to a larger register class.
14120b57cec5SDimitry Andric ///
14130b57cec5SDimitry Andric /// This is similar to spilling to a larger register class.
tryInstructionSplit(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)141481ad6265SDimitry Andric unsigned RAGreedy::tryInstructionSplit(const LiveInterval &VirtReg,
141581ad6265SDimitry Andric AllocationOrder &Order,
14165ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
1417e8d8bef9SDimitry Andric const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
14180b57cec5SDimitry Andric // There is no point to this if there are no larger sub-classes.
1419bdd1243dSDimitry Andric
1420bdd1243dSDimitry Andric bool SplitSubClass = true;
1421bdd1243dSDimitry Andric if (!RegClassInfo.isProperSubClass(CurRC)) {
1422bdd1243dSDimitry Andric if (!VirtReg.hasSubRanges())
14230b57cec5SDimitry Andric return 0;
1424bdd1243dSDimitry Andric SplitSubClass = false;
1425bdd1243dSDimitry Andric }
14260b57cec5SDimitry Andric
14270b57cec5SDimitry Andric // Always enable split spill mode, since we're effectively spilling to a
14280b57cec5SDimitry Andric // register.
14290b57cec5SDimitry Andric LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
14300b57cec5SDimitry Andric SE->reset(LREdit, SplitEditor::SM_Size);
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andric ArrayRef<SlotIndex> Uses = SA->getUseSlots();
14330b57cec5SDimitry Andric if (Uses.size() <= 1)
14340b57cec5SDimitry Andric return 0;
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Split around " << Uses.size()
14370b57cec5SDimitry Andric << " individual instrs.\n");
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andric const TargetRegisterClass *SuperRC =
14400b57cec5SDimitry Andric TRI->getLargestLegalSuperClass(CurRC, *MF);
144181ad6265SDimitry Andric unsigned SuperRCNumAllocatableRegs =
144281ad6265SDimitry Andric RegClassInfo.getNumAllocatableRegs(SuperRC);
14430b57cec5SDimitry Andric // Split around every non-copy instruction if this split will relax
14440b57cec5SDimitry Andric // the constraints on the virtual register.
14450b57cec5SDimitry Andric // Otherwise, splitting just inserts uncoalescable copies that do not help
14460b57cec5SDimitry Andric // the allocation.
1447349cc55cSDimitry Andric for (const SlotIndex Use : Uses) {
1448bdd1243dSDimitry Andric if (const MachineInstr *MI = Indexes->getInstructionFromIndex(Use)) {
14495f757f3fSDimitry Andric if (TII->isFullCopyInstr(*MI) ||
1450bdd1243dSDimitry Andric (SplitSubClass &&
14510b57cec5SDimitry Andric SuperRCNumAllocatableRegs ==
1452e8d8bef9SDimitry Andric getNumAllocatableRegsForConstraints(MI, VirtReg.reg(), SuperRC,
1453bdd1243dSDimitry Andric TII, TRI, RegClassInfo)) ||
1454bdd1243dSDimitry Andric // TODO: Handle split for subranges with subclass constraints?
1455bdd1243dSDimitry Andric (!SplitSubClass && VirtReg.hasSubRanges() &&
14565f757f3fSDimitry Andric !readsLaneSubset(*MRI, MI, VirtReg, TRI, Use, TII))) {
1457e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << " skip:\t" << Use << '\t' << *MI);
14580b57cec5SDimitry Andric continue;
14590b57cec5SDimitry Andric }
1460bdd1243dSDimitry Andric }
14610b57cec5SDimitry Andric SE->openIntv();
1462e8d8bef9SDimitry Andric SlotIndex SegStart = SE->enterIntvBefore(Use);
1463e8d8bef9SDimitry Andric SlotIndex SegStop = SE->leaveIntvAfter(Use);
14640b57cec5SDimitry Andric SE->useIntv(SegStart, SegStop);
14650b57cec5SDimitry Andric }
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric if (LREdit.empty()) {
14680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "All uses were copies.\n");
14690b57cec5SDimitry Andric return 0;
14700b57cec5SDimitry Andric }
14710b57cec5SDimitry Andric
14720b57cec5SDimitry Andric SmallVector<unsigned, 8> IntvMap;
14730b57cec5SDimitry Andric SE->finish(&IntvMap);
1474e8d8bef9SDimitry Andric DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
14750b57cec5SDimitry Andric // Assign all new registers to RS_Spill. This was the last chance.
14760eae32dcSDimitry Andric ExtraInfo->setStage(LREdit.begin(), LREdit.end(), RS_Spill);
14770b57cec5SDimitry Andric return 0;
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14810b57cec5SDimitry Andric // Local Splitting
14820b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14830b57cec5SDimitry Andric
14840b57cec5SDimitry Andric /// calcGapWeights - Compute the maximum spill weight that needs to be evicted
14850b57cec5SDimitry Andric /// in order to use PhysReg between two entries in SA->UseSlots.
14860b57cec5SDimitry Andric ///
1487e8d8bef9SDimitry Andric /// GapWeight[I] represents the gap between UseSlots[I] and UseSlots[I + 1].
14880b57cec5SDimitry Andric ///
calcGapWeights(MCRegister PhysReg,SmallVectorImpl<float> & GapWeight)1489e8d8bef9SDimitry Andric void RAGreedy::calcGapWeights(MCRegister PhysReg,
14900b57cec5SDimitry Andric SmallVectorImpl<float> &GapWeight) {
14910b57cec5SDimitry Andric assert(SA->getUseBlocks().size() == 1 && "Not a local interval");
14920b57cec5SDimitry Andric const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
14930b57cec5SDimitry Andric ArrayRef<SlotIndex> Uses = SA->getUseSlots();
14940b57cec5SDimitry Andric const unsigned NumGaps = Uses.size()-1;
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andric // Start and end points for the interference check.
14970b57cec5SDimitry Andric SlotIndex StartIdx =
14980b57cec5SDimitry Andric BI.LiveIn ? BI.FirstInstr.getBaseIndex() : BI.FirstInstr;
14990b57cec5SDimitry Andric SlotIndex StopIdx =
15000b57cec5SDimitry Andric BI.LiveOut ? BI.LastInstr.getBoundaryIndex() : BI.LastInstr;
15010b57cec5SDimitry Andric
15020b57cec5SDimitry Andric GapWeight.assign(NumGaps, 0.0f);
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andric // Add interference from each overlapping register.
150506c3fb27SDimitry Andric for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
150606c3fb27SDimitry Andric if (!Matrix->query(const_cast<LiveInterval &>(SA->getParent()), Unit)
15070b57cec5SDimitry Andric .checkInterference())
15080b57cec5SDimitry Andric continue;
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andric // We know that VirtReg is a continuous interval from FirstInstr to
15110b57cec5SDimitry Andric // LastInstr, so we don't need InterferenceQuery.
15120b57cec5SDimitry Andric //
15130b57cec5SDimitry Andric // Interference that overlaps an instruction is counted in both gaps
15140b57cec5SDimitry Andric // surrounding the instruction. The exception is interference before
15150b57cec5SDimitry Andric // StartIdx and after StopIdx.
15160b57cec5SDimitry Andric //
15170b57cec5SDimitry Andric LiveIntervalUnion::SegmentIter IntI =
151806c3fb27SDimitry Andric Matrix->getLiveUnions()[Unit].find(StartIdx);
15190b57cec5SDimitry Andric for (unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
15200b57cec5SDimitry Andric // Skip the gaps before IntI.
15210b57cec5SDimitry Andric while (Uses[Gap+1].getBoundaryIndex() < IntI.start())
15220b57cec5SDimitry Andric if (++Gap == NumGaps)
15230b57cec5SDimitry Andric break;
15240b57cec5SDimitry Andric if (Gap == NumGaps)
15250b57cec5SDimitry Andric break;
15260b57cec5SDimitry Andric
15270b57cec5SDimitry Andric // Update the gaps covered by IntI.
1528e8d8bef9SDimitry Andric const float weight = IntI.value()->weight();
15290b57cec5SDimitry Andric for (; Gap != NumGaps; ++Gap) {
15300b57cec5SDimitry Andric GapWeight[Gap] = std::max(GapWeight[Gap], weight);
15310b57cec5SDimitry Andric if (Uses[Gap+1].getBaseIndex() >= IntI.stop())
15320b57cec5SDimitry Andric break;
15330b57cec5SDimitry Andric }
15340b57cec5SDimitry Andric if (Gap == NumGaps)
15350b57cec5SDimitry Andric break;
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric }
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andric // Add fixed interference.
154006c3fb27SDimitry Andric for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
154106c3fb27SDimitry Andric const LiveRange &LR = LIS->getRegUnit(Unit);
15420b57cec5SDimitry Andric LiveRange::const_iterator I = LR.find(StartIdx);
15430b57cec5SDimitry Andric LiveRange::const_iterator E = LR.end();
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric // Same loop as above. Mark any overlapped gaps as HUGE_VALF.
15460b57cec5SDimitry Andric for (unsigned Gap = 0; I != E && I->start < StopIdx; ++I) {
15470b57cec5SDimitry Andric while (Uses[Gap+1].getBoundaryIndex() < I->start)
15480b57cec5SDimitry Andric if (++Gap == NumGaps)
15490b57cec5SDimitry Andric break;
15500b57cec5SDimitry Andric if (Gap == NumGaps)
15510b57cec5SDimitry Andric break;
15520b57cec5SDimitry Andric
15530b57cec5SDimitry Andric for (; Gap != NumGaps; ++Gap) {
15540b57cec5SDimitry Andric GapWeight[Gap] = huge_valf;
15550b57cec5SDimitry Andric if (Uses[Gap+1].getBaseIndex() >= I->end)
15560b57cec5SDimitry Andric break;
15570b57cec5SDimitry Andric }
15580b57cec5SDimitry Andric if (Gap == NumGaps)
15590b57cec5SDimitry Andric break;
15600b57cec5SDimitry Andric }
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric }
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric /// tryLocalSplit - Try to split VirtReg into smaller intervals inside its only
15650b57cec5SDimitry Andric /// basic block.
15660b57cec5SDimitry Andric ///
tryLocalSplit(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)156781ad6265SDimitry Andric unsigned RAGreedy::tryLocalSplit(const LiveInterval &VirtReg,
156881ad6265SDimitry Andric AllocationOrder &Order,
15695ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
15700b57cec5SDimitry Andric // TODO: the function currently only handles a single UseBlock; it should be
15710b57cec5SDimitry Andric // possible to generalize.
15720b57cec5SDimitry Andric if (SA->getUseBlocks().size() != 1)
15730b57cec5SDimitry Andric return 0;
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andric // Note that it is possible to have an interval that is live-in or live-out
15780b57cec5SDimitry Andric // while only covering a single block - A phi-def can use undef values from
15790b57cec5SDimitry Andric // predecessors, and the block could be a single-block loop.
15800b57cec5SDimitry Andric // We don't bother doing anything clever about such a case, we simply assume
15810b57cec5SDimitry Andric // that the interval is continuous from FirstInstr to LastInstr. We should
15820b57cec5SDimitry Andric // make sure that we don't do anything illegal to such an interval, though.
15830b57cec5SDimitry Andric
15840b57cec5SDimitry Andric ArrayRef<SlotIndex> Uses = SA->getUseSlots();
15850b57cec5SDimitry Andric if (Uses.size() <= 2)
15860b57cec5SDimitry Andric return 0;
15870b57cec5SDimitry Andric const unsigned NumGaps = Uses.size()-1;
15880b57cec5SDimitry Andric
15890b57cec5SDimitry Andric LLVM_DEBUG({
15900b57cec5SDimitry Andric dbgs() << "tryLocalSplit: ";
1591e8d8bef9SDimitry Andric for (const auto &Use : Uses)
1592e8d8bef9SDimitry Andric dbgs() << ' ' << Use;
15930b57cec5SDimitry Andric dbgs() << '\n';
15940b57cec5SDimitry Andric });
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andric // If VirtReg is live across any register mask operands, compute a list of
15970b57cec5SDimitry Andric // gaps with register masks.
15980b57cec5SDimitry Andric SmallVector<unsigned, 8> RegMaskGaps;
15990b57cec5SDimitry Andric if (Matrix->checkRegMaskInterference(VirtReg)) {
16000b57cec5SDimitry Andric // Get regmask slots for the whole block.
16010b57cec5SDimitry Andric ArrayRef<SlotIndex> RMS = LIS->getRegMaskSlotsInBlock(BI.MBB->getNumber());
16020b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << RMS.size() << " regmasks in block:");
16030b57cec5SDimitry Andric // Constrain to VirtReg's live range.
1604e8d8bef9SDimitry Andric unsigned RI =
16050b57cec5SDimitry Andric llvm::lower_bound(RMS, Uses.front().getRegSlot()) - RMS.begin();
1606e8d8bef9SDimitry Andric unsigned RE = RMS.size();
1607e8d8bef9SDimitry Andric for (unsigned I = 0; I != NumGaps && RI != RE; ++I) {
1608e8d8bef9SDimitry Andric // Look for Uses[I] <= RMS <= Uses[I + 1].
1609e8d8bef9SDimitry Andric assert(!SlotIndex::isEarlierInstr(RMS[RI], Uses[I]));
1610e8d8bef9SDimitry Andric if (SlotIndex::isEarlierInstr(Uses[I + 1], RMS[RI]))
16110b57cec5SDimitry Andric continue;
16120b57cec5SDimitry Andric // Skip a regmask on the same instruction as the last use. It doesn't
16130b57cec5SDimitry Andric // overlap the live range.
1614e8d8bef9SDimitry Andric if (SlotIndex::isSameInstr(Uses[I + 1], RMS[RI]) && I + 1 == NumGaps)
16150b57cec5SDimitry Andric break;
1616e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << ' ' << RMS[RI] << ':' << Uses[I] << '-'
1617e8d8bef9SDimitry Andric << Uses[I + 1]);
1618e8d8bef9SDimitry Andric RegMaskGaps.push_back(I);
16190b57cec5SDimitry Andric // Advance ri to the next gap. A regmask on one of the uses counts in
16200b57cec5SDimitry Andric // both gaps.
1621e8d8bef9SDimitry Andric while (RI != RE && SlotIndex::isEarlierInstr(RMS[RI], Uses[I + 1]))
1622e8d8bef9SDimitry Andric ++RI;
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << '\n');
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric
16270b57cec5SDimitry Andric // Since we allow local split results to be split again, there is a risk of
16280b57cec5SDimitry Andric // creating infinite loops. It is tempting to require that the new live
16290b57cec5SDimitry Andric // ranges have less instructions than the original. That would guarantee
16300b57cec5SDimitry Andric // convergence, but it is too strict. A live range with 3 instructions can be
16310b57cec5SDimitry Andric // split 2+3 (including the COPY), and we want to allow that.
16320b57cec5SDimitry Andric //
16330b57cec5SDimitry Andric // Instead we use these rules:
16340b57cec5SDimitry Andric //
16350b57cec5SDimitry Andric // 1. Allow any split for ranges with getStage() < RS_Split2. (Except for the
16360b57cec5SDimitry Andric // noop split, of course).
16370b57cec5SDimitry Andric // 2. Require progress be made for ranges with getStage() == RS_Split2. All
16380b57cec5SDimitry Andric // the new ranges must have fewer instructions than before the split.
16390b57cec5SDimitry Andric // 3. New ranges with the same number of instructions are marked RS_Split2,
16400b57cec5SDimitry Andric // smaller ranges are marked RS_New.
16410b57cec5SDimitry Andric //
16420b57cec5SDimitry Andric // These rules allow a 3 -> 2+3 split once, which we need. They also prevent
16430b57cec5SDimitry Andric // excessive splitting and infinite loops.
16440b57cec5SDimitry Andric //
16450eae32dcSDimitry Andric bool ProgressRequired = ExtraInfo->getStage(VirtReg) >= RS_Split2;
16460b57cec5SDimitry Andric
16470b57cec5SDimitry Andric // Best split candidate.
16480b57cec5SDimitry Andric unsigned BestBefore = NumGaps;
16490b57cec5SDimitry Andric unsigned BestAfter = 0;
16500b57cec5SDimitry Andric float BestDiff = 0;
16510b57cec5SDimitry Andric
16520b57cec5SDimitry Andric const float blockFreq =
16530b57cec5SDimitry Andric SpillPlacer->getBlockFrequency(BI.MBB->getNumber()).getFrequency() *
16545f757f3fSDimitry Andric (1.0f / MBFI->getEntryFreq().getFrequency());
16550b57cec5SDimitry Andric SmallVector<float, 8> GapWeight;
16560b57cec5SDimitry Andric
1657e8d8bef9SDimitry Andric for (MCPhysReg PhysReg : Order) {
1658e8d8bef9SDimitry Andric assert(PhysReg);
16590b57cec5SDimitry Andric // Keep track of the largest spill weight that would need to be evicted in
1660e8d8bef9SDimitry Andric // order to make use of PhysReg between UseSlots[I] and UseSlots[I + 1].
16610b57cec5SDimitry Andric calcGapWeights(PhysReg, GapWeight);
16620b57cec5SDimitry Andric
16630b57cec5SDimitry Andric // Remove any gaps with regmask clobbers.
16640b57cec5SDimitry Andric if (Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1665*0fca6ea1SDimitry Andric for (unsigned Gap : RegMaskGaps)
1666*0fca6ea1SDimitry Andric GapWeight[Gap] = huge_valf;
16670b57cec5SDimitry Andric
16680b57cec5SDimitry Andric // Try to find the best sequence of gaps to close.
16690b57cec5SDimitry Andric // The new spill weight must be larger than any gap interference.
16700b57cec5SDimitry Andric
16710b57cec5SDimitry Andric // We will split before Uses[SplitBefore] and after Uses[SplitAfter].
16720b57cec5SDimitry Andric unsigned SplitBefore = 0, SplitAfter = 1;
16730b57cec5SDimitry Andric
16740b57cec5SDimitry Andric // MaxGap should always be max(GapWeight[SplitBefore..SplitAfter-1]).
16750b57cec5SDimitry Andric // It is the spill weight that needs to be evicted.
16760b57cec5SDimitry Andric float MaxGap = GapWeight[0];
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andric while (true) {
16790b57cec5SDimitry Andric // Live before/after split?
16800b57cec5SDimitry Andric const bool LiveBefore = SplitBefore != 0 || BI.LiveIn;
16810b57cec5SDimitry Andric const bool LiveAfter = SplitAfter != NumGaps || BI.LiveOut;
16820b57cec5SDimitry Andric
16830b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << ' ' << Uses[SplitBefore]
1684e8d8bef9SDimitry Andric << '-' << Uses[SplitAfter] << " I=" << MaxGap);
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andric // Stop before the interval gets so big we wouldn't be making progress.
16870b57cec5SDimitry Andric if (!LiveBefore && !LiveAfter) {
16880b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " all\n");
16890b57cec5SDimitry Andric break;
16900b57cec5SDimitry Andric }
16910b57cec5SDimitry Andric // Should the interval be extended or shrunk?
16920b57cec5SDimitry Andric bool Shrink = true;
16930b57cec5SDimitry Andric
16940b57cec5SDimitry Andric // How many gaps would the new range have?
16950b57cec5SDimitry Andric unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric // Legally, without causing looping?
16980b57cec5SDimitry Andric bool Legal = !ProgressRequired || NewGaps < NumGaps;
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andric if (Legal && MaxGap < huge_valf) {
17010b57cec5SDimitry Andric // Estimate the new spill weight. Each instruction reads or writes the
17020b57cec5SDimitry Andric // register. Conservatively assume there are no read-modify-write
17030b57cec5SDimitry Andric // instructions.
17040b57cec5SDimitry Andric //
17050b57cec5SDimitry Andric // Try to guess the size of the new interval.
17060b57cec5SDimitry Andric const float EstWeight = normalizeSpillWeight(
17070b57cec5SDimitry Andric blockFreq * (NewGaps + 1),
17080b57cec5SDimitry Andric Uses[SplitBefore].distance(Uses[SplitAfter]) +
17090b57cec5SDimitry Andric (LiveBefore + LiveAfter) * SlotIndex::InstrDist,
17100b57cec5SDimitry Andric 1);
17110b57cec5SDimitry Andric // Would this split be possible to allocate?
17120b57cec5SDimitry Andric // Never allocate all gaps, we wouldn't be making progress.
17130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " w=" << EstWeight);
17140b57cec5SDimitry Andric if (EstWeight * Hysteresis >= MaxGap) {
17150b57cec5SDimitry Andric Shrink = false;
17160b57cec5SDimitry Andric float Diff = EstWeight - MaxGap;
17170b57cec5SDimitry Andric if (Diff > BestDiff) {
17180b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " (best)");
17190b57cec5SDimitry Andric BestDiff = Hysteresis * Diff;
17200b57cec5SDimitry Andric BestBefore = SplitBefore;
17210b57cec5SDimitry Andric BestAfter = SplitAfter;
17220b57cec5SDimitry Andric }
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric }
17250b57cec5SDimitry Andric
17260b57cec5SDimitry Andric // Try to shrink.
17270b57cec5SDimitry Andric if (Shrink) {
17280b57cec5SDimitry Andric if (++SplitBefore < SplitAfter) {
17290b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " shrink\n");
17300b57cec5SDimitry Andric // Recompute the max when necessary.
17310b57cec5SDimitry Andric if (GapWeight[SplitBefore - 1] >= MaxGap) {
17320b57cec5SDimitry Andric MaxGap = GapWeight[SplitBefore];
1733e8d8bef9SDimitry Andric for (unsigned I = SplitBefore + 1; I != SplitAfter; ++I)
1734e8d8bef9SDimitry Andric MaxGap = std::max(MaxGap, GapWeight[I]);
17350b57cec5SDimitry Andric }
17360b57cec5SDimitry Andric continue;
17370b57cec5SDimitry Andric }
17380b57cec5SDimitry Andric MaxGap = 0;
17390b57cec5SDimitry Andric }
17400b57cec5SDimitry Andric
17410b57cec5SDimitry Andric // Try to extend the interval.
17420b57cec5SDimitry Andric if (SplitAfter >= NumGaps) {
17430b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " end\n");
17440b57cec5SDimitry Andric break;
17450b57cec5SDimitry Andric }
17460b57cec5SDimitry Andric
17470b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " extend\n");
17480b57cec5SDimitry Andric MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
17490b57cec5SDimitry Andric }
17500b57cec5SDimitry Andric }
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andric // Didn't find any candidates?
17530b57cec5SDimitry Andric if (BestBefore == NumGaps)
17540b57cec5SDimitry Andric return 0;
17550b57cec5SDimitry Andric
17560b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Best local split range: " << Uses[BestBefore] << '-'
17570b57cec5SDimitry Andric << Uses[BestAfter] << ", " << BestDiff << ", "
17580b57cec5SDimitry Andric << (BestAfter - BestBefore + 1) << " instrs\n");
17590b57cec5SDimitry Andric
17600b57cec5SDimitry Andric LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
17610b57cec5SDimitry Andric SE->reset(LREdit);
17620b57cec5SDimitry Andric
17630b57cec5SDimitry Andric SE->openIntv();
17640b57cec5SDimitry Andric SlotIndex SegStart = SE->enterIntvBefore(Uses[BestBefore]);
17650b57cec5SDimitry Andric SlotIndex SegStop = SE->leaveIntvAfter(Uses[BestAfter]);
17660b57cec5SDimitry Andric SE->useIntv(SegStart, SegStop);
17670b57cec5SDimitry Andric SmallVector<unsigned, 8> IntvMap;
17680b57cec5SDimitry Andric SE->finish(&IntvMap);
1769e8d8bef9SDimitry Andric DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
17700b57cec5SDimitry Andric // If the new range has the same number of instructions as before, mark it as
17710b57cec5SDimitry Andric // RS_Split2 so the next split will be forced to make progress. Otherwise,
17720b57cec5SDimitry Andric // leave the new intervals as RS_New so they can compete.
17730b57cec5SDimitry Andric bool LiveBefore = BestBefore != 0 || BI.LiveIn;
17740b57cec5SDimitry Andric bool LiveAfter = BestAfter != NumGaps || BI.LiveOut;
17750b57cec5SDimitry Andric unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
17760b57cec5SDimitry Andric if (NewGaps >= NumGaps) {
17770b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Tagging non-progress ranges:");
17780b57cec5SDimitry Andric assert(!ProgressRequired && "Didn't make progress when it was required.");
1779e8d8bef9SDimitry Andric for (unsigned I = 0, E = IntvMap.size(); I != E; ++I)
1780e8d8bef9SDimitry Andric if (IntvMap[I] == 1) {
17810eae32dcSDimitry Andric ExtraInfo->setStage(LIS->getInterval(LREdit.get(I)), RS_Split2);
1782349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << ' ' << printReg(LREdit.get(I)));
17830b57cec5SDimitry Andric }
17840b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << '\n');
17850b57cec5SDimitry Andric }
17860b57cec5SDimitry Andric ++NumLocalSplits;
17870b57cec5SDimitry Andric
17880b57cec5SDimitry Andric return 0;
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17920b57cec5SDimitry Andric // Live Range Splitting
17930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andric /// trySplit - Try to split VirtReg or one of its interferences, making it
17960b57cec5SDimitry Andric /// assignable.
17970b57cec5SDimitry Andric /// @return Physreg when VirtReg may be assigned and/or new NewVRegs.
trySplit(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,const SmallVirtRegSet & FixedRegisters)179881ad6265SDimitry Andric unsigned RAGreedy::trySplit(const LiveInterval &VirtReg, AllocationOrder &Order,
17995ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
18000b57cec5SDimitry Andric const SmallVirtRegSet &FixedRegisters) {
18010b57cec5SDimitry Andric // Ranges must be Split2 or less.
18020eae32dcSDimitry Andric if (ExtraInfo->getStage(VirtReg) >= RS_Spill)
18030b57cec5SDimitry Andric return 0;
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric // Local intervals are handled separately.
18060b57cec5SDimitry Andric if (LIS->intervalIsInOneMBB(VirtReg)) {
18070b57cec5SDimitry Andric NamedRegionTimer T("local_split", "Local Splitting", TimerGroupName,
18080b57cec5SDimitry Andric TimerGroupDescription, TimePassesIsEnabled);
18090b57cec5SDimitry Andric SA->analyze(&VirtReg);
18105ffd83dbSDimitry Andric Register PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
18110b57cec5SDimitry Andric if (PhysReg || !NewVRegs.empty())
18120b57cec5SDimitry Andric return PhysReg;
18130b57cec5SDimitry Andric return tryInstructionSplit(VirtReg, Order, NewVRegs);
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric
18160b57cec5SDimitry Andric NamedRegionTimer T("global_split", "Global Splitting", TimerGroupName,
18170b57cec5SDimitry Andric TimerGroupDescription, TimePassesIsEnabled);
18180b57cec5SDimitry Andric
18190b57cec5SDimitry Andric SA->analyze(&VirtReg);
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andric // First try to split around a region spanning multiple blocks. RS_Split2
18220b57cec5SDimitry Andric // ranges already made dubious progress with region splitting, so they go
18230b57cec5SDimitry Andric // straight to single block splitting.
18240eae32dcSDimitry Andric if (ExtraInfo->getStage(VirtReg) < RS_Split2) {
1825e8d8bef9SDimitry Andric MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
18260b57cec5SDimitry Andric if (PhysReg || !NewVRegs.empty())
18270b57cec5SDimitry Andric return PhysReg;
18280b57cec5SDimitry Andric }
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andric // Then isolate blocks.
18310b57cec5SDimitry Andric return tryBlockSplit(VirtReg, Order, NewVRegs);
18320b57cec5SDimitry Andric }
18330b57cec5SDimitry Andric
18340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18350b57cec5SDimitry Andric // Last Chance Recoloring
18360b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18370b57cec5SDimitry Andric
18380b57cec5SDimitry Andric /// Return true if \p reg has any tied def operand.
hasTiedDef(MachineRegisterInfo * MRI,unsigned reg)18390b57cec5SDimitry Andric static bool hasTiedDef(MachineRegisterInfo *MRI, unsigned reg) {
18400b57cec5SDimitry Andric for (const MachineOperand &MO : MRI->def_operands(reg))
18410b57cec5SDimitry Andric if (MO.isTied())
18420b57cec5SDimitry Andric return true;
18430b57cec5SDimitry Andric
18440b57cec5SDimitry Andric return false;
18450b57cec5SDimitry Andric }
18460b57cec5SDimitry Andric
184781ad6265SDimitry Andric /// Return true if the existing assignment of \p Intf overlaps, but is not the
184881ad6265SDimitry Andric /// same, as \p PhysReg.
assignedRegPartiallyOverlaps(const TargetRegisterInfo & TRI,const VirtRegMap & VRM,MCRegister PhysReg,const LiveInterval & Intf)184981ad6265SDimitry Andric static bool assignedRegPartiallyOverlaps(const TargetRegisterInfo &TRI,
185081ad6265SDimitry Andric const VirtRegMap &VRM,
185181ad6265SDimitry Andric MCRegister PhysReg,
185281ad6265SDimitry Andric const LiveInterval &Intf) {
185381ad6265SDimitry Andric MCRegister AssignedReg = VRM.getPhys(Intf.reg());
185481ad6265SDimitry Andric if (PhysReg == AssignedReg)
185581ad6265SDimitry Andric return false;
185681ad6265SDimitry Andric return TRI.regsOverlap(PhysReg, AssignedReg);
185781ad6265SDimitry Andric }
185881ad6265SDimitry Andric
18590b57cec5SDimitry Andric /// mayRecolorAllInterferences - Check if the virtual registers that
18600b57cec5SDimitry Andric /// interfere with \p VirtReg on \p PhysReg (or one of its aliases) may be
18610b57cec5SDimitry Andric /// recolored to free \p PhysReg.
18620b57cec5SDimitry Andric /// When true is returned, \p RecoloringCandidates has been augmented with all
18630b57cec5SDimitry Andric /// the live intervals that need to be recolored in order to free \p PhysReg
18640b57cec5SDimitry Andric /// for \p VirtReg.
18650b57cec5SDimitry Andric /// \p FixedRegisters contains all the virtual registers that cannot be
18660b57cec5SDimitry Andric /// recolored.
mayRecolorAllInterferences(MCRegister PhysReg,const LiveInterval & VirtReg,SmallLISet & RecoloringCandidates,const SmallVirtRegSet & FixedRegisters)1867e8d8bef9SDimitry Andric bool RAGreedy::mayRecolorAllInterferences(
186881ad6265SDimitry Andric MCRegister PhysReg, const LiveInterval &VirtReg,
186981ad6265SDimitry Andric SmallLISet &RecoloringCandidates, const SmallVirtRegSet &FixedRegisters) {
1870e8d8bef9SDimitry Andric const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
18710b57cec5SDimitry Andric
187206c3fb27SDimitry Andric for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
187306c3fb27SDimitry Andric LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
18740b57cec5SDimitry Andric // If there is LastChanceRecoloringMaxInterference or more interferences,
18750b57cec5SDimitry Andric // chances are one would not be recolorable.
1876349cc55cSDimitry Andric if (Q.interferingVRegs(LastChanceRecoloringMaxInterference).size() >=
1877349cc55cSDimitry Andric LastChanceRecoloringMaxInterference &&
1878349cc55cSDimitry Andric !ExhaustiveSearch) {
18790b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Early abort: too many interferences.\n");
18800b57cec5SDimitry Andric CutOffInfo |= CO_Interf;
18810b57cec5SDimitry Andric return false;
18820b57cec5SDimitry Andric }
188381ad6265SDimitry Andric for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) {
188481ad6265SDimitry Andric // If Intf is done and sits on the same register class as VirtReg, it
188581ad6265SDimitry Andric // would not be recolorable as it is in the same state as
188681ad6265SDimitry Andric // VirtReg. However there are at least two exceptions.
188781ad6265SDimitry Andric //
188881ad6265SDimitry Andric // If VirtReg has tied defs and Intf doesn't, then
18890b57cec5SDimitry Andric // there is still a point in examining if it can be recolorable.
189081ad6265SDimitry Andric //
189181ad6265SDimitry Andric // Additionally, if the register class has overlapping tuple members, it
189281ad6265SDimitry Andric // may still be recolorable using a different tuple. This is more likely
189381ad6265SDimitry Andric // if the existing assignment aliases with the candidate.
189481ad6265SDimitry Andric //
18950eae32dcSDimitry Andric if (((ExtraInfo->getStage(*Intf) == RS_Done &&
189681ad6265SDimitry Andric MRI->getRegClass(Intf->reg()) == CurRC &&
189781ad6265SDimitry Andric !assignedRegPartiallyOverlaps(*TRI, *VRM, PhysReg, *Intf)) &&
1898e8d8bef9SDimitry Andric !(hasTiedDef(MRI, VirtReg.reg()) &&
1899e8d8bef9SDimitry Andric !hasTiedDef(MRI, Intf->reg()))) ||
1900e8d8bef9SDimitry Andric FixedRegisters.count(Intf->reg())) {
19010b57cec5SDimitry Andric LLVM_DEBUG(
19020b57cec5SDimitry Andric dbgs() << "Early abort: the interference is not recolorable.\n");
19030b57cec5SDimitry Andric return false;
19040b57cec5SDimitry Andric }
19050b57cec5SDimitry Andric RecoloringCandidates.insert(Intf);
19060b57cec5SDimitry Andric }
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric return true;
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric
19110b57cec5SDimitry Andric /// tryLastChanceRecoloring - Try to assign a color to \p VirtReg by recoloring
19120b57cec5SDimitry Andric /// its interferences.
19130b57cec5SDimitry Andric /// Last chance recoloring chooses a color for \p VirtReg and recolors every
19140b57cec5SDimitry Andric /// virtual register that was using it. The recoloring process may recursively
19150b57cec5SDimitry Andric /// use the last chance recoloring. Therefore, when a virtual register has been
19160b57cec5SDimitry Andric /// assigned a color by this mechanism, it is marked as Fixed, i.e., it cannot
19170b57cec5SDimitry Andric /// be last-chance-recolored again during this recoloring "session".
19180b57cec5SDimitry Andric /// E.g.,
19190b57cec5SDimitry Andric /// Let
19200b57cec5SDimitry Andric /// vA can use {R1, R2 }
19210b57cec5SDimitry Andric /// vB can use { R2, R3}
19220b57cec5SDimitry Andric /// vC can use {R1 }
19230b57cec5SDimitry Andric /// Where vA, vB, and vC cannot be split anymore (they are reloads for
19240b57cec5SDimitry Andric /// instance) and they all interfere.
19250b57cec5SDimitry Andric ///
19260b57cec5SDimitry Andric /// vA is assigned R1
19270b57cec5SDimitry Andric /// vB is assigned R2
19280b57cec5SDimitry Andric /// vC tries to evict vA but vA is already done.
19290b57cec5SDimitry Andric /// Regular register allocation fails.
19300b57cec5SDimitry Andric ///
19310b57cec5SDimitry Andric /// Last chance recoloring kicks in:
19320b57cec5SDimitry Andric /// vC does as if vA was evicted => vC uses R1.
19330b57cec5SDimitry Andric /// vC is marked as fixed.
19340b57cec5SDimitry Andric /// vA needs to find a color.
19350b57cec5SDimitry Andric /// None are available.
19360b57cec5SDimitry Andric /// vA cannot evict vC: vC is a fixed virtual register now.
19370b57cec5SDimitry Andric /// vA does as if vB was evicted => vA uses R2.
19380b57cec5SDimitry Andric /// vB needs to find a color.
19390b57cec5SDimitry Andric /// R3 is available.
19400b57cec5SDimitry Andric /// Recoloring => vC = R1, vA = R2, vB = R3
19410b57cec5SDimitry Andric ///
19420b57cec5SDimitry Andric /// \p Order defines the preferred allocation order for \p VirtReg.
19430b57cec5SDimitry Andric /// \p NewRegs will contain any new virtual register that have been created
19440b57cec5SDimitry Andric /// (split, spill) during the process and that must be assigned.
19450b57cec5SDimitry Andric /// \p FixedRegisters contains all the virtual registers that cannot be
19460b57cec5SDimitry Andric /// recolored.
194781ad6265SDimitry Andric ///
194881ad6265SDimitry Andric /// \p RecolorStack tracks the original assignments of successfully recolored
194981ad6265SDimitry Andric /// registers.
195081ad6265SDimitry Andric ///
19510b57cec5SDimitry Andric /// \p Depth gives the current depth of the last chance recoloring.
19520b57cec5SDimitry Andric /// \return a physical register that can be used for VirtReg or ~0u if none
19530b57cec5SDimitry Andric /// exists.
tryLastChanceRecoloring(const LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,RecoloringStack & RecolorStack,unsigned Depth)195481ad6265SDimitry Andric unsigned RAGreedy::tryLastChanceRecoloring(const LiveInterval &VirtReg,
19550b57cec5SDimitry Andric AllocationOrder &Order,
19565ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
19570b57cec5SDimitry Andric SmallVirtRegSet &FixedRegisters,
195881ad6265SDimitry Andric RecoloringStack &RecolorStack,
19590b57cec5SDimitry Andric unsigned Depth) {
1960e8d8bef9SDimitry Andric if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
1961e8d8bef9SDimitry Andric return ~0u;
1962e8d8bef9SDimitry Andric
19630b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Try last chance recoloring for " << VirtReg << '\n');
196481ad6265SDimitry Andric
196581ad6265SDimitry Andric const ssize_t EntryStackSize = RecolorStack.size();
196681ad6265SDimitry Andric
19670b57cec5SDimitry Andric // Ranges must be Done.
19680eae32dcSDimitry Andric assert((ExtraInfo->getStage(VirtReg) >= RS_Done || !VirtReg.isSpillable()) &&
19690b57cec5SDimitry Andric "Last chance recoloring should really be last chance");
19700b57cec5SDimitry Andric // Set the max depth to LastChanceRecoloringMaxDepth.
19710b57cec5SDimitry Andric // We may want to reconsider that if we end up with a too large search space
19720b57cec5SDimitry Andric // for target with hundreds of registers.
19730b57cec5SDimitry Andric // Indeed, in that case we may want to cut the search space earlier.
19740b57cec5SDimitry Andric if (Depth >= LastChanceRecoloringMaxDepth && !ExhaustiveSearch) {
19750b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Abort because max depth has been reached.\n");
19760b57cec5SDimitry Andric CutOffInfo |= CO_Depth;
19770b57cec5SDimitry Andric return ~0u;
19780b57cec5SDimitry Andric }
19790b57cec5SDimitry Andric
19800b57cec5SDimitry Andric // Set of Live intervals that will need to be recolored.
19810b57cec5SDimitry Andric SmallLISet RecoloringCandidates;
198281ad6265SDimitry Andric
19830b57cec5SDimitry Andric // Mark VirtReg as fixed, i.e., it will not be recolored pass this point in
19840b57cec5SDimitry Andric // this recoloring "session".
1985e8d8bef9SDimitry Andric assert(!FixedRegisters.count(VirtReg.reg()));
1986e8d8bef9SDimitry Andric FixedRegisters.insert(VirtReg.reg());
19875ffd83dbSDimitry Andric SmallVector<Register, 4> CurrentNewVRegs;
19880b57cec5SDimitry Andric
1989e8d8bef9SDimitry Andric for (MCRegister PhysReg : Order) {
1990e8d8bef9SDimitry Andric assert(PhysReg.isValid());
19910b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Try to assign: " << VirtReg << " to "
19920b57cec5SDimitry Andric << printReg(PhysReg, TRI) << '\n');
19930b57cec5SDimitry Andric RecoloringCandidates.clear();
19940b57cec5SDimitry Andric CurrentNewVRegs.clear();
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andric // It is only possible to recolor virtual register interference.
19970b57cec5SDimitry Andric if (Matrix->checkInterference(VirtReg, PhysReg) >
19980b57cec5SDimitry Andric LiveRegMatrix::IK_VirtReg) {
19990b57cec5SDimitry Andric LLVM_DEBUG(
20000b57cec5SDimitry Andric dbgs() << "Some interferences are not with virtual registers.\n");
20010b57cec5SDimitry Andric
20020b57cec5SDimitry Andric continue;
20030b57cec5SDimitry Andric }
20040b57cec5SDimitry Andric
20050b57cec5SDimitry Andric // Early give up on this PhysReg if it is obvious we cannot recolor all
20060b57cec5SDimitry Andric // the interferences.
20070b57cec5SDimitry Andric if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
20080b57cec5SDimitry Andric FixedRegisters)) {
20090b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Some interferences cannot be recolored.\n");
20100b57cec5SDimitry Andric continue;
20110b57cec5SDimitry Andric }
20120b57cec5SDimitry Andric
201381ad6265SDimitry Andric // RecoloringCandidates contains all the virtual registers that interfere
201481ad6265SDimitry Andric // with VirtReg on PhysReg (or one of its aliases). Enqueue them for
201581ad6265SDimitry Andric // recoloring and perform the actual recoloring.
20160b57cec5SDimitry Andric PQueue RecoloringQueue;
201781ad6265SDimitry Andric for (const LiveInterval *RC : RecoloringCandidates) {
2018fe6060f1SDimitry Andric Register ItVirtReg = RC->reg();
2019fe6060f1SDimitry Andric enqueue(RecoloringQueue, RC);
20200b57cec5SDimitry Andric assert(VRM->hasPhys(ItVirtReg) &&
20210b57cec5SDimitry Andric "Interferences are supposed to be with allocated variables");
20220b57cec5SDimitry Andric
20230b57cec5SDimitry Andric // Record the current allocation.
202481ad6265SDimitry Andric RecolorStack.push_back(std::make_pair(RC, VRM->getPhys(ItVirtReg)));
202581ad6265SDimitry Andric
20260b57cec5SDimitry Andric // unset the related struct.
2027fe6060f1SDimitry Andric Matrix->unassign(*RC);
20280b57cec5SDimitry Andric }
20290b57cec5SDimitry Andric
20300b57cec5SDimitry Andric // Do as if VirtReg was assigned to PhysReg so that the underlying
20310b57cec5SDimitry Andric // recoloring has the right information about the interferes and
20320b57cec5SDimitry Andric // available colors.
20330b57cec5SDimitry Andric Matrix->assign(VirtReg, PhysReg);
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andric // Save the current recoloring state.
20360b57cec5SDimitry Andric // If we cannot recolor all the interferences, we will have to start again
20370b57cec5SDimitry Andric // at this point for the next physical register.
20380b57cec5SDimitry Andric SmallVirtRegSet SaveFixedRegisters(FixedRegisters);
20390b57cec5SDimitry Andric if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
204081ad6265SDimitry Andric FixedRegisters, RecolorStack, Depth)) {
20410b57cec5SDimitry Andric // Push the queued vregs into the main queue.
20425ffd83dbSDimitry Andric for (Register NewVReg : CurrentNewVRegs)
20430b57cec5SDimitry Andric NewVRegs.push_back(NewVReg);
20440b57cec5SDimitry Andric // Do not mess up with the global assignment process.
20450b57cec5SDimitry Andric // I.e., VirtReg must be unassigned.
20460b57cec5SDimitry Andric Matrix->unassign(VirtReg);
20470b57cec5SDimitry Andric return PhysReg;
20480b57cec5SDimitry Andric }
20490b57cec5SDimitry Andric
20500b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Fail to assign: " << VirtReg << " to "
20510b57cec5SDimitry Andric << printReg(PhysReg, TRI) << '\n');
20520b57cec5SDimitry Andric
20530b57cec5SDimitry Andric // The recoloring attempt failed, undo the changes.
20540b57cec5SDimitry Andric FixedRegisters = SaveFixedRegisters;
20550b57cec5SDimitry Andric Matrix->unassign(VirtReg);
20560b57cec5SDimitry Andric
20570b57cec5SDimitry Andric // For a newly created vreg which is also in RecoloringCandidates,
20580b57cec5SDimitry Andric // don't add it to NewVRegs because its physical register will be restored
20590b57cec5SDimitry Andric // below. Other vregs in CurrentNewVRegs are created by calling
20600b57cec5SDimitry Andric // selectOrSplit and should be added into NewVRegs.
206106c3fb27SDimitry Andric for (Register R : CurrentNewVRegs) {
2062fe6060f1SDimitry Andric if (RecoloringCandidates.count(&LIS->getInterval(R)))
20630b57cec5SDimitry Andric continue;
2064fe6060f1SDimitry Andric NewVRegs.push_back(R);
20650b57cec5SDimitry Andric }
20660b57cec5SDimitry Andric
206781ad6265SDimitry Andric // Roll back our unsuccessful recoloring. Also roll back any successful
206881ad6265SDimitry Andric // recolorings in any recursive recoloring attempts, since it's possible
206981ad6265SDimitry Andric // they would have introduced conflicts with assignments we will be
207081ad6265SDimitry Andric // restoring further up the stack. Perform all unassignments prior to
207181ad6265SDimitry Andric // reassigning, since sub-recolorings may have conflicted with the registers
207281ad6265SDimitry Andric // we are going to restore to their original assignments.
207381ad6265SDimitry Andric for (ssize_t I = RecolorStack.size() - 1; I >= EntryStackSize; --I) {
207481ad6265SDimitry Andric const LiveInterval *LI;
207581ad6265SDimitry Andric MCRegister PhysReg;
207681ad6265SDimitry Andric std::tie(LI, PhysReg) = RecolorStack[I];
207781ad6265SDimitry Andric
207881ad6265SDimitry Andric if (VRM->hasPhys(LI->reg()))
207981ad6265SDimitry Andric Matrix->unassign(*LI);
20800b57cec5SDimitry Andric }
208181ad6265SDimitry Andric
208281ad6265SDimitry Andric for (size_t I = EntryStackSize; I != RecolorStack.size(); ++I) {
208381ad6265SDimitry Andric const LiveInterval *LI;
208481ad6265SDimitry Andric MCRegister PhysReg;
208581ad6265SDimitry Andric std::tie(LI, PhysReg) = RecolorStack[I];
208681ad6265SDimitry Andric if (!LI->empty() && !MRI->reg_nodbg_empty(LI->reg()))
208781ad6265SDimitry Andric Matrix->assign(*LI, PhysReg);
208881ad6265SDimitry Andric }
208981ad6265SDimitry Andric
209081ad6265SDimitry Andric // Pop the stack of recoloring attempts.
209181ad6265SDimitry Andric RecolorStack.resize(EntryStackSize);
20920b57cec5SDimitry Andric }
20930b57cec5SDimitry Andric
20940b57cec5SDimitry Andric // Last chance recoloring did not worked either, give up.
20950b57cec5SDimitry Andric return ~0u;
20960b57cec5SDimitry Andric }
20970b57cec5SDimitry Andric
20980b57cec5SDimitry Andric /// tryRecoloringCandidates - Try to assign a new color to every register
20990b57cec5SDimitry Andric /// in \RecoloringQueue.
21000b57cec5SDimitry Andric /// \p NewRegs will contain any new virtual register created during the
21010b57cec5SDimitry Andric /// recoloring process.
21020b57cec5SDimitry Andric /// \p FixedRegisters[in/out] contains all the registers that have been
21030b57cec5SDimitry Andric /// recolored.
21040b57cec5SDimitry Andric /// \return true if all virtual registers in RecoloringQueue were successfully
21050b57cec5SDimitry Andric /// recolored, false otherwise.
tryRecoloringCandidates(PQueue & RecoloringQueue,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,RecoloringStack & RecolorStack,unsigned Depth)21060b57cec5SDimitry Andric bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
21075ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
21080b57cec5SDimitry Andric SmallVirtRegSet &FixedRegisters,
210981ad6265SDimitry Andric RecoloringStack &RecolorStack,
21100b57cec5SDimitry Andric unsigned Depth) {
21110b57cec5SDimitry Andric while (!RecoloringQueue.empty()) {
211281ad6265SDimitry Andric const LiveInterval *LI = dequeue(RecoloringQueue);
21130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Try to recolor: " << *LI << '\n');
211481ad6265SDimitry Andric MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
211581ad6265SDimitry Andric RecolorStack, Depth + 1);
21160b57cec5SDimitry Andric // When splitting happens, the live-range may actually be empty.
21170b57cec5SDimitry Andric // In that case, this is okay to continue the recoloring even
21180b57cec5SDimitry Andric // if we did not find an alternative color for it. Indeed,
21190b57cec5SDimitry Andric // there will not be anything to color for LI in the end.
21200b57cec5SDimitry Andric if (PhysReg == ~0u || (!PhysReg && !LI->empty()))
21210b57cec5SDimitry Andric return false;
21220b57cec5SDimitry Andric
21230b57cec5SDimitry Andric if (!PhysReg) {
21240b57cec5SDimitry Andric assert(LI->empty() && "Only empty live-range do not require a register");
21250b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Recoloring of " << *LI
21260b57cec5SDimitry Andric << " succeeded. Empty LI.\n");
21270b57cec5SDimitry Andric continue;
21280b57cec5SDimitry Andric }
21290b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Recoloring of " << *LI
21300b57cec5SDimitry Andric << " succeeded with: " << printReg(PhysReg, TRI) << '\n');
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric Matrix->assign(*LI, PhysReg);
2133e8d8bef9SDimitry Andric FixedRegisters.insert(LI->reg());
21340b57cec5SDimitry Andric }
21350b57cec5SDimitry Andric return true;
21360b57cec5SDimitry Andric }
21370b57cec5SDimitry Andric
21380b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21390b57cec5SDimitry Andric // Main Entry Point
21400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21410b57cec5SDimitry Andric
selectOrSplit(const LiveInterval & VirtReg,SmallVectorImpl<Register> & NewVRegs)214281ad6265SDimitry Andric MCRegister RAGreedy::selectOrSplit(const LiveInterval &VirtReg,
21435ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs) {
21440b57cec5SDimitry Andric CutOffInfo = CO_None;
21450b57cec5SDimitry Andric LLVMContext &Ctx = MF->getFunction().getContext();
21460b57cec5SDimitry Andric SmallVirtRegSet FixedRegisters;
214781ad6265SDimitry Andric RecoloringStack RecolorStack;
214881ad6265SDimitry Andric MCRegister Reg =
214981ad6265SDimitry Andric selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
21500b57cec5SDimitry Andric if (Reg == ~0U && (CutOffInfo != CO_None)) {
21510b57cec5SDimitry Andric uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
21520b57cec5SDimitry Andric if (CutOffEncountered == CO_Depth)
21530b57cec5SDimitry Andric Ctx.emitError("register allocation failed: maximum depth for recoloring "
21540b57cec5SDimitry Andric "reached. Use -fexhaustive-register-search to skip "
21550b57cec5SDimitry Andric "cutoffs");
21560b57cec5SDimitry Andric else if (CutOffEncountered == CO_Interf)
21570b57cec5SDimitry Andric Ctx.emitError("register allocation failed: maximum interference for "
21580b57cec5SDimitry Andric "recoloring reached. Use -fexhaustive-register-search "
21590b57cec5SDimitry Andric "to skip cutoffs");
21600b57cec5SDimitry Andric else if (CutOffEncountered == (CO_Depth | CO_Interf))
21610b57cec5SDimitry Andric Ctx.emitError("register allocation failed: maximum interference and "
21620b57cec5SDimitry Andric "depth for recoloring reached. Use "
21630b57cec5SDimitry Andric "-fexhaustive-register-search to skip cutoffs");
21640b57cec5SDimitry Andric }
21650b57cec5SDimitry Andric return Reg;
21660b57cec5SDimitry Andric }
21670b57cec5SDimitry Andric
21680b57cec5SDimitry Andric /// Using a CSR for the first time has a cost because it causes push|pop
21690b57cec5SDimitry Andric /// to be added to prologue|epilogue. Splitting a cold section of the live
21700b57cec5SDimitry Andric /// range can have lower cost than using the CSR for the first time;
21710b57cec5SDimitry Andric /// Spilling a live range in the cold path can have lower cost than using
21720b57cec5SDimitry Andric /// the CSR for the first time. Returns the physical register if we decide
21730b57cec5SDimitry Andric /// to use the CSR; otherwise return 0.
tryAssignCSRFirstTime(const LiveInterval & VirtReg,AllocationOrder & Order,MCRegister PhysReg,uint8_t & CostPerUseLimit,SmallVectorImpl<Register> & NewVRegs)217481ad6265SDimitry Andric MCRegister RAGreedy::tryAssignCSRFirstTime(
217581ad6265SDimitry Andric const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
217681ad6265SDimitry Andric uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &NewVRegs) {
21770eae32dcSDimitry Andric if (ExtraInfo->getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) {
21780b57cec5SDimitry Andric // We choose spill over using the CSR for the first time if the spill cost
21790b57cec5SDimitry Andric // is lower than CSRCost.
21800b57cec5SDimitry Andric SA->analyze(&VirtReg);
21810b57cec5SDimitry Andric if (calcSpillCost() >= CSRCost)
21820b57cec5SDimitry Andric return PhysReg;
21830b57cec5SDimitry Andric
21840b57cec5SDimitry Andric // We are going to spill, set CostPerUseLimit to 1 to make sure that
21850b57cec5SDimitry Andric // we will not use a callee-saved register in tryEvict.
21860b57cec5SDimitry Andric CostPerUseLimit = 1;
21870b57cec5SDimitry Andric return 0;
21880b57cec5SDimitry Andric }
21890eae32dcSDimitry Andric if (ExtraInfo->getStage(VirtReg) < RS_Split) {
21900b57cec5SDimitry Andric // We choose pre-splitting over using the CSR for the first time if
21910b57cec5SDimitry Andric // the cost of splitting is lower than CSRCost.
21920b57cec5SDimitry Andric SA->analyze(&VirtReg);
21930b57cec5SDimitry Andric unsigned NumCands = 0;
21940b57cec5SDimitry Andric BlockFrequency BestCost = CSRCost; // Don't modify CSRCost.
21950b57cec5SDimitry Andric unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
21960b57cec5SDimitry Andric NumCands, true /*IgnoreCSR*/);
21970b57cec5SDimitry Andric if (BestCand == NoCand)
21980b57cec5SDimitry Andric // Use the CSR if we can't find a region split below CSRCost.
21990b57cec5SDimitry Andric return PhysReg;
22000b57cec5SDimitry Andric
22010b57cec5SDimitry Andric // Perform the actual pre-splitting.
22020b57cec5SDimitry Andric doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);
22030b57cec5SDimitry Andric return 0;
22040b57cec5SDimitry Andric }
22050b57cec5SDimitry Andric return PhysReg;
22060b57cec5SDimitry Andric }
22070b57cec5SDimitry Andric
aboutToRemoveInterval(const LiveInterval & LI)220881ad6265SDimitry Andric void RAGreedy::aboutToRemoveInterval(const LiveInterval &LI) {
22090b57cec5SDimitry Andric // Do not keep invalid information around.
22100b57cec5SDimitry Andric SetOfBrokenHints.remove(&LI);
22110b57cec5SDimitry Andric }
22120b57cec5SDimitry Andric
initializeCSRCost()22130b57cec5SDimitry Andric void RAGreedy::initializeCSRCost() {
22140b57cec5SDimitry Andric // We use the larger one out of the command-line option and the value report
22150b57cec5SDimitry Andric // by TRI.
22160b57cec5SDimitry Andric CSRCost = BlockFrequency(
22170b57cec5SDimitry Andric std::max((unsigned)CSRFirstTimeCost, TRI->getCSRFirstUseCost()));
22180b57cec5SDimitry Andric if (!CSRCost.getFrequency())
22190b57cec5SDimitry Andric return;
22200b57cec5SDimitry Andric
22210b57cec5SDimitry Andric // Raw cost is relative to Entry == 2^14; scale it appropriately.
22225f757f3fSDimitry Andric uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
22230b57cec5SDimitry Andric if (!ActualEntry) {
22245f757f3fSDimitry Andric CSRCost = BlockFrequency(0);
22250b57cec5SDimitry Andric return;
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric uint64_t FixedEntry = 1 << 14;
22280b57cec5SDimitry Andric if (ActualEntry < FixedEntry)
22290b57cec5SDimitry Andric CSRCost *= BranchProbability(ActualEntry, FixedEntry);
22300b57cec5SDimitry Andric else if (ActualEntry <= UINT32_MAX)
22310b57cec5SDimitry Andric // Invert the fraction and divide.
22320b57cec5SDimitry Andric CSRCost /= BranchProbability(FixedEntry, ActualEntry);
22330b57cec5SDimitry Andric else
22340b57cec5SDimitry Andric // Can't use BranchProbability in general, since it takes 32-bit numbers.
22355f757f3fSDimitry Andric CSRCost =
22365f757f3fSDimitry Andric BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
22370b57cec5SDimitry Andric }
22380b57cec5SDimitry Andric
22390b57cec5SDimitry Andric /// Collect the hint info for \p Reg.
22400b57cec5SDimitry Andric /// The results are stored into \p Out.
22410b57cec5SDimitry Andric /// \p Out is not cleared before being populated.
collectHintInfo(Register Reg,HintsInfo & Out)2242e8d8bef9SDimitry Andric void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
22430b57cec5SDimitry Andric for (const MachineInstr &Instr : MRI->reg_nodbg_instructions(Reg)) {
22445f757f3fSDimitry Andric if (!TII->isFullCopyInstr(Instr))
22450b57cec5SDimitry Andric continue;
22460b57cec5SDimitry Andric // Look for the other end of the copy.
22470b57cec5SDimitry Andric Register OtherReg = Instr.getOperand(0).getReg();
22480b57cec5SDimitry Andric if (OtherReg == Reg) {
22490b57cec5SDimitry Andric OtherReg = Instr.getOperand(1).getReg();
22500b57cec5SDimitry Andric if (OtherReg == Reg)
22510b57cec5SDimitry Andric continue;
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric // Get the current assignment.
2254e8d8bef9SDimitry Andric MCRegister OtherPhysReg =
2255e8d8bef9SDimitry Andric OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
22560b57cec5SDimitry Andric // Push the collected information.
22570b57cec5SDimitry Andric Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
22580b57cec5SDimitry Andric OtherPhysReg));
22590b57cec5SDimitry Andric }
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric
22620b57cec5SDimitry Andric /// Using the given \p List, compute the cost of the broken hints if
22630b57cec5SDimitry Andric /// \p PhysReg was used.
22640b57cec5SDimitry Andric /// \return The cost of \p List for \p PhysReg.
getBrokenHintFreq(const HintsInfo & List,MCRegister PhysReg)22650b57cec5SDimitry Andric BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
2266e8d8bef9SDimitry Andric MCRegister PhysReg) {
22675f757f3fSDimitry Andric BlockFrequency Cost = BlockFrequency(0);
22680b57cec5SDimitry Andric for (const HintInfo &Info : List) {
22690b57cec5SDimitry Andric if (Info.PhysReg != PhysReg)
22700b57cec5SDimitry Andric Cost += Info.Freq;
22710b57cec5SDimitry Andric }
22720b57cec5SDimitry Andric return Cost;
22730b57cec5SDimitry Andric }
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andric /// Using the register assigned to \p VirtReg, try to recolor
22760b57cec5SDimitry Andric /// all the live ranges that are copy-related with \p VirtReg.
22770b57cec5SDimitry Andric /// The recoloring is then propagated to all the live-ranges that have
22780b57cec5SDimitry Andric /// been recolored and so on, until no more copies can be coalesced or
22790b57cec5SDimitry Andric /// it is not profitable.
22800b57cec5SDimitry Andric /// For a given live range, profitability is determined by the sum of the
22810b57cec5SDimitry Andric /// frequencies of the non-identity copies it would introduce with the old
22820b57cec5SDimitry Andric /// and new register.
tryHintRecoloring(const LiveInterval & VirtReg)228381ad6265SDimitry Andric void RAGreedy::tryHintRecoloring(const LiveInterval &VirtReg) {
22840b57cec5SDimitry Andric // We have a broken hint, check if it is possible to fix it by
22850b57cec5SDimitry Andric // reusing PhysReg for the copy-related live-ranges. Indeed, we evicted
22860b57cec5SDimitry Andric // some register and PhysReg may be available for the other live-ranges.
2287e8d8bef9SDimitry Andric SmallSet<Register, 4> Visited;
22880b57cec5SDimitry Andric SmallVector<unsigned, 2> RecoloringCandidates;
22890b57cec5SDimitry Andric HintsInfo Info;
2290e8d8bef9SDimitry Andric Register Reg = VirtReg.reg();
2291e8d8bef9SDimitry Andric MCRegister PhysReg = VRM->getPhys(Reg);
22920b57cec5SDimitry Andric // Start the recoloring algorithm from the input live-interval, then
22930b57cec5SDimitry Andric // it will propagate to the ones that are copy-related with it.
22940b57cec5SDimitry Andric Visited.insert(Reg);
22950b57cec5SDimitry Andric RecoloringCandidates.push_back(Reg);
22960b57cec5SDimitry Andric
22970b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying to reconcile hints for: " << printReg(Reg, TRI)
22980b57cec5SDimitry Andric << '(' << printReg(PhysReg, TRI) << ")\n");
22990b57cec5SDimitry Andric
23000b57cec5SDimitry Andric do {
23010b57cec5SDimitry Andric Reg = RecoloringCandidates.pop_back_val();
23020b57cec5SDimitry Andric
23030b57cec5SDimitry Andric // We cannot recolor physical register.
2304bdd1243dSDimitry Andric if (Reg.isPhysical())
23050b57cec5SDimitry Andric continue;
23060b57cec5SDimitry Andric
2307*0fca6ea1SDimitry Andric // This may be a skipped register.
2308fe6060f1SDimitry Andric if (!VRM->hasPhys(Reg)) {
2309*0fca6ea1SDimitry Andric assert(!shouldAllocateRegister(Reg) &&
2310fe6060f1SDimitry Andric "We have an unallocated variable which should have been handled");
2311fe6060f1SDimitry Andric continue;
2312fe6060f1SDimitry Andric }
23130b57cec5SDimitry Andric
23140b57cec5SDimitry Andric // Get the live interval mapped with this virtual register to be able
23150b57cec5SDimitry Andric // to check for the interference with the new color.
23160b57cec5SDimitry Andric LiveInterval &LI = LIS->getInterval(Reg);
2317e8d8bef9SDimitry Andric MCRegister CurrPhys = VRM->getPhys(Reg);
23180b57cec5SDimitry Andric // Check that the new color matches the register class constraints and
23190b57cec5SDimitry Andric // that it is free for this live range.
23200b57cec5SDimitry Andric if (CurrPhys != PhysReg && (!MRI->getRegClass(Reg)->contains(PhysReg) ||
23210b57cec5SDimitry Andric Matrix->checkInterference(LI, PhysReg)))
23220b57cec5SDimitry Andric continue;
23230b57cec5SDimitry Andric
23240b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(Reg, TRI) << '(' << printReg(CurrPhys, TRI)
23250b57cec5SDimitry Andric << ") is recolorable.\n");
23260b57cec5SDimitry Andric
23270b57cec5SDimitry Andric // Gather the hint info.
23280b57cec5SDimitry Andric Info.clear();
23290b57cec5SDimitry Andric collectHintInfo(Reg, Info);
23300b57cec5SDimitry Andric // Check if recoloring the live-range will increase the cost of the
23310b57cec5SDimitry Andric // non-identity copies.
23320b57cec5SDimitry Andric if (CurrPhys != PhysReg) {
23330b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Checking profitability:\n");
23340b57cec5SDimitry Andric BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
23350b57cec5SDimitry Andric BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
23365f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "Old Cost: " << printBlockFreq(*MBFI, OldCopiesCost)
23375f757f3fSDimitry Andric << "\nNew Cost: "
23385f757f3fSDimitry Andric << printBlockFreq(*MBFI, NewCopiesCost) << '\n');
23390b57cec5SDimitry Andric if (OldCopiesCost < NewCopiesCost) {
23400b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> Not profitable.\n");
23410b57cec5SDimitry Andric continue;
23420b57cec5SDimitry Andric }
23430b57cec5SDimitry Andric // At this point, the cost is either cheaper or equal. If it is
23440b57cec5SDimitry Andric // equal, we consider this is profitable because it may expose
23450b57cec5SDimitry Andric // more recoloring opportunities.
23460b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> Profitable.\n");
23470b57cec5SDimitry Andric // Recolor the live-range.
23480b57cec5SDimitry Andric Matrix->unassign(LI);
23490b57cec5SDimitry Andric Matrix->assign(LI, PhysReg);
23500b57cec5SDimitry Andric }
23510b57cec5SDimitry Andric // Push all copy-related live-ranges to keep reconciling the broken
23520b57cec5SDimitry Andric // hints.
23530b57cec5SDimitry Andric for (const HintInfo &HI : Info) {
23540b57cec5SDimitry Andric if (Visited.insert(HI.Reg).second)
23550b57cec5SDimitry Andric RecoloringCandidates.push_back(HI.Reg);
23560b57cec5SDimitry Andric }
23570b57cec5SDimitry Andric } while (!RecoloringCandidates.empty());
23580b57cec5SDimitry Andric }
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andric /// Try to recolor broken hints.
23610b57cec5SDimitry Andric /// Broken hints may be repaired by recoloring when an evicted variable
23620b57cec5SDimitry Andric /// freed up a register for a larger live-range.
23630b57cec5SDimitry Andric /// Consider the following example:
23640b57cec5SDimitry Andric /// BB1:
23650b57cec5SDimitry Andric /// a =
23660b57cec5SDimitry Andric /// b =
23670b57cec5SDimitry Andric /// BB2:
23680b57cec5SDimitry Andric /// ...
23690b57cec5SDimitry Andric /// = b
23700b57cec5SDimitry Andric /// = a
23710b57cec5SDimitry Andric /// Let us assume b gets split:
23720b57cec5SDimitry Andric /// BB1:
23730b57cec5SDimitry Andric /// a =
23740b57cec5SDimitry Andric /// b =
23750b57cec5SDimitry Andric /// BB2:
23760b57cec5SDimitry Andric /// c = b
23770b57cec5SDimitry Andric /// ...
23780b57cec5SDimitry Andric /// d = c
23790b57cec5SDimitry Andric /// = d
23800b57cec5SDimitry Andric /// = a
23810b57cec5SDimitry Andric /// Because of how the allocation work, b, c, and d may be assigned different
23820b57cec5SDimitry Andric /// colors. Now, if a gets evicted later:
23830b57cec5SDimitry Andric /// BB1:
23840b57cec5SDimitry Andric /// a =
23850b57cec5SDimitry Andric /// st a, SpillSlot
23860b57cec5SDimitry Andric /// b =
23870b57cec5SDimitry Andric /// BB2:
23880b57cec5SDimitry Andric /// c = b
23890b57cec5SDimitry Andric /// ...
23900b57cec5SDimitry Andric /// d = c
23910b57cec5SDimitry Andric /// = d
23920b57cec5SDimitry Andric /// e = ld SpillSlot
23930b57cec5SDimitry Andric /// = e
23940b57cec5SDimitry Andric /// This is likely that we can assign the same register for b, c, and d,
23950b57cec5SDimitry Andric /// getting rid of 2 copies.
tryHintsRecoloring()23960b57cec5SDimitry Andric void RAGreedy::tryHintsRecoloring() {
239781ad6265SDimitry Andric for (const LiveInterval *LI : SetOfBrokenHints) {
2398bdd1243dSDimitry Andric assert(LI->reg().isVirtual() &&
23990b57cec5SDimitry Andric "Recoloring is possible only for virtual registers");
24000b57cec5SDimitry Andric // Some dead defs may be around (e.g., because of debug uses).
24010b57cec5SDimitry Andric // Ignore those.
2402e8d8bef9SDimitry Andric if (!VRM->hasPhys(LI->reg()))
24030b57cec5SDimitry Andric continue;
24040b57cec5SDimitry Andric tryHintRecoloring(*LI);
24050b57cec5SDimitry Andric }
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric
selectOrSplitImpl(const LiveInterval & VirtReg,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,RecoloringStack & RecolorStack,unsigned Depth)240881ad6265SDimitry Andric MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg,
24095ffd83dbSDimitry Andric SmallVectorImpl<Register> &NewVRegs,
24100b57cec5SDimitry Andric SmallVirtRegSet &FixedRegisters,
241181ad6265SDimitry Andric RecoloringStack &RecolorStack,
24120b57cec5SDimitry Andric unsigned Depth) {
2413fe6060f1SDimitry Andric uint8_t CostPerUseLimit = uint8_t(~0u);
24140b57cec5SDimitry Andric // First try assigning a free register.
2415e8d8bef9SDimitry Andric auto Order =
2416e8d8bef9SDimitry Andric AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
2417e8d8bef9SDimitry Andric if (MCRegister PhysReg =
2418e8d8bef9SDimitry Andric tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
24190b57cec5SDimitry Andric // When NewVRegs is not empty, we may have made decisions such as evicting
24200b57cec5SDimitry Andric // a virtual register, go with the earlier decisions and use the physical
24210b57cec5SDimitry Andric // register.
24220eae32dcSDimitry Andric if (CSRCost.getFrequency() &&
24230eae32dcSDimitry Andric EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.empty()) {
2424e8d8bef9SDimitry Andric MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
24250b57cec5SDimitry Andric CostPerUseLimit, NewVRegs);
24260b57cec5SDimitry Andric if (CSRReg || !NewVRegs.empty())
24270b57cec5SDimitry Andric // Return now if we decide to use a CSR or create new vregs due to
24280b57cec5SDimitry Andric // pre-splitting.
24290b57cec5SDimitry Andric return CSRReg;
24300b57cec5SDimitry Andric } else
24310b57cec5SDimitry Andric return PhysReg;
24320b57cec5SDimitry Andric }
24335f757f3fSDimitry Andric // Non emtpy NewVRegs means VirtReg has been split.
24345f757f3fSDimitry Andric if (!NewVRegs.empty())
24355f757f3fSDimitry Andric return 0;
24360b57cec5SDimitry Andric
24370eae32dcSDimitry Andric LiveRangeStage Stage = ExtraInfo->getStage(VirtReg);
24380b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << StageName[Stage] << " Cascade "
24390eae32dcSDimitry Andric << ExtraInfo->getCascade(VirtReg.reg()) << '\n');
24400b57cec5SDimitry Andric
24410b57cec5SDimitry Andric // Try to evict a less worthy live range, but only for ranges from the primary
24420b57cec5SDimitry Andric // queue. The RS_Split ranges already failed to do this, and they should not
24430b57cec5SDimitry Andric // get a second chance until they have been split.
24440b57cec5SDimitry Andric if (Stage != RS_Split)
24455ffd83dbSDimitry Andric if (Register PhysReg =
24460b57cec5SDimitry Andric tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
24470b57cec5SDimitry Andric FixedRegisters)) {
2448e8d8bef9SDimitry Andric Register Hint = MRI->getSimpleHint(VirtReg.reg());
24490b57cec5SDimitry Andric // If VirtReg has a hint and that hint is broken record this
24500b57cec5SDimitry Andric // virtual register as a recoloring candidate for broken hint.
24510b57cec5SDimitry Andric // Indeed, since we evicted a variable in its neighborhood it is
24520b57cec5SDimitry Andric // likely we can at least partially recolor some of the
24530b57cec5SDimitry Andric // copy-related live-ranges.
24540b57cec5SDimitry Andric if (Hint && Hint != PhysReg)
24550b57cec5SDimitry Andric SetOfBrokenHints.insert(&VirtReg);
24560b57cec5SDimitry Andric return PhysReg;
24570b57cec5SDimitry Andric }
24580b57cec5SDimitry Andric
24590b57cec5SDimitry Andric assert((NewVRegs.empty() || Depth) && "Cannot append to existing NewVRegs");
24600b57cec5SDimitry Andric
24610b57cec5SDimitry Andric // The first time we see a live range, don't try to split or spill.
24620b57cec5SDimitry Andric // Wait until the second time, when all smaller ranges have been allocated.
24630b57cec5SDimitry Andric // This gives a better picture of the interference to split around.
24640b57cec5SDimitry Andric if (Stage < RS_Split) {
24650eae32dcSDimitry Andric ExtraInfo->setStage(VirtReg, RS_Split);
24660b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "wait for second round\n");
2467e8d8bef9SDimitry Andric NewVRegs.push_back(VirtReg.reg());
24680b57cec5SDimitry Andric return 0;
24690b57cec5SDimitry Andric }
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric if (Stage < RS_Spill) {
24720b57cec5SDimitry Andric // Try splitting VirtReg or interferences.
24730b57cec5SDimitry Andric unsigned NewVRegSizeBefore = NewVRegs.size();
24745ffd83dbSDimitry Andric Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
247581ad6265SDimitry Andric if (PhysReg || (NewVRegs.size() - NewVRegSizeBefore))
24760b57cec5SDimitry Andric return PhysReg;
24770b57cec5SDimitry Andric }
24780b57cec5SDimitry Andric
24790b57cec5SDimitry Andric // If we couldn't allocate a register from spilling, there is probably some
24800b57cec5SDimitry Andric // invalid inline assembly. The base class will report it.
248181ad6265SDimitry Andric if (Stage >= RS_Done || !VirtReg.isSpillable()) {
24820b57cec5SDimitry Andric return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
248381ad6265SDimitry Andric RecolorStack, Depth);
248481ad6265SDimitry Andric }
24850b57cec5SDimitry Andric
24860b57cec5SDimitry Andric // Finally spill VirtReg itself.
2487e8d8bef9SDimitry Andric if ((EnableDeferredSpilling ||
2488e8d8bef9SDimitry Andric TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
24890eae32dcSDimitry Andric ExtraInfo->getStage(VirtReg) < RS_Memory) {
24900b57cec5SDimitry Andric // TODO: This is experimental and in particular, we do not model
24910b57cec5SDimitry Andric // the live range splitting done by spilling correctly.
24920b57cec5SDimitry Andric // We would need a deep integration with the spiller to do the
24930b57cec5SDimitry Andric // right thing here. Anyway, that is still good for early testing.
24940eae32dcSDimitry Andric ExtraInfo->setStage(VirtReg, RS_Memory);
24950b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Do as if this register is in memory\n");
2496e8d8bef9SDimitry Andric NewVRegs.push_back(VirtReg.reg());
24970b57cec5SDimitry Andric } else {
24980b57cec5SDimitry Andric NamedRegionTimer T("spill", "Spiller", TimerGroupName,
24990b57cec5SDimitry Andric TimerGroupDescription, TimePassesIsEnabled);
25000b57cec5SDimitry Andric LiveRangeEdit LRE(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
25010b57cec5SDimitry Andric spiller().spill(LRE);
25020eae32dcSDimitry Andric ExtraInfo->setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done);
25030b57cec5SDimitry Andric
2504480093f4SDimitry Andric // Tell LiveDebugVariables about the new ranges. Ranges not being covered by
2505480093f4SDimitry Andric // the new regs are kept in LDV (still mapping to the old register), until
2506480093f4SDimitry Andric // we rewrite spilled locations in LDV at a later stage.
2507e8d8bef9SDimitry Andric DebugVars->splitRegister(VirtReg.reg(), LRE.regs(), *LIS);
2508480093f4SDimitry Andric
25090b57cec5SDimitry Andric if (VerifyEnabled)
25100b57cec5SDimitry Andric MF->verify(this, "After spilling");
25110b57cec5SDimitry Andric }
25120b57cec5SDimitry Andric
25130b57cec5SDimitry Andric // The live virtual register requesting allocation was spilled, so tell
25140b57cec5SDimitry Andric // the caller not to allocate anything during this round.
25150b57cec5SDimitry Andric return 0;
25160b57cec5SDimitry Andric }
25170b57cec5SDimitry Andric
report(MachineOptimizationRemarkMissed & R)2518fe6060f1SDimitry Andric void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2519fe6060f1SDimitry Andric using namespace ore;
2520fe6060f1SDimitry Andric if (Spills) {
2521fe6060f1SDimitry Andric R << NV("NumSpills", Spills) << " spills ";
2522fe6060f1SDimitry Andric R << NV("TotalSpillsCost", SpillsCost) << " total spills cost ";
2523fe6060f1SDimitry Andric }
2524fe6060f1SDimitry Andric if (FoldedSpills) {
2525fe6060f1SDimitry Andric R << NV("NumFoldedSpills", FoldedSpills) << " folded spills ";
2526fe6060f1SDimitry Andric R << NV("TotalFoldedSpillsCost", FoldedSpillsCost)
2527fe6060f1SDimitry Andric << " total folded spills cost ";
2528fe6060f1SDimitry Andric }
2529fe6060f1SDimitry Andric if (Reloads) {
2530fe6060f1SDimitry Andric R << NV("NumReloads", Reloads) << " reloads ";
2531fe6060f1SDimitry Andric R << NV("TotalReloadsCost", ReloadsCost) << " total reloads cost ";
2532fe6060f1SDimitry Andric }
2533fe6060f1SDimitry Andric if (FoldedReloads) {
2534fe6060f1SDimitry Andric R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads ";
2535fe6060f1SDimitry Andric R << NV("TotalFoldedReloadsCost", FoldedReloadsCost)
2536fe6060f1SDimitry Andric << " total folded reloads cost ";
2537fe6060f1SDimitry Andric }
2538fe6060f1SDimitry Andric if (ZeroCostFoldedReloads)
2539fe6060f1SDimitry Andric R << NV("NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2540fe6060f1SDimitry Andric << " zero cost folded reloads ";
2541fe6060f1SDimitry Andric if (Copies) {
2542fe6060f1SDimitry Andric R << NV("NumVRCopies", Copies) << " virtual registers copies ";
2543fe6060f1SDimitry Andric R << NV("TotalCopiesCost", CopiesCost) << " total copies cost ";
2544fe6060f1SDimitry Andric }
25450b57cec5SDimitry Andric }
25460b57cec5SDimitry Andric
computeStats(MachineBasicBlock & MBB)2547fe6060f1SDimitry Andric RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &MBB) {
2548fe6060f1SDimitry Andric RAGreedyStats Stats;
25490b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo();
25500b57cec5SDimitry Andric int FI;
25510b57cec5SDimitry Andric
2552fe6060f1SDimitry Andric auto isSpillSlotAccess = [&MFI](const MachineMemOperand *A) {
2553fe6060f1SDimitry Andric return MFI.isSpillSlotObjectIndex(cast<FixedStackPseudoSourceValue>(
2554fe6060f1SDimitry Andric A->getPseudoValue())->getFrameIndex());
2555fe6060f1SDimitry Andric };
2556fe6060f1SDimitry Andric auto isPatchpointInstr = [](const MachineInstr &MI) {
2557fe6060f1SDimitry Andric return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2558fe6060f1SDimitry Andric MI.getOpcode() == TargetOpcode::STACKMAP ||
2559fe6060f1SDimitry Andric MI.getOpcode() == TargetOpcode::STATEPOINT;
2560fe6060f1SDimitry Andric };
2561fe6060f1SDimitry Andric for (MachineInstr &MI : MBB) {
25625f757f3fSDimitry Andric auto DestSrc = TII->isCopyInstr(MI);
25635f757f3fSDimitry Andric if (DestSrc) {
25645f757f3fSDimitry Andric const MachineOperand &Dest = *DestSrc->Destination;
25655f757f3fSDimitry Andric const MachineOperand &Src = *DestSrc->Source;
2566bdd1243dSDimitry Andric Register SrcReg = Src.getReg();
2567bdd1243dSDimitry Andric Register DestReg = Dest.getReg();
2568bdd1243dSDimitry Andric // Only count `COPY`s with a virtual register as source or destination.
2569bdd1243dSDimitry Andric if (SrcReg.isVirtual() || DestReg.isVirtual()) {
2570bdd1243dSDimitry Andric if (SrcReg.isVirtual()) {
2571bdd1243dSDimitry Andric SrcReg = VRM->getPhys(SrcReg);
257206c3fb27SDimitry Andric if (SrcReg && Src.getSubReg())
2573bdd1243dSDimitry Andric SrcReg = TRI->getSubReg(SrcReg, Src.getSubReg());
2574bdd1243dSDimitry Andric }
2575bdd1243dSDimitry Andric if (DestReg.isVirtual()) {
2576bdd1243dSDimitry Andric DestReg = VRM->getPhys(DestReg);
257706c3fb27SDimitry Andric if (DestReg && Dest.getSubReg())
2578bdd1243dSDimitry Andric DestReg = TRI->getSubReg(DestReg, Dest.getSubReg());
2579bdd1243dSDimitry Andric }
2580bdd1243dSDimitry Andric if (SrcReg != DestReg)
2581fe6060f1SDimitry Andric ++Stats.Copies;
2582bdd1243dSDimitry Andric }
2583fe6060f1SDimitry Andric continue;
2584fe6060f1SDimitry Andric }
2585fe6060f1SDimitry Andric
2586fe6060f1SDimitry Andric SmallVector<const MachineMemOperand *, 2> Accesses;
2587fe6060f1SDimitry Andric if (TII->isLoadFromStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) {
2588fe6060f1SDimitry Andric ++Stats.Reloads;
2589fe6060f1SDimitry Andric continue;
2590fe6060f1SDimitry Andric }
2591fe6060f1SDimitry Andric if (TII->isStoreToStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) {
2592fe6060f1SDimitry Andric ++Stats.Spills;
2593fe6060f1SDimitry Andric continue;
2594fe6060f1SDimitry Andric }
2595fe6060f1SDimitry Andric if (TII->hasLoadFromStackSlot(MI, Accesses) &&
2596fe6060f1SDimitry Andric llvm::any_of(Accesses, isSpillSlotAccess)) {
2597fe6060f1SDimitry Andric if (!isPatchpointInstr(MI)) {
2598fe6060f1SDimitry Andric Stats.FoldedReloads += Accesses.size();
2599fe6060f1SDimitry Andric continue;
2600fe6060f1SDimitry Andric }
2601fe6060f1SDimitry Andric // For statepoint there may be folded and zero cost folded stack reloads.
2602fe6060f1SDimitry Andric std::pair<unsigned, unsigned> NonZeroCostRange =
2603fe6060f1SDimitry Andric TII->getPatchpointUnfoldableRange(MI);
2604fe6060f1SDimitry Andric SmallSet<unsigned, 16> FoldedReloads;
2605fe6060f1SDimitry Andric SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2606fe6060f1SDimitry Andric for (unsigned Idx = 0, E = MI.getNumOperands(); Idx < E; ++Idx) {
2607fe6060f1SDimitry Andric MachineOperand &MO = MI.getOperand(Idx);
2608fe6060f1SDimitry Andric if (!MO.isFI() || !MFI.isSpillSlotObjectIndex(MO.getIndex()))
2609fe6060f1SDimitry Andric continue;
2610fe6060f1SDimitry Andric if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2611fe6060f1SDimitry Andric FoldedReloads.insert(MO.getIndex());
2612fe6060f1SDimitry Andric else
2613fe6060f1SDimitry Andric ZeroCostFoldedReloads.insert(MO.getIndex());
2614fe6060f1SDimitry Andric }
2615fe6060f1SDimitry Andric // If stack slot is used in folded reload it is not zero cost then.
2616fe6060f1SDimitry Andric for (unsigned Slot : FoldedReloads)
2617fe6060f1SDimitry Andric ZeroCostFoldedReloads.erase(Slot);
2618fe6060f1SDimitry Andric Stats.FoldedReloads += FoldedReloads.size();
2619fe6060f1SDimitry Andric Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.size();
2620fe6060f1SDimitry Andric continue;
2621fe6060f1SDimitry Andric }
2622fe6060f1SDimitry Andric Accesses.clear();
2623fe6060f1SDimitry Andric if (TII->hasStoreToStackSlot(MI, Accesses) &&
2624fe6060f1SDimitry Andric llvm::any_of(Accesses, isSpillSlotAccess)) {
2625fe6060f1SDimitry Andric Stats.FoldedSpills += Accesses.size();
2626fe6060f1SDimitry Andric }
2627fe6060f1SDimitry Andric }
2628fe6060f1SDimitry Andric // Set cost of collected statistic by multiplication to relative frequency of
2629fe6060f1SDimitry Andric // this basic block.
2630fe6060f1SDimitry Andric float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&MBB);
2631fe6060f1SDimitry Andric Stats.ReloadsCost = RelFreq * Stats.Reloads;
2632fe6060f1SDimitry Andric Stats.FoldedReloadsCost = RelFreq * Stats.FoldedReloads;
2633fe6060f1SDimitry Andric Stats.SpillsCost = RelFreq * Stats.Spills;
2634fe6060f1SDimitry Andric Stats.FoldedSpillsCost = RelFreq * Stats.FoldedSpills;
2635fe6060f1SDimitry Andric Stats.CopiesCost = RelFreq * Stats.Copies;
2636fe6060f1SDimitry Andric return Stats;
2637fe6060f1SDimitry Andric }
2638fe6060f1SDimitry Andric
reportStats(MachineLoop * L)2639fe6060f1SDimitry Andric RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2640fe6060f1SDimitry Andric RAGreedyStats Stats;
2641fe6060f1SDimitry Andric
2642fe6060f1SDimitry Andric // Sum up the spill and reloads in subloops.
2643fe6060f1SDimitry Andric for (MachineLoop *SubLoop : *L)
2644fe6060f1SDimitry Andric Stats.add(reportStats(SubLoop));
2645fe6060f1SDimitry Andric
26460b57cec5SDimitry Andric for (MachineBasicBlock *MBB : L->getBlocks())
26470b57cec5SDimitry Andric // Handle blocks that were not included in subloops.
26480b57cec5SDimitry Andric if (Loops->getLoopFor(MBB) == L)
2649fe6060f1SDimitry Andric Stats.add(computeStats(*MBB));
26500b57cec5SDimitry Andric
2651fe6060f1SDimitry Andric if (!Stats.isEmpty()) {
26520b57cec5SDimitry Andric using namespace ore;
26530b57cec5SDimitry Andric
26540b57cec5SDimitry Andric ORE->emit([&]() {
2655fe6060f1SDimitry Andric MachineOptimizationRemarkMissed R(DEBUG_TYPE, "LoopSpillReloadCopies",
26560b57cec5SDimitry Andric L->getStartLoc(), L->getHeader());
2657fe6060f1SDimitry Andric Stats.report(R);
26580b57cec5SDimitry Andric R << "generated in loop";
26590b57cec5SDimitry Andric return R;
26600b57cec5SDimitry Andric });
26610b57cec5SDimitry Andric }
2662fe6060f1SDimitry Andric return Stats;
2663fe6060f1SDimitry Andric }
2664fe6060f1SDimitry Andric
reportStats()2665fe6060f1SDimitry Andric void RAGreedy::reportStats() {
2666fe6060f1SDimitry Andric if (!ORE->allowExtraAnalysis(DEBUG_TYPE))
2667fe6060f1SDimitry Andric return;
2668fe6060f1SDimitry Andric RAGreedyStats Stats;
2669fe6060f1SDimitry Andric for (MachineLoop *L : *Loops)
2670fe6060f1SDimitry Andric Stats.add(reportStats(L));
2671fe6060f1SDimitry Andric // Process non-loop blocks.
2672fe6060f1SDimitry Andric for (MachineBasicBlock &MBB : *MF)
2673fe6060f1SDimitry Andric if (!Loops->getLoopFor(&MBB))
2674fe6060f1SDimitry Andric Stats.add(computeStats(MBB));
2675fe6060f1SDimitry Andric if (!Stats.isEmpty()) {
2676fe6060f1SDimitry Andric using namespace ore;
2677fe6060f1SDimitry Andric
2678fe6060f1SDimitry Andric ORE->emit([&]() {
2679fe6060f1SDimitry Andric DebugLoc Loc;
2680fe6060f1SDimitry Andric if (auto *SP = MF->getFunction().getSubprogram())
2681fe6060f1SDimitry Andric Loc = DILocation::get(SP->getContext(), SP->getLine(), 1, SP);
2682fe6060f1SDimitry Andric MachineOptimizationRemarkMissed R(DEBUG_TYPE, "SpillReloadCopies", Loc,
2683fe6060f1SDimitry Andric &MF->front());
2684fe6060f1SDimitry Andric Stats.report(R);
2685fe6060f1SDimitry Andric R << "generated in function";
2686fe6060f1SDimitry Andric return R;
2687fe6060f1SDimitry Andric });
2688fe6060f1SDimitry Andric }
26890b57cec5SDimitry Andric }
26900b57cec5SDimitry Andric
hasVirtRegAlloc()269181ad6265SDimitry Andric bool RAGreedy::hasVirtRegAlloc() {
269281ad6265SDimitry Andric for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
269381ad6265SDimitry Andric Register Reg = Register::index2VirtReg(I);
269481ad6265SDimitry Andric if (MRI->reg_nodbg_empty(Reg))
269581ad6265SDimitry Andric continue;
269681ad6265SDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(Reg);
269781ad6265SDimitry Andric if (!RC)
269881ad6265SDimitry Andric continue;
2699*0fca6ea1SDimitry Andric if (shouldAllocateRegister(Reg))
270081ad6265SDimitry Andric return true;
270181ad6265SDimitry Andric }
270281ad6265SDimitry Andric
270381ad6265SDimitry Andric return false;
270481ad6265SDimitry Andric }
270581ad6265SDimitry Andric
runOnMachineFunction(MachineFunction & mf)27060b57cec5SDimitry Andric bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
27070b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "********** GREEDY REGISTER ALLOCATION **********\n"
27080b57cec5SDimitry Andric << "********** Function: " << mf.getName() << '\n');
27090b57cec5SDimitry Andric
27100b57cec5SDimitry Andric MF = &mf;
27110b57cec5SDimitry Andric TII = MF->getSubtarget().getInstrInfo();
27120b57cec5SDimitry Andric
27130b57cec5SDimitry Andric if (VerifyEnabled)
27140b57cec5SDimitry Andric MF->verify(this, "Before greedy register allocator");
27150b57cec5SDimitry Andric
27160b57cec5SDimitry Andric RegAllocBase::init(getAnalysis<VirtRegMap>(),
2717*0fca6ea1SDimitry Andric getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
27180b57cec5SDimitry Andric getAnalysis<LiveRegMatrix>());
271981ad6265SDimitry Andric
272081ad6265SDimitry Andric // Early return if there is no virtual register to be allocated to a
272181ad6265SDimitry Andric // physical register.
272281ad6265SDimitry Andric if (!hasVirtRegAlloc())
272381ad6265SDimitry Andric return false;
272481ad6265SDimitry Andric
2725*0fca6ea1SDimitry Andric Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
27265f757f3fSDimitry Andric // Renumber to get accurate and consistent results from
27275f757f3fSDimitry Andric // SlotIndexes::getApproxInstrDistance.
27285f757f3fSDimitry Andric Indexes->packIndexes();
2729*0fca6ea1SDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
2730*0fca6ea1SDimitry Andric DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
27310b57cec5SDimitry Andric ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
2732*0fca6ea1SDimitry Andric Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
27330b57cec5SDimitry Andric Bundles = &getAnalysis<EdgeBundles>();
27340b57cec5SDimitry Andric SpillPlacer = &getAnalysis<SpillPlacement>();
27350b57cec5SDimitry Andric DebugVars = &getAnalysis<LiveDebugVariables>();
27360b57cec5SDimitry Andric
27370b57cec5SDimitry Andric initializeCSRCost();
27380b57cec5SDimitry Andric
2739fe6060f1SDimitry Andric RegCosts = TRI->getRegisterCosts(*MF);
274081ad6265SDimitry Andric RegClassPriorityTrumpsGlobalness =
274181ad6265SDimitry Andric GreedyRegClassPriorityTrumpsGlobalness.getNumOccurrences()
274281ad6265SDimitry Andric ? GreedyRegClassPriorityTrumpsGlobalness
274381ad6265SDimitry Andric : TRI->regClassPriorityTrumpsGlobalness(*MF);
2744fe6060f1SDimitry Andric
2745972a253aSDimitry Andric ReverseLocalAssignment = GreedyReverseLocalAssignment.getNumOccurrences()
2746972a253aSDimitry Andric ? GreedyReverseLocalAssignment
2747972a253aSDimitry Andric : TRI->reverseLocalAssignment();
2748972a253aSDimitry Andric
27491fd87a68SDimitry Andric ExtraInfo.emplace();
27501fd87a68SDimitry Andric EvictAdvisor =
27511fd87a68SDimitry Andric getAnalysis<RegAllocEvictionAdvisorAnalysis>().getAdvisor(*MF, *this);
2752bdd1243dSDimitry Andric PriorityAdvisor =
2753bdd1243dSDimitry Andric getAnalysis<RegAllocPriorityAdvisorAnalysis>().getAdvisor(*MF, *this);
27541fd87a68SDimitry Andric
2755e8d8bef9SDimitry Andric VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
2756fe6060f1SDimitry Andric SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI));
2757e8d8bef9SDimitry Andric
2758e8d8bef9SDimitry Andric VRAI->calculateSpillWeightsAndHints();
27590b57cec5SDimitry Andric
27600b57cec5SDimitry Andric LLVM_DEBUG(LIS->dump());
27610b57cec5SDimitry Andric
27620b57cec5SDimitry Andric SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops));
2763fcaf7f86SDimitry Andric SE.reset(new SplitEditor(*SA, *LIS, *VRM, *DomTree, *MBFI, *VRAI));
27641fd87a68SDimitry Andric
27650b57cec5SDimitry Andric IntfCache.init(MF, Matrix->getLiveUnions(), Indexes, LIS, TRI);
27660b57cec5SDimitry Andric GlobalCand.resize(32); // This will grow as needed.
27670b57cec5SDimitry Andric SetOfBrokenHints.clear();
27680b57cec5SDimitry Andric
27690b57cec5SDimitry Andric allocatePhysRegs();
27700b57cec5SDimitry Andric tryHintsRecoloring();
2771fe6060f1SDimitry Andric
2772fe6060f1SDimitry Andric if (VerifyEnabled)
2773fe6060f1SDimitry Andric MF->verify(this, "Before post optimization");
27740b57cec5SDimitry Andric postOptimization();
2775fe6060f1SDimitry Andric reportStats();
27760b57cec5SDimitry Andric
27770b57cec5SDimitry Andric releaseMemory();
27780b57cec5SDimitry Andric return true;
27790b57cec5SDimitry Andric }
2780