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