xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegAllocGreedy.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
1910b57cec5SDimitry Andric FunctionPass* llvm::createGreedyRegisterAllocator() {
1920b57cec5SDimitry Andric   return new RAGreedy();
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
195*0fca6ea1SDimitry Andric FunctionPass *llvm::createGreedyRegisterAllocator(RegAllocFilterFunc Ftor) {
196fe6060f1SDimitry Andric   return new RAGreedy(Ftor);
197fe6060f1SDimitry Andric }
198fe6060f1SDimitry Andric 
199*0fca6ea1SDimitry Andric RAGreedy::RAGreedy(RegAllocFilterFunc F)
200*0fca6ea1SDimitry Andric     : MachineFunctionPass(ID), RegAllocBase(F) {}
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry 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 
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 
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 
259e8d8bef9SDimitry Andric void RAGreedy::LRE_DidCloneVirtReg(Register New, Register Old) {
2600eae32dcSDimitry Andric   ExtraInfo->LRE_DidCloneVirtReg(New, Old);
2610eae32dcSDimitry Andric }
2620eae32dcSDimitry Andric 
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 
2770b57cec5SDimitry Andric void RAGreedy::releaseMemory() {
2780b57cec5SDimitry Andric   SpillerInstance.reset();
2790b57cec5SDimitry Andric   GlobalCand.clear();
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
28281ad6265SDimitry Andric void RAGreedy::enqueueImpl(const LiveInterval *LI) { enqueue(Queue, LI); }
2830b57cec5SDimitry Andric 
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 
303bdd1243dSDimitry 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 
38281ad6265SDimitry Andric const LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); }
3830b57cec5SDimitry Andric 
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.
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 
45506c3fb27SDimitry 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.
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.
5220eae32dcSDimitry 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>
53104eeddc0SDimitry 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 
55704eeddc0SDimitry 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.
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.
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.
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 
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.
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.
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 ///
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.
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 
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
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 
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 
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.
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.
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.
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 
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.
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.
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 ///
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 ///
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.
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.
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.
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.
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.
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.
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 
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.
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 
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 
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.
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.
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.
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.
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 
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 
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 
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 
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 
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 
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 
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