|
|
|||
File indexing completed on 2026-05-10 08:43:36
0001 //===- SpillPlacement.h - Optimal Spill Code Placement ---------*- C++ -*--===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This analysis computes the optimal spill code placement between basic blocks. 0010 // 0011 // The runOnMachineFunction() method only precomputes some profiling information 0012 // about the CFG. The real work is done by prepare(), addConstraints(), and 0013 // finish() which are called by the register allocator. 0014 // 0015 // Given a variable that is live across multiple basic blocks, and given 0016 // constraints on the basic blocks where the variable is live, determine which 0017 // edge bundles should have the variable in a register and which edge bundles 0018 // should have the variable in a stack slot. 0019 // 0020 // The returned bit vector can be used to place optimal spill code at basic 0021 // block entries and exits. Spill code placement inside a basic block is not 0022 // considered. 0023 // 0024 //===----------------------------------------------------------------------===// 0025 0026 #ifndef LLVM_LIB_CODEGEN_SPILLPLACEMENT_H 0027 #define LLVM_LIB_CODEGEN_SPILLPLACEMENT_H 0028 0029 #include "llvm/ADT/ArrayRef.h" 0030 #include "llvm/ADT/SmallVector.h" 0031 #include "llvm/ADT/SparseSet.h" 0032 #include "llvm/CodeGen/MachineFunctionAnalysis.h" 0033 #include "llvm/CodeGen/MachineFunctionPass.h" 0034 #include "llvm/Support/BlockFrequency.h" 0035 0036 namespace llvm { 0037 0038 class BitVector; 0039 class EdgeBundles; 0040 class MachineBlockFrequencyInfo; 0041 class MachineFunction; 0042 class SpillPlacementWrapperLegacy; 0043 class SpillPlacementAnalysis; 0044 0045 class SpillPlacement { 0046 friend class SpillPlacementWrapperLegacy; 0047 friend class SpillPlacementAnalysis; 0048 0049 struct Node; 0050 0051 const MachineFunction *MF = nullptr; 0052 const EdgeBundles *bundles = nullptr; 0053 const MachineBlockFrequencyInfo *MBFI = nullptr; 0054 0055 std::unique_ptr<Node[]> nodes; 0056 0057 // Nodes that are active in the current computation. Owned by the prepare() 0058 // caller. 0059 BitVector *ActiveNodes = nullptr; 0060 0061 // Nodes with active links. Populated by scanActiveBundles. 0062 SmallVector<unsigned, 8> Linked; 0063 0064 // Nodes that went positive during the last call to scanActiveBundles or 0065 // iterate. 0066 SmallVector<unsigned, 8> RecentPositive; 0067 0068 // Block frequencies are computed once. Indexed by block number. 0069 SmallVector<BlockFrequency, 8> BlockFrequencies; 0070 0071 /// Decision threshold. A node gets the output value 0 if the weighted sum of 0072 /// its inputs falls in the open interval (-Threshold;Threshold). 0073 BlockFrequency Threshold; 0074 0075 /// List of nodes that need to be updated in ::iterate. 0076 SparseSet<unsigned> TodoList; 0077 0078 public: 0079 /// BorderConstraint - A basic block has separate constraints for entry and 0080 /// exit. 0081 enum BorderConstraint { 0082 DontCare, ///< Block doesn't care / variable not live. 0083 PrefReg, ///< Block entry/exit prefers a register. 0084 PrefSpill, ///< Block entry/exit prefers a stack slot. 0085 PrefBoth, ///< Block entry prefers both register and stack. 0086 MustSpill ///< A register is impossible, variable must be spilled. 0087 }; 0088 0089 /// BlockConstraint - Entry and exit constraints for a basic block. 0090 struct BlockConstraint { 0091 unsigned Number; ///< Basic block number (from MBB::getNumber()). 0092 BorderConstraint Entry : 8; ///< Constraint on block entry. 0093 BorderConstraint Exit : 8; ///< Constraint on block exit. 0094 0095 /// True when this block changes the value of the live range. This means 0096 /// the block has a non-PHI def. When this is false, a live-in value on 0097 /// the stack can be live-out on the stack without inserting a spill. 0098 bool ChangesValue; 0099 0100 void print(raw_ostream &OS) const; 0101 void dump() const; 0102 }; 0103 0104 /// prepare - Reset state and prepare for a new spill placement computation. 0105 /// @param RegBundles Bit vector to receive the edge bundles where the 0106 /// variable should be kept in a register. Each bit 0107 /// corresponds to an edge bundle, a set bit means the 0108 /// variable should be kept in a register through the 0109 /// bundle. A clear bit means the variable should be 0110 /// spilled. This vector is retained. 0111 void prepare(BitVector &RegBundles); 0112 0113 /// addConstraints - Add constraints and biases. This method may be called 0114 /// more than once to accumulate constraints. 0115 /// @param LiveBlocks Constraints for blocks that have the variable live in or 0116 /// live out. 0117 void addConstraints(ArrayRef<BlockConstraint> LiveBlocks); 0118 0119 /// addPrefSpill - Add PrefSpill constraints to all blocks listed. This is 0120 /// equivalent to calling addConstraint with identical BlockConstraints with 0121 /// Entry = Exit = PrefSpill, and ChangesValue = false. 0122 /// 0123 /// @param Blocks Array of block numbers that prefer to spill in and out. 0124 /// @param Strong When true, double the negative bias for these blocks. 0125 void addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong); 0126 0127 /// addLinks - Add transparent blocks with the given numbers. 0128 void addLinks(ArrayRef<unsigned> Links); 0129 0130 /// scanActiveBundles - Perform an initial scan of all bundles activated by 0131 /// addConstraints and addLinks, updating their state. Add all the bundles 0132 /// that now prefer a register to RecentPositive. 0133 /// Prepare internal data structures for iterate. 0134 /// Return true is there are any positive nodes. 0135 bool scanActiveBundles(); 0136 0137 /// iterate - Update the network iteratively until convergence, or new bundles 0138 /// are found. 0139 void iterate(); 0140 0141 /// getRecentPositive - Return an array of bundles that became positive during 0142 /// the previous call to scanActiveBundles or iterate. 0143 ArrayRef<unsigned> getRecentPositive() { return RecentPositive; } 0144 0145 /// finish - Compute the optimal spill code placement given the 0146 /// constraints. No MustSpill constraints will be violated, and the smallest 0147 /// possible number of PrefX constraints will be violated, weighted by 0148 /// expected execution frequencies. 0149 /// The selected bundles are returned in the bitvector passed to prepare(). 0150 /// @return True if a perfect solution was found, allowing the variable to be 0151 /// in a register through all relevant bundles. 0152 bool finish(); 0153 0154 /// getBlockFrequency - Return the estimated block execution frequency per 0155 /// function invocation. 0156 BlockFrequency getBlockFrequency(unsigned Number) const { 0157 return BlockFrequencies[Number]; 0158 } 0159 0160 bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, 0161 MachineFunctionAnalysisManager::Invalidator &Inv); 0162 0163 SpillPlacement(SpillPlacement &&); 0164 ~SpillPlacement(); 0165 0166 private: 0167 SpillPlacement(); 0168 0169 void releaseMemory(); 0170 0171 void run(MachineFunction &MF, EdgeBundles *Bundles, 0172 MachineBlockFrequencyInfo *MBFI); 0173 void activate(unsigned n); 0174 void setThreshold(BlockFrequency Entry); 0175 0176 bool update(unsigned n); 0177 }; 0178 0179 class SpillPlacementWrapperLegacy : public MachineFunctionPass { 0180 public: 0181 static char ID; 0182 SpillPlacementWrapperLegacy() : MachineFunctionPass(ID) {} 0183 0184 SpillPlacement &getResult() { return Impl; } 0185 const SpillPlacement &getResult() const { return Impl; } 0186 0187 private: 0188 SpillPlacement Impl; 0189 bool runOnMachineFunction(MachineFunction &MF) override; 0190 void getAnalysisUsage(AnalysisUsage &AU) const override; 0191 void releaseMemory() override { Impl.releaseMemory(); } 0192 }; 0193 0194 class SpillPlacementAnalysis 0195 : public AnalysisInfoMixin<SpillPlacementAnalysis> { 0196 friend AnalysisInfoMixin<SpillPlacementAnalysis>; 0197 static AnalysisKey Key; 0198 0199 public: 0200 using Result = SpillPlacement; 0201 SpillPlacement run(MachineFunction &, MachineFunctionAnalysisManager &); 0202 }; 0203 0204 } // end namespace llvm 0205 0206 #endif // LLVM_LIB_CODEGEN_SPILLPLACEMENT_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|