17330f729Sjoerg //===- RegAllocGreedy.cpp - greedy register allocator ---------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file defines the RAGreedy function pass for register allocation in
107330f729Sjoerg // optimized builds.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg
147330f729Sjoerg #include "AllocationOrder.h"
157330f729Sjoerg #include "InterferenceCache.h"
167330f729Sjoerg #include "LiveDebugVariables.h"
177330f729Sjoerg #include "RegAllocBase.h"
187330f729Sjoerg #include "SpillPlacement.h"
197330f729Sjoerg #include "SplitKit.h"
207330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
217330f729Sjoerg #include "llvm/ADT/BitVector.h"
227330f729Sjoerg #include "llvm/ADT/DenseMap.h"
237330f729Sjoerg #include "llvm/ADT/IndexedMap.h"
247330f729Sjoerg #include "llvm/ADT/MapVector.h"
257330f729Sjoerg #include "llvm/ADT/SetVector.h"
267330f729Sjoerg #include "llvm/ADT/SmallPtrSet.h"
277330f729Sjoerg #include "llvm/ADT/SmallSet.h"
287330f729Sjoerg #include "llvm/ADT/SmallVector.h"
297330f729Sjoerg #include "llvm/ADT/Statistic.h"
307330f729Sjoerg #include "llvm/ADT/StringRef.h"
317330f729Sjoerg #include "llvm/Analysis/AliasAnalysis.h"
327330f729Sjoerg #include "llvm/Analysis/OptimizationRemarkEmitter.h"
337330f729Sjoerg #include "llvm/CodeGen/CalcSpillWeights.h"
347330f729Sjoerg #include "llvm/CodeGen/EdgeBundles.h"
357330f729Sjoerg #include "llvm/CodeGen/LiveInterval.h"
367330f729Sjoerg #include "llvm/CodeGen/LiveIntervalUnion.h"
377330f729Sjoerg #include "llvm/CodeGen/LiveIntervals.h"
387330f729Sjoerg #include "llvm/CodeGen/LiveRangeEdit.h"
397330f729Sjoerg #include "llvm/CodeGen/LiveRegMatrix.h"
407330f729Sjoerg #include "llvm/CodeGen/LiveStacks.h"
417330f729Sjoerg #include "llvm/CodeGen/MachineBasicBlock.h"
427330f729Sjoerg #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
437330f729Sjoerg #include "llvm/CodeGen/MachineDominators.h"
447330f729Sjoerg #include "llvm/CodeGen/MachineFrameInfo.h"
457330f729Sjoerg #include "llvm/CodeGen/MachineFunction.h"
467330f729Sjoerg #include "llvm/CodeGen/MachineFunctionPass.h"
477330f729Sjoerg #include "llvm/CodeGen/MachineInstr.h"
487330f729Sjoerg #include "llvm/CodeGen/MachineLoopInfo.h"
497330f729Sjoerg #include "llvm/CodeGen/MachineOperand.h"
507330f729Sjoerg #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
517330f729Sjoerg #include "llvm/CodeGen/MachineRegisterInfo.h"
527330f729Sjoerg #include "llvm/CodeGen/RegAllocRegistry.h"
537330f729Sjoerg #include "llvm/CodeGen/RegisterClassInfo.h"
547330f729Sjoerg #include "llvm/CodeGen/SlotIndexes.h"
55*82d56013Sjoerg #include "llvm/CodeGen/Spiller.h"
567330f729Sjoerg #include "llvm/CodeGen/TargetInstrInfo.h"
577330f729Sjoerg #include "llvm/CodeGen/TargetRegisterInfo.h"
587330f729Sjoerg #include "llvm/CodeGen/TargetSubtargetInfo.h"
597330f729Sjoerg #include "llvm/CodeGen/VirtRegMap.h"
607330f729Sjoerg #include "llvm/IR/Function.h"
617330f729Sjoerg #include "llvm/IR/LLVMContext.h"
627330f729Sjoerg #include "llvm/MC/MCRegisterInfo.h"
637330f729Sjoerg #include "llvm/Pass.h"
647330f729Sjoerg #include "llvm/Support/BlockFrequency.h"
657330f729Sjoerg #include "llvm/Support/BranchProbability.h"
667330f729Sjoerg #include "llvm/Support/CommandLine.h"
677330f729Sjoerg #include "llvm/Support/Debug.h"
687330f729Sjoerg #include "llvm/Support/MathExtras.h"
697330f729Sjoerg #include "llvm/Support/Timer.h"
707330f729Sjoerg #include "llvm/Support/raw_ostream.h"
717330f729Sjoerg #include "llvm/Target/TargetMachine.h"
72*82d56013Sjoerg #include "llvm/IR/DebugInfoMetadata.h"
737330f729Sjoerg #include <algorithm>
747330f729Sjoerg #include <cassert>
757330f729Sjoerg #include <cstdint>
767330f729Sjoerg #include <memory>
777330f729Sjoerg #include <queue>
787330f729Sjoerg #include <tuple>
797330f729Sjoerg #include <utility>
807330f729Sjoerg
817330f729Sjoerg using namespace llvm;
827330f729Sjoerg
837330f729Sjoerg #define DEBUG_TYPE "regalloc"
847330f729Sjoerg
857330f729Sjoerg STATISTIC(NumGlobalSplits, "Number of split global live ranges");
867330f729Sjoerg STATISTIC(NumLocalSplits, "Number of split local live ranges");
877330f729Sjoerg STATISTIC(NumEvicted, "Number of interferences evicted");
887330f729Sjoerg
897330f729Sjoerg static cl::opt<SplitEditor::ComplementSpillMode> SplitSpillMode(
907330f729Sjoerg "split-spill-mode", cl::Hidden,
917330f729Sjoerg cl::desc("Spill mode for splitting live ranges"),
927330f729Sjoerg cl::values(clEnumValN(SplitEditor::SM_Partition, "default", "Default"),
937330f729Sjoerg clEnumValN(SplitEditor::SM_Size, "size", "Optimize for size"),
947330f729Sjoerg clEnumValN(SplitEditor::SM_Speed, "speed", "Optimize for speed")),
957330f729Sjoerg cl::init(SplitEditor::SM_Speed));
967330f729Sjoerg
977330f729Sjoerg static cl::opt<unsigned>
987330f729Sjoerg LastChanceRecoloringMaxDepth("lcr-max-depth", cl::Hidden,
997330f729Sjoerg cl::desc("Last chance recoloring max depth"),
1007330f729Sjoerg cl::init(5));
1017330f729Sjoerg
1027330f729Sjoerg static cl::opt<unsigned> LastChanceRecoloringMaxInterference(
1037330f729Sjoerg "lcr-max-interf", cl::Hidden,
1047330f729Sjoerg cl::desc("Last chance recoloring maximum number of considered"
1057330f729Sjoerg " interference at a time"),
1067330f729Sjoerg cl::init(8));
1077330f729Sjoerg
1087330f729Sjoerg static cl::opt<bool> ExhaustiveSearch(
1097330f729Sjoerg "exhaustive-register-search", cl::NotHidden,
1107330f729Sjoerg cl::desc("Exhaustive Search for registers bypassing the depth "
1117330f729Sjoerg "and interference cutoffs of last chance recoloring"),
1127330f729Sjoerg cl::Hidden);
1137330f729Sjoerg
1147330f729Sjoerg static cl::opt<bool> EnableLocalReassignment(
1157330f729Sjoerg "enable-local-reassign", cl::Hidden,
1167330f729Sjoerg cl::desc("Local reassignment can yield better allocation decisions, but "
1177330f729Sjoerg "may be compile time intensive"),
1187330f729Sjoerg cl::init(false));
1197330f729Sjoerg
1207330f729Sjoerg static cl::opt<bool> EnableDeferredSpilling(
1217330f729Sjoerg "enable-deferred-spilling", cl::Hidden,
1227330f729Sjoerg cl::desc("Instead of spilling a variable right away, defer the actual "
1237330f729Sjoerg "code insertion to the end of the allocation. That way the "
1247330f729Sjoerg "allocator might still find a suitable coloring for this "
1257330f729Sjoerg "variable because of other evicted variables."),
1267330f729Sjoerg cl::init(false));
1277330f729Sjoerg
1287330f729Sjoerg // FIXME: Find a good default for this flag and remove the flag.
1297330f729Sjoerg static cl::opt<unsigned>
1307330f729Sjoerg CSRFirstTimeCost("regalloc-csr-first-time-cost",
1317330f729Sjoerg cl::desc("Cost for first time use of callee-saved register."),
1327330f729Sjoerg cl::init(0), cl::Hidden);
1337330f729Sjoerg
1347330f729Sjoerg static cl::opt<bool> ConsiderLocalIntervalCost(
1357330f729Sjoerg "consider-local-interval-cost", cl::Hidden,
1367330f729Sjoerg cl::desc("Consider the cost of local intervals created by a split "
1377330f729Sjoerg "candidate when choosing the best split candidate."),
1387330f729Sjoerg cl::init(false));
1397330f729Sjoerg
1407330f729Sjoerg static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
1417330f729Sjoerg createGreedyRegisterAllocator);
1427330f729Sjoerg
1437330f729Sjoerg namespace {
1447330f729Sjoerg
1457330f729Sjoerg class RAGreedy : public MachineFunctionPass,
1467330f729Sjoerg public RegAllocBase,
1477330f729Sjoerg private LiveRangeEdit::Delegate {
1487330f729Sjoerg // Convenient shortcuts.
1497330f729Sjoerg using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
1507330f729Sjoerg using SmallLISet = SmallPtrSet<LiveInterval *, 4>;
151*82d56013Sjoerg using SmallVirtRegSet = SmallSet<Register, 16>;
1527330f729Sjoerg
1537330f729Sjoerg // context
1547330f729Sjoerg MachineFunction *MF;
1557330f729Sjoerg
1567330f729Sjoerg // Shortcuts to some useful interface.
1577330f729Sjoerg const TargetInstrInfo *TII;
1587330f729Sjoerg const TargetRegisterInfo *TRI;
1597330f729Sjoerg RegisterClassInfo RCI;
1607330f729Sjoerg
1617330f729Sjoerg // analyses
1627330f729Sjoerg SlotIndexes *Indexes;
1637330f729Sjoerg MachineBlockFrequencyInfo *MBFI;
1647330f729Sjoerg MachineDominatorTree *DomTree;
1657330f729Sjoerg MachineLoopInfo *Loops;
1667330f729Sjoerg MachineOptimizationRemarkEmitter *ORE;
1677330f729Sjoerg EdgeBundles *Bundles;
1687330f729Sjoerg SpillPlacement *SpillPlacer;
1697330f729Sjoerg LiveDebugVariables *DebugVars;
1707330f729Sjoerg AliasAnalysis *AA;
1717330f729Sjoerg
1727330f729Sjoerg // state
1737330f729Sjoerg std::unique_ptr<Spiller> SpillerInstance;
1747330f729Sjoerg PQueue Queue;
1757330f729Sjoerg unsigned NextCascade;
176*82d56013Sjoerg std::unique_ptr<VirtRegAuxInfo> VRAI;
1777330f729Sjoerg
1787330f729Sjoerg // Live ranges pass through a number of stages as we try to allocate them.
1797330f729Sjoerg // Some of the stages may also create new live ranges:
1807330f729Sjoerg //
1817330f729Sjoerg // - Region splitting.
1827330f729Sjoerg // - Per-block splitting.
1837330f729Sjoerg // - Local splitting.
1847330f729Sjoerg // - Spilling.
1857330f729Sjoerg //
1867330f729Sjoerg // Ranges produced by one of the stages skip the previous stages when they are
1877330f729Sjoerg // dequeued. This improves performance because we can skip interference checks
1887330f729Sjoerg // that are unlikely to give any results. It also guarantees that the live
1897330f729Sjoerg // range splitting algorithm terminates, something that is otherwise hard to
1907330f729Sjoerg // ensure.
1917330f729Sjoerg enum LiveRangeStage {
1927330f729Sjoerg /// Newly created live range that has never been queued.
1937330f729Sjoerg RS_New,
1947330f729Sjoerg
1957330f729Sjoerg /// Only attempt assignment and eviction. Then requeue as RS_Split.
1967330f729Sjoerg RS_Assign,
1977330f729Sjoerg
1987330f729Sjoerg /// Attempt live range splitting if assignment is impossible.
1997330f729Sjoerg RS_Split,
2007330f729Sjoerg
2017330f729Sjoerg /// Attempt more aggressive live range splitting that is guaranteed to make
2027330f729Sjoerg /// progress. This is used for split products that may not be making
2037330f729Sjoerg /// progress.
2047330f729Sjoerg RS_Split2,
2057330f729Sjoerg
2067330f729Sjoerg /// Live range will be spilled. No more splitting will be attempted.
2077330f729Sjoerg RS_Spill,
2087330f729Sjoerg
2097330f729Sjoerg
2107330f729Sjoerg /// Live range is in memory. Because of other evictions, it might get moved
2117330f729Sjoerg /// in a register in the end.
2127330f729Sjoerg RS_Memory,
2137330f729Sjoerg
2147330f729Sjoerg /// There is nothing more we can do to this live range. Abort compilation
2157330f729Sjoerg /// if it can't be assigned.
2167330f729Sjoerg RS_Done
2177330f729Sjoerg };
2187330f729Sjoerg
2197330f729Sjoerg // Enum CutOffStage to keep a track whether the register allocation failed
2207330f729Sjoerg // because of the cutoffs encountered in last chance recoloring.
2217330f729Sjoerg // Note: This is used as bitmask. New value should be next power of 2.
2227330f729Sjoerg enum CutOffStage {
2237330f729Sjoerg // No cutoffs encountered
2247330f729Sjoerg CO_None = 0,
2257330f729Sjoerg
2267330f729Sjoerg // lcr-max-depth cutoff encountered
2277330f729Sjoerg CO_Depth = 1,
2287330f729Sjoerg
2297330f729Sjoerg // lcr-max-interf cutoff encountered
2307330f729Sjoerg CO_Interf = 2
2317330f729Sjoerg };
2327330f729Sjoerg
2337330f729Sjoerg uint8_t CutOffInfo;
2347330f729Sjoerg
2357330f729Sjoerg #ifndef NDEBUG
2367330f729Sjoerg static const char *const StageName[];
2377330f729Sjoerg #endif
2387330f729Sjoerg
2397330f729Sjoerg // RegInfo - Keep additional information about each live range.
2407330f729Sjoerg struct RegInfo {
2417330f729Sjoerg LiveRangeStage Stage = RS_New;
2427330f729Sjoerg
2437330f729Sjoerg // Cascade - Eviction loop prevention. See canEvictInterference().
2447330f729Sjoerg unsigned Cascade = 0;
2457330f729Sjoerg
2467330f729Sjoerg RegInfo() = default;
2477330f729Sjoerg };
2487330f729Sjoerg
2497330f729Sjoerg IndexedMap<RegInfo, VirtReg2IndexFunctor> ExtraRegInfo;
2507330f729Sjoerg
getStage(const LiveInterval & VirtReg) const2517330f729Sjoerg LiveRangeStage getStage(const LiveInterval &VirtReg) const {
252*82d56013Sjoerg return ExtraRegInfo[VirtReg.reg()].Stage;
2537330f729Sjoerg }
2547330f729Sjoerg
setStage(const LiveInterval & VirtReg,LiveRangeStage Stage)2557330f729Sjoerg void setStage(const LiveInterval &VirtReg, LiveRangeStage Stage) {
2567330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
257*82d56013Sjoerg ExtraRegInfo[VirtReg.reg()].Stage = Stage;
2587330f729Sjoerg }
2597330f729Sjoerg
2607330f729Sjoerg template<typename Iterator>
setStage(Iterator Begin,Iterator End,LiveRangeStage NewStage)2617330f729Sjoerg void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
2627330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
2637330f729Sjoerg for (;Begin != End; ++Begin) {
264*82d56013Sjoerg Register Reg = *Begin;
2657330f729Sjoerg if (ExtraRegInfo[Reg].Stage == RS_New)
2667330f729Sjoerg ExtraRegInfo[Reg].Stage = NewStage;
2677330f729Sjoerg }
2687330f729Sjoerg }
2697330f729Sjoerg
2707330f729Sjoerg /// Cost of evicting interference.
2717330f729Sjoerg struct EvictionCost {
2727330f729Sjoerg unsigned BrokenHints = 0; ///< Total number of broken hints.
2737330f729Sjoerg float MaxWeight = 0; ///< Maximum spill weight evicted.
2747330f729Sjoerg
2757330f729Sjoerg EvictionCost() = default;
2767330f729Sjoerg
isMax__anone1e285680111::RAGreedy::EvictionCost2777330f729Sjoerg bool isMax() const { return BrokenHints == ~0u; }
2787330f729Sjoerg
setMax__anone1e285680111::RAGreedy::EvictionCost2797330f729Sjoerg void setMax() { BrokenHints = ~0u; }
2807330f729Sjoerg
setBrokenHints__anone1e285680111::RAGreedy::EvictionCost2817330f729Sjoerg void setBrokenHints(unsigned NHints) { BrokenHints = NHints; }
2827330f729Sjoerg
operator <__anone1e285680111::RAGreedy::EvictionCost2837330f729Sjoerg bool operator<(const EvictionCost &O) const {
2847330f729Sjoerg return std::tie(BrokenHints, MaxWeight) <
2857330f729Sjoerg std::tie(O.BrokenHints, O.MaxWeight);
2867330f729Sjoerg }
2877330f729Sjoerg };
2887330f729Sjoerg
2897330f729Sjoerg /// EvictionTrack - Keeps track of past evictions in order to optimize region
2907330f729Sjoerg /// split decision.
2917330f729Sjoerg class EvictionTrack {
2927330f729Sjoerg
2937330f729Sjoerg public:
2947330f729Sjoerg using EvictorInfo =
295*82d56013Sjoerg std::pair<Register /* evictor */, MCRegister /* physreg */>;
296*82d56013Sjoerg using EvicteeInfo = llvm::DenseMap<Register /* evictee */, EvictorInfo>;
2977330f729Sjoerg
2987330f729Sjoerg private:
2997330f729Sjoerg /// Each Vreg that has been evicted in the last stage of selectOrSplit will
3007330f729Sjoerg /// be mapped to the evictor Vreg and the PhysReg it was evicted from.
3017330f729Sjoerg EvicteeInfo Evictees;
3027330f729Sjoerg
3037330f729Sjoerg public:
3047330f729Sjoerg /// Clear all eviction information.
clear()3057330f729Sjoerg void clear() { Evictees.clear(); }
3067330f729Sjoerg
3077330f729Sjoerg /// Clear eviction information for the given evictee Vreg.
3087330f729Sjoerg /// E.g. when Vreg get's a new allocation, the old eviction info is no
3097330f729Sjoerg /// longer relevant.
3107330f729Sjoerg /// \param Evictee The evictee Vreg for whom we want to clear collected
3117330f729Sjoerg /// eviction info.
clearEvicteeInfo(Register Evictee)312*82d56013Sjoerg void clearEvicteeInfo(Register Evictee) { Evictees.erase(Evictee); }
3137330f729Sjoerg
3147330f729Sjoerg /// Track new eviction.
3157330f729Sjoerg /// The Evictor vreg has evicted the Evictee vreg from Physreg.
3167330f729Sjoerg /// \param PhysReg The physical register Evictee was evicted from.
3177330f729Sjoerg /// \param Evictor The evictor Vreg that evicted Evictee.
3187330f729Sjoerg /// \param Evictee The evictee Vreg.
addEviction(MCRegister PhysReg,Register Evictor,Register Evictee)319*82d56013Sjoerg void addEviction(MCRegister PhysReg, Register Evictor, Register Evictee) {
3207330f729Sjoerg Evictees[Evictee].first = Evictor;
3217330f729Sjoerg Evictees[Evictee].second = PhysReg;
3227330f729Sjoerg }
3237330f729Sjoerg
3247330f729Sjoerg /// Return the Evictor Vreg which evicted Evictee Vreg from PhysReg.
3257330f729Sjoerg /// \param Evictee The evictee vreg.
3267330f729Sjoerg /// \return The Evictor vreg which evicted Evictee vreg from PhysReg. 0 if
3277330f729Sjoerg /// nobody has evicted Evictee from PhysReg.
getEvictor(Register Evictee)328*82d56013Sjoerg EvictorInfo getEvictor(Register Evictee) {
3297330f729Sjoerg if (Evictees.count(Evictee)) {
3307330f729Sjoerg return Evictees[Evictee];
3317330f729Sjoerg }
3327330f729Sjoerg
3337330f729Sjoerg return EvictorInfo(0, 0);
3347330f729Sjoerg }
3357330f729Sjoerg };
3367330f729Sjoerg
3377330f729Sjoerg // Keeps track of past evictions in order to optimize region split decision.
3387330f729Sjoerg EvictionTrack LastEvicted;
3397330f729Sjoerg
3407330f729Sjoerg // splitting state.
3417330f729Sjoerg std::unique_ptr<SplitAnalysis> SA;
3427330f729Sjoerg std::unique_ptr<SplitEditor> SE;
3437330f729Sjoerg
3447330f729Sjoerg /// Cached per-block interference maps
3457330f729Sjoerg InterferenceCache IntfCache;
3467330f729Sjoerg
3477330f729Sjoerg /// All basic blocks where the current register has uses.
3487330f729Sjoerg SmallVector<SpillPlacement::BlockConstraint, 8> SplitConstraints;
3497330f729Sjoerg
3507330f729Sjoerg /// Global live range splitting candidate info.
3517330f729Sjoerg struct GlobalSplitCandidate {
3527330f729Sjoerg // Register intended for assignment, or 0.
353*82d56013Sjoerg MCRegister PhysReg;
3547330f729Sjoerg
3557330f729Sjoerg // SplitKit interval index for this candidate.
3567330f729Sjoerg unsigned IntvIdx;
3577330f729Sjoerg
3587330f729Sjoerg // Interference for PhysReg.
3597330f729Sjoerg InterferenceCache::Cursor Intf;
3607330f729Sjoerg
3617330f729Sjoerg // Bundles where this candidate should be live.
3627330f729Sjoerg BitVector LiveBundles;
3637330f729Sjoerg SmallVector<unsigned, 8> ActiveBlocks;
3647330f729Sjoerg
reset__anone1e285680111::RAGreedy::GlobalSplitCandidate365*82d56013Sjoerg void reset(InterferenceCache &Cache, MCRegister Reg) {
3667330f729Sjoerg PhysReg = Reg;
3677330f729Sjoerg IntvIdx = 0;
3687330f729Sjoerg Intf.setPhysReg(Cache, Reg);
3697330f729Sjoerg LiveBundles.clear();
3707330f729Sjoerg ActiveBlocks.clear();
3717330f729Sjoerg }
3727330f729Sjoerg
373*82d56013Sjoerg // Set B[I] = C for every live bundle where B[I] was NoCand.
getBundles__anone1e285680111::RAGreedy::GlobalSplitCandidate3747330f729Sjoerg unsigned getBundles(SmallVectorImpl<unsigned> &B, unsigned C) {
3757330f729Sjoerg unsigned Count = 0;
376*82d56013Sjoerg for (unsigned I : LiveBundles.set_bits())
377*82d56013Sjoerg if (B[I] == NoCand) {
378*82d56013Sjoerg B[I] = C;
3797330f729Sjoerg Count++;
3807330f729Sjoerg }
3817330f729Sjoerg return Count;
3827330f729Sjoerg }
3837330f729Sjoerg };
3847330f729Sjoerg
3857330f729Sjoerg /// Candidate info for each PhysReg in AllocationOrder.
3867330f729Sjoerg /// This vector never shrinks, but grows to the size of the largest register
3877330f729Sjoerg /// class.
3887330f729Sjoerg SmallVector<GlobalSplitCandidate, 32> GlobalCand;
3897330f729Sjoerg
3907330f729Sjoerg enum : unsigned { NoCand = ~0u };
3917330f729Sjoerg
3927330f729Sjoerg /// Candidate map. Each edge bundle is assigned to a GlobalCand entry, or to
3937330f729Sjoerg /// NoCand which indicates the stack interval.
3947330f729Sjoerg SmallVector<unsigned, 32> BundleCand;
3957330f729Sjoerg
3967330f729Sjoerg /// Callee-save register cost, calculated once per machine function.
3977330f729Sjoerg BlockFrequency CSRCost;
3987330f729Sjoerg
3997330f729Sjoerg /// Run or not the local reassignment heuristic. This information is
4007330f729Sjoerg /// obtained from the TargetSubtargetInfo.
4017330f729Sjoerg bool EnableLocalReassign;
4027330f729Sjoerg
4037330f729Sjoerg /// Enable or not the consideration of the cost of local intervals created
4047330f729Sjoerg /// by a split candidate when choosing the best split candidate.
4057330f729Sjoerg bool EnableAdvancedRASplitCost;
4067330f729Sjoerg
4077330f729Sjoerg /// Set of broken hints that may be reconciled later because of eviction.
4087330f729Sjoerg SmallSetVector<LiveInterval *, 8> SetOfBrokenHints;
4097330f729Sjoerg
410*82d56013Sjoerg /// The register cost values. This list will be recreated for each Machine
411*82d56013Sjoerg /// Function
412*82d56013Sjoerg ArrayRef<uint8_t> RegCosts;
413*82d56013Sjoerg
4147330f729Sjoerg public:
4157330f729Sjoerg RAGreedy();
4167330f729Sjoerg
4177330f729Sjoerg /// Return the pass name.
getPassName() const4187330f729Sjoerg StringRef getPassName() const override { return "Greedy Register Allocator"; }
4197330f729Sjoerg
4207330f729Sjoerg /// RAGreedy analysis usage.
4217330f729Sjoerg void getAnalysisUsage(AnalysisUsage &AU) const override;
4227330f729Sjoerg void releaseMemory() override;
spiller()4237330f729Sjoerg Spiller &spiller() override { return *SpillerInstance; }
4247330f729Sjoerg void enqueue(LiveInterval *LI) override;
4257330f729Sjoerg LiveInterval *dequeue() override;
426*82d56013Sjoerg MCRegister selectOrSplit(LiveInterval &,
427*82d56013Sjoerg SmallVectorImpl<Register> &) override;
4287330f729Sjoerg void aboutToRemoveInterval(LiveInterval &) override;
4297330f729Sjoerg
4307330f729Sjoerg /// Perform register allocation.
4317330f729Sjoerg bool runOnMachineFunction(MachineFunction &mf) override;
4327330f729Sjoerg
getRequiredProperties() const4337330f729Sjoerg MachineFunctionProperties getRequiredProperties() const override {
4347330f729Sjoerg return MachineFunctionProperties().set(
4357330f729Sjoerg MachineFunctionProperties::Property::NoPHIs);
4367330f729Sjoerg }
4377330f729Sjoerg
getClearedProperties() const438*82d56013Sjoerg MachineFunctionProperties getClearedProperties() const override {
439*82d56013Sjoerg return MachineFunctionProperties().set(
440*82d56013Sjoerg MachineFunctionProperties::Property::IsSSA);
441*82d56013Sjoerg }
442*82d56013Sjoerg
4437330f729Sjoerg static char ID;
4447330f729Sjoerg
4457330f729Sjoerg private:
446*82d56013Sjoerg MCRegister selectOrSplitImpl(LiveInterval &, SmallVectorImpl<Register> &,
4477330f729Sjoerg SmallVirtRegSet &, unsigned = 0);
4487330f729Sjoerg
449*82d56013Sjoerg bool LRE_CanEraseVirtReg(Register) override;
450*82d56013Sjoerg void LRE_WillShrinkVirtReg(Register) override;
451*82d56013Sjoerg void LRE_DidCloneVirtReg(Register, Register) override;
4527330f729Sjoerg void enqueue(PQueue &CurQueue, LiveInterval *LI);
4537330f729Sjoerg LiveInterval *dequeue(PQueue &CurQueue);
4547330f729Sjoerg
4557330f729Sjoerg BlockFrequency calcSpillCost();
4567330f729Sjoerg bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency&);
4577330f729Sjoerg bool addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>);
4587330f729Sjoerg bool growRegion(GlobalSplitCandidate &Cand);
459*82d56013Sjoerg bool splitCanCauseEvictionChain(Register Evictee, GlobalSplitCandidate &Cand,
4607330f729Sjoerg unsigned BBNumber,
4617330f729Sjoerg const AllocationOrder &Order);
4627330f729Sjoerg bool splitCanCauseLocalSpill(unsigned VirtRegToSplit,
4637330f729Sjoerg GlobalSplitCandidate &Cand, unsigned BBNumber,
4647330f729Sjoerg const AllocationOrder &Order);
4657330f729Sjoerg BlockFrequency calcGlobalSplitCost(GlobalSplitCandidate &,
4667330f729Sjoerg const AllocationOrder &Order,
4677330f729Sjoerg bool *CanCauseEvictionChain);
4687330f729Sjoerg bool calcCompactRegion(GlobalSplitCandidate&);
4697330f729Sjoerg void splitAroundRegion(LiveRangeEdit&, ArrayRef<unsigned>);
470*82d56013Sjoerg void calcGapWeights(MCRegister, SmallVectorImpl<float> &);
471*82d56013Sjoerg Register canReassign(LiveInterval &VirtReg, Register PrevReg) const;
472*82d56013Sjoerg bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool) const;
473*82d56013Sjoerg bool canEvictInterference(LiveInterval &, MCRegister, bool, EvictionCost &,
474*82d56013Sjoerg const SmallVirtRegSet &) const;
475*82d56013Sjoerg bool canEvictInterferenceInRange(const LiveInterval &VirtReg,
476*82d56013Sjoerg MCRegister PhysReg, SlotIndex Start,
477*82d56013Sjoerg SlotIndex End, EvictionCost &MaxCost) const;
478*82d56013Sjoerg MCRegister getCheapestEvicteeWeight(const AllocationOrder &Order,
479*82d56013Sjoerg const LiveInterval &VirtReg,
4807330f729Sjoerg SlotIndex Start, SlotIndex End,
481*82d56013Sjoerg float *BestEvictWeight) const;
482*82d56013Sjoerg void evictInterference(LiveInterval &, MCRegister,
483*82d56013Sjoerg SmallVectorImpl<Register> &);
484*82d56013Sjoerg bool mayRecolorAllInterferences(MCRegister PhysReg, LiveInterval &VirtReg,
4857330f729Sjoerg SmallLISet &RecoloringCandidates,
4867330f729Sjoerg const SmallVirtRegSet &FixedRegisters);
4877330f729Sjoerg
488*82d56013Sjoerg MCRegister tryAssign(LiveInterval&, AllocationOrder&,
489*82d56013Sjoerg SmallVectorImpl<Register>&,
4907330f729Sjoerg const SmallVirtRegSet&);
491*82d56013Sjoerg MCRegister tryEvict(LiveInterval &, AllocationOrder &,
492*82d56013Sjoerg SmallVectorImpl<Register> &, uint8_t,
4937330f729Sjoerg const SmallVirtRegSet &);
494*82d56013Sjoerg MCRegister tryRegionSplit(LiveInterval &, AllocationOrder &,
495*82d56013Sjoerg SmallVectorImpl<Register> &);
4967330f729Sjoerg /// Calculate cost of region splitting.
4977330f729Sjoerg unsigned calculateRegionSplitCost(LiveInterval &VirtReg,
4987330f729Sjoerg AllocationOrder &Order,
4997330f729Sjoerg BlockFrequency &BestCost,
5007330f729Sjoerg unsigned &NumCands, bool IgnoreCSR,
5017330f729Sjoerg bool *CanCauseEvictionChain = nullptr);
5027330f729Sjoerg /// Perform region splitting.
5037330f729Sjoerg unsigned doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
5047330f729Sjoerg bool HasCompact,
505*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs);
5067330f729Sjoerg /// Check other options before using a callee-saved register for the first
5077330f729Sjoerg /// time.
508*82d56013Sjoerg MCRegister tryAssignCSRFirstTime(LiveInterval &VirtReg,
509*82d56013Sjoerg AllocationOrder &Order, MCRegister PhysReg,
510*82d56013Sjoerg uint8_t &CostPerUseLimit,
511*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs);
5127330f729Sjoerg void initializeCSRCost();
5137330f729Sjoerg unsigned tryBlockSplit(LiveInterval&, AllocationOrder&,
514*82d56013Sjoerg SmallVectorImpl<Register>&);
5157330f729Sjoerg unsigned tryInstructionSplit(LiveInterval&, AllocationOrder&,
516*82d56013Sjoerg SmallVectorImpl<Register>&);
5177330f729Sjoerg unsigned tryLocalSplit(LiveInterval&, AllocationOrder&,
518*82d56013Sjoerg SmallVectorImpl<Register>&);
5197330f729Sjoerg unsigned trySplit(LiveInterval&, AllocationOrder&,
520*82d56013Sjoerg SmallVectorImpl<Register>&,
5217330f729Sjoerg const SmallVirtRegSet&);
5227330f729Sjoerg unsigned tryLastChanceRecoloring(LiveInterval &, AllocationOrder &,
523*82d56013Sjoerg SmallVectorImpl<Register> &,
5247330f729Sjoerg SmallVirtRegSet &, unsigned);
525*82d56013Sjoerg bool tryRecoloringCandidates(PQueue &, SmallVectorImpl<Register> &,
5267330f729Sjoerg SmallVirtRegSet &, unsigned);
5277330f729Sjoerg void tryHintRecoloring(LiveInterval &);
5287330f729Sjoerg void tryHintsRecoloring();
5297330f729Sjoerg
5307330f729Sjoerg /// Model the information carried by one end of a copy.
5317330f729Sjoerg struct HintInfo {
5327330f729Sjoerg /// The frequency of the copy.
5337330f729Sjoerg BlockFrequency Freq;
5347330f729Sjoerg /// The virtual register or physical register.
535*82d56013Sjoerg Register Reg;
5367330f729Sjoerg /// Its currently assigned register.
5377330f729Sjoerg /// In case of a physical register Reg == PhysReg.
538*82d56013Sjoerg MCRegister PhysReg;
5397330f729Sjoerg
HintInfo__anone1e285680111::RAGreedy::HintInfo540*82d56013Sjoerg HintInfo(BlockFrequency Freq, Register Reg, MCRegister PhysReg)
5417330f729Sjoerg : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
5427330f729Sjoerg };
5437330f729Sjoerg using HintsInfo = SmallVector<HintInfo, 4>;
5447330f729Sjoerg
545*82d56013Sjoerg BlockFrequency getBrokenHintFreq(const HintsInfo &, MCRegister);
546*82d56013Sjoerg void collectHintInfo(Register, HintsInfo &);
5477330f729Sjoerg
548*82d56013Sjoerg bool isUnusedCalleeSavedReg(MCRegister PhysReg) const;
5497330f729Sjoerg
550*82d56013Sjoerg /// Greedy RA statistic to remark.
551*82d56013Sjoerg struct RAGreedyStats {
552*82d56013Sjoerg unsigned Reloads = 0;
553*82d56013Sjoerg unsigned FoldedReloads = 0;
554*82d56013Sjoerg unsigned ZeroCostFoldedReloads = 0;
555*82d56013Sjoerg unsigned Spills = 0;
556*82d56013Sjoerg unsigned FoldedSpills = 0;
557*82d56013Sjoerg unsigned Copies = 0;
558*82d56013Sjoerg float ReloadsCost = 0.0f;
559*82d56013Sjoerg float FoldedReloadsCost = 0.0f;
560*82d56013Sjoerg float SpillsCost = 0.0f;
561*82d56013Sjoerg float FoldedSpillsCost = 0.0f;
562*82d56013Sjoerg float CopiesCost = 0.0f;
5637330f729Sjoerg
isEmpty__anone1e285680111::RAGreedy::RAGreedyStats564*82d56013Sjoerg bool isEmpty() {
565*82d56013Sjoerg return !(Reloads || FoldedReloads || Spills || FoldedSpills ||
566*82d56013Sjoerg ZeroCostFoldedReloads || Copies);
5677330f729Sjoerg }
568*82d56013Sjoerg
add__anone1e285680111::RAGreedy::RAGreedyStats569*82d56013Sjoerg void add(RAGreedyStats other) {
570*82d56013Sjoerg Reloads += other.Reloads;
571*82d56013Sjoerg FoldedReloads += other.FoldedReloads;
572*82d56013Sjoerg ZeroCostFoldedReloads += other.ZeroCostFoldedReloads;
573*82d56013Sjoerg Spills += other.Spills;
574*82d56013Sjoerg FoldedSpills += other.FoldedSpills;
575*82d56013Sjoerg Copies += other.Copies;
576*82d56013Sjoerg ReloadsCost += other.ReloadsCost;
577*82d56013Sjoerg FoldedReloadsCost += other.FoldedReloadsCost;
578*82d56013Sjoerg SpillsCost += other.SpillsCost;
579*82d56013Sjoerg FoldedSpillsCost += other.FoldedSpillsCost;
580*82d56013Sjoerg CopiesCost += other.CopiesCost;
5817330f729Sjoerg }
582*82d56013Sjoerg
583*82d56013Sjoerg void report(MachineOptimizationRemarkMissed &R);
584*82d56013Sjoerg };
585*82d56013Sjoerg
586*82d56013Sjoerg /// Compute statistic for a basic block.
587*82d56013Sjoerg RAGreedyStats computeStats(MachineBasicBlock &MBB);
588*82d56013Sjoerg
589*82d56013Sjoerg /// Compute and report statistic through a remark.
590*82d56013Sjoerg RAGreedyStats reportStats(MachineLoop *L);
591*82d56013Sjoerg
592*82d56013Sjoerg /// Report the statistic for each loop.
593*82d56013Sjoerg void reportStats();
5947330f729Sjoerg };
5957330f729Sjoerg
5967330f729Sjoerg } // end anonymous namespace
5977330f729Sjoerg
5987330f729Sjoerg char RAGreedy::ID = 0;
5997330f729Sjoerg char &llvm::RAGreedyID = RAGreedy::ID;
6007330f729Sjoerg
6017330f729Sjoerg INITIALIZE_PASS_BEGIN(RAGreedy, "greedy",
6027330f729Sjoerg "Greedy Register Allocator", false, false)
6037330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
6047330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
6057330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
6067330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
6077330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
6087330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(LiveStacks)
6097330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
6107330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
6117330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
6127330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
6137330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(EdgeBundles)
6147330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(SpillPlacement)
6157330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
6167330f729Sjoerg INITIALIZE_PASS_END(RAGreedy, "greedy",
6177330f729Sjoerg "Greedy Register Allocator", false, false)
6187330f729Sjoerg
6197330f729Sjoerg #ifndef NDEBUG
6207330f729Sjoerg const char *const RAGreedy::StageName[] = {
6217330f729Sjoerg "RS_New",
6227330f729Sjoerg "RS_Assign",
6237330f729Sjoerg "RS_Split",
6247330f729Sjoerg "RS_Split2",
6257330f729Sjoerg "RS_Spill",
6267330f729Sjoerg "RS_Memory",
6277330f729Sjoerg "RS_Done"
6287330f729Sjoerg };
6297330f729Sjoerg #endif
6307330f729Sjoerg
6317330f729Sjoerg // Hysteresis to use when comparing floats.
6327330f729Sjoerg // This helps stabilize decisions based on float comparisons.
6337330f729Sjoerg const float Hysteresis = (2007 / 2048.0f); // 0.97998046875
6347330f729Sjoerg
createGreedyRegisterAllocator()6357330f729Sjoerg FunctionPass* llvm::createGreedyRegisterAllocator() {
6367330f729Sjoerg return new RAGreedy();
6377330f729Sjoerg }
6387330f729Sjoerg
RAGreedy()6397330f729Sjoerg RAGreedy::RAGreedy(): MachineFunctionPass(ID) {
6407330f729Sjoerg }
6417330f729Sjoerg
getAnalysisUsage(AnalysisUsage & AU) const6427330f729Sjoerg void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
6437330f729Sjoerg AU.setPreservesCFG();
6447330f729Sjoerg AU.addRequired<MachineBlockFrequencyInfo>();
6457330f729Sjoerg AU.addPreserved<MachineBlockFrequencyInfo>();
6467330f729Sjoerg AU.addRequired<AAResultsWrapperPass>();
6477330f729Sjoerg AU.addPreserved<AAResultsWrapperPass>();
6487330f729Sjoerg AU.addRequired<LiveIntervals>();
6497330f729Sjoerg AU.addPreserved<LiveIntervals>();
6507330f729Sjoerg AU.addRequired<SlotIndexes>();
6517330f729Sjoerg AU.addPreserved<SlotIndexes>();
6527330f729Sjoerg AU.addRequired<LiveDebugVariables>();
6537330f729Sjoerg AU.addPreserved<LiveDebugVariables>();
6547330f729Sjoerg AU.addRequired<LiveStacks>();
6557330f729Sjoerg AU.addPreserved<LiveStacks>();
6567330f729Sjoerg AU.addRequired<MachineDominatorTree>();
6577330f729Sjoerg AU.addPreserved<MachineDominatorTree>();
6587330f729Sjoerg AU.addRequired<MachineLoopInfo>();
6597330f729Sjoerg AU.addPreserved<MachineLoopInfo>();
6607330f729Sjoerg AU.addRequired<VirtRegMap>();
6617330f729Sjoerg AU.addPreserved<VirtRegMap>();
6627330f729Sjoerg AU.addRequired<LiveRegMatrix>();
6637330f729Sjoerg AU.addPreserved<LiveRegMatrix>();
6647330f729Sjoerg AU.addRequired<EdgeBundles>();
6657330f729Sjoerg AU.addRequired<SpillPlacement>();
6667330f729Sjoerg AU.addRequired<MachineOptimizationRemarkEmitterPass>();
6677330f729Sjoerg MachineFunctionPass::getAnalysisUsage(AU);
6687330f729Sjoerg }
6697330f729Sjoerg
6707330f729Sjoerg //===----------------------------------------------------------------------===//
6717330f729Sjoerg // LiveRangeEdit delegate methods
6727330f729Sjoerg //===----------------------------------------------------------------------===//
6737330f729Sjoerg
LRE_CanEraseVirtReg(Register VirtReg)674*82d56013Sjoerg bool RAGreedy::LRE_CanEraseVirtReg(Register VirtReg) {
6757330f729Sjoerg LiveInterval &LI = LIS->getInterval(VirtReg);
6767330f729Sjoerg if (VRM->hasPhys(VirtReg)) {
6777330f729Sjoerg Matrix->unassign(LI);
6787330f729Sjoerg aboutToRemoveInterval(LI);
6797330f729Sjoerg return true;
6807330f729Sjoerg }
6817330f729Sjoerg // Unassigned virtreg is probably in the priority queue.
6827330f729Sjoerg // RegAllocBase will erase it after dequeueing.
6837330f729Sjoerg // Nonetheless, clear the live-range so that the debug
6847330f729Sjoerg // dump will show the right state for that VirtReg.
6857330f729Sjoerg LI.clear();
6867330f729Sjoerg return false;
6877330f729Sjoerg }
6887330f729Sjoerg
LRE_WillShrinkVirtReg(Register VirtReg)689*82d56013Sjoerg void RAGreedy::LRE_WillShrinkVirtReg(Register VirtReg) {
6907330f729Sjoerg if (!VRM->hasPhys(VirtReg))
6917330f729Sjoerg return;
6927330f729Sjoerg
6937330f729Sjoerg // Register is assigned, put it back on the queue for reassignment.
6947330f729Sjoerg LiveInterval &LI = LIS->getInterval(VirtReg);
6957330f729Sjoerg Matrix->unassign(LI);
6967330f729Sjoerg enqueue(&LI);
6977330f729Sjoerg }
6987330f729Sjoerg
LRE_DidCloneVirtReg(Register New,Register Old)699*82d56013Sjoerg void RAGreedy::LRE_DidCloneVirtReg(Register New, Register Old) {
7007330f729Sjoerg // Cloning a register we haven't even heard about yet? Just ignore it.
7017330f729Sjoerg if (!ExtraRegInfo.inBounds(Old))
7027330f729Sjoerg return;
7037330f729Sjoerg
7047330f729Sjoerg // LRE may clone a virtual register because dead code elimination causes it to
7057330f729Sjoerg // be split into connected components. The new components are much smaller
7067330f729Sjoerg // than the original, so they should get a new chance at being assigned.
7077330f729Sjoerg // same stage as the parent.
7087330f729Sjoerg ExtraRegInfo[Old].Stage = RS_Assign;
7097330f729Sjoerg ExtraRegInfo.grow(New);
7107330f729Sjoerg ExtraRegInfo[New] = ExtraRegInfo[Old];
7117330f729Sjoerg }
7127330f729Sjoerg
releaseMemory()7137330f729Sjoerg void RAGreedy::releaseMemory() {
7147330f729Sjoerg SpillerInstance.reset();
7157330f729Sjoerg ExtraRegInfo.clear();
7167330f729Sjoerg GlobalCand.clear();
7177330f729Sjoerg }
7187330f729Sjoerg
enqueue(LiveInterval * LI)7197330f729Sjoerg void RAGreedy::enqueue(LiveInterval *LI) { enqueue(Queue, LI); }
7207330f729Sjoerg
enqueue(PQueue & CurQueue,LiveInterval * LI)7217330f729Sjoerg void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) {
7227330f729Sjoerg // Prioritize live ranges by size, assigning larger ranges first.
7237330f729Sjoerg // The queue holds (size, reg) pairs.
7247330f729Sjoerg const unsigned Size = LI->getSize();
725*82d56013Sjoerg const Register Reg = LI->reg();
726*82d56013Sjoerg assert(Reg.isVirtual() && "Can only enqueue virtual registers");
7277330f729Sjoerg unsigned Prio;
7287330f729Sjoerg
7297330f729Sjoerg ExtraRegInfo.grow(Reg);
7307330f729Sjoerg if (ExtraRegInfo[Reg].Stage == RS_New)
7317330f729Sjoerg ExtraRegInfo[Reg].Stage = RS_Assign;
7327330f729Sjoerg
7337330f729Sjoerg if (ExtraRegInfo[Reg].Stage == RS_Split) {
7347330f729Sjoerg // Unsplit ranges that couldn't be allocated immediately are deferred until
7357330f729Sjoerg // everything else has been allocated.
7367330f729Sjoerg Prio = Size;
7377330f729Sjoerg } else if (ExtraRegInfo[Reg].Stage == RS_Memory) {
7387330f729Sjoerg // Memory operand should be considered last.
7397330f729Sjoerg // Change the priority such that Memory operand are assigned in
7407330f729Sjoerg // the reverse order that they came in.
7417330f729Sjoerg // TODO: Make this a member variable and probably do something about hints.
7427330f729Sjoerg static unsigned MemOp = 0;
7437330f729Sjoerg Prio = MemOp++;
7447330f729Sjoerg } else {
7457330f729Sjoerg // Giant live ranges fall back to the global assignment heuristic, which
7467330f729Sjoerg // prevents excessive spilling in pathological cases.
7477330f729Sjoerg bool ReverseLocal = TRI->reverseLocalAssignment();
7487330f729Sjoerg const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
7497330f729Sjoerg bool ForceGlobal = !ReverseLocal &&
7507330f729Sjoerg (Size / SlotIndex::InstrDist) > (2 * RC.getNumRegs());
7517330f729Sjoerg
7527330f729Sjoerg if (ExtraRegInfo[Reg].Stage == RS_Assign && !ForceGlobal && !LI->empty() &&
7537330f729Sjoerg LIS->intervalIsInOneMBB(*LI)) {
7547330f729Sjoerg // Allocate original local ranges in linear instruction order. Since they
7557330f729Sjoerg // are singly defined, this produces optimal coloring in the absence of
7567330f729Sjoerg // global interference and other constraints.
7577330f729Sjoerg if (!ReverseLocal)
7587330f729Sjoerg Prio = LI->beginIndex().getInstrDistance(Indexes->getLastIndex());
7597330f729Sjoerg else {
7607330f729Sjoerg // Allocating bottom up may allow many short LRGs to be assigned first
7617330f729Sjoerg // to one of the cheap registers. This could be much faster for very
7627330f729Sjoerg // large blocks on targets with many physical registers.
7637330f729Sjoerg Prio = Indexes->getZeroIndex().getInstrDistance(LI->endIndex());
7647330f729Sjoerg }
7657330f729Sjoerg Prio |= RC.AllocationPriority << 24;
7667330f729Sjoerg } else {
7677330f729Sjoerg // Allocate global and split ranges in long->short order. Long ranges that
7687330f729Sjoerg // don't fit should be spilled (or split) ASAP so they don't create
7697330f729Sjoerg // interference. Mark a bit to prioritize global above local ranges.
7707330f729Sjoerg Prio = (1u << 29) + Size;
7717330f729Sjoerg }
7727330f729Sjoerg // Mark a higher bit to prioritize global and local above RS_Split.
7737330f729Sjoerg Prio |= (1u << 31);
7747330f729Sjoerg
7757330f729Sjoerg // Boost ranges that have a physical register hint.
7767330f729Sjoerg if (VRM->hasKnownPreference(Reg))
7777330f729Sjoerg Prio |= (1u << 30);
7787330f729Sjoerg }
7797330f729Sjoerg // The virtual register number is a tie breaker for same-sized ranges.
7807330f729Sjoerg // Give lower vreg numbers higher priority to assign them first.
7817330f729Sjoerg CurQueue.push(std::make_pair(Prio, ~Reg));
7827330f729Sjoerg }
7837330f729Sjoerg
dequeue()7847330f729Sjoerg LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); }
7857330f729Sjoerg
dequeue(PQueue & CurQueue)7867330f729Sjoerg LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) {
7877330f729Sjoerg if (CurQueue.empty())
7887330f729Sjoerg return nullptr;
7897330f729Sjoerg LiveInterval *LI = &LIS->getInterval(~CurQueue.top().second);
7907330f729Sjoerg CurQueue.pop();
7917330f729Sjoerg return LI;
7927330f729Sjoerg }
7937330f729Sjoerg
7947330f729Sjoerg //===----------------------------------------------------------------------===//
7957330f729Sjoerg // Direct Assignment
7967330f729Sjoerg //===----------------------------------------------------------------------===//
7977330f729Sjoerg
7987330f729Sjoerg /// tryAssign - Try to assign VirtReg to an available register.
tryAssign(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,const SmallVirtRegSet & FixedRegisters)799*82d56013Sjoerg MCRegister RAGreedy::tryAssign(LiveInterval &VirtReg,
8007330f729Sjoerg AllocationOrder &Order,
801*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
8027330f729Sjoerg const SmallVirtRegSet &FixedRegisters) {
803*82d56013Sjoerg MCRegister PhysReg;
804*82d56013Sjoerg for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
805*82d56013Sjoerg assert(*I);
806*82d56013Sjoerg if (!Matrix->checkInterference(VirtReg, *I)) {
807*82d56013Sjoerg if (I.isHint())
808*82d56013Sjoerg return *I;
809*82d56013Sjoerg else
810*82d56013Sjoerg PhysReg = *I;
811*82d56013Sjoerg }
812*82d56013Sjoerg }
813*82d56013Sjoerg if (!PhysReg.isValid())
8147330f729Sjoerg return PhysReg;
8157330f729Sjoerg
8167330f729Sjoerg // PhysReg is available, but there may be a better choice.
8177330f729Sjoerg
8187330f729Sjoerg // If we missed a simple hint, try to cheaply evict interference from the
8197330f729Sjoerg // preferred register.
820*82d56013Sjoerg if (Register Hint = MRI->getSimpleHint(VirtReg.reg()))
8217330f729Sjoerg if (Order.isHint(Hint)) {
822*82d56013Sjoerg MCRegister PhysHint = Hint.asMCReg();
823*82d56013Sjoerg LLVM_DEBUG(dbgs() << "missed hint " << printReg(PhysHint, TRI) << '\n');
8247330f729Sjoerg EvictionCost MaxCost;
8257330f729Sjoerg MaxCost.setBrokenHints(1);
826*82d56013Sjoerg if (canEvictInterference(VirtReg, PhysHint, true, MaxCost,
827*82d56013Sjoerg FixedRegisters)) {
828*82d56013Sjoerg evictInterference(VirtReg, PhysHint, NewVRegs);
829*82d56013Sjoerg return PhysHint;
8307330f729Sjoerg }
8317330f729Sjoerg // Record the missed hint, we may be able to recover
8327330f729Sjoerg // at the end if the surrounding allocation changed.
8337330f729Sjoerg SetOfBrokenHints.insert(&VirtReg);
8347330f729Sjoerg }
8357330f729Sjoerg
8367330f729Sjoerg // Try to evict interference from a cheaper alternative.
837*82d56013Sjoerg uint8_t Cost = RegCosts[PhysReg];
8387330f729Sjoerg
8397330f729Sjoerg // Most registers have 0 additional cost.
8407330f729Sjoerg if (!Cost)
8417330f729Sjoerg return PhysReg;
8427330f729Sjoerg
8437330f729Sjoerg LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << " is available at cost "
8447330f729Sjoerg << Cost << '\n');
845*82d56013Sjoerg MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs, Cost, FixedRegisters);
8467330f729Sjoerg return CheapReg ? CheapReg : PhysReg;
8477330f729Sjoerg }
8487330f729Sjoerg
8497330f729Sjoerg //===----------------------------------------------------------------------===//
8507330f729Sjoerg // Interference eviction
8517330f729Sjoerg //===----------------------------------------------------------------------===//
8527330f729Sjoerg
canReassign(LiveInterval & VirtReg,Register PrevReg) const853*82d56013Sjoerg Register RAGreedy::canReassign(LiveInterval &VirtReg, Register PrevReg) const {
854*82d56013Sjoerg auto Order =
855*82d56013Sjoerg AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
856*82d56013Sjoerg MCRegister PhysReg;
857*82d56013Sjoerg for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
858*82d56013Sjoerg if ((*I).id() == PrevReg.id())
8597330f729Sjoerg continue;
8607330f729Sjoerg
861*82d56013Sjoerg MCRegUnitIterator Units(*I, TRI);
8627330f729Sjoerg for (; Units.isValid(); ++Units) {
8637330f729Sjoerg // Instantiate a "subquery", not to be confused with the Queries array.
8647330f729Sjoerg LiveIntervalUnion::Query subQ(VirtReg, Matrix->getLiveUnions()[*Units]);
8657330f729Sjoerg if (subQ.checkInterference())
8667330f729Sjoerg break;
8677330f729Sjoerg }
8687330f729Sjoerg // If no units have interference, break out with the current PhysReg.
8697330f729Sjoerg if (!Units.isValid())
870*82d56013Sjoerg PhysReg = *I;
8717330f729Sjoerg }
8727330f729Sjoerg if (PhysReg)
8737330f729Sjoerg LLVM_DEBUG(dbgs() << "can reassign: " << VirtReg << " from "
8747330f729Sjoerg << printReg(PrevReg, TRI) << " to "
8757330f729Sjoerg << printReg(PhysReg, TRI) << '\n');
8767330f729Sjoerg return PhysReg;
8777330f729Sjoerg }
8787330f729Sjoerg
8797330f729Sjoerg /// shouldEvict - determine if A should evict the assigned live range B. The
8807330f729Sjoerg /// eviction policy defined by this function together with the allocation order
8817330f729Sjoerg /// defined by enqueue() decides which registers ultimately end up being split
8827330f729Sjoerg /// and spilled.
8837330f729Sjoerg ///
8847330f729Sjoerg /// Cascade numbers are used to prevent infinite loops if this function is a
8857330f729Sjoerg /// cyclic relation.
8867330f729Sjoerg ///
8877330f729Sjoerg /// @param A The live range to be assigned.
8887330f729Sjoerg /// @param IsHint True when A is about to be assigned to its preferred
8897330f729Sjoerg /// register.
8907330f729Sjoerg /// @param B The live range to be evicted.
8917330f729Sjoerg /// @param BreaksHint True when B is already assigned to its preferred register.
shouldEvict(LiveInterval & A,bool IsHint,LiveInterval & B,bool BreaksHint) const8927330f729Sjoerg bool RAGreedy::shouldEvict(LiveInterval &A, bool IsHint,
893*82d56013Sjoerg LiveInterval &B, bool BreaksHint) const {
8947330f729Sjoerg bool CanSplit = getStage(B) < RS_Spill;
8957330f729Sjoerg
8967330f729Sjoerg // Be fairly aggressive about following hints as long as the evictee can be
8977330f729Sjoerg // split.
8987330f729Sjoerg if (CanSplit && IsHint && !BreaksHint)
8997330f729Sjoerg return true;
9007330f729Sjoerg
901*82d56013Sjoerg if (A.weight() > B.weight()) {
902*82d56013Sjoerg LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << B.weight() << '\n');
9037330f729Sjoerg return true;
9047330f729Sjoerg }
9057330f729Sjoerg return false;
9067330f729Sjoerg }
9077330f729Sjoerg
9087330f729Sjoerg /// canEvictInterference - Return true if all interferences between VirtReg and
9097330f729Sjoerg /// PhysReg can be evicted.
9107330f729Sjoerg ///
9117330f729Sjoerg /// @param VirtReg Live range that is about to be assigned.
9127330f729Sjoerg /// @param PhysReg Desired register for assignment.
9137330f729Sjoerg /// @param IsHint True when PhysReg is VirtReg's preferred register.
9147330f729Sjoerg /// @param MaxCost Only look for cheaper candidates and update with new cost
9157330f729Sjoerg /// when returning true.
9167330f729Sjoerg /// @returns True when interference can be evicted cheaper than MaxCost.
canEvictInterference(LiveInterval & VirtReg,MCRegister PhysReg,bool IsHint,EvictionCost & MaxCost,const SmallVirtRegSet & FixedRegisters) const917*82d56013Sjoerg bool RAGreedy::canEvictInterference(
918*82d56013Sjoerg LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint,
919*82d56013Sjoerg EvictionCost &MaxCost, const SmallVirtRegSet &FixedRegisters) const {
9207330f729Sjoerg // It is only possible to evict virtual register interference.
9217330f729Sjoerg if (Matrix->checkInterference(VirtReg, PhysReg) > LiveRegMatrix::IK_VirtReg)
9227330f729Sjoerg return false;
9237330f729Sjoerg
9247330f729Sjoerg bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
9257330f729Sjoerg
9267330f729Sjoerg // Find VirtReg's cascade number. This will be unassigned if VirtReg was never
9277330f729Sjoerg // involved in an eviction before. If a cascade number was assigned, deny
9287330f729Sjoerg // evicting anything with the same or a newer cascade number. This prevents
9297330f729Sjoerg // infinite eviction loops.
9307330f729Sjoerg //
9317330f729Sjoerg // This works out so a register without a cascade number is allowed to evict
9327330f729Sjoerg // anything, and it can be evicted by anything.
933*82d56013Sjoerg unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
9347330f729Sjoerg if (!Cascade)
9357330f729Sjoerg Cascade = NextCascade;
9367330f729Sjoerg
9377330f729Sjoerg EvictionCost Cost;
9387330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
9397330f729Sjoerg LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
9407330f729Sjoerg // If there is 10 or more interferences, chances are one is heavier.
9417330f729Sjoerg if (Q.collectInterferingVRegs(10) >= 10)
9427330f729Sjoerg return false;
9437330f729Sjoerg
9447330f729Sjoerg // Check if any interfering live range is heavier than MaxWeight.
945*82d56013Sjoerg for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
946*82d56013Sjoerg assert(Register::isVirtualRegister(Intf->reg()) &&
9477330f729Sjoerg "Only expecting virtual register interference from query");
9487330f729Sjoerg
9497330f729Sjoerg // Do not allow eviction of a virtual register if we are in the middle
9507330f729Sjoerg // of last-chance recoloring and this virtual register is one that we
9517330f729Sjoerg // have scavenged a physical register for.
952*82d56013Sjoerg if (FixedRegisters.count(Intf->reg()))
9537330f729Sjoerg return false;
9547330f729Sjoerg
9557330f729Sjoerg // Never evict spill products. They cannot split or spill.
9567330f729Sjoerg if (getStage(*Intf) == RS_Done)
9577330f729Sjoerg return false;
9587330f729Sjoerg // Once a live range becomes small enough, it is urgent that we find a
9597330f729Sjoerg // register for it. This is indicated by an infinite spill weight. These
9607330f729Sjoerg // urgent live ranges get to evict almost anything.
9617330f729Sjoerg //
9627330f729Sjoerg // Also allow urgent evictions of unspillable ranges from a strictly
9637330f729Sjoerg // larger allocation order.
964*82d56013Sjoerg bool Urgent =
965*82d56013Sjoerg !VirtReg.isSpillable() &&
9667330f729Sjoerg (Intf->isSpillable() ||
967*82d56013Sjoerg RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
968*82d56013Sjoerg RegClassInfo.getNumAllocatableRegs(
969*82d56013Sjoerg MRI->getRegClass(Intf->reg())));
9707330f729Sjoerg // Only evict older cascades or live ranges without a cascade.
971*82d56013Sjoerg unsigned IntfCascade = ExtraRegInfo[Intf->reg()].Cascade;
9727330f729Sjoerg if (Cascade <= IntfCascade) {
9737330f729Sjoerg if (!Urgent)
9747330f729Sjoerg return false;
9757330f729Sjoerg // We permit breaking cascades for urgent evictions. It should be the
9767330f729Sjoerg // last resort, though, so make it really expensive.
9777330f729Sjoerg Cost.BrokenHints += 10;
9787330f729Sjoerg }
9797330f729Sjoerg // Would this break a satisfied hint?
980*82d56013Sjoerg bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
9817330f729Sjoerg // Update eviction cost.
9827330f729Sjoerg Cost.BrokenHints += BreaksHint;
983*82d56013Sjoerg Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
9847330f729Sjoerg // Abort if this would be too expensive.
9857330f729Sjoerg if (!(Cost < MaxCost))
9867330f729Sjoerg return false;
9877330f729Sjoerg if (Urgent)
9887330f729Sjoerg continue;
9897330f729Sjoerg // Apply the eviction policy for non-urgent evictions.
9907330f729Sjoerg if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))
9917330f729Sjoerg return false;
9927330f729Sjoerg // If !MaxCost.isMax(), then we're just looking for a cheap register.
9937330f729Sjoerg // Evicting another local live range in this case could lead to suboptimal
9947330f729Sjoerg // coloring.
9957330f729Sjoerg if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
9967330f729Sjoerg (!EnableLocalReassign || !canReassign(*Intf, PhysReg))) {
9977330f729Sjoerg return false;
9987330f729Sjoerg }
9997330f729Sjoerg }
10007330f729Sjoerg }
10017330f729Sjoerg MaxCost = Cost;
10027330f729Sjoerg return true;
10037330f729Sjoerg }
10047330f729Sjoerg
10057330f729Sjoerg /// Return true if all interferences between VirtReg and PhysReg between
10067330f729Sjoerg /// Start and End can be evicted.
10077330f729Sjoerg ///
10087330f729Sjoerg /// \param VirtReg Live range that is about to be assigned.
10097330f729Sjoerg /// \param PhysReg Desired register for assignment.
10107330f729Sjoerg /// \param Start Start of range to look for interferences.
10117330f729Sjoerg /// \param End End of range to look for interferences.
10127330f729Sjoerg /// \param MaxCost Only look for cheaper candidates and update with new cost
10137330f729Sjoerg /// when returning true.
10147330f729Sjoerg /// \return True when interference can be evicted cheaper than MaxCost.
canEvictInterferenceInRange(const LiveInterval & VirtReg,MCRegister PhysReg,SlotIndex Start,SlotIndex End,EvictionCost & MaxCost) const1015*82d56013Sjoerg bool RAGreedy::canEvictInterferenceInRange(const LiveInterval &VirtReg,
1016*82d56013Sjoerg MCRegister PhysReg, SlotIndex Start,
10177330f729Sjoerg SlotIndex End,
1018*82d56013Sjoerg EvictionCost &MaxCost) const {
10197330f729Sjoerg EvictionCost Cost;
10207330f729Sjoerg
10217330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
10227330f729Sjoerg LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
1023*82d56013Sjoerg Q.collectInterferingVRegs();
10247330f729Sjoerg
10257330f729Sjoerg // Check if any interfering live range is heavier than MaxWeight.
1026*82d56013Sjoerg for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) {
10277330f729Sjoerg // Check if interference overlast the segment in interest.
10287330f729Sjoerg if (!Intf->overlaps(Start, End))
10297330f729Sjoerg continue;
10307330f729Sjoerg
10317330f729Sjoerg // Cannot evict non virtual reg interference.
1032*82d56013Sjoerg if (!Register::isVirtualRegister(Intf->reg()))
10337330f729Sjoerg return false;
10347330f729Sjoerg // Never evict spill products. They cannot split or spill.
10357330f729Sjoerg if (getStage(*Intf) == RS_Done)
10367330f729Sjoerg return false;
10377330f729Sjoerg
10387330f729Sjoerg // Would this break a satisfied hint?
1039*82d56013Sjoerg bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
10407330f729Sjoerg // Update eviction cost.
10417330f729Sjoerg Cost.BrokenHints += BreaksHint;
1042*82d56013Sjoerg Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
10437330f729Sjoerg // Abort if this would be too expensive.
10447330f729Sjoerg if (!(Cost < MaxCost))
10457330f729Sjoerg return false;
10467330f729Sjoerg }
10477330f729Sjoerg }
10487330f729Sjoerg
10497330f729Sjoerg if (Cost.MaxWeight == 0)
10507330f729Sjoerg return false;
10517330f729Sjoerg
10527330f729Sjoerg MaxCost = Cost;
10537330f729Sjoerg return true;
10547330f729Sjoerg }
10557330f729Sjoerg
10567330f729Sjoerg /// Return the physical register that will be best
10577330f729Sjoerg /// candidate for eviction by a local split interval that will be created
10587330f729Sjoerg /// between Start and End.
10597330f729Sjoerg ///
10607330f729Sjoerg /// \param Order The allocation order
10617330f729Sjoerg /// \param VirtReg Live range that is about to be assigned.
10627330f729Sjoerg /// \param Start Start of range to look for interferences
10637330f729Sjoerg /// \param End End of range to look for interferences
10647330f729Sjoerg /// \param BestEvictweight The eviction cost of that eviction
10657330f729Sjoerg /// \return The PhysReg which is the best candidate for eviction and the
10667330f729Sjoerg /// eviction cost in BestEvictweight
getCheapestEvicteeWeight(const AllocationOrder & Order,const LiveInterval & VirtReg,SlotIndex Start,SlotIndex End,float * BestEvictweight) const1067*82d56013Sjoerg MCRegister RAGreedy::getCheapestEvicteeWeight(const AllocationOrder &Order,
1068*82d56013Sjoerg const LiveInterval &VirtReg,
10697330f729Sjoerg SlotIndex Start, SlotIndex End,
1070*82d56013Sjoerg float *BestEvictweight) const {
10717330f729Sjoerg EvictionCost BestEvictCost;
10727330f729Sjoerg BestEvictCost.setMax();
1073*82d56013Sjoerg BestEvictCost.MaxWeight = VirtReg.weight();
1074*82d56013Sjoerg MCRegister BestEvicteePhys;
10757330f729Sjoerg
10767330f729Sjoerg // Go over all physical registers and find the best candidate for eviction
1077*82d56013Sjoerg for (MCRegister PhysReg : Order.getOrder()) {
10787330f729Sjoerg
10797330f729Sjoerg if (!canEvictInterferenceInRange(VirtReg, PhysReg, Start, End,
10807330f729Sjoerg BestEvictCost))
10817330f729Sjoerg continue;
10827330f729Sjoerg
10837330f729Sjoerg // Best so far.
10847330f729Sjoerg BestEvicteePhys = PhysReg;
10857330f729Sjoerg }
10867330f729Sjoerg *BestEvictweight = BestEvictCost.MaxWeight;
10877330f729Sjoerg return BestEvicteePhys;
10887330f729Sjoerg }
10897330f729Sjoerg
10907330f729Sjoerg /// evictInterference - Evict any interferring registers that prevent VirtReg
10917330f729Sjoerg /// from being assigned to Physreg. This assumes that canEvictInterference
10927330f729Sjoerg /// returned true.
evictInterference(LiveInterval & VirtReg,MCRegister PhysReg,SmallVectorImpl<Register> & NewVRegs)1093*82d56013Sjoerg void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
1094*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
10957330f729Sjoerg // Make sure that VirtReg has a cascade number, and assign that cascade
10967330f729Sjoerg // number to every evicted register. These live ranges than then only be
10977330f729Sjoerg // evicted by a newer cascade, preventing infinite loops.
1098*82d56013Sjoerg unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
10997330f729Sjoerg if (!Cascade)
1100*82d56013Sjoerg Cascade = ExtraRegInfo[VirtReg.reg()].Cascade = NextCascade++;
11017330f729Sjoerg
11027330f729Sjoerg LLVM_DEBUG(dbgs() << "evicting " << printReg(PhysReg, TRI)
11037330f729Sjoerg << " interference: Cascade " << Cascade << '\n');
11047330f729Sjoerg
11057330f729Sjoerg // Collect all interfering virtregs first.
11067330f729Sjoerg SmallVector<LiveInterval*, 8> Intfs;
11077330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
11087330f729Sjoerg LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
11097330f729Sjoerg // We usually have the interfering VRegs cached so collectInterferingVRegs()
11107330f729Sjoerg // should be fast, we may need to recalculate if when different physregs
11117330f729Sjoerg // overlap the same register unit so we had different SubRanges queried
11127330f729Sjoerg // against it.
11137330f729Sjoerg Q.collectInterferingVRegs();
11147330f729Sjoerg ArrayRef<LiveInterval*> IVR = Q.interferingVRegs();
11157330f729Sjoerg Intfs.append(IVR.begin(), IVR.end());
11167330f729Sjoerg }
11177330f729Sjoerg
11187330f729Sjoerg // Evict them second. This will invalidate the queries.
1119*82d56013Sjoerg for (LiveInterval *Intf : Intfs) {
11207330f729Sjoerg // The same VirtReg may be present in multiple RegUnits. Skip duplicates.
1121*82d56013Sjoerg if (!VRM->hasPhys(Intf->reg()))
11227330f729Sjoerg continue;
11237330f729Sjoerg
1124*82d56013Sjoerg LastEvicted.addEviction(PhysReg, VirtReg.reg(), Intf->reg());
11257330f729Sjoerg
11267330f729Sjoerg Matrix->unassign(*Intf);
1127*82d56013Sjoerg assert((ExtraRegInfo[Intf->reg()].Cascade < Cascade ||
11287330f729Sjoerg VirtReg.isSpillable() < Intf->isSpillable()) &&
11297330f729Sjoerg "Cannot decrease cascade number, illegal eviction");
1130*82d56013Sjoerg ExtraRegInfo[Intf->reg()].Cascade = Cascade;
11317330f729Sjoerg ++NumEvicted;
1132*82d56013Sjoerg NewVRegs.push_back(Intf->reg());
11337330f729Sjoerg }
11347330f729Sjoerg }
11357330f729Sjoerg
11367330f729Sjoerg /// Returns true if the given \p PhysReg is a callee saved register and has not
11377330f729Sjoerg /// been used for allocation yet.
isUnusedCalleeSavedReg(MCRegister PhysReg) const1138*82d56013Sjoerg bool RAGreedy::isUnusedCalleeSavedReg(MCRegister PhysReg) const {
1139*82d56013Sjoerg MCRegister CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg);
1140*82d56013Sjoerg if (!CSR)
11417330f729Sjoerg return false;
11427330f729Sjoerg
11437330f729Sjoerg return !Matrix->isPhysRegUsed(PhysReg);
11447330f729Sjoerg }
11457330f729Sjoerg
11467330f729Sjoerg /// tryEvict - Try to evict all interferences for a physreg.
11477330f729Sjoerg /// @param VirtReg Currently unassigned virtual register.
11487330f729Sjoerg /// @param Order Physregs to try.
11497330f729Sjoerg /// @return Physreg to assign VirtReg, or 0.
tryEvict(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,uint8_t CostPerUseLimit,const SmallVirtRegSet & FixedRegisters)1150*82d56013Sjoerg MCRegister RAGreedy::tryEvict(LiveInterval &VirtReg, AllocationOrder &Order,
1151*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
1152*82d56013Sjoerg uint8_t CostPerUseLimit,
11537330f729Sjoerg const SmallVirtRegSet &FixedRegisters) {
11547330f729Sjoerg NamedRegionTimer T("evict", "Evict", TimerGroupName, TimerGroupDescription,
11557330f729Sjoerg TimePassesIsEnabled);
11567330f729Sjoerg
11577330f729Sjoerg // Keep track of the cheapest interference seen so far.
11587330f729Sjoerg EvictionCost BestCost;
11597330f729Sjoerg BestCost.setMax();
1160*82d56013Sjoerg MCRegister BestPhys;
11617330f729Sjoerg unsigned OrderLimit = Order.getOrder().size();
11627330f729Sjoerg
11637330f729Sjoerg // When we are just looking for a reduced cost per use, don't break any
11647330f729Sjoerg // hints, and only evict smaller spill weights.
1165*82d56013Sjoerg if (CostPerUseLimit < uint8_t(~0u)) {
11667330f729Sjoerg BestCost.BrokenHints = 0;
1167*82d56013Sjoerg BestCost.MaxWeight = VirtReg.weight();
11687330f729Sjoerg
11697330f729Sjoerg // Check of any registers in RC are below CostPerUseLimit.
1170*82d56013Sjoerg const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg());
1171*82d56013Sjoerg uint8_t MinCost = RegClassInfo.getMinCost(RC);
11727330f729Sjoerg if (MinCost >= CostPerUseLimit) {
11737330f729Sjoerg LLVM_DEBUG(dbgs() << TRI->getRegClassName(RC) << " minimum cost = "
11747330f729Sjoerg << MinCost << ", no cheaper registers to be found.\n");
11757330f729Sjoerg return 0;
11767330f729Sjoerg }
11777330f729Sjoerg
11787330f729Sjoerg // It is normal for register classes to have a long tail of registers with
11797330f729Sjoerg // the same cost. We don't need to look at them if they're too expensive.
1180*82d56013Sjoerg if (RegCosts[Order.getOrder().back()] >= CostPerUseLimit) {
11817330f729Sjoerg OrderLimit = RegClassInfo.getLastCostChange(RC);
11827330f729Sjoerg LLVM_DEBUG(dbgs() << "Only trying the first " << OrderLimit
11837330f729Sjoerg << " regs.\n");
11847330f729Sjoerg }
11857330f729Sjoerg }
11867330f729Sjoerg
1187*82d56013Sjoerg for (auto I = Order.begin(), E = Order.getOrderLimitEnd(OrderLimit); I != E;
1188*82d56013Sjoerg ++I) {
1189*82d56013Sjoerg MCRegister PhysReg = *I;
1190*82d56013Sjoerg assert(PhysReg);
1191*82d56013Sjoerg if (RegCosts[PhysReg] >= CostPerUseLimit)
11927330f729Sjoerg continue;
11937330f729Sjoerg // The first use of a callee-saved register in a function has cost 1.
11947330f729Sjoerg // Don't start using a CSR when the CostPerUseLimit is low.
11957330f729Sjoerg if (CostPerUseLimit == 1 && isUnusedCalleeSavedReg(PhysReg)) {
11967330f729Sjoerg LLVM_DEBUG(
11977330f729Sjoerg dbgs() << printReg(PhysReg, TRI) << " would clobber CSR "
11987330f729Sjoerg << printReg(RegClassInfo.getLastCalleeSavedAlias(PhysReg), TRI)
11997330f729Sjoerg << '\n');
12007330f729Sjoerg continue;
12017330f729Sjoerg }
12027330f729Sjoerg
12037330f729Sjoerg if (!canEvictInterference(VirtReg, PhysReg, false, BestCost,
12047330f729Sjoerg FixedRegisters))
12057330f729Sjoerg continue;
12067330f729Sjoerg
12077330f729Sjoerg // Best so far.
12087330f729Sjoerg BestPhys = PhysReg;
12097330f729Sjoerg
12107330f729Sjoerg // Stop if the hint can be used.
1211*82d56013Sjoerg if (I.isHint())
12127330f729Sjoerg break;
12137330f729Sjoerg }
12147330f729Sjoerg
1215*82d56013Sjoerg if (BestPhys.isValid())
12167330f729Sjoerg evictInterference(VirtReg, BestPhys, NewVRegs);
12177330f729Sjoerg return BestPhys;
12187330f729Sjoerg }
12197330f729Sjoerg
12207330f729Sjoerg //===----------------------------------------------------------------------===//
12217330f729Sjoerg // Region Splitting
12227330f729Sjoerg //===----------------------------------------------------------------------===//
12237330f729Sjoerg
12247330f729Sjoerg /// addSplitConstraints - Fill out the SplitConstraints vector based on the
12257330f729Sjoerg /// interference pattern in Physreg and its aliases. Add the constraints to
12267330f729Sjoerg /// SpillPlacement and return the static cost of this split in Cost, assuming
12277330f729Sjoerg /// that all preferences in SplitConstraints are met.
12287330f729Sjoerg /// Return false if there are no bundles with positive bias.
addSplitConstraints(InterferenceCache::Cursor Intf,BlockFrequency & Cost)12297330f729Sjoerg bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
12307330f729Sjoerg BlockFrequency &Cost) {
12317330f729Sjoerg ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
12327330f729Sjoerg
12337330f729Sjoerg // Reset interference dependent info.
12347330f729Sjoerg SplitConstraints.resize(UseBlocks.size());
12357330f729Sjoerg BlockFrequency StaticCost = 0;
1236*82d56013Sjoerg for (unsigned I = 0; I != UseBlocks.size(); ++I) {
1237*82d56013Sjoerg const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
1238*82d56013Sjoerg SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
12397330f729Sjoerg
12407330f729Sjoerg BC.Number = BI.MBB->getNumber();
12417330f729Sjoerg Intf.moveToBlock(BC.Number);
12427330f729Sjoerg BC.Entry = BI.LiveIn ? SpillPlacement::PrefReg : SpillPlacement::DontCare;
12437330f729Sjoerg BC.Exit = (BI.LiveOut &&
12447330f729Sjoerg !LIS->getInstructionFromIndex(BI.LastInstr)->isImplicitDef())
12457330f729Sjoerg ? SpillPlacement::PrefReg
12467330f729Sjoerg : SpillPlacement::DontCare;
12477330f729Sjoerg BC.ChangesValue = BI.FirstDef.isValid();
12487330f729Sjoerg
12497330f729Sjoerg if (!Intf.hasInterference())
12507330f729Sjoerg continue;
12517330f729Sjoerg
12527330f729Sjoerg // Number of spill code instructions to insert.
12537330f729Sjoerg unsigned Ins = 0;
12547330f729Sjoerg
12557330f729Sjoerg // Interference for the live-in value.
12567330f729Sjoerg if (BI.LiveIn) {
12577330f729Sjoerg if (Intf.first() <= Indexes->getMBBStartIdx(BC.Number)) {
12587330f729Sjoerg BC.Entry = SpillPlacement::MustSpill;
12597330f729Sjoerg ++Ins;
12607330f729Sjoerg } else if (Intf.first() < BI.FirstInstr) {
12617330f729Sjoerg BC.Entry = SpillPlacement::PrefSpill;
12627330f729Sjoerg ++Ins;
12637330f729Sjoerg } else if (Intf.first() < BI.LastInstr) {
12647330f729Sjoerg ++Ins;
12657330f729Sjoerg }
12667330f729Sjoerg
12677330f729Sjoerg // Abort if the spill cannot be inserted at the MBB' start
12687330f729Sjoerg if (((BC.Entry == SpillPlacement::MustSpill) ||
12697330f729Sjoerg (BC.Entry == SpillPlacement::PrefSpill)) &&
12707330f729Sjoerg SlotIndex::isEarlierInstr(BI.FirstInstr,
12717330f729Sjoerg SA->getFirstSplitPoint(BC.Number)))
12727330f729Sjoerg return false;
12737330f729Sjoerg }
12747330f729Sjoerg
12757330f729Sjoerg // Interference for the live-out value.
12767330f729Sjoerg if (BI.LiveOut) {
12777330f729Sjoerg if (Intf.last() >= SA->getLastSplitPoint(BC.Number)) {
12787330f729Sjoerg BC.Exit = SpillPlacement::MustSpill;
12797330f729Sjoerg ++Ins;
12807330f729Sjoerg } else if (Intf.last() > BI.LastInstr) {
12817330f729Sjoerg BC.Exit = SpillPlacement::PrefSpill;
12827330f729Sjoerg ++Ins;
12837330f729Sjoerg } else if (Intf.last() > BI.FirstInstr) {
12847330f729Sjoerg ++Ins;
12857330f729Sjoerg }
12867330f729Sjoerg }
12877330f729Sjoerg
12887330f729Sjoerg // Accumulate the total frequency of inserted spill code.
12897330f729Sjoerg while (Ins--)
12907330f729Sjoerg StaticCost += SpillPlacer->getBlockFrequency(BC.Number);
12917330f729Sjoerg }
12927330f729Sjoerg Cost = StaticCost;
12937330f729Sjoerg
12947330f729Sjoerg // Add constraints for use-blocks. Note that these are the only constraints
12957330f729Sjoerg // that may add a positive bias, it is downhill from here.
12967330f729Sjoerg SpillPlacer->addConstraints(SplitConstraints);
12977330f729Sjoerg return SpillPlacer->scanActiveBundles();
12987330f729Sjoerg }
12997330f729Sjoerg
13007330f729Sjoerg /// addThroughConstraints - Add constraints and links to SpillPlacer from the
13017330f729Sjoerg /// live-through blocks in Blocks.
addThroughConstraints(InterferenceCache::Cursor Intf,ArrayRef<unsigned> Blocks)13027330f729Sjoerg bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
13037330f729Sjoerg ArrayRef<unsigned> Blocks) {
13047330f729Sjoerg const unsigned GroupSize = 8;
13057330f729Sjoerg SpillPlacement::BlockConstraint BCS[GroupSize];
13067330f729Sjoerg unsigned TBS[GroupSize];
13077330f729Sjoerg unsigned B = 0, T = 0;
13087330f729Sjoerg
1309*82d56013Sjoerg for (unsigned Number : Blocks) {
13107330f729Sjoerg Intf.moveToBlock(Number);
13117330f729Sjoerg
13127330f729Sjoerg if (!Intf.hasInterference()) {
13137330f729Sjoerg assert(T < GroupSize && "Array overflow");
13147330f729Sjoerg TBS[T] = Number;
13157330f729Sjoerg if (++T == GroupSize) {
13167330f729Sjoerg SpillPlacer->addLinks(makeArrayRef(TBS, T));
13177330f729Sjoerg T = 0;
13187330f729Sjoerg }
13197330f729Sjoerg continue;
13207330f729Sjoerg }
13217330f729Sjoerg
13227330f729Sjoerg assert(B < GroupSize && "Array overflow");
13237330f729Sjoerg BCS[B].Number = Number;
13247330f729Sjoerg
13257330f729Sjoerg // Abort if the spill cannot be inserted at the MBB' start
13267330f729Sjoerg MachineBasicBlock *MBB = MF->getBlockNumbered(Number);
1327*82d56013Sjoerg auto FirstNonDebugInstr = MBB->getFirstNonDebugInstr();
1328*82d56013Sjoerg if (FirstNonDebugInstr != MBB->end() &&
1329*82d56013Sjoerg SlotIndex::isEarlierInstr(LIS->getInstructionIndex(*FirstNonDebugInstr),
13307330f729Sjoerg SA->getFirstSplitPoint(Number)))
13317330f729Sjoerg return false;
13327330f729Sjoerg // Interference for the live-in value.
13337330f729Sjoerg if (Intf.first() <= Indexes->getMBBStartIdx(Number))
13347330f729Sjoerg BCS[B].Entry = SpillPlacement::MustSpill;
13357330f729Sjoerg else
13367330f729Sjoerg BCS[B].Entry = SpillPlacement::PrefSpill;
13377330f729Sjoerg
13387330f729Sjoerg // Interference for the live-out value.
13397330f729Sjoerg if (Intf.last() >= SA->getLastSplitPoint(Number))
13407330f729Sjoerg BCS[B].Exit = SpillPlacement::MustSpill;
13417330f729Sjoerg else
13427330f729Sjoerg BCS[B].Exit = SpillPlacement::PrefSpill;
13437330f729Sjoerg
13447330f729Sjoerg if (++B == GroupSize) {
13457330f729Sjoerg SpillPlacer->addConstraints(makeArrayRef(BCS, B));
13467330f729Sjoerg B = 0;
13477330f729Sjoerg }
13487330f729Sjoerg }
13497330f729Sjoerg
13507330f729Sjoerg SpillPlacer->addConstraints(makeArrayRef(BCS, B));
13517330f729Sjoerg SpillPlacer->addLinks(makeArrayRef(TBS, T));
13527330f729Sjoerg return true;
13537330f729Sjoerg }
13547330f729Sjoerg
growRegion(GlobalSplitCandidate & Cand)13557330f729Sjoerg bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
13567330f729Sjoerg // Keep track of through blocks that have not been added to SpillPlacer.
13577330f729Sjoerg BitVector Todo = SA->getThroughBlocks();
13587330f729Sjoerg SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
13597330f729Sjoerg unsigned AddedTo = 0;
13607330f729Sjoerg #ifndef NDEBUG
13617330f729Sjoerg unsigned Visited = 0;
13627330f729Sjoerg #endif
13637330f729Sjoerg
13647330f729Sjoerg while (true) {
13657330f729Sjoerg ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
13667330f729Sjoerg // Find new through blocks in the periphery of PrefRegBundles.
1367*82d56013Sjoerg for (unsigned Bundle : NewBundles) {
13687330f729Sjoerg // Look at all blocks connected to Bundle in the full graph.
13697330f729Sjoerg ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
1370*82d56013Sjoerg for (unsigned Block : Blocks) {
13717330f729Sjoerg if (!Todo.test(Block))
13727330f729Sjoerg continue;
13737330f729Sjoerg Todo.reset(Block);
13747330f729Sjoerg // This is a new through block. Add it to SpillPlacer later.
13757330f729Sjoerg ActiveBlocks.push_back(Block);
13767330f729Sjoerg #ifndef NDEBUG
13777330f729Sjoerg ++Visited;
13787330f729Sjoerg #endif
13797330f729Sjoerg }
13807330f729Sjoerg }
13817330f729Sjoerg // Any new blocks to add?
13827330f729Sjoerg if (ActiveBlocks.size() == AddedTo)
13837330f729Sjoerg break;
13847330f729Sjoerg
13857330f729Sjoerg // Compute through constraints from the interference, or assume that all
13867330f729Sjoerg // through blocks prefer spilling when forming compact regions.
13877330f729Sjoerg auto NewBlocks = makeArrayRef(ActiveBlocks).slice(AddedTo);
13887330f729Sjoerg if (Cand.PhysReg) {
13897330f729Sjoerg if (!addThroughConstraints(Cand.Intf, NewBlocks))
13907330f729Sjoerg return false;
13917330f729Sjoerg } else
13927330f729Sjoerg // Provide a strong negative bias on through blocks to prevent unwanted
13937330f729Sjoerg // liveness on loop backedges.
13947330f729Sjoerg SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true);
13957330f729Sjoerg AddedTo = ActiveBlocks.size();
13967330f729Sjoerg
13977330f729Sjoerg // Perhaps iterating can enable more bundles?
13987330f729Sjoerg SpillPlacer->iterate();
13997330f729Sjoerg }
14007330f729Sjoerg LLVM_DEBUG(dbgs() << ", v=" << Visited);
14017330f729Sjoerg return true;
14027330f729Sjoerg }
14037330f729Sjoerg
14047330f729Sjoerg /// calcCompactRegion - Compute the set of edge bundles that should be live
14057330f729Sjoerg /// when splitting the current live range into compact regions. Compact
14067330f729Sjoerg /// regions can be computed without looking at interference. They are the
14077330f729Sjoerg /// regions formed by removing all the live-through blocks from the live range.
14087330f729Sjoerg ///
14097330f729Sjoerg /// Returns false if the current live range is already compact, or if the
14107330f729Sjoerg /// compact regions would form single block regions anyway.
calcCompactRegion(GlobalSplitCandidate & Cand)14117330f729Sjoerg bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
14127330f729Sjoerg // Without any through blocks, the live range is already compact.
14137330f729Sjoerg if (!SA->getNumThroughBlocks())
14147330f729Sjoerg return false;
14157330f729Sjoerg
14167330f729Sjoerg // Compact regions don't correspond to any physreg.
1417*82d56013Sjoerg Cand.reset(IntfCache, MCRegister::NoRegister);
14187330f729Sjoerg
14197330f729Sjoerg LLVM_DEBUG(dbgs() << "Compact region bundles");
14207330f729Sjoerg
14217330f729Sjoerg // Use the spill placer to determine the live bundles. GrowRegion pretends
14227330f729Sjoerg // that all the through blocks have interference when PhysReg is unset.
14237330f729Sjoerg SpillPlacer->prepare(Cand.LiveBundles);
14247330f729Sjoerg
14257330f729Sjoerg // The static split cost will be zero since Cand.Intf reports no interference.
14267330f729Sjoerg BlockFrequency Cost;
14277330f729Sjoerg if (!addSplitConstraints(Cand.Intf, Cost)) {
14287330f729Sjoerg LLVM_DEBUG(dbgs() << ", none.\n");
14297330f729Sjoerg return false;
14307330f729Sjoerg }
14317330f729Sjoerg
14327330f729Sjoerg if (!growRegion(Cand)) {
14337330f729Sjoerg LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
14347330f729Sjoerg return false;
14357330f729Sjoerg }
14367330f729Sjoerg
14377330f729Sjoerg SpillPlacer->finish();
14387330f729Sjoerg
14397330f729Sjoerg if (!Cand.LiveBundles.any()) {
14407330f729Sjoerg LLVM_DEBUG(dbgs() << ", none.\n");
14417330f729Sjoerg return false;
14427330f729Sjoerg }
14437330f729Sjoerg
14447330f729Sjoerg LLVM_DEBUG({
1445*82d56013Sjoerg for (int I : Cand.LiveBundles.set_bits())
1446*82d56013Sjoerg dbgs() << " EB#" << I;
14477330f729Sjoerg dbgs() << ".\n";
14487330f729Sjoerg });
14497330f729Sjoerg return true;
14507330f729Sjoerg }
14517330f729Sjoerg
14527330f729Sjoerg /// calcSpillCost - Compute how expensive it would be to split the live range in
14537330f729Sjoerg /// SA around all use blocks instead of forming bundle regions.
calcSpillCost()14547330f729Sjoerg BlockFrequency RAGreedy::calcSpillCost() {
14557330f729Sjoerg BlockFrequency Cost = 0;
14567330f729Sjoerg ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
1457*82d56013Sjoerg for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
14587330f729Sjoerg unsigned Number = BI.MBB->getNumber();
14597330f729Sjoerg // We normally only need one spill instruction - a load or a store.
14607330f729Sjoerg Cost += SpillPlacer->getBlockFrequency(Number);
14617330f729Sjoerg
14627330f729Sjoerg // Unless the value is redefined in the block.
14637330f729Sjoerg if (BI.LiveIn && BI.LiveOut && BI.FirstDef)
14647330f729Sjoerg Cost += SpillPlacer->getBlockFrequency(Number);
14657330f729Sjoerg }
14667330f729Sjoerg return Cost;
14677330f729Sjoerg }
14687330f729Sjoerg
14697330f729Sjoerg /// Check if splitting Evictee will create a local split interval in
14707330f729Sjoerg /// basic block number BBNumber that may cause a bad eviction chain. This is
14717330f729Sjoerg /// intended to prevent bad eviction sequences like:
14727330f729Sjoerg /// movl %ebp, 8(%esp) # 4-byte Spill
14737330f729Sjoerg /// movl %ecx, %ebp
14747330f729Sjoerg /// movl %ebx, %ecx
14757330f729Sjoerg /// movl %edi, %ebx
14767330f729Sjoerg /// movl %edx, %edi
14777330f729Sjoerg /// cltd
14787330f729Sjoerg /// idivl %esi
14797330f729Sjoerg /// movl %edi, %edx
14807330f729Sjoerg /// movl %ebx, %edi
14817330f729Sjoerg /// movl %ecx, %ebx
14827330f729Sjoerg /// movl %ebp, %ecx
14837330f729Sjoerg /// movl 16(%esp), %ebp # 4 - byte Reload
14847330f729Sjoerg ///
14857330f729Sjoerg /// Such sequences are created in 2 scenarios:
14867330f729Sjoerg ///
14877330f729Sjoerg /// Scenario #1:
14887330f729Sjoerg /// %0 is evicted from physreg0 by %1.
14897330f729Sjoerg /// Evictee %0 is intended for region splitting with split candidate
14907330f729Sjoerg /// physreg0 (the reg %0 was evicted from).
14917330f729Sjoerg /// Region splitting creates a local interval because of interference with the
14927330f729Sjoerg /// evictor %1 (normally region splitting creates 2 interval, the "by reg"
14937330f729Sjoerg /// and "by stack" intervals and local interval created when interference
14947330f729Sjoerg /// occurs).
14957330f729Sjoerg /// One of the split intervals ends up evicting %2 from physreg1.
14967330f729Sjoerg /// Evictee %2 is intended for region splitting with split candidate
14977330f729Sjoerg /// physreg1.
14987330f729Sjoerg /// One of the split intervals ends up evicting %3 from physreg2, etc.
14997330f729Sjoerg ///
15007330f729Sjoerg /// Scenario #2
15017330f729Sjoerg /// %0 is evicted from physreg0 by %1.
15027330f729Sjoerg /// %2 is evicted from physreg2 by %3 etc.
15037330f729Sjoerg /// Evictee %0 is intended for region splitting with split candidate
15047330f729Sjoerg /// physreg1.
15057330f729Sjoerg /// Region splitting creates a local interval because of interference with the
15067330f729Sjoerg /// evictor %1.
15077330f729Sjoerg /// One of the split intervals ends up evicting back original evictor %1
15087330f729Sjoerg /// from physreg0 (the reg %0 was evicted from).
15097330f729Sjoerg /// Another evictee %2 is intended for region splitting with split candidate
15107330f729Sjoerg /// physreg1.
15117330f729Sjoerg /// One of the split intervals ends up evicting %3 from physreg2, etc.
15127330f729Sjoerg ///
15137330f729Sjoerg /// \param Evictee The register considered to be split.
15147330f729Sjoerg /// \param Cand The split candidate that determines the physical register
15157330f729Sjoerg /// we are splitting for and the interferences.
15167330f729Sjoerg /// \param BBNumber The number of a BB for which the region split process will
15177330f729Sjoerg /// create a local split interval.
15187330f729Sjoerg /// \param Order The physical registers that may get evicted by a split
15197330f729Sjoerg /// artifact of Evictee.
15207330f729Sjoerg /// \return True if splitting Evictee may cause a bad eviction chain, false
15217330f729Sjoerg /// otherwise.
splitCanCauseEvictionChain(Register Evictee,GlobalSplitCandidate & Cand,unsigned BBNumber,const AllocationOrder & Order)1522*82d56013Sjoerg bool RAGreedy::splitCanCauseEvictionChain(Register Evictee,
15237330f729Sjoerg GlobalSplitCandidate &Cand,
15247330f729Sjoerg unsigned BBNumber,
15257330f729Sjoerg const AllocationOrder &Order) {
15267330f729Sjoerg EvictionTrack::EvictorInfo VregEvictorInfo = LastEvicted.getEvictor(Evictee);
15277330f729Sjoerg unsigned Evictor = VregEvictorInfo.first;
1528*82d56013Sjoerg MCRegister PhysReg = VregEvictorInfo.second;
15297330f729Sjoerg
15307330f729Sjoerg // No actual evictor.
15317330f729Sjoerg if (!Evictor || !PhysReg)
15327330f729Sjoerg return false;
15337330f729Sjoerg
15347330f729Sjoerg float MaxWeight = 0;
1535*82d56013Sjoerg MCRegister FutureEvictedPhysReg =
15367330f729Sjoerg getCheapestEvicteeWeight(Order, LIS->getInterval(Evictee),
15377330f729Sjoerg Cand.Intf.first(), Cand.Intf.last(), &MaxWeight);
15387330f729Sjoerg
15397330f729Sjoerg // The bad eviction chain occurs when either the split candidate is the
15407330f729Sjoerg // evicting reg or one of the split artifact will evict the evicting reg.
15417330f729Sjoerg if ((PhysReg != Cand.PhysReg) && (PhysReg != FutureEvictedPhysReg))
15427330f729Sjoerg return false;
15437330f729Sjoerg
15447330f729Sjoerg Cand.Intf.moveToBlock(BBNumber);
15457330f729Sjoerg
15467330f729Sjoerg // Check to see if the Evictor contains interference (with Evictee) in the
15477330f729Sjoerg // given BB. If so, this interference caused the eviction of Evictee from
15487330f729Sjoerg // PhysReg. This suggest that we will create a local interval during the
15497330f729Sjoerg // region split to avoid this interference This local interval may cause a bad
15507330f729Sjoerg // eviction chain.
15517330f729Sjoerg if (!LIS->hasInterval(Evictor))
15527330f729Sjoerg return false;
15537330f729Sjoerg LiveInterval &EvictorLI = LIS->getInterval(Evictor);
15547330f729Sjoerg if (EvictorLI.FindSegmentContaining(Cand.Intf.first()) == EvictorLI.end())
15557330f729Sjoerg return false;
15567330f729Sjoerg
15577330f729Sjoerg // Now, check to see if the local interval we will create is going to be
15587330f729Sjoerg // expensive enough to evict somebody If so, this may cause a bad eviction
15597330f729Sjoerg // chain.
15607330f729Sjoerg float splitArtifactWeight =
1561*82d56013Sjoerg VRAI->futureWeight(LIS->getInterval(Evictee),
15627330f729Sjoerg Cand.Intf.first().getPrevIndex(), Cand.Intf.last());
15637330f729Sjoerg if (splitArtifactWeight >= 0 && splitArtifactWeight < MaxWeight)
15647330f729Sjoerg return false;
15657330f729Sjoerg
15667330f729Sjoerg return true;
15677330f729Sjoerg }
15687330f729Sjoerg
15697330f729Sjoerg /// Check if splitting VirtRegToSplit will create a local split interval
15707330f729Sjoerg /// in basic block number BBNumber that may cause a spill.
15717330f729Sjoerg ///
15727330f729Sjoerg /// \param VirtRegToSplit The register considered to be split.
15737330f729Sjoerg /// \param Cand The split candidate that determines the physical
15747330f729Sjoerg /// register we are splitting for and the interferences.
15757330f729Sjoerg /// \param BBNumber The number of a BB for which the region split process
15767330f729Sjoerg /// will create a local split interval.
15777330f729Sjoerg /// \param Order The physical registers that may get evicted by a
15787330f729Sjoerg /// split artifact of VirtRegToSplit.
15797330f729Sjoerg /// \return True if splitting VirtRegToSplit may cause a spill, false
15807330f729Sjoerg /// otherwise.
splitCanCauseLocalSpill(unsigned VirtRegToSplit,GlobalSplitCandidate & Cand,unsigned BBNumber,const AllocationOrder & Order)15817330f729Sjoerg bool RAGreedy::splitCanCauseLocalSpill(unsigned VirtRegToSplit,
15827330f729Sjoerg GlobalSplitCandidate &Cand,
15837330f729Sjoerg unsigned BBNumber,
15847330f729Sjoerg const AllocationOrder &Order) {
15857330f729Sjoerg Cand.Intf.moveToBlock(BBNumber);
15867330f729Sjoerg
15877330f729Sjoerg // Check if the local interval will find a non interfereing assignment.
15887330f729Sjoerg for (auto PhysReg : Order.getOrder()) {
15897330f729Sjoerg if (!Matrix->checkInterference(Cand.Intf.first().getPrevIndex(),
15907330f729Sjoerg Cand.Intf.last(), PhysReg))
15917330f729Sjoerg return false;
15927330f729Sjoerg }
15937330f729Sjoerg
1594*82d56013Sjoerg // The local interval is not able to find non interferencing assignment
1595*82d56013Sjoerg // and not able to evict a less worthy interval, therfore, it can cause a
1596*82d56013Sjoerg // spill.
15977330f729Sjoerg return true;
15987330f729Sjoerg }
15997330f729Sjoerg
16007330f729Sjoerg /// calcGlobalSplitCost - Return the global split cost of following the split
16017330f729Sjoerg /// pattern in LiveBundles. This cost should be added to the local cost of the
16027330f729Sjoerg /// interference pattern in SplitConstraints.
16037330f729Sjoerg ///
calcGlobalSplitCost(GlobalSplitCandidate & Cand,const AllocationOrder & Order,bool * CanCauseEvictionChain)16047330f729Sjoerg BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
16057330f729Sjoerg const AllocationOrder &Order,
16067330f729Sjoerg bool *CanCauseEvictionChain) {
16077330f729Sjoerg BlockFrequency GlobalCost = 0;
16087330f729Sjoerg const BitVector &LiveBundles = Cand.LiveBundles;
1609*82d56013Sjoerg Register VirtRegToSplit = SA->getParent().reg();
16107330f729Sjoerg ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
1611*82d56013Sjoerg for (unsigned I = 0; I != UseBlocks.size(); ++I) {
1612*82d56013Sjoerg const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
1613*82d56013Sjoerg SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
16147330f729Sjoerg bool RegIn = LiveBundles[Bundles->getBundle(BC.Number, false)];
16157330f729Sjoerg bool RegOut = LiveBundles[Bundles->getBundle(BC.Number, true)];
16167330f729Sjoerg unsigned Ins = 0;
16177330f729Sjoerg
16187330f729Sjoerg Cand.Intf.moveToBlock(BC.Number);
16197330f729Sjoerg // Check wheather a local interval is going to be created during the region
16207330f729Sjoerg // split. Calculate adavanced spilt cost (cost of local intervals) if option
16217330f729Sjoerg // is enabled.
16227330f729Sjoerg if (EnableAdvancedRASplitCost && Cand.Intf.hasInterference() && BI.LiveIn &&
16237330f729Sjoerg BI.LiveOut && RegIn && RegOut) {
16247330f729Sjoerg
16257330f729Sjoerg if (CanCauseEvictionChain &&
16267330f729Sjoerg splitCanCauseEvictionChain(VirtRegToSplit, Cand, BC.Number, Order)) {
16277330f729Sjoerg // This interference causes our eviction from this assignment, we might
16287330f729Sjoerg // evict somebody else and eventually someone will spill, add that cost.
16297330f729Sjoerg // See splitCanCauseEvictionChain for detailed description of scenarios.
16307330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
16317330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
16327330f729Sjoerg
16337330f729Sjoerg *CanCauseEvictionChain = true;
16347330f729Sjoerg
16357330f729Sjoerg } else if (splitCanCauseLocalSpill(VirtRegToSplit, Cand, BC.Number,
16367330f729Sjoerg Order)) {
16377330f729Sjoerg // This interference causes local interval to spill, add that cost.
16387330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
16397330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
16407330f729Sjoerg }
16417330f729Sjoerg }
16427330f729Sjoerg
16437330f729Sjoerg if (BI.LiveIn)
16447330f729Sjoerg Ins += RegIn != (BC.Entry == SpillPlacement::PrefReg);
16457330f729Sjoerg if (BI.LiveOut)
16467330f729Sjoerg Ins += RegOut != (BC.Exit == SpillPlacement::PrefReg);
16477330f729Sjoerg while (Ins--)
16487330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
16497330f729Sjoerg }
16507330f729Sjoerg
1651*82d56013Sjoerg for (unsigned Number : Cand.ActiveBlocks) {
16527330f729Sjoerg bool RegIn = LiveBundles[Bundles->getBundle(Number, false)];
16537330f729Sjoerg bool RegOut = LiveBundles[Bundles->getBundle(Number, true)];
16547330f729Sjoerg if (!RegIn && !RegOut)
16557330f729Sjoerg continue;
16567330f729Sjoerg if (RegIn && RegOut) {
16577330f729Sjoerg // We need double spill code if this block has interference.
16587330f729Sjoerg Cand.Intf.moveToBlock(Number);
16597330f729Sjoerg if (Cand.Intf.hasInterference()) {
16607330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(Number);
16617330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(Number);
16627330f729Sjoerg
16637330f729Sjoerg // Check wheather a local interval is going to be created during the
16647330f729Sjoerg // region split.
16657330f729Sjoerg if (EnableAdvancedRASplitCost && CanCauseEvictionChain &&
16667330f729Sjoerg splitCanCauseEvictionChain(VirtRegToSplit, Cand, Number, Order)) {
16677330f729Sjoerg // This interference cause our eviction from this assignment, we might
16687330f729Sjoerg // evict somebody else, add that cost.
16697330f729Sjoerg // See splitCanCauseEvictionChain for detailed description of
16707330f729Sjoerg // scenarios.
16717330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(Number);
16727330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(Number);
16737330f729Sjoerg
16747330f729Sjoerg *CanCauseEvictionChain = true;
16757330f729Sjoerg }
16767330f729Sjoerg }
16777330f729Sjoerg continue;
16787330f729Sjoerg }
16797330f729Sjoerg // live-in / stack-out or stack-in live-out.
16807330f729Sjoerg GlobalCost += SpillPlacer->getBlockFrequency(Number);
16817330f729Sjoerg }
16827330f729Sjoerg return GlobalCost;
16837330f729Sjoerg }
16847330f729Sjoerg
16857330f729Sjoerg /// splitAroundRegion - Split the current live range around the regions
16867330f729Sjoerg /// determined by BundleCand and GlobalCand.
16877330f729Sjoerg ///
16887330f729Sjoerg /// Before calling this function, GlobalCand and BundleCand must be initialized
16897330f729Sjoerg /// so each bundle is assigned to a valid candidate, or NoCand for the
16907330f729Sjoerg /// stack-bound bundles. The shared SA/SE SplitAnalysis and SplitEditor
16917330f729Sjoerg /// objects must be initialized for the current live range, and intervals
16927330f729Sjoerg /// created for the used candidates.
16937330f729Sjoerg ///
16947330f729Sjoerg /// @param LREdit The LiveRangeEdit object handling the current split.
16957330f729Sjoerg /// @param UsedCands List of used GlobalCand entries. Every BundleCand value
16967330f729Sjoerg /// must appear in this list.
splitAroundRegion(LiveRangeEdit & LREdit,ArrayRef<unsigned> UsedCands)16977330f729Sjoerg void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
16987330f729Sjoerg ArrayRef<unsigned> UsedCands) {
16997330f729Sjoerg // These are the intervals created for new global ranges. We may create more
17007330f729Sjoerg // intervals for local ranges.
17017330f729Sjoerg const unsigned NumGlobalIntvs = LREdit.size();
17027330f729Sjoerg LLVM_DEBUG(dbgs() << "splitAroundRegion with " << NumGlobalIntvs
17037330f729Sjoerg << " globals.\n");
17047330f729Sjoerg assert(NumGlobalIntvs && "No global intervals configured");
17057330f729Sjoerg
17067330f729Sjoerg // Isolate even single instructions when dealing with a proper sub-class.
17077330f729Sjoerg // That guarantees register class inflation for the stack interval because it
17087330f729Sjoerg // is all copies.
1709*82d56013Sjoerg Register Reg = SA->getParent().reg();
17107330f729Sjoerg bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
17117330f729Sjoerg
17127330f729Sjoerg // First handle all the blocks with uses.
17137330f729Sjoerg ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
1714*82d56013Sjoerg for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
17157330f729Sjoerg unsigned Number = BI.MBB->getNumber();
17167330f729Sjoerg unsigned IntvIn = 0, IntvOut = 0;
17177330f729Sjoerg SlotIndex IntfIn, IntfOut;
17187330f729Sjoerg if (BI.LiveIn) {
17197330f729Sjoerg unsigned CandIn = BundleCand[Bundles->getBundle(Number, false)];
17207330f729Sjoerg if (CandIn != NoCand) {
17217330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[CandIn];
17227330f729Sjoerg IntvIn = Cand.IntvIdx;
17237330f729Sjoerg Cand.Intf.moveToBlock(Number);
17247330f729Sjoerg IntfIn = Cand.Intf.first();
17257330f729Sjoerg }
17267330f729Sjoerg }
17277330f729Sjoerg if (BI.LiveOut) {
17287330f729Sjoerg unsigned CandOut = BundleCand[Bundles->getBundle(Number, true)];
17297330f729Sjoerg if (CandOut != NoCand) {
17307330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[CandOut];
17317330f729Sjoerg IntvOut = Cand.IntvIdx;
17327330f729Sjoerg Cand.Intf.moveToBlock(Number);
17337330f729Sjoerg IntfOut = Cand.Intf.last();
17347330f729Sjoerg }
17357330f729Sjoerg }
17367330f729Sjoerg
17377330f729Sjoerg // Create separate intervals for isolated blocks with multiple uses.
17387330f729Sjoerg if (!IntvIn && !IntvOut) {
17397330f729Sjoerg LLVM_DEBUG(dbgs() << printMBBReference(*BI.MBB) << " isolated.\n");
17407330f729Sjoerg if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
17417330f729Sjoerg SE->splitSingleBlock(BI);
17427330f729Sjoerg continue;
17437330f729Sjoerg }
17447330f729Sjoerg
17457330f729Sjoerg if (IntvIn && IntvOut)
17467330f729Sjoerg SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut);
17477330f729Sjoerg else if (IntvIn)
17487330f729Sjoerg SE->splitRegInBlock(BI, IntvIn, IntfIn);
17497330f729Sjoerg else
17507330f729Sjoerg SE->splitRegOutBlock(BI, IntvOut, IntfOut);
17517330f729Sjoerg }
17527330f729Sjoerg
17537330f729Sjoerg // Handle live-through blocks. The relevant live-through blocks are stored in
17547330f729Sjoerg // the ActiveBlocks list with each candidate. We need to filter out
17557330f729Sjoerg // duplicates.
17567330f729Sjoerg BitVector Todo = SA->getThroughBlocks();
17577330f729Sjoerg for (unsigned c = 0; c != UsedCands.size(); ++c) {
17587330f729Sjoerg ArrayRef<unsigned> Blocks = GlobalCand[UsedCands[c]].ActiveBlocks;
1759*82d56013Sjoerg for (unsigned Number : Blocks) {
17607330f729Sjoerg if (!Todo.test(Number))
17617330f729Sjoerg continue;
17627330f729Sjoerg Todo.reset(Number);
17637330f729Sjoerg
17647330f729Sjoerg unsigned IntvIn = 0, IntvOut = 0;
17657330f729Sjoerg SlotIndex IntfIn, IntfOut;
17667330f729Sjoerg
17677330f729Sjoerg unsigned CandIn = BundleCand[Bundles->getBundle(Number, false)];
17687330f729Sjoerg if (CandIn != NoCand) {
17697330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[CandIn];
17707330f729Sjoerg IntvIn = Cand.IntvIdx;
17717330f729Sjoerg Cand.Intf.moveToBlock(Number);
17727330f729Sjoerg IntfIn = Cand.Intf.first();
17737330f729Sjoerg }
17747330f729Sjoerg
17757330f729Sjoerg unsigned CandOut = BundleCand[Bundles->getBundle(Number, true)];
17767330f729Sjoerg if (CandOut != NoCand) {
17777330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[CandOut];
17787330f729Sjoerg IntvOut = Cand.IntvIdx;
17797330f729Sjoerg Cand.Intf.moveToBlock(Number);
17807330f729Sjoerg IntfOut = Cand.Intf.last();
17817330f729Sjoerg }
17827330f729Sjoerg if (!IntvIn && !IntvOut)
17837330f729Sjoerg continue;
17847330f729Sjoerg SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut);
17857330f729Sjoerg }
17867330f729Sjoerg }
17877330f729Sjoerg
17887330f729Sjoerg ++NumGlobalSplits;
17897330f729Sjoerg
17907330f729Sjoerg SmallVector<unsigned, 8> IntvMap;
17917330f729Sjoerg SE->finish(&IntvMap);
17927330f729Sjoerg DebugVars->splitRegister(Reg, LREdit.regs(), *LIS);
17937330f729Sjoerg
17947330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
17957330f729Sjoerg unsigned OrigBlocks = SA->getNumLiveBlocks();
17967330f729Sjoerg
17977330f729Sjoerg // Sort out the new intervals created by splitting. We get four kinds:
17987330f729Sjoerg // - Remainder intervals should not be split again.
17997330f729Sjoerg // - Candidate intervals can be assigned to Cand.PhysReg.
18007330f729Sjoerg // - Block-local splits are candidates for local splitting.
18017330f729Sjoerg // - DCE leftovers should go back on the queue.
1802*82d56013Sjoerg for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
1803*82d56013Sjoerg LiveInterval &Reg = LIS->getInterval(LREdit.get(I));
18047330f729Sjoerg
18057330f729Sjoerg // Ignore old intervals from DCE.
18067330f729Sjoerg if (getStage(Reg) != RS_New)
18077330f729Sjoerg continue;
18087330f729Sjoerg
18097330f729Sjoerg // Remainder interval. Don't try splitting again, spill if it doesn't
18107330f729Sjoerg // allocate.
1811*82d56013Sjoerg if (IntvMap[I] == 0) {
18127330f729Sjoerg setStage(Reg, RS_Spill);
18137330f729Sjoerg continue;
18147330f729Sjoerg }
18157330f729Sjoerg
18167330f729Sjoerg // Global intervals. Allow repeated splitting as long as the number of live
18177330f729Sjoerg // blocks is strictly decreasing.
1818*82d56013Sjoerg if (IntvMap[I] < NumGlobalIntvs) {
18197330f729Sjoerg if (SA->countLiveBlocks(&Reg) >= OrigBlocks) {
18207330f729Sjoerg LLVM_DEBUG(dbgs() << "Main interval covers the same " << OrigBlocks
18217330f729Sjoerg << " blocks as original.\n");
18227330f729Sjoerg // Don't allow repeated splitting as a safe guard against looping.
18237330f729Sjoerg setStage(Reg, RS_Split2);
18247330f729Sjoerg }
18257330f729Sjoerg continue;
18267330f729Sjoerg }
18277330f729Sjoerg
18287330f729Sjoerg // Other intervals are treated as new. This includes local intervals created
18297330f729Sjoerg // for blocks with multiple uses, and anything created by DCE.
18307330f729Sjoerg }
18317330f729Sjoerg
18327330f729Sjoerg if (VerifyEnabled)
18337330f729Sjoerg MF->verify(this, "After splitting live range around region");
18347330f729Sjoerg }
18357330f729Sjoerg
tryRegionSplit(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)1836*82d56013Sjoerg MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
1837*82d56013Sjoerg AllocationOrder &Order,
1838*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
1839*82d56013Sjoerg if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1840*82d56013Sjoerg return MCRegister::NoRegister;
18417330f729Sjoerg unsigned NumCands = 0;
18427330f729Sjoerg BlockFrequency SpillCost = calcSpillCost();
18437330f729Sjoerg BlockFrequency BestCost;
18447330f729Sjoerg
18457330f729Sjoerg // Check if we can split this live range around a compact region.
18467330f729Sjoerg bool HasCompact = calcCompactRegion(GlobalCand.front());
18477330f729Sjoerg if (HasCompact) {
18487330f729Sjoerg // Yes, keep GlobalCand[0] as the compact region candidate.
18497330f729Sjoerg NumCands = 1;
18507330f729Sjoerg BestCost = BlockFrequency::getMaxFrequency();
18517330f729Sjoerg } else {
18527330f729Sjoerg // No benefit from the compact region, our fallback will be per-block
18537330f729Sjoerg // splitting. Make sure we find a solution that is cheaper than spilling.
18547330f729Sjoerg BestCost = SpillCost;
18557330f729Sjoerg LLVM_DEBUG(dbgs() << "Cost of isolating all blocks = ";
18567330f729Sjoerg MBFI->printBlockFreq(dbgs(), BestCost) << '\n');
18577330f729Sjoerg }
18587330f729Sjoerg
18597330f729Sjoerg bool CanCauseEvictionChain = false;
18607330f729Sjoerg unsigned BestCand =
18617330f729Sjoerg calculateRegionSplitCost(VirtReg, Order, BestCost, NumCands,
18627330f729Sjoerg false /*IgnoreCSR*/, &CanCauseEvictionChain);
18637330f729Sjoerg
18647330f729Sjoerg // Split candidates with compact regions can cause a bad eviction sequence.
18657330f729Sjoerg // See splitCanCauseEvictionChain for detailed description of scenarios.
18667330f729Sjoerg // To avoid it, we need to comapre the cost with the spill cost and not the
18677330f729Sjoerg // current max frequency.
18687330f729Sjoerg if (HasCompact && (BestCost > SpillCost) && (BestCand != NoCand) &&
18697330f729Sjoerg CanCauseEvictionChain) {
1870*82d56013Sjoerg return MCRegister::NoRegister;
18717330f729Sjoerg }
18727330f729Sjoerg
18737330f729Sjoerg // No solutions found, fall back to single block splitting.
18747330f729Sjoerg if (!HasCompact && BestCand == NoCand)
1875*82d56013Sjoerg return MCRegister::NoRegister;
18767330f729Sjoerg
18777330f729Sjoerg return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
18787330f729Sjoerg }
18797330f729Sjoerg
calculateRegionSplitCost(LiveInterval & VirtReg,AllocationOrder & Order,BlockFrequency & BestCost,unsigned & NumCands,bool IgnoreCSR,bool * CanCauseEvictionChain)18807330f729Sjoerg unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
18817330f729Sjoerg AllocationOrder &Order,
18827330f729Sjoerg BlockFrequency &BestCost,
18837330f729Sjoerg unsigned &NumCands, bool IgnoreCSR,
18847330f729Sjoerg bool *CanCauseEvictionChain) {
18857330f729Sjoerg unsigned BestCand = NoCand;
1886*82d56013Sjoerg for (MCPhysReg PhysReg : Order) {
1887*82d56013Sjoerg assert(PhysReg);
18887330f729Sjoerg if (IgnoreCSR && isUnusedCalleeSavedReg(PhysReg))
18897330f729Sjoerg continue;
18907330f729Sjoerg
18917330f729Sjoerg // Discard bad candidates before we run out of interference cache cursors.
18927330f729Sjoerg // This will only affect register classes with a lot of registers (>32).
18937330f729Sjoerg if (NumCands == IntfCache.getMaxCursors()) {
18947330f729Sjoerg unsigned WorstCount = ~0u;
18957330f729Sjoerg unsigned Worst = 0;
1896*82d56013Sjoerg for (unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1897*82d56013Sjoerg if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
18987330f729Sjoerg continue;
1899*82d56013Sjoerg unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
19007330f729Sjoerg if (Count < WorstCount) {
1901*82d56013Sjoerg Worst = CandIndex;
19027330f729Sjoerg WorstCount = Count;
19037330f729Sjoerg }
19047330f729Sjoerg }
19057330f729Sjoerg --NumCands;
19067330f729Sjoerg GlobalCand[Worst] = GlobalCand[NumCands];
19077330f729Sjoerg if (BestCand == NumCands)
19087330f729Sjoerg BestCand = Worst;
19097330f729Sjoerg }
19107330f729Sjoerg
19117330f729Sjoerg if (GlobalCand.size() <= NumCands)
19127330f729Sjoerg GlobalCand.resize(NumCands+1);
19137330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[NumCands];
19147330f729Sjoerg Cand.reset(IntfCache, PhysReg);
19157330f729Sjoerg
19167330f729Sjoerg SpillPlacer->prepare(Cand.LiveBundles);
19177330f729Sjoerg BlockFrequency Cost;
19187330f729Sjoerg if (!addSplitConstraints(Cand.Intf, Cost)) {
19197330f729Sjoerg LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << "\tno positive bundles\n");
19207330f729Sjoerg continue;
19217330f729Sjoerg }
19227330f729Sjoerg LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << "\tstatic = ";
19237330f729Sjoerg MBFI->printBlockFreq(dbgs(), Cost));
19247330f729Sjoerg if (Cost >= BestCost) {
19257330f729Sjoerg LLVM_DEBUG({
19267330f729Sjoerg if (BestCand == NoCand)
19277330f729Sjoerg dbgs() << " worse than no bundles\n";
19287330f729Sjoerg else
19297330f729Sjoerg dbgs() << " worse than "
19307330f729Sjoerg << printReg(GlobalCand[BestCand].PhysReg, TRI) << '\n';
19317330f729Sjoerg });
19327330f729Sjoerg continue;
19337330f729Sjoerg }
19347330f729Sjoerg if (!growRegion(Cand)) {
19357330f729Sjoerg LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
19367330f729Sjoerg continue;
19377330f729Sjoerg }
19387330f729Sjoerg
19397330f729Sjoerg SpillPlacer->finish();
19407330f729Sjoerg
19417330f729Sjoerg // No live bundles, defer to splitSingleBlocks().
19427330f729Sjoerg if (!Cand.LiveBundles.any()) {
19437330f729Sjoerg LLVM_DEBUG(dbgs() << " no bundles.\n");
19447330f729Sjoerg continue;
19457330f729Sjoerg }
19467330f729Sjoerg
19477330f729Sjoerg bool HasEvictionChain = false;
19487330f729Sjoerg Cost += calcGlobalSplitCost(Cand, Order, &HasEvictionChain);
19497330f729Sjoerg LLVM_DEBUG({
19507330f729Sjoerg dbgs() << ", total = ";
19517330f729Sjoerg MBFI->printBlockFreq(dbgs(), Cost) << " with bundles";
1952*82d56013Sjoerg for (int I : Cand.LiveBundles.set_bits())
1953*82d56013Sjoerg dbgs() << " EB#" << I;
19547330f729Sjoerg dbgs() << ".\n";
19557330f729Sjoerg });
19567330f729Sjoerg if (Cost < BestCost) {
19577330f729Sjoerg BestCand = NumCands;
19587330f729Sjoerg BestCost = Cost;
19597330f729Sjoerg // See splitCanCauseEvictionChain for detailed description of bad
19607330f729Sjoerg // eviction chain scenarios.
19617330f729Sjoerg if (CanCauseEvictionChain)
19627330f729Sjoerg *CanCauseEvictionChain = HasEvictionChain;
19637330f729Sjoerg }
19647330f729Sjoerg ++NumCands;
19657330f729Sjoerg }
19667330f729Sjoerg
19677330f729Sjoerg if (CanCauseEvictionChain && BestCand != NoCand) {
19687330f729Sjoerg // See splitCanCauseEvictionChain for detailed description of bad
19697330f729Sjoerg // eviction chain scenarios.
19707330f729Sjoerg LLVM_DEBUG(dbgs() << "Best split candidate of vreg "
1971*82d56013Sjoerg << printReg(VirtReg.reg(), TRI) << " may ");
19727330f729Sjoerg if (!(*CanCauseEvictionChain))
19737330f729Sjoerg LLVM_DEBUG(dbgs() << "not ");
19747330f729Sjoerg LLVM_DEBUG(dbgs() << "cause bad eviction chain\n");
19757330f729Sjoerg }
19767330f729Sjoerg
19777330f729Sjoerg return BestCand;
19787330f729Sjoerg }
19797330f729Sjoerg
doRegionSplit(LiveInterval & VirtReg,unsigned BestCand,bool HasCompact,SmallVectorImpl<Register> & NewVRegs)19807330f729Sjoerg unsigned RAGreedy::doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
19817330f729Sjoerg bool HasCompact,
1982*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
19837330f729Sjoerg SmallVector<unsigned, 8> UsedCands;
19847330f729Sjoerg // Prepare split editor.
19857330f729Sjoerg LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
19867330f729Sjoerg SE->reset(LREdit, SplitSpillMode);
19877330f729Sjoerg
19887330f729Sjoerg // Assign all edge bundles to the preferred candidate, or NoCand.
19897330f729Sjoerg BundleCand.assign(Bundles->getNumBundles(), NoCand);
19907330f729Sjoerg
19917330f729Sjoerg // Assign bundles for the best candidate region.
19927330f729Sjoerg if (BestCand != NoCand) {
19937330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand[BestCand];
19947330f729Sjoerg if (unsigned B = Cand.getBundles(BundleCand, BestCand)) {
19957330f729Sjoerg UsedCands.push_back(BestCand);
19967330f729Sjoerg Cand.IntvIdx = SE->openIntv();
19977330f729Sjoerg LLVM_DEBUG(dbgs() << "Split for " << printReg(Cand.PhysReg, TRI) << " in "
19987330f729Sjoerg << B << " bundles, intv " << Cand.IntvIdx << ".\n");
19997330f729Sjoerg (void)B;
20007330f729Sjoerg }
20017330f729Sjoerg }
20027330f729Sjoerg
20037330f729Sjoerg // Assign bundles for the compact region.
20047330f729Sjoerg if (HasCompact) {
20057330f729Sjoerg GlobalSplitCandidate &Cand = GlobalCand.front();
20067330f729Sjoerg assert(!Cand.PhysReg && "Compact region has no physreg");
20077330f729Sjoerg if (unsigned B = Cand.getBundles(BundleCand, 0)) {
20087330f729Sjoerg UsedCands.push_back(0);
20097330f729Sjoerg Cand.IntvIdx = SE->openIntv();
20107330f729Sjoerg LLVM_DEBUG(dbgs() << "Split for compact region in " << B
20117330f729Sjoerg << " bundles, intv " << Cand.IntvIdx << ".\n");
20127330f729Sjoerg (void)B;
20137330f729Sjoerg }
20147330f729Sjoerg }
20157330f729Sjoerg
20167330f729Sjoerg splitAroundRegion(LREdit, UsedCands);
20177330f729Sjoerg return 0;
20187330f729Sjoerg }
20197330f729Sjoerg
20207330f729Sjoerg //===----------------------------------------------------------------------===//
20217330f729Sjoerg // Per-Block Splitting
20227330f729Sjoerg //===----------------------------------------------------------------------===//
20237330f729Sjoerg
20247330f729Sjoerg /// tryBlockSplit - Split a global live range around every block with uses. This
20257330f729Sjoerg /// creates a lot of local live ranges, that will be split by tryLocalSplit if
20267330f729Sjoerg /// they don't allocate.
tryBlockSplit(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)20277330f729Sjoerg unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order,
2028*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
20297330f729Sjoerg assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed");
2030*82d56013Sjoerg Register Reg = VirtReg.reg();
20317330f729Sjoerg bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
20327330f729Sjoerg LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
20337330f729Sjoerg SE->reset(LREdit, SplitSpillMode);
20347330f729Sjoerg ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
2035*82d56013Sjoerg for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
20367330f729Sjoerg if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
20377330f729Sjoerg SE->splitSingleBlock(BI);
20387330f729Sjoerg }
20397330f729Sjoerg // No blocks were split.
20407330f729Sjoerg if (LREdit.empty())
20417330f729Sjoerg return 0;
20427330f729Sjoerg
20437330f729Sjoerg // We did split for some blocks.
20447330f729Sjoerg SmallVector<unsigned, 8> IntvMap;
20457330f729Sjoerg SE->finish(&IntvMap);
20467330f729Sjoerg
20477330f729Sjoerg // Tell LiveDebugVariables about the new ranges.
20487330f729Sjoerg DebugVars->splitRegister(Reg, LREdit.regs(), *LIS);
20497330f729Sjoerg
20507330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
20517330f729Sjoerg
20527330f729Sjoerg // Sort out the new intervals created by splitting. The remainder interval
20537330f729Sjoerg // goes straight to spilling, the new local ranges get to stay RS_New.
2054*82d56013Sjoerg for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
2055*82d56013Sjoerg LiveInterval &LI = LIS->getInterval(LREdit.get(I));
2056*82d56013Sjoerg if (getStage(LI) == RS_New && IntvMap[I] == 0)
20577330f729Sjoerg setStage(LI, RS_Spill);
20587330f729Sjoerg }
20597330f729Sjoerg
20607330f729Sjoerg if (VerifyEnabled)
20617330f729Sjoerg MF->verify(this, "After splitting live range around basic blocks");
20627330f729Sjoerg return 0;
20637330f729Sjoerg }
20647330f729Sjoerg
20657330f729Sjoerg //===----------------------------------------------------------------------===//
20667330f729Sjoerg // Per-Instruction Splitting
20677330f729Sjoerg //===----------------------------------------------------------------------===//
20687330f729Sjoerg
20697330f729Sjoerg /// Get the number of allocatable registers that match the constraints of \p Reg
20707330f729Sjoerg /// on \p MI and that are also in \p SuperRC.
getNumAllocatableRegsForConstraints(const MachineInstr * MI,Register Reg,const TargetRegisterClass * SuperRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,const RegisterClassInfo & RCI)20717330f729Sjoerg static unsigned getNumAllocatableRegsForConstraints(
2072*82d56013Sjoerg const MachineInstr *MI, Register Reg, const TargetRegisterClass *SuperRC,
20737330f729Sjoerg const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
20747330f729Sjoerg const RegisterClassInfo &RCI) {
20757330f729Sjoerg assert(SuperRC && "Invalid register class");
20767330f729Sjoerg
20777330f729Sjoerg const TargetRegisterClass *ConstrainedRC =
20787330f729Sjoerg MI->getRegClassConstraintEffectForVReg(Reg, SuperRC, TII, TRI,
20797330f729Sjoerg /* ExploreBundle */ true);
20807330f729Sjoerg if (!ConstrainedRC)
20817330f729Sjoerg return 0;
20827330f729Sjoerg return RCI.getNumAllocatableRegs(ConstrainedRC);
20837330f729Sjoerg }
20847330f729Sjoerg
20857330f729Sjoerg /// tryInstructionSplit - Split a live range around individual instructions.
20867330f729Sjoerg /// This is normally not worthwhile since the spiller is doing essentially the
20877330f729Sjoerg /// same thing. However, when the live range is in a constrained register
20887330f729Sjoerg /// class, it may help to insert copies such that parts of the live range can
20897330f729Sjoerg /// be moved to a larger register class.
20907330f729Sjoerg ///
20917330f729Sjoerg /// This is similar to spilling to a larger register class.
20927330f729Sjoerg unsigned
tryInstructionSplit(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)20937330f729Sjoerg RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
2094*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
2095*82d56013Sjoerg const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
20967330f729Sjoerg // There is no point to this if there are no larger sub-classes.
20977330f729Sjoerg if (!RegClassInfo.isProperSubClass(CurRC))
20987330f729Sjoerg return 0;
20997330f729Sjoerg
21007330f729Sjoerg // Always enable split spill mode, since we're effectively spilling to a
21017330f729Sjoerg // register.
21027330f729Sjoerg LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
21037330f729Sjoerg SE->reset(LREdit, SplitEditor::SM_Size);
21047330f729Sjoerg
21057330f729Sjoerg ArrayRef<SlotIndex> Uses = SA->getUseSlots();
21067330f729Sjoerg if (Uses.size() <= 1)
21077330f729Sjoerg return 0;
21087330f729Sjoerg
21097330f729Sjoerg LLVM_DEBUG(dbgs() << "Split around " << Uses.size()
21107330f729Sjoerg << " individual instrs.\n");
21117330f729Sjoerg
21127330f729Sjoerg const TargetRegisterClass *SuperRC =
21137330f729Sjoerg TRI->getLargestLegalSuperClass(CurRC, *MF);
21147330f729Sjoerg unsigned SuperRCNumAllocatableRegs = RCI.getNumAllocatableRegs(SuperRC);
21157330f729Sjoerg // Split around every non-copy instruction if this split will relax
21167330f729Sjoerg // the constraints on the virtual register.
21177330f729Sjoerg // Otherwise, splitting just inserts uncoalescable copies that do not help
21187330f729Sjoerg // the allocation.
2119*82d56013Sjoerg for (const auto &Use : Uses) {
2120*82d56013Sjoerg if (const MachineInstr *MI = Indexes->getInstructionFromIndex(Use))
21217330f729Sjoerg if (MI->isFullCopy() ||
21227330f729Sjoerg SuperRCNumAllocatableRegs ==
2123*82d56013Sjoerg getNumAllocatableRegsForConstraints(MI, VirtReg.reg(), SuperRC,
2124*82d56013Sjoerg TII, TRI, RCI)) {
2125*82d56013Sjoerg LLVM_DEBUG(dbgs() << " skip:\t" << Use << '\t' << *MI);
21267330f729Sjoerg continue;
21277330f729Sjoerg }
21287330f729Sjoerg SE->openIntv();
2129*82d56013Sjoerg SlotIndex SegStart = SE->enterIntvBefore(Use);
2130*82d56013Sjoerg SlotIndex SegStop = SE->leaveIntvAfter(Use);
21317330f729Sjoerg SE->useIntv(SegStart, SegStop);
21327330f729Sjoerg }
21337330f729Sjoerg
21347330f729Sjoerg if (LREdit.empty()) {
21357330f729Sjoerg LLVM_DEBUG(dbgs() << "All uses were copies.\n");
21367330f729Sjoerg return 0;
21377330f729Sjoerg }
21387330f729Sjoerg
21397330f729Sjoerg SmallVector<unsigned, 8> IntvMap;
21407330f729Sjoerg SE->finish(&IntvMap);
2141*82d56013Sjoerg DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
21427330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
21437330f729Sjoerg
21447330f729Sjoerg // Assign all new registers to RS_Spill. This was the last chance.
21457330f729Sjoerg setStage(LREdit.begin(), LREdit.end(), RS_Spill);
21467330f729Sjoerg return 0;
21477330f729Sjoerg }
21487330f729Sjoerg
21497330f729Sjoerg //===----------------------------------------------------------------------===//
21507330f729Sjoerg // Local Splitting
21517330f729Sjoerg //===----------------------------------------------------------------------===//
21527330f729Sjoerg
21537330f729Sjoerg /// calcGapWeights - Compute the maximum spill weight that needs to be evicted
21547330f729Sjoerg /// in order to use PhysReg between two entries in SA->UseSlots.
21557330f729Sjoerg ///
2156*82d56013Sjoerg /// GapWeight[I] represents the gap between UseSlots[I] and UseSlots[I + 1].
21577330f729Sjoerg ///
calcGapWeights(MCRegister PhysReg,SmallVectorImpl<float> & GapWeight)2158*82d56013Sjoerg void RAGreedy::calcGapWeights(MCRegister PhysReg,
21597330f729Sjoerg SmallVectorImpl<float> &GapWeight) {
21607330f729Sjoerg assert(SA->getUseBlocks().size() == 1 && "Not a local interval");
21617330f729Sjoerg const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
21627330f729Sjoerg ArrayRef<SlotIndex> Uses = SA->getUseSlots();
21637330f729Sjoerg const unsigned NumGaps = Uses.size()-1;
21647330f729Sjoerg
21657330f729Sjoerg // Start and end points for the interference check.
21667330f729Sjoerg SlotIndex StartIdx =
21677330f729Sjoerg BI.LiveIn ? BI.FirstInstr.getBaseIndex() : BI.FirstInstr;
21687330f729Sjoerg SlotIndex StopIdx =
21697330f729Sjoerg BI.LiveOut ? BI.LastInstr.getBoundaryIndex() : BI.LastInstr;
21707330f729Sjoerg
21717330f729Sjoerg GapWeight.assign(NumGaps, 0.0f);
21727330f729Sjoerg
21737330f729Sjoerg // Add interference from each overlapping register.
21747330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
21757330f729Sjoerg if (!Matrix->query(const_cast<LiveInterval&>(SA->getParent()), *Units)
21767330f729Sjoerg .checkInterference())
21777330f729Sjoerg continue;
21787330f729Sjoerg
21797330f729Sjoerg // We know that VirtReg is a continuous interval from FirstInstr to
21807330f729Sjoerg // LastInstr, so we don't need InterferenceQuery.
21817330f729Sjoerg //
21827330f729Sjoerg // Interference that overlaps an instruction is counted in both gaps
21837330f729Sjoerg // surrounding the instruction. The exception is interference before
21847330f729Sjoerg // StartIdx and after StopIdx.
21857330f729Sjoerg //
21867330f729Sjoerg LiveIntervalUnion::SegmentIter IntI =
21877330f729Sjoerg Matrix->getLiveUnions()[*Units] .find(StartIdx);
21887330f729Sjoerg for (unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
21897330f729Sjoerg // Skip the gaps before IntI.
21907330f729Sjoerg while (Uses[Gap+1].getBoundaryIndex() < IntI.start())
21917330f729Sjoerg if (++Gap == NumGaps)
21927330f729Sjoerg break;
21937330f729Sjoerg if (Gap == NumGaps)
21947330f729Sjoerg break;
21957330f729Sjoerg
21967330f729Sjoerg // Update the gaps covered by IntI.
2197*82d56013Sjoerg const float weight = IntI.value()->weight();
21987330f729Sjoerg for (; Gap != NumGaps; ++Gap) {
21997330f729Sjoerg GapWeight[Gap] = std::max(GapWeight[Gap], weight);
22007330f729Sjoerg if (Uses[Gap+1].getBaseIndex() >= IntI.stop())
22017330f729Sjoerg break;
22027330f729Sjoerg }
22037330f729Sjoerg if (Gap == NumGaps)
22047330f729Sjoerg break;
22057330f729Sjoerg }
22067330f729Sjoerg }
22077330f729Sjoerg
22087330f729Sjoerg // Add fixed interference.
22097330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
22107330f729Sjoerg const LiveRange &LR = LIS->getRegUnit(*Units);
22117330f729Sjoerg LiveRange::const_iterator I = LR.find(StartIdx);
22127330f729Sjoerg LiveRange::const_iterator E = LR.end();
22137330f729Sjoerg
22147330f729Sjoerg // Same loop as above. Mark any overlapped gaps as HUGE_VALF.
22157330f729Sjoerg for (unsigned Gap = 0; I != E && I->start < StopIdx; ++I) {
22167330f729Sjoerg while (Uses[Gap+1].getBoundaryIndex() < I->start)
22177330f729Sjoerg if (++Gap == NumGaps)
22187330f729Sjoerg break;
22197330f729Sjoerg if (Gap == NumGaps)
22207330f729Sjoerg break;
22217330f729Sjoerg
22227330f729Sjoerg for (; Gap != NumGaps; ++Gap) {
22237330f729Sjoerg GapWeight[Gap] = huge_valf;
22247330f729Sjoerg if (Uses[Gap+1].getBaseIndex() >= I->end)
22257330f729Sjoerg break;
22267330f729Sjoerg }
22277330f729Sjoerg if (Gap == NumGaps)
22287330f729Sjoerg break;
22297330f729Sjoerg }
22307330f729Sjoerg }
22317330f729Sjoerg }
22327330f729Sjoerg
22337330f729Sjoerg /// tryLocalSplit - Try to split VirtReg into smaller intervals inside its only
22347330f729Sjoerg /// basic block.
22357330f729Sjoerg ///
tryLocalSplit(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs)22367330f729Sjoerg unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
2237*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
22387330f729Sjoerg // TODO: the function currently only handles a single UseBlock; it should be
22397330f729Sjoerg // possible to generalize.
22407330f729Sjoerg if (SA->getUseBlocks().size() != 1)
22417330f729Sjoerg return 0;
22427330f729Sjoerg
22437330f729Sjoerg const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
22447330f729Sjoerg
22457330f729Sjoerg // Note that it is possible to have an interval that is live-in or live-out
22467330f729Sjoerg // while only covering a single block - A phi-def can use undef values from
22477330f729Sjoerg // predecessors, and the block could be a single-block loop.
22487330f729Sjoerg // We don't bother doing anything clever about such a case, we simply assume
22497330f729Sjoerg // that the interval is continuous from FirstInstr to LastInstr. We should
22507330f729Sjoerg // make sure that we don't do anything illegal to such an interval, though.
22517330f729Sjoerg
22527330f729Sjoerg ArrayRef<SlotIndex> Uses = SA->getUseSlots();
22537330f729Sjoerg if (Uses.size() <= 2)
22547330f729Sjoerg return 0;
22557330f729Sjoerg const unsigned NumGaps = Uses.size()-1;
22567330f729Sjoerg
22577330f729Sjoerg LLVM_DEBUG({
22587330f729Sjoerg dbgs() << "tryLocalSplit: ";
2259*82d56013Sjoerg for (const auto &Use : Uses)
2260*82d56013Sjoerg dbgs() << ' ' << Use;
22617330f729Sjoerg dbgs() << '\n';
22627330f729Sjoerg });
22637330f729Sjoerg
22647330f729Sjoerg // If VirtReg is live across any register mask operands, compute a list of
22657330f729Sjoerg // gaps with register masks.
22667330f729Sjoerg SmallVector<unsigned, 8> RegMaskGaps;
22677330f729Sjoerg if (Matrix->checkRegMaskInterference(VirtReg)) {
22687330f729Sjoerg // Get regmask slots for the whole block.
22697330f729Sjoerg ArrayRef<SlotIndex> RMS = LIS->getRegMaskSlotsInBlock(BI.MBB->getNumber());
22707330f729Sjoerg LLVM_DEBUG(dbgs() << RMS.size() << " regmasks in block:");
22717330f729Sjoerg // Constrain to VirtReg's live range.
2272*82d56013Sjoerg unsigned RI =
22737330f729Sjoerg llvm::lower_bound(RMS, Uses.front().getRegSlot()) - RMS.begin();
2274*82d56013Sjoerg unsigned RE = RMS.size();
2275*82d56013Sjoerg for (unsigned I = 0; I != NumGaps && RI != RE; ++I) {
2276*82d56013Sjoerg // Look for Uses[I] <= RMS <= Uses[I + 1].
2277*82d56013Sjoerg assert(!SlotIndex::isEarlierInstr(RMS[RI], Uses[I]));
2278*82d56013Sjoerg if (SlotIndex::isEarlierInstr(Uses[I + 1], RMS[RI]))
22797330f729Sjoerg continue;
22807330f729Sjoerg // Skip a regmask on the same instruction as the last use. It doesn't
22817330f729Sjoerg // overlap the live range.
2282*82d56013Sjoerg if (SlotIndex::isSameInstr(Uses[I + 1], RMS[RI]) && I + 1 == NumGaps)
22837330f729Sjoerg break;
2284*82d56013Sjoerg LLVM_DEBUG(dbgs() << ' ' << RMS[RI] << ':' << Uses[I] << '-'
2285*82d56013Sjoerg << Uses[I + 1]);
2286*82d56013Sjoerg RegMaskGaps.push_back(I);
22877330f729Sjoerg // Advance ri to the next gap. A regmask on one of the uses counts in
22887330f729Sjoerg // both gaps.
2289*82d56013Sjoerg while (RI != RE && SlotIndex::isEarlierInstr(RMS[RI], Uses[I + 1]))
2290*82d56013Sjoerg ++RI;
22917330f729Sjoerg }
22927330f729Sjoerg LLVM_DEBUG(dbgs() << '\n');
22937330f729Sjoerg }
22947330f729Sjoerg
22957330f729Sjoerg // Since we allow local split results to be split again, there is a risk of
22967330f729Sjoerg // creating infinite loops. It is tempting to require that the new live
22977330f729Sjoerg // ranges have less instructions than the original. That would guarantee
22987330f729Sjoerg // convergence, but it is too strict. A live range with 3 instructions can be
22997330f729Sjoerg // split 2+3 (including the COPY), and we want to allow that.
23007330f729Sjoerg //
23017330f729Sjoerg // Instead we use these rules:
23027330f729Sjoerg //
23037330f729Sjoerg // 1. Allow any split for ranges with getStage() < RS_Split2. (Except for the
23047330f729Sjoerg // noop split, of course).
23057330f729Sjoerg // 2. Require progress be made for ranges with getStage() == RS_Split2. All
23067330f729Sjoerg // the new ranges must have fewer instructions than before the split.
23077330f729Sjoerg // 3. New ranges with the same number of instructions are marked RS_Split2,
23087330f729Sjoerg // smaller ranges are marked RS_New.
23097330f729Sjoerg //
23107330f729Sjoerg // These rules allow a 3 -> 2+3 split once, which we need. They also prevent
23117330f729Sjoerg // excessive splitting and infinite loops.
23127330f729Sjoerg //
23137330f729Sjoerg bool ProgressRequired = getStage(VirtReg) >= RS_Split2;
23147330f729Sjoerg
23157330f729Sjoerg // Best split candidate.
23167330f729Sjoerg unsigned BestBefore = NumGaps;
23177330f729Sjoerg unsigned BestAfter = 0;
23187330f729Sjoerg float BestDiff = 0;
23197330f729Sjoerg
23207330f729Sjoerg const float blockFreq =
23217330f729Sjoerg SpillPlacer->getBlockFrequency(BI.MBB->getNumber()).getFrequency() *
23227330f729Sjoerg (1.0f / MBFI->getEntryFreq());
23237330f729Sjoerg SmallVector<float, 8> GapWeight;
23247330f729Sjoerg
2325*82d56013Sjoerg for (MCPhysReg PhysReg : Order) {
2326*82d56013Sjoerg assert(PhysReg);
23277330f729Sjoerg // Keep track of the largest spill weight that would need to be evicted in
2328*82d56013Sjoerg // order to make use of PhysReg between UseSlots[I] and UseSlots[I + 1].
23297330f729Sjoerg calcGapWeights(PhysReg, GapWeight);
23307330f729Sjoerg
23317330f729Sjoerg // Remove any gaps with regmask clobbers.
23327330f729Sjoerg if (Matrix->checkRegMaskInterference(VirtReg, PhysReg))
2333*82d56013Sjoerg for (unsigned I = 0, E = RegMaskGaps.size(); I != E; ++I)
2334*82d56013Sjoerg GapWeight[RegMaskGaps[I]] = huge_valf;
23357330f729Sjoerg
23367330f729Sjoerg // Try to find the best sequence of gaps to close.
23377330f729Sjoerg // The new spill weight must be larger than any gap interference.
23387330f729Sjoerg
23397330f729Sjoerg // We will split before Uses[SplitBefore] and after Uses[SplitAfter].
23407330f729Sjoerg unsigned SplitBefore = 0, SplitAfter = 1;
23417330f729Sjoerg
23427330f729Sjoerg // MaxGap should always be max(GapWeight[SplitBefore..SplitAfter-1]).
23437330f729Sjoerg // It is the spill weight that needs to be evicted.
23447330f729Sjoerg float MaxGap = GapWeight[0];
23457330f729Sjoerg
23467330f729Sjoerg while (true) {
23477330f729Sjoerg // Live before/after split?
23487330f729Sjoerg const bool LiveBefore = SplitBefore != 0 || BI.LiveIn;
23497330f729Sjoerg const bool LiveAfter = SplitAfter != NumGaps || BI.LiveOut;
23507330f729Sjoerg
23517330f729Sjoerg LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << ' ' << Uses[SplitBefore]
2352*82d56013Sjoerg << '-' << Uses[SplitAfter] << " I=" << MaxGap);
23537330f729Sjoerg
23547330f729Sjoerg // Stop before the interval gets so big we wouldn't be making progress.
23557330f729Sjoerg if (!LiveBefore && !LiveAfter) {
23567330f729Sjoerg LLVM_DEBUG(dbgs() << " all\n");
23577330f729Sjoerg break;
23587330f729Sjoerg }
23597330f729Sjoerg // Should the interval be extended or shrunk?
23607330f729Sjoerg bool Shrink = true;
23617330f729Sjoerg
23627330f729Sjoerg // How many gaps would the new range have?
23637330f729Sjoerg unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
23647330f729Sjoerg
23657330f729Sjoerg // Legally, without causing looping?
23667330f729Sjoerg bool Legal = !ProgressRequired || NewGaps < NumGaps;
23677330f729Sjoerg
23687330f729Sjoerg if (Legal && MaxGap < huge_valf) {
23697330f729Sjoerg // Estimate the new spill weight. Each instruction reads or writes the
23707330f729Sjoerg // register. Conservatively assume there are no read-modify-write
23717330f729Sjoerg // instructions.
23727330f729Sjoerg //
23737330f729Sjoerg // Try to guess the size of the new interval.
23747330f729Sjoerg const float EstWeight = normalizeSpillWeight(
23757330f729Sjoerg blockFreq * (NewGaps + 1),
23767330f729Sjoerg Uses[SplitBefore].distance(Uses[SplitAfter]) +
23777330f729Sjoerg (LiveBefore + LiveAfter) * SlotIndex::InstrDist,
23787330f729Sjoerg 1);
23797330f729Sjoerg // Would this split be possible to allocate?
23807330f729Sjoerg // Never allocate all gaps, we wouldn't be making progress.
23817330f729Sjoerg LLVM_DEBUG(dbgs() << " w=" << EstWeight);
23827330f729Sjoerg if (EstWeight * Hysteresis >= MaxGap) {
23837330f729Sjoerg Shrink = false;
23847330f729Sjoerg float Diff = EstWeight - MaxGap;
23857330f729Sjoerg if (Diff > BestDiff) {
23867330f729Sjoerg LLVM_DEBUG(dbgs() << " (best)");
23877330f729Sjoerg BestDiff = Hysteresis * Diff;
23887330f729Sjoerg BestBefore = SplitBefore;
23897330f729Sjoerg BestAfter = SplitAfter;
23907330f729Sjoerg }
23917330f729Sjoerg }
23927330f729Sjoerg }
23937330f729Sjoerg
23947330f729Sjoerg // Try to shrink.
23957330f729Sjoerg if (Shrink) {
23967330f729Sjoerg if (++SplitBefore < SplitAfter) {
23977330f729Sjoerg LLVM_DEBUG(dbgs() << " shrink\n");
23987330f729Sjoerg // Recompute the max when necessary.
23997330f729Sjoerg if (GapWeight[SplitBefore - 1] >= MaxGap) {
24007330f729Sjoerg MaxGap = GapWeight[SplitBefore];
2401*82d56013Sjoerg for (unsigned I = SplitBefore + 1; I != SplitAfter; ++I)
2402*82d56013Sjoerg MaxGap = std::max(MaxGap, GapWeight[I]);
24037330f729Sjoerg }
24047330f729Sjoerg continue;
24057330f729Sjoerg }
24067330f729Sjoerg MaxGap = 0;
24077330f729Sjoerg }
24087330f729Sjoerg
24097330f729Sjoerg // Try to extend the interval.
24107330f729Sjoerg if (SplitAfter >= NumGaps) {
24117330f729Sjoerg LLVM_DEBUG(dbgs() << " end\n");
24127330f729Sjoerg break;
24137330f729Sjoerg }
24147330f729Sjoerg
24157330f729Sjoerg LLVM_DEBUG(dbgs() << " extend\n");
24167330f729Sjoerg MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
24177330f729Sjoerg }
24187330f729Sjoerg }
24197330f729Sjoerg
24207330f729Sjoerg // Didn't find any candidates?
24217330f729Sjoerg if (BestBefore == NumGaps)
24227330f729Sjoerg return 0;
24237330f729Sjoerg
24247330f729Sjoerg LLVM_DEBUG(dbgs() << "Best local split range: " << Uses[BestBefore] << '-'
24257330f729Sjoerg << Uses[BestAfter] << ", " << BestDiff << ", "
24267330f729Sjoerg << (BestAfter - BestBefore + 1) << " instrs\n");
24277330f729Sjoerg
24287330f729Sjoerg LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
24297330f729Sjoerg SE->reset(LREdit);
24307330f729Sjoerg
24317330f729Sjoerg SE->openIntv();
24327330f729Sjoerg SlotIndex SegStart = SE->enterIntvBefore(Uses[BestBefore]);
24337330f729Sjoerg SlotIndex SegStop = SE->leaveIntvAfter(Uses[BestAfter]);
24347330f729Sjoerg SE->useIntv(SegStart, SegStop);
24357330f729Sjoerg SmallVector<unsigned, 8> IntvMap;
24367330f729Sjoerg SE->finish(&IntvMap);
2437*82d56013Sjoerg DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
24387330f729Sjoerg
24397330f729Sjoerg // If the new range has the same number of instructions as before, mark it as
24407330f729Sjoerg // RS_Split2 so the next split will be forced to make progress. Otherwise,
24417330f729Sjoerg // leave the new intervals as RS_New so they can compete.
24427330f729Sjoerg bool LiveBefore = BestBefore != 0 || BI.LiveIn;
24437330f729Sjoerg bool LiveAfter = BestAfter != NumGaps || BI.LiveOut;
24447330f729Sjoerg unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
24457330f729Sjoerg if (NewGaps >= NumGaps) {
24467330f729Sjoerg LLVM_DEBUG(dbgs() << "Tagging non-progress ranges: ");
24477330f729Sjoerg assert(!ProgressRequired && "Didn't make progress when it was required.");
2448*82d56013Sjoerg for (unsigned I = 0, E = IntvMap.size(); I != E; ++I)
2449*82d56013Sjoerg if (IntvMap[I] == 1) {
2450*82d56013Sjoerg setStage(LIS->getInterval(LREdit.get(I)), RS_Split2);
2451*82d56013Sjoerg LLVM_DEBUG(dbgs() << printReg(LREdit.get(I)));
24527330f729Sjoerg }
24537330f729Sjoerg LLVM_DEBUG(dbgs() << '\n');
24547330f729Sjoerg }
24557330f729Sjoerg ++NumLocalSplits;
24567330f729Sjoerg
24577330f729Sjoerg return 0;
24587330f729Sjoerg }
24597330f729Sjoerg
24607330f729Sjoerg //===----------------------------------------------------------------------===//
24617330f729Sjoerg // Live Range Splitting
24627330f729Sjoerg //===----------------------------------------------------------------------===//
24637330f729Sjoerg
24647330f729Sjoerg /// trySplit - Try to split VirtReg or one of its interferences, making it
24657330f729Sjoerg /// assignable.
24667330f729Sjoerg /// @return Physreg when VirtReg may be assigned and/or new NewVRegs.
trySplit(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,const SmallVirtRegSet & FixedRegisters)24677330f729Sjoerg unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
2468*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
24697330f729Sjoerg const SmallVirtRegSet &FixedRegisters) {
24707330f729Sjoerg // Ranges must be Split2 or less.
24717330f729Sjoerg if (getStage(VirtReg) >= RS_Spill)
24727330f729Sjoerg return 0;
24737330f729Sjoerg
24747330f729Sjoerg // Local intervals are handled separately.
24757330f729Sjoerg if (LIS->intervalIsInOneMBB(VirtReg)) {
24767330f729Sjoerg NamedRegionTimer T("local_split", "Local Splitting", TimerGroupName,
24777330f729Sjoerg TimerGroupDescription, TimePassesIsEnabled);
24787330f729Sjoerg SA->analyze(&VirtReg);
2479*82d56013Sjoerg Register PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
24807330f729Sjoerg if (PhysReg || !NewVRegs.empty())
24817330f729Sjoerg return PhysReg;
24827330f729Sjoerg return tryInstructionSplit(VirtReg, Order, NewVRegs);
24837330f729Sjoerg }
24847330f729Sjoerg
24857330f729Sjoerg NamedRegionTimer T("global_split", "Global Splitting", TimerGroupName,
24867330f729Sjoerg TimerGroupDescription, TimePassesIsEnabled);
24877330f729Sjoerg
24887330f729Sjoerg SA->analyze(&VirtReg);
24897330f729Sjoerg
24907330f729Sjoerg // FIXME: SplitAnalysis may repair broken live ranges coming from the
24917330f729Sjoerg // coalescer. That may cause the range to become allocatable which means that
24927330f729Sjoerg // tryRegionSplit won't be making progress. This check should be replaced with
24937330f729Sjoerg // an assertion when the coalescer is fixed.
24947330f729Sjoerg if (SA->didRepairRange()) {
24957330f729Sjoerg // VirtReg has changed, so all cached queries are invalid.
24967330f729Sjoerg Matrix->invalidateVirtRegs();
2497*82d56013Sjoerg if (Register PhysReg = tryAssign(VirtReg, Order, NewVRegs, FixedRegisters))
24987330f729Sjoerg return PhysReg;
24997330f729Sjoerg }
25007330f729Sjoerg
25017330f729Sjoerg // First try to split around a region spanning multiple blocks. RS_Split2
25027330f729Sjoerg // ranges already made dubious progress with region splitting, so they go
25037330f729Sjoerg // straight to single block splitting.
25047330f729Sjoerg if (getStage(VirtReg) < RS_Split2) {
2505*82d56013Sjoerg MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
25067330f729Sjoerg if (PhysReg || !NewVRegs.empty())
25077330f729Sjoerg return PhysReg;
25087330f729Sjoerg }
25097330f729Sjoerg
25107330f729Sjoerg // Then isolate blocks.
25117330f729Sjoerg return tryBlockSplit(VirtReg, Order, NewVRegs);
25127330f729Sjoerg }
25137330f729Sjoerg
25147330f729Sjoerg //===----------------------------------------------------------------------===//
25157330f729Sjoerg // Last Chance Recoloring
25167330f729Sjoerg //===----------------------------------------------------------------------===//
25177330f729Sjoerg
25187330f729Sjoerg /// Return true if \p reg has any tied def operand.
hasTiedDef(MachineRegisterInfo * MRI,unsigned reg)25197330f729Sjoerg static bool hasTiedDef(MachineRegisterInfo *MRI, unsigned reg) {
25207330f729Sjoerg for (const MachineOperand &MO : MRI->def_operands(reg))
25217330f729Sjoerg if (MO.isTied())
25227330f729Sjoerg return true;
25237330f729Sjoerg
25247330f729Sjoerg return false;
25257330f729Sjoerg }
25267330f729Sjoerg
25277330f729Sjoerg /// mayRecolorAllInterferences - Check if the virtual registers that
25287330f729Sjoerg /// interfere with \p VirtReg on \p PhysReg (or one of its aliases) may be
25297330f729Sjoerg /// recolored to free \p PhysReg.
25307330f729Sjoerg /// When true is returned, \p RecoloringCandidates has been augmented with all
25317330f729Sjoerg /// the live intervals that need to be recolored in order to free \p PhysReg
25327330f729Sjoerg /// for \p VirtReg.
25337330f729Sjoerg /// \p FixedRegisters contains all the virtual registers that cannot be
25347330f729Sjoerg /// recolored.
mayRecolorAllInterferences(MCRegister PhysReg,LiveInterval & VirtReg,SmallLISet & RecoloringCandidates,const SmallVirtRegSet & FixedRegisters)2535*82d56013Sjoerg bool RAGreedy::mayRecolorAllInterferences(
2536*82d56013Sjoerg MCRegister PhysReg, LiveInterval &VirtReg, SmallLISet &RecoloringCandidates,
25377330f729Sjoerg const SmallVirtRegSet &FixedRegisters) {
2538*82d56013Sjoerg const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
25397330f729Sjoerg
25407330f729Sjoerg for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
25417330f729Sjoerg LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
25427330f729Sjoerg // If there is LastChanceRecoloringMaxInterference or more interferences,
25437330f729Sjoerg // chances are one would not be recolorable.
25447330f729Sjoerg if (Q.collectInterferingVRegs(LastChanceRecoloringMaxInterference) >=
25457330f729Sjoerg LastChanceRecoloringMaxInterference && !ExhaustiveSearch) {
25467330f729Sjoerg LLVM_DEBUG(dbgs() << "Early abort: too many interferences.\n");
25477330f729Sjoerg CutOffInfo |= CO_Interf;
25487330f729Sjoerg return false;
25497330f729Sjoerg }
2550*82d56013Sjoerg for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
25517330f729Sjoerg // If Intf is done and sit on the same register class as VirtReg,
25527330f729Sjoerg // it would not be recolorable as it is in the same state as VirtReg.
25537330f729Sjoerg // However, if VirtReg has tied defs and Intf doesn't, then
25547330f729Sjoerg // there is still a point in examining if it can be recolorable.
25557330f729Sjoerg if (((getStage(*Intf) == RS_Done &&
2556*82d56013Sjoerg MRI->getRegClass(Intf->reg()) == CurRC) &&
2557*82d56013Sjoerg !(hasTiedDef(MRI, VirtReg.reg()) &&
2558*82d56013Sjoerg !hasTiedDef(MRI, Intf->reg()))) ||
2559*82d56013Sjoerg FixedRegisters.count(Intf->reg())) {
25607330f729Sjoerg LLVM_DEBUG(
25617330f729Sjoerg dbgs() << "Early abort: the interference is not recolorable.\n");
25627330f729Sjoerg return false;
25637330f729Sjoerg }
25647330f729Sjoerg RecoloringCandidates.insert(Intf);
25657330f729Sjoerg }
25667330f729Sjoerg }
25677330f729Sjoerg return true;
25687330f729Sjoerg }
25697330f729Sjoerg
25707330f729Sjoerg /// tryLastChanceRecoloring - Try to assign a color to \p VirtReg by recoloring
25717330f729Sjoerg /// its interferences.
25727330f729Sjoerg /// Last chance recoloring chooses a color for \p VirtReg and recolors every
25737330f729Sjoerg /// virtual register that was using it. The recoloring process may recursively
25747330f729Sjoerg /// use the last chance recoloring. Therefore, when a virtual register has been
25757330f729Sjoerg /// assigned a color by this mechanism, it is marked as Fixed, i.e., it cannot
25767330f729Sjoerg /// be last-chance-recolored again during this recoloring "session".
25777330f729Sjoerg /// E.g.,
25787330f729Sjoerg /// Let
25797330f729Sjoerg /// vA can use {R1, R2 }
25807330f729Sjoerg /// vB can use { R2, R3}
25817330f729Sjoerg /// vC can use {R1 }
25827330f729Sjoerg /// Where vA, vB, and vC cannot be split anymore (they are reloads for
25837330f729Sjoerg /// instance) and they all interfere.
25847330f729Sjoerg ///
25857330f729Sjoerg /// vA is assigned R1
25867330f729Sjoerg /// vB is assigned R2
25877330f729Sjoerg /// vC tries to evict vA but vA is already done.
25887330f729Sjoerg /// Regular register allocation fails.
25897330f729Sjoerg ///
25907330f729Sjoerg /// Last chance recoloring kicks in:
25917330f729Sjoerg /// vC does as if vA was evicted => vC uses R1.
25927330f729Sjoerg /// vC is marked as fixed.
25937330f729Sjoerg /// vA needs to find a color.
25947330f729Sjoerg /// None are available.
25957330f729Sjoerg /// vA cannot evict vC: vC is a fixed virtual register now.
25967330f729Sjoerg /// vA does as if vB was evicted => vA uses R2.
25977330f729Sjoerg /// vB needs to find a color.
25987330f729Sjoerg /// R3 is available.
25997330f729Sjoerg /// Recoloring => vC = R1, vA = R2, vB = R3
26007330f729Sjoerg ///
26017330f729Sjoerg /// \p Order defines the preferred allocation order for \p VirtReg.
26027330f729Sjoerg /// \p NewRegs will contain any new virtual register that have been created
26037330f729Sjoerg /// (split, spill) during the process and that must be assigned.
26047330f729Sjoerg /// \p FixedRegisters contains all the virtual registers that cannot be
26057330f729Sjoerg /// recolored.
26067330f729Sjoerg /// \p Depth gives the current depth of the last chance recoloring.
26077330f729Sjoerg /// \return a physical register that can be used for VirtReg or ~0u if none
26087330f729Sjoerg /// exists.
tryLastChanceRecoloring(LiveInterval & VirtReg,AllocationOrder & Order,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,unsigned Depth)26097330f729Sjoerg unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
26107330f729Sjoerg AllocationOrder &Order,
2611*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
26127330f729Sjoerg SmallVirtRegSet &FixedRegisters,
26137330f729Sjoerg unsigned Depth) {
2614*82d56013Sjoerg if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2615*82d56013Sjoerg return ~0u;
2616*82d56013Sjoerg
26177330f729Sjoerg LLVM_DEBUG(dbgs() << "Try last chance recoloring for " << VirtReg << '\n');
26187330f729Sjoerg // Ranges must be Done.
26197330f729Sjoerg assert((getStage(VirtReg) >= RS_Done || !VirtReg.isSpillable()) &&
26207330f729Sjoerg "Last chance recoloring should really be last chance");
26217330f729Sjoerg // Set the max depth to LastChanceRecoloringMaxDepth.
26227330f729Sjoerg // We may want to reconsider that if we end up with a too large search space
26237330f729Sjoerg // for target with hundreds of registers.
26247330f729Sjoerg // Indeed, in that case we may want to cut the search space earlier.
26257330f729Sjoerg if (Depth >= LastChanceRecoloringMaxDepth && !ExhaustiveSearch) {
26267330f729Sjoerg LLVM_DEBUG(dbgs() << "Abort because max depth has been reached.\n");
26277330f729Sjoerg CutOffInfo |= CO_Depth;
26287330f729Sjoerg return ~0u;
26297330f729Sjoerg }
26307330f729Sjoerg
26317330f729Sjoerg // Set of Live intervals that will need to be recolored.
26327330f729Sjoerg SmallLISet RecoloringCandidates;
26337330f729Sjoerg // Record the original mapping virtual register to physical register in case
26347330f729Sjoerg // the recoloring fails.
2635*82d56013Sjoerg DenseMap<Register, MCRegister> VirtRegToPhysReg;
26367330f729Sjoerg // Mark VirtReg as fixed, i.e., it will not be recolored pass this point in
26377330f729Sjoerg // this recoloring "session".
2638*82d56013Sjoerg assert(!FixedRegisters.count(VirtReg.reg()));
2639*82d56013Sjoerg FixedRegisters.insert(VirtReg.reg());
2640*82d56013Sjoerg SmallVector<Register, 4> CurrentNewVRegs;
26417330f729Sjoerg
2642*82d56013Sjoerg for (MCRegister PhysReg : Order) {
2643*82d56013Sjoerg assert(PhysReg.isValid());
26447330f729Sjoerg LLVM_DEBUG(dbgs() << "Try to assign: " << VirtReg << " to "
26457330f729Sjoerg << printReg(PhysReg, TRI) << '\n');
26467330f729Sjoerg RecoloringCandidates.clear();
26477330f729Sjoerg VirtRegToPhysReg.clear();
26487330f729Sjoerg CurrentNewVRegs.clear();
26497330f729Sjoerg
26507330f729Sjoerg // It is only possible to recolor virtual register interference.
26517330f729Sjoerg if (Matrix->checkInterference(VirtReg, PhysReg) >
26527330f729Sjoerg LiveRegMatrix::IK_VirtReg) {
26537330f729Sjoerg LLVM_DEBUG(
26547330f729Sjoerg dbgs() << "Some interferences are not with virtual registers.\n");
26557330f729Sjoerg
26567330f729Sjoerg continue;
26577330f729Sjoerg }
26587330f729Sjoerg
26597330f729Sjoerg // Early give up on this PhysReg if it is obvious we cannot recolor all
26607330f729Sjoerg // the interferences.
26617330f729Sjoerg if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
26627330f729Sjoerg FixedRegisters)) {
26637330f729Sjoerg LLVM_DEBUG(dbgs() << "Some interferences cannot be recolored.\n");
26647330f729Sjoerg continue;
26657330f729Sjoerg }
26667330f729Sjoerg
26677330f729Sjoerg // RecoloringCandidates contains all the virtual registers that interfer
26687330f729Sjoerg // with VirtReg on PhysReg (or one of its aliases).
26697330f729Sjoerg // Enqueue them for recoloring and perform the actual recoloring.
26707330f729Sjoerg PQueue RecoloringQueue;
2671*82d56013Sjoerg for (LiveInterval *RC : RecoloringCandidates) {
2672*82d56013Sjoerg Register ItVirtReg = RC->reg();
2673*82d56013Sjoerg enqueue(RecoloringQueue, RC);
26747330f729Sjoerg assert(VRM->hasPhys(ItVirtReg) &&
26757330f729Sjoerg "Interferences are supposed to be with allocated variables");
26767330f729Sjoerg
26777330f729Sjoerg // Record the current allocation.
26787330f729Sjoerg VirtRegToPhysReg[ItVirtReg] = VRM->getPhys(ItVirtReg);
26797330f729Sjoerg // unset the related struct.
2680*82d56013Sjoerg Matrix->unassign(*RC);
26817330f729Sjoerg }
26827330f729Sjoerg
26837330f729Sjoerg // Do as if VirtReg was assigned to PhysReg so that the underlying
26847330f729Sjoerg // recoloring has the right information about the interferes and
26857330f729Sjoerg // available colors.
26867330f729Sjoerg Matrix->assign(VirtReg, PhysReg);
26877330f729Sjoerg
26887330f729Sjoerg // Save the current recoloring state.
26897330f729Sjoerg // If we cannot recolor all the interferences, we will have to start again
26907330f729Sjoerg // at this point for the next physical register.
26917330f729Sjoerg SmallVirtRegSet SaveFixedRegisters(FixedRegisters);
26927330f729Sjoerg if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
26937330f729Sjoerg FixedRegisters, Depth)) {
26947330f729Sjoerg // Push the queued vregs into the main queue.
2695*82d56013Sjoerg for (Register NewVReg : CurrentNewVRegs)
26967330f729Sjoerg NewVRegs.push_back(NewVReg);
26977330f729Sjoerg // Do not mess up with the global assignment process.
26987330f729Sjoerg // I.e., VirtReg must be unassigned.
26997330f729Sjoerg Matrix->unassign(VirtReg);
27007330f729Sjoerg return PhysReg;
27017330f729Sjoerg }
27027330f729Sjoerg
27037330f729Sjoerg LLVM_DEBUG(dbgs() << "Fail to assign: " << VirtReg << " to "
27047330f729Sjoerg << printReg(PhysReg, TRI) << '\n');
27057330f729Sjoerg
27067330f729Sjoerg // The recoloring attempt failed, undo the changes.
27077330f729Sjoerg FixedRegisters = SaveFixedRegisters;
27087330f729Sjoerg Matrix->unassign(VirtReg);
27097330f729Sjoerg
27107330f729Sjoerg // For a newly created vreg which is also in RecoloringCandidates,
27117330f729Sjoerg // don't add it to NewVRegs because its physical register will be restored
27127330f729Sjoerg // below. Other vregs in CurrentNewVRegs are created by calling
27137330f729Sjoerg // selectOrSplit and should be added into NewVRegs.
2714*82d56013Sjoerg for (Register &R : CurrentNewVRegs) {
2715*82d56013Sjoerg if (RecoloringCandidates.count(&LIS->getInterval(R)))
27167330f729Sjoerg continue;
2717*82d56013Sjoerg NewVRegs.push_back(R);
27187330f729Sjoerg }
27197330f729Sjoerg
2720*82d56013Sjoerg for (LiveInterval *RC : RecoloringCandidates) {
2721*82d56013Sjoerg Register ItVirtReg = RC->reg();
27227330f729Sjoerg if (VRM->hasPhys(ItVirtReg))
2723*82d56013Sjoerg Matrix->unassign(*RC);
2724*82d56013Sjoerg MCRegister ItPhysReg = VirtRegToPhysReg[ItVirtReg];
2725*82d56013Sjoerg Matrix->assign(*RC, ItPhysReg);
27267330f729Sjoerg }
27277330f729Sjoerg }
27287330f729Sjoerg
27297330f729Sjoerg // Last chance recoloring did not worked either, give up.
27307330f729Sjoerg return ~0u;
27317330f729Sjoerg }
27327330f729Sjoerg
27337330f729Sjoerg /// tryRecoloringCandidates - Try to assign a new color to every register
27347330f729Sjoerg /// in \RecoloringQueue.
27357330f729Sjoerg /// \p NewRegs will contain any new virtual register created during the
27367330f729Sjoerg /// recoloring process.
27377330f729Sjoerg /// \p FixedRegisters[in/out] contains all the registers that have been
27387330f729Sjoerg /// recolored.
27397330f729Sjoerg /// \return true if all virtual registers in RecoloringQueue were successfully
27407330f729Sjoerg /// recolored, false otherwise.
tryRecoloringCandidates(PQueue & RecoloringQueue,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,unsigned Depth)27417330f729Sjoerg bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2742*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
27437330f729Sjoerg SmallVirtRegSet &FixedRegisters,
27447330f729Sjoerg unsigned Depth) {
27457330f729Sjoerg while (!RecoloringQueue.empty()) {
27467330f729Sjoerg LiveInterval *LI = dequeue(RecoloringQueue);
27477330f729Sjoerg LLVM_DEBUG(dbgs() << "Try to recolor: " << *LI << '\n');
2748*82d56013Sjoerg MCRegister PhysReg =
2749*82d56013Sjoerg selectOrSplitImpl(*LI, NewVRegs, FixedRegisters, Depth + 1);
27507330f729Sjoerg // When splitting happens, the live-range may actually be empty.
27517330f729Sjoerg // In that case, this is okay to continue the recoloring even
27527330f729Sjoerg // if we did not find an alternative color for it. Indeed,
27537330f729Sjoerg // there will not be anything to color for LI in the end.
27547330f729Sjoerg if (PhysReg == ~0u || (!PhysReg && !LI->empty()))
27557330f729Sjoerg return false;
27567330f729Sjoerg
27577330f729Sjoerg if (!PhysReg) {
27587330f729Sjoerg assert(LI->empty() && "Only empty live-range do not require a register");
27597330f729Sjoerg LLVM_DEBUG(dbgs() << "Recoloring of " << *LI
27607330f729Sjoerg << " succeeded. Empty LI.\n");
27617330f729Sjoerg continue;
27627330f729Sjoerg }
27637330f729Sjoerg LLVM_DEBUG(dbgs() << "Recoloring of " << *LI
27647330f729Sjoerg << " succeeded with: " << printReg(PhysReg, TRI) << '\n');
27657330f729Sjoerg
27667330f729Sjoerg Matrix->assign(*LI, PhysReg);
2767*82d56013Sjoerg FixedRegisters.insert(LI->reg());
27687330f729Sjoerg }
27697330f729Sjoerg return true;
27707330f729Sjoerg }
27717330f729Sjoerg
27727330f729Sjoerg //===----------------------------------------------------------------------===//
27737330f729Sjoerg // Main Entry Point
27747330f729Sjoerg //===----------------------------------------------------------------------===//
27757330f729Sjoerg
selectOrSplit(LiveInterval & VirtReg,SmallVectorImpl<Register> & NewVRegs)2776*82d56013Sjoerg MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
2777*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
27787330f729Sjoerg CutOffInfo = CO_None;
27797330f729Sjoerg LLVMContext &Ctx = MF->getFunction().getContext();
27807330f729Sjoerg SmallVirtRegSet FixedRegisters;
2781*82d56013Sjoerg MCRegister Reg = selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters);
27827330f729Sjoerg if (Reg == ~0U && (CutOffInfo != CO_None)) {
27837330f729Sjoerg uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
27847330f729Sjoerg if (CutOffEncountered == CO_Depth)
27857330f729Sjoerg Ctx.emitError("register allocation failed: maximum depth for recoloring "
27867330f729Sjoerg "reached. Use -fexhaustive-register-search to skip "
27877330f729Sjoerg "cutoffs");
27887330f729Sjoerg else if (CutOffEncountered == CO_Interf)
27897330f729Sjoerg Ctx.emitError("register allocation failed: maximum interference for "
27907330f729Sjoerg "recoloring reached. Use -fexhaustive-register-search "
27917330f729Sjoerg "to skip cutoffs");
27927330f729Sjoerg else if (CutOffEncountered == (CO_Depth | CO_Interf))
27937330f729Sjoerg Ctx.emitError("register allocation failed: maximum interference and "
27947330f729Sjoerg "depth for recoloring reached. Use "
27957330f729Sjoerg "-fexhaustive-register-search to skip cutoffs");
27967330f729Sjoerg }
27977330f729Sjoerg return Reg;
27987330f729Sjoerg }
27997330f729Sjoerg
28007330f729Sjoerg /// Using a CSR for the first time has a cost because it causes push|pop
28017330f729Sjoerg /// to be added to prologue|epilogue. Splitting a cold section of the live
28027330f729Sjoerg /// range can have lower cost than using the CSR for the first time;
28037330f729Sjoerg /// Spilling a live range in the cold path can have lower cost than using
28047330f729Sjoerg /// the CSR for the first time. Returns the physical register if we decide
28057330f729Sjoerg /// to use the CSR; otherwise return 0.
2806*82d56013Sjoerg MCRegister
tryAssignCSRFirstTime(LiveInterval & VirtReg,AllocationOrder & Order,MCRegister PhysReg,uint8_t & CostPerUseLimit,SmallVectorImpl<Register> & NewVRegs)2807*82d56013Sjoerg RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order,
2808*82d56013Sjoerg MCRegister PhysReg, uint8_t &CostPerUseLimit,
2809*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs) {
28107330f729Sjoerg if (getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) {
28117330f729Sjoerg // We choose spill over using the CSR for the first time if the spill cost
28127330f729Sjoerg // is lower than CSRCost.
28137330f729Sjoerg SA->analyze(&VirtReg);
28147330f729Sjoerg if (calcSpillCost() >= CSRCost)
28157330f729Sjoerg return PhysReg;
28167330f729Sjoerg
28177330f729Sjoerg // We are going to spill, set CostPerUseLimit to 1 to make sure that
28187330f729Sjoerg // we will not use a callee-saved register in tryEvict.
28197330f729Sjoerg CostPerUseLimit = 1;
28207330f729Sjoerg return 0;
28217330f729Sjoerg }
28227330f729Sjoerg if (getStage(VirtReg) < RS_Split) {
28237330f729Sjoerg // We choose pre-splitting over using the CSR for the first time if
28247330f729Sjoerg // the cost of splitting is lower than CSRCost.
28257330f729Sjoerg SA->analyze(&VirtReg);
28267330f729Sjoerg unsigned NumCands = 0;
28277330f729Sjoerg BlockFrequency BestCost = CSRCost; // Don't modify CSRCost.
28287330f729Sjoerg unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
28297330f729Sjoerg NumCands, true /*IgnoreCSR*/);
28307330f729Sjoerg if (BestCand == NoCand)
28317330f729Sjoerg // Use the CSR if we can't find a region split below CSRCost.
28327330f729Sjoerg return PhysReg;
28337330f729Sjoerg
28347330f729Sjoerg // Perform the actual pre-splitting.
28357330f729Sjoerg doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);
28367330f729Sjoerg return 0;
28377330f729Sjoerg }
28387330f729Sjoerg return PhysReg;
28397330f729Sjoerg }
28407330f729Sjoerg
aboutToRemoveInterval(LiveInterval & LI)28417330f729Sjoerg void RAGreedy::aboutToRemoveInterval(LiveInterval &LI) {
28427330f729Sjoerg // Do not keep invalid information around.
28437330f729Sjoerg SetOfBrokenHints.remove(&LI);
28447330f729Sjoerg }
28457330f729Sjoerg
initializeCSRCost()28467330f729Sjoerg void RAGreedy::initializeCSRCost() {
28477330f729Sjoerg // We use the larger one out of the command-line option and the value report
28487330f729Sjoerg // by TRI.
28497330f729Sjoerg CSRCost = BlockFrequency(
28507330f729Sjoerg std::max((unsigned)CSRFirstTimeCost, TRI->getCSRFirstUseCost()));
28517330f729Sjoerg if (!CSRCost.getFrequency())
28527330f729Sjoerg return;
28537330f729Sjoerg
28547330f729Sjoerg // Raw cost is relative to Entry == 2^14; scale it appropriately.
28557330f729Sjoerg uint64_t ActualEntry = MBFI->getEntryFreq();
28567330f729Sjoerg if (!ActualEntry) {
28577330f729Sjoerg CSRCost = 0;
28587330f729Sjoerg return;
28597330f729Sjoerg }
28607330f729Sjoerg uint64_t FixedEntry = 1 << 14;
28617330f729Sjoerg if (ActualEntry < FixedEntry)
28627330f729Sjoerg CSRCost *= BranchProbability(ActualEntry, FixedEntry);
28637330f729Sjoerg else if (ActualEntry <= UINT32_MAX)
28647330f729Sjoerg // Invert the fraction and divide.
28657330f729Sjoerg CSRCost /= BranchProbability(FixedEntry, ActualEntry);
28667330f729Sjoerg else
28677330f729Sjoerg // Can't use BranchProbability in general, since it takes 32-bit numbers.
28687330f729Sjoerg CSRCost = CSRCost.getFrequency() * (ActualEntry / FixedEntry);
28697330f729Sjoerg }
28707330f729Sjoerg
28717330f729Sjoerg /// Collect the hint info for \p Reg.
28727330f729Sjoerg /// The results are stored into \p Out.
28737330f729Sjoerg /// \p Out is not cleared before being populated.
collectHintInfo(Register Reg,HintsInfo & Out)2874*82d56013Sjoerg void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
28757330f729Sjoerg for (const MachineInstr &Instr : MRI->reg_nodbg_instructions(Reg)) {
28767330f729Sjoerg if (!Instr.isFullCopy())
28777330f729Sjoerg continue;
28787330f729Sjoerg // Look for the other end of the copy.
28797330f729Sjoerg Register OtherReg = Instr.getOperand(0).getReg();
28807330f729Sjoerg if (OtherReg == Reg) {
28817330f729Sjoerg OtherReg = Instr.getOperand(1).getReg();
28827330f729Sjoerg if (OtherReg == Reg)
28837330f729Sjoerg continue;
28847330f729Sjoerg }
28857330f729Sjoerg // Get the current assignment.
2886*82d56013Sjoerg MCRegister OtherPhysReg =
2887*82d56013Sjoerg OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
28887330f729Sjoerg // Push the collected information.
28897330f729Sjoerg Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
28907330f729Sjoerg OtherPhysReg));
28917330f729Sjoerg }
28927330f729Sjoerg }
28937330f729Sjoerg
28947330f729Sjoerg /// Using the given \p List, compute the cost of the broken hints if
28957330f729Sjoerg /// \p PhysReg was used.
28967330f729Sjoerg /// \return The cost of \p List for \p PhysReg.
getBrokenHintFreq(const HintsInfo & List,MCRegister PhysReg)28977330f729Sjoerg BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
2898*82d56013Sjoerg MCRegister PhysReg) {
28997330f729Sjoerg BlockFrequency Cost = 0;
29007330f729Sjoerg for (const HintInfo &Info : List) {
29017330f729Sjoerg if (Info.PhysReg != PhysReg)
29027330f729Sjoerg Cost += Info.Freq;
29037330f729Sjoerg }
29047330f729Sjoerg return Cost;
29057330f729Sjoerg }
29067330f729Sjoerg
29077330f729Sjoerg /// Using the register assigned to \p VirtReg, try to recolor
29087330f729Sjoerg /// all the live ranges that are copy-related with \p VirtReg.
29097330f729Sjoerg /// The recoloring is then propagated to all the live-ranges that have
29107330f729Sjoerg /// been recolored and so on, until no more copies can be coalesced or
29117330f729Sjoerg /// it is not profitable.
29127330f729Sjoerg /// For a given live range, profitability is determined by the sum of the
29137330f729Sjoerg /// frequencies of the non-identity copies it would introduce with the old
29147330f729Sjoerg /// and new register.
tryHintRecoloring(LiveInterval & VirtReg)29157330f729Sjoerg void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) {
29167330f729Sjoerg // We have a broken hint, check if it is possible to fix it by
29177330f729Sjoerg // reusing PhysReg for the copy-related live-ranges. Indeed, we evicted
29187330f729Sjoerg // some register and PhysReg may be available for the other live-ranges.
2919*82d56013Sjoerg SmallSet<Register, 4> Visited;
29207330f729Sjoerg SmallVector<unsigned, 2> RecoloringCandidates;
29217330f729Sjoerg HintsInfo Info;
2922*82d56013Sjoerg Register Reg = VirtReg.reg();
2923*82d56013Sjoerg MCRegister PhysReg = VRM->getPhys(Reg);
29247330f729Sjoerg // Start the recoloring algorithm from the input live-interval, then
29257330f729Sjoerg // it will propagate to the ones that are copy-related with it.
29267330f729Sjoerg Visited.insert(Reg);
29277330f729Sjoerg RecoloringCandidates.push_back(Reg);
29287330f729Sjoerg
29297330f729Sjoerg LLVM_DEBUG(dbgs() << "Trying to reconcile hints for: " << printReg(Reg, TRI)
29307330f729Sjoerg << '(' << printReg(PhysReg, TRI) << ")\n");
29317330f729Sjoerg
29327330f729Sjoerg do {
29337330f729Sjoerg Reg = RecoloringCandidates.pop_back_val();
29347330f729Sjoerg
29357330f729Sjoerg // We cannot recolor physical register.
29367330f729Sjoerg if (Register::isPhysicalRegister(Reg))
29377330f729Sjoerg continue;
29387330f729Sjoerg
29397330f729Sjoerg assert(VRM->hasPhys(Reg) && "We have unallocated variable!!");
29407330f729Sjoerg
29417330f729Sjoerg // Get the live interval mapped with this virtual register to be able
29427330f729Sjoerg // to check for the interference with the new color.
29437330f729Sjoerg LiveInterval &LI = LIS->getInterval(Reg);
2944*82d56013Sjoerg MCRegister CurrPhys = VRM->getPhys(Reg);
29457330f729Sjoerg // Check that the new color matches the register class constraints and
29467330f729Sjoerg // that it is free for this live range.
29477330f729Sjoerg if (CurrPhys != PhysReg && (!MRI->getRegClass(Reg)->contains(PhysReg) ||
29487330f729Sjoerg Matrix->checkInterference(LI, PhysReg)))
29497330f729Sjoerg continue;
29507330f729Sjoerg
29517330f729Sjoerg LLVM_DEBUG(dbgs() << printReg(Reg, TRI) << '(' << printReg(CurrPhys, TRI)
29527330f729Sjoerg << ") is recolorable.\n");
29537330f729Sjoerg
29547330f729Sjoerg // Gather the hint info.
29557330f729Sjoerg Info.clear();
29567330f729Sjoerg collectHintInfo(Reg, Info);
29577330f729Sjoerg // Check if recoloring the live-range will increase the cost of the
29587330f729Sjoerg // non-identity copies.
29597330f729Sjoerg if (CurrPhys != PhysReg) {
29607330f729Sjoerg LLVM_DEBUG(dbgs() << "Checking profitability:\n");
29617330f729Sjoerg BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
29627330f729Sjoerg BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
29637330f729Sjoerg LLVM_DEBUG(dbgs() << "Old Cost: " << OldCopiesCost.getFrequency()
29647330f729Sjoerg << "\nNew Cost: " << NewCopiesCost.getFrequency()
29657330f729Sjoerg << '\n');
29667330f729Sjoerg if (OldCopiesCost < NewCopiesCost) {
29677330f729Sjoerg LLVM_DEBUG(dbgs() << "=> Not profitable.\n");
29687330f729Sjoerg continue;
29697330f729Sjoerg }
29707330f729Sjoerg // At this point, the cost is either cheaper or equal. If it is
29717330f729Sjoerg // equal, we consider this is profitable because it may expose
29727330f729Sjoerg // more recoloring opportunities.
29737330f729Sjoerg LLVM_DEBUG(dbgs() << "=> Profitable.\n");
29747330f729Sjoerg // Recolor the live-range.
29757330f729Sjoerg Matrix->unassign(LI);
29767330f729Sjoerg Matrix->assign(LI, PhysReg);
29777330f729Sjoerg }
29787330f729Sjoerg // Push all copy-related live-ranges to keep reconciling the broken
29797330f729Sjoerg // hints.
29807330f729Sjoerg for (const HintInfo &HI : Info) {
29817330f729Sjoerg if (Visited.insert(HI.Reg).second)
29827330f729Sjoerg RecoloringCandidates.push_back(HI.Reg);
29837330f729Sjoerg }
29847330f729Sjoerg } while (!RecoloringCandidates.empty());
29857330f729Sjoerg }
29867330f729Sjoerg
29877330f729Sjoerg /// Try to recolor broken hints.
29887330f729Sjoerg /// Broken hints may be repaired by recoloring when an evicted variable
29897330f729Sjoerg /// freed up a register for a larger live-range.
29907330f729Sjoerg /// Consider the following example:
29917330f729Sjoerg /// BB1:
29927330f729Sjoerg /// a =
29937330f729Sjoerg /// b =
29947330f729Sjoerg /// BB2:
29957330f729Sjoerg /// ...
29967330f729Sjoerg /// = b
29977330f729Sjoerg /// = a
29987330f729Sjoerg /// Let us assume b gets split:
29997330f729Sjoerg /// BB1:
30007330f729Sjoerg /// a =
30017330f729Sjoerg /// b =
30027330f729Sjoerg /// BB2:
30037330f729Sjoerg /// c = b
30047330f729Sjoerg /// ...
30057330f729Sjoerg /// d = c
30067330f729Sjoerg /// = d
30077330f729Sjoerg /// = a
30087330f729Sjoerg /// Because of how the allocation work, b, c, and d may be assigned different
30097330f729Sjoerg /// colors. Now, if a gets evicted later:
30107330f729Sjoerg /// BB1:
30117330f729Sjoerg /// a =
30127330f729Sjoerg /// st a, SpillSlot
30137330f729Sjoerg /// b =
30147330f729Sjoerg /// BB2:
30157330f729Sjoerg /// c = b
30167330f729Sjoerg /// ...
30177330f729Sjoerg /// d = c
30187330f729Sjoerg /// = d
30197330f729Sjoerg /// e = ld SpillSlot
30207330f729Sjoerg /// = e
30217330f729Sjoerg /// This is likely that we can assign the same register for b, c, and d,
30227330f729Sjoerg /// getting rid of 2 copies.
tryHintsRecoloring()30237330f729Sjoerg void RAGreedy::tryHintsRecoloring() {
30247330f729Sjoerg for (LiveInterval *LI : SetOfBrokenHints) {
3025*82d56013Sjoerg assert(Register::isVirtualRegister(LI->reg()) &&
30267330f729Sjoerg "Recoloring is possible only for virtual registers");
30277330f729Sjoerg // Some dead defs may be around (e.g., because of debug uses).
30287330f729Sjoerg // Ignore those.
3029*82d56013Sjoerg if (!VRM->hasPhys(LI->reg()))
30307330f729Sjoerg continue;
30317330f729Sjoerg tryHintRecoloring(*LI);
30327330f729Sjoerg }
30337330f729Sjoerg }
30347330f729Sjoerg
selectOrSplitImpl(LiveInterval & VirtReg,SmallVectorImpl<Register> & NewVRegs,SmallVirtRegSet & FixedRegisters,unsigned Depth)3035*82d56013Sjoerg MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
3036*82d56013Sjoerg SmallVectorImpl<Register> &NewVRegs,
30377330f729Sjoerg SmallVirtRegSet &FixedRegisters,
30387330f729Sjoerg unsigned Depth) {
3039*82d56013Sjoerg uint8_t CostPerUseLimit = uint8_t(~0u);
30407330f729Sjoerg // First try assigning a free register.
3041*82d56013Sjoerg auto Order =
3042*82d56013Sjoerg AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
3043*82d56013Sjoerg if (MCRegister PhysReg =
3044*82d56013Sjoerg tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
3045*82d56013Sjoerg // If VirtReg got an assignment, the eviction info is no longer relevant.
3046*82d56013Sjoerg LastEvicted.clearEvicteeInfo(VirtReg.reg());
30477330f729Sjoerg // When NewVRegs is not empty, we may have made decisions such as evicting
30487330f729Sjoerg // a virtual register, go with the earlier decisions and use the physical
30497330f729Sjoerg // register.
30507330f729Sjoerg if (CSRCost.getFrequency() && isUnusedCalleeSavedReg(PhysReg) &&
30517330f729Sjoerg NewVRegs.empty()) {
3052*82d56013Sjoerg MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
30537330f729Sjoerg CostPerUseLimit, NewVRegs);
30547330f729Sjoerg if (CSRReg || !NewVRegs.empty())
30557330f729Sjoerg // Return now if we decide to use a CSR or create new vregs due to
30567330f729Sjoerg // pre-splitting.
30577330f729Sjoerg return CSRReg;
30587330f729Sjoerg } else
30597330f729Sjoerg return PhysReg;
30607330f729Sjoerg }
30617330f729Sjoerg
30627330f729Sjoerg LiveRangeStage Stage = getStage(VirtReg);
30637330f729Sjoerg LLVM_DEBUG(dbgs() << StageName[Stage] << " Cascade "
3064*82d56013Sjoerg << ExtraRegInfo[VirtReg.reg()].Cascade << '\n');
30657330f729Sjoerg
30667330f729Sjoerg // Try to evict a less worthy live range, but only for ranges from the primary
30677330f729Sjoerg // queue. The RS_Split ranges already failed to do this, and they should not
30687330f729Sjoerg // get a second chance until they have been split.
30697330f729Sjoerg if (Stage != RS_Split)
3070*82d56013Sjoerg if (Register PhysReg =
30717330f729Sjoerg tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
30727330f729Sjoerg FixedRegisters)) {
3073*82d56013Sjoerg Register Hint = MRI->getSimpleHint(VirtReg.reg());
30747330f729Sjoerg // If VirtReg has a hint and that hint is broken record this
30757330f729Sjoerg // virtual register as a recoloring candidate for broken hint.
30767330f729Sjoerg // Indeed, since we evicted a variable in its neighborhood it is
30777330f729Sjoerg // likely we can at least partially recolor some of the
30787330f729Sjoerg // copy-related live-ranges.
30797330f729Sjoerg if (Hint && Hint != PhysReg)
30807330f729Sjoerg SetOfBrokenHints.insert(&VirtReg);
30817330f729Sjoerg // If VirtReg eviction someone, the eviction info for it as an evictee is
3082*82d56013Sjoerg // no longer relevant.
3083*82d56013Sjoerg LastEvicted.clearEvicteeInfo(VirtReg.reg());
30847330f729Sjoerg return PhysReg;
30857330f729Sjoerg }
30867330f729Sjoerg
30877330f729Sjoerg assert((NewVRegs.empty() || Depth) && "Cannot append to existing NewVRegs");
30887330f729Sjoerg
30897330f729Sjoerg // The first time we see a live range, don't try to split or spill.
30907330f729Sjoerg // Wait until the second time, when all smaller ranges have been allocated.
30917330f729Sjoerg // This gives a better picture of the interference to split around.
30927330f729Sjoerg if (Stage < RS_Split) {
30937330f729Sjoerg setStage(VirtReg, RS_Split);
30947330f729Sjoerg LLVM_DEBUG(dbgs() << "wait for second round\n");
3095*82d56013Sjoerg NewVRegs.push_back(VirtReg.reg());
30967330f729Sjoerg return 0;
30977330f729Sjoerg }
30987330f729Sjoerg
30997330f729Sjoerg if (Stage < RS_Spill) {
31007330f729Sjoerg // Try splitting VirtReg or interferences.
31017330f729Sjoerg unsigned NewVRegSizeBefore = NewVRegs.size();
3102*82d56013Sjoerg Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
31037330f729Sjoerg if (PhysReg || (NewVRegs.size() - NewVRegSizeBefore)) {
3104*82d56013Sjoerg // If VirtReg got split, the eviction info is no longer relevant.
3105*82d56013Sjoerg LastEvicted.clearEvicteeInfo(VirtReg.reg());
31067330f729Sjoerg return PhysReg;
31077330f729Sjoerg }
31087330f729Sjoerg }
31097330f729Sjoerg
31107330f729Sjoerg // If we couldn't allocate a register from spilling, there is probably some
31117330f729Sjoerg // invalid inline assembly. The base class will report it.
31127330f729Sjoerg if (Stage >= RS_Done || !VirtReg.isSpillable())
31137330f729Sjoerg return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
31147330f729Sjoerg Depth);
31157330f729Sjoerg
31167330f729Sjoerg // Finally spill VirtReg itself.
3117*82d56013Sjoerg if ((EnableDeferredSpilling ||
3118*82d56013Sjoerg TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
3119*82d56013Sjoerg getStage(VirtReg) < RS_Memory) {
31207330f729Sjoerg // TODO: This is experimental and in particular, we do not model
31217330f729Sjoerg // the live range splitting done by spilling correctly.
31227330f729Sjoerg // We would need a deep integration with the spiller to do the
31237330f729Sjoerg // right thing here. Anyway, that is still good for early testing.
31247330f729Sjoerg setStage(VirtReg, RS_Memory);
31257330f729Sjoerg LLVM_DEBUG(dbgs() << "Do as if this register is in memory\n");
3126*82d56013Sjoerg NewVRegs.push_back(VirtReg.reg());
31277330f729Sjoerg } else {
31287330f729Sjoerg NamedRegionTimer T("spill", "Spiller", TimerGroupName,
31297330f729Sjoerg TimerGroupDescription, TimePassesIsEnabled);
31307330f729Sjoerg LiveRangeEdit LRE(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
31317330f729Sjoerg spiller().spill(LRE);
31327330f729Sjoerg setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done);
31337330f729Sjoerg
3134*82d56013Sjoerg // Tell LiveDebugVariables about the new ranges. Ranges not being covered by
3135*82d56013Sjoerg // the new regs are kept in LDV (still mapping to the old register), until
3136*82d56013Sjoerg // we rewrite spilled locations in LDV at a later stage.
3137*82d56013Sjoerg DebugVars->splitRegister(VirtReg.reg(), LRE.regs(), *LIS);
3138*82d56013Sjoerg
31397330f729Sjoerg if (VerifyEnabled)
31407330f729Sjoerg MF->verify(this, "After spilling");
31417330f729Sjoerg }
31427330f729Sjoerg
31437330f729Sjoerg // The live virtual register requesting allocation was spilled, so tell
31447330f729Sjoerg // the caller not to allocate anything during this round.
31457330f729Sjoerg return 0;
31467330f729Sjoerg }
31477330f729Sjoerg
report(MachineOptimizationRemarkMissed & R)3148*82d56013Sjoerg void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
3149*82d56013Sjoerg using namespace ore;
3150*82d56013Sjoerg if (Spills) {
3151*82d56013Sjoerg R << NV("NumSpills", Spills) << " spills ";
3152*82d56013Sjoerg R << NV("TotalSpillsCost", SpillsCost) << " total spills cost ";
3153*82d56013Sjoerg }
3154*82d56013Sjoerg if (FoldedSpills) {
3155*82d56013Sjoerg R << NV("NumFoldedSpills", FoldedSpills) << " folded spills ";
3156*82d56013Sjoerg R << NV("TotalFoldedSpillsCost", FoldedSpillsCost)
3157*82d56013Sjoerg << " total folded spills cost ";
3158*82d56013Sjoerg }
3159*82d56013Sjoerg if (Reloads) {
3160*82d56013Sjoerg R << NV("NumReloads", Reloads) << " reloads ";
3161*82d56013Sjoerg R << NV("TotalReloadsCost", ReloadsCost) << " total reloads cost ";
3162*82d56013Sjoerg }
3163*82d56013Sjoerg if (FoldedReloads) {
3164*82d56013Sjoerg R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads ";
3165*82d56013Sjoerg R << NV("TotalFoldedReloadsCost", FoldedReloadsCost)
3166*82d56013Sjoerg << " total folded reloads cost ";
3167*82d56013Sjoerg }
3168*82d56013Sjoerg if (ZeroCostFoldedReloads)
3169*82d56013Sjoerg R << NV("NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
3170*82d56013Sjoerg << " zero cost folded reloads ";
3171*82d56013Sjoerg if (Copies) {
3172*82d56013Sjoerg R << NV("NumVRCopies", Copies) << " virtual registers copies ";
3173*82d56013Sjoerg R << NV("TotalCopiesCost", CopiesCost) << " total copies cost ";
3174*82d56013Sjoerg }
31757330f729Sjoerg }
31767330f729Sjoerg
computeStats(MachineBasicBlock & MBB)3177*82d56013Sjoerg RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &MBB) {
3178*82d56013Sjoerg RAGreedyStats Stats;
31797330f729Sjoerg const MachineFrameInfo &MFI = MF->getFrameInfo();
31807330f729Sjoerg int FI;
31817330f729Sjoerg
3182*82d56013Sjoerg auto isSpillSlotAccess = [&MFI](const MachineMemOperand *A) {
3183*82d56013Sjoerg return MFI.isSpillSlotObjectIndex(cast<FixedStackPseudoSourceValue>(
3184*82d56013Sjoerg A->getPseudoValue())->getFrameIndex());
3185*82d56013Sjoerg };
3186*82d56013Sjoerg auto isPatchpointInstr = [](const MachineInstr &MI) {
3187*82d56013Sjoerg return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
3188*82d56013Sjoerg MI.getOpcode() == TargetOpcode::STACKMAP ||
3189*82d56013Sjoerg MI.getOpcode() == TargetOpcode::STATEPOINT;
3190*82d56013Sjoerg };
3191*82d56013Sjoerg for (MachineInstr &MI : MBB) {
3192*82d56013Sjoerg if (MI.isCopy()) {
3193*82d56013Sjoerg MachineOperand &Dest = MI.getOperand(0);
3194*82d56013Sjoerg MachineOperand &Src = MI.getOperand(1);
3195*82d56013Sjoerg if (Dest.isReg() && Src.isReg() && Dest.getReg().isVirtual() &&
3196*82d56013Sjoerg Src.getReg().isVirtual())
3197*82d56013Sjoerg ++Stats.Copies;
3198*82d56013Sjoerg continue;
3199*82d56013Sjoerg }
3200*82d56013Sjoerg
3201*82d56013Sjoerg SmallVector<const MachineMemOperand *, 2> Accesses;
3202*82d56013Sjoerg if (TII->isLoadFromStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) {
3203*82d56013Sjoerg ++Stats.Reloads;
3204*82d56013Sjoerg continue;
3205*82d56013Sjoerg }
3206*82d56013Sjoerg if (TII->isStoreToStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) {
3207*82d56013Sjoerg ++Stats.Spills;
3208*82d56013Sjoerg continue;
3209*82d56013Sjoerg }
3210*82d56013Sjoerg if (TII->hasLoadFromStackSlot(MI, Accesses) &&
3211*82d56013Sjoerg llvm::any_of(Accesses, isSpillSlotAccess)) {
3212*82d56013Sjoerg if (!isPatchpointInstr(MI)) {
3213*82d56013Sjoerg Stats.FoldedReloads += Accesses.size();
3214*82d56013Sjoerg continue;
3215*82d56013Sjoerg }
3216*82d56013Sjoerg // For statepoint there may be folded and zero cost folded stack reloads.
3217*82d56013Sjoerg std::pair<unsigned, unsigned> NonZeroCostRange =
3218*82d56013Sjoerg TII->getPatchpointUnfoldableRange(MI);
3219*82d56013Sjoerg SmallSet<unsigned, 16> FoldedReloads;
3220*82d56013Sjoerg SmallSet<unsigned, 16> ZeroCostFoldedReloads;
3221*82d56013Sjoerg for (unsigned Idx = 0, E = MI.getNumOperands(); Idx < E; ++Idx) {
3222*82d56013Sjoerg MachineOperand &MO = MI.getOperand(Idx);
3223*82d56013Sjoerg if (!MO.isFI() || !MFI.isSpillSlotObjectIndex(MO.getIndex()))
3224*82d56013Sjoerg continue;
3225*82d56013Sjoerg if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
3226*82d56013Sjoerg FoldedReloads.insert(MO.getIndex());
3227*82d56013Sjoerg else
3228*82d56013Sjoerg ZeroCostFoldedReloads.insert(MO.getIndex());
3229*82d56013Sjoerg }
3230*82d56013Sjoerg // If stack slot is used in folded reload it is not zero cost then.
3231*82d56013Sjoerg for (unsigned Slot : FoldedReloads)
3232*82d56013Sjoerg ZeroCostFoldedReloads.erase(Slot);
3233*82d56013Sjoerg Stats.FoldedReloads += FoldedReloads.size();
3234*82d56013Sjoerg Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.size();
3235*82d56013Sjoerg continue;
3236*82d56013Sjoerg }
3237*82d56013Sjoerg Accesses.clear();
3238*82d56013Sjoerg if (TII->hasStoreToStackSlot(MI, Accesses) &&
3239*82d56013Sjoerg llvm::any_of(Accesses, isSpillSlotAccess)) {
3240*82d56013Sjoerg Stats.FoldedSpills += Accesses.size();
3241*82d56013Sjoerg }
3242*82d56013Sjoerg }
3243*82d56013Sjoerg // Set cost of collected statistic by multiplication to relative frequency of
3244*82d56013Sjoerg // this basic block.
3245*82d56013Sjoerg float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&MBB);
3246*82d56013Sjoerg Stats.ReloadsCost = RelFreq * Stats.Reloads;
3247*82d56013Sjoerg Stats.FoldedReloadsCost = RelFreq * Stats.FoldedReloads;
3248*82d56013Sjoerg Stats.SpillsCost = RelFreq * Stats.Spills;
3249*82d56013Sjoerg Stats.FoldedSpillsCost = RelFreq * Stats.FoldedSpills;
3250*82d56013Sjoerg Stats.CopiesCost = RelFreq * Stats.Copies;
3251*82d56013Sjoerg return Stats;
3252*82d56013Sjoerg }
3253*82d56013Sjoerg
reportStats(MachineLoop * L)3254*82d56013Sjoerg RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
3255*82d56013Sjoerg RAGreedyStats Stats;
3256*82d56013Sjoerg
3257*82d56013Sjoerg // Sum up the spill and reloads in subloops.
3258*82d56013Sjoerg for (MachineLoop *SubLoop : *L)
3259*82d56013Sjoerg Stats.add(reportStats(SubLoop));
3260*82d56013Sjoerg
32617330f729Sjoerg for (MachineBasicBlock *MBB : L->getBlocks())
32627330f729Sjoerg // Handle blocks that were not included in subloops.
32637330f729Sjoerg if (Loops->getLoopFor(MBB) == L)
3264*82d56013Sjoerg Stats.add(computeStats(*MBB));
32657330f729Sjoerg
3266*82d56013Sjoerg if (!Stats.isEmpty()) {
32677330f729Sjoerg using namespace ore;
32687330f729Sjoerg
32697330f729Sjoerg ORE->emit([&]() {
3270*82d56013Sjoerg MachineOptimizationRemarkMissed R(DEBUG_TYPE, "LoopSpillReloadCopies",
32717330f729Sjoerg L->getStartLoc(), L->getHeader());
3272*82d56013Sjoerg Stats.report(R);
32737330f729Sjoerg R << "generated in loop";
32747330f729Sjoerg return R;
32757330f729Sjoerg });
32767330f729Sjoerg }
3277*82d56013Sjoerg return Stats;
3278*82d56013Sjoerg }
3279*82d56013Sjoerg
reportStats()3280*82d56013Sjoerg void RAGreedy::reportStats() {
3281*82d56013Sjoerg if (!ORE->allowExtraAnalysis(DEBUG_TYPE))
3282*82d56013Sjoerg return;
3283*82d56013Sjoerg RAGreedyStats Stats;
3284*82d56013Sjoerg for (MachineLoop *L : *Loops)
3285*82d56013Sjoerg Stats.add(reportStats(L));
3286*82d56013Sjoerg // Process non-loop blocks.
3287*82d56013Sjoerg for (MachineBasicBlock &MBB : *MF)
3288*82d56013Sjoerg if (!Loops->getLoopFor(&MBB))
3289*82d56013Sjoerg Stats.add(computeStats(MBB));
3290*82d56013Sjoerg if (!Stats.isEmpty()) {
3291*82d56013Sjoerg using namespace ore;
3292*82d56013Sjoerg
3293*82d56013Sjoerg ORE->emit([&]() {
3294*82d56013Sjoerg DebugLoc Loc;
3295*82d56013Sjoerg if (auto *SP = MF->getFunction().getSubprogram())
3296*82d56013Sjoerg Loc = DILocation::get(SP->getContext(), SP->getLine(), 1, SP);
3297*82d56013Sjoerg MachineOptimizationRemarkMissed R(DEBUG_TYPE, "SpillReloadCopies", Loc,
3298*82d56013Sjoerg &MF->front());
3299*82d56013Sjoerg Stats.report(R);
3300*82d56013Sjoerg R << "generated in function";
3301*82d56013Sjoerg return R;
3302*82d56013Sjoerg });
3303*82d56013Sjoerg }
33047330f729Sjoerg }
33057330f729Sjoerg
runOnMachineFunction(MachineFunction & mf)33067330f729Sjoerg bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
33077330f729Sjoerg LLVM_DEBUG(dbgs() << "********** GREEDY REGISTER ALLOCATION **********\n"
33087330f729Sjoerg << "********** Function: " << mf.getName() << '\n');
33097330f729Sjoerg
33107330f729Sjoerg MF = &mf;
33117330f729Sjoerg TRI = MF->getSubtarget().getRegisterInfo();
33127330f729Sjoerg TII = MF->getSubtarget().getInstrInfo();
33137330f729Sjoerg RCI.runOnMachineFunction(mf);
33147330f729Sjoerg
33157330f729Sjoerg EnableLocalReassign = EnableLocalReassignment ||
33167330f729Sjoerg MF->getSubtarget().enableRALocalReassignment(
33177330f729Sjoerg MF->getTarget().getOptLevel());
33187330f729Sjoerg
3319*82d56013Sjoerg EnableAdvancedRASplitCost =
3320*82d56013Sjoerg ConsiderLocalIntervalCost.getNumOccurrences()
3321*82d56013Sjoerg ? ConsiderLocalIntervalCost
3322*82d56013Sjoerg : MF->getSubtarget().enableAdvancedRASplitCost();
33237330f729Sjoerg
33247330f729Sjoerg if (VerifyEnabled)
33257330f729Sjoerg MF->verify(this, "Before greedy register allocator");
33267330f729Sjoerg
33277330f729Sjoerg RegAllocBase::init(getAnalysis<VirtRegMap>(),
33287330f729Sjoerg getAnalysis<LiveIntervals>(),
33297330f729Sjoerg getAnalysis<LiveRegMatrix>());
33307330f729Sjoerg Indexes = &getAnalysis<SlotIndexes>();
33317330f729Sjoerg MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
33327330f729Sjoerg DomTree = &getAnalysis<MachineDominatorTree>();
33337330f729Sjoerg ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
33347330f729Sjoerg Loops = &getAnalysis<MachineLoopInfo>();
33357330f729Sjoerg Bundles = &getAnalysis<EdgeBundles>();
33367330f729Sjoerg SpillPlacer = &getAnalysis<SpillPlacement>();
33377330f729Sjoerg DebugVars = &getAnalysis<LiveDebugVariables>();
33387330f729Sjoerg AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
33397330f729Sjoerg
33407330f729Sjoerg initializeCSRCost();
33417330f729Sjoerg
3342*82d56013Sjoerg RegCosts = TRI->getRegisterCosts(*MF);
3343*82d56013Sjoerg
3344*82d56013Sjoerg VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
3345*82d56013Sjoerg SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI));
3346*82d56013Sjoerg
3347*82d56013Sjoerg VRAI->calculateSpillWeightsAndHints();
33487330f729Sjoerg
33497330f729Sjoerg LLVM_DEBUG(LIS->dump());
33507330f729Sjoerg
33517330f729Sjoerg SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops));
3352*82d56013Sjoerg SE.reset(new SplitEditor(*SA, *AA, *LIS, *VRM, *DomTree, *MBFI, *VRAI));
33537330f729Sjoerg ExtraRegInfo.clear();
33547330f729Sjoerg ExtraRegInfo.resize(MRI->getNumVirtRegs());
33557330f729Sjoerg NextCascade = 1;
33567330f729Sjoerg IntfCache.init(MF, Matrix->getLiveUnions(), Indexes, LIS, TRI);
33577330f729Sjoerg GlobalCand.resize(32); // This will grow as needed.
33587330f729Sjoerg SetOfBrokenHints.clear();
33597330f729Sjoerg LastEvicted.clear();
33607330f729Sjoerg
33617330f729Sjoerg allocatePhysRegs();
33627330f729Sjoerg tryHintsRecoloring();
3363*82d56013Sjoerg
3364*82d56013Sjoerg if (VerifyEnabled)
3365*82d56013Sjoerg MF->verify(this, "Before post optimization");
33667330f729Sjoerg postOptimization();
3367*82d56013Sjoerg reportStats();
33687330f729Sjoerg
33697330f729Sjoerg releaseMemory();
33707330f729Sjoerg return true;
33717330f729Sjoerg }
3372