1*9880d681SAndroid Build Coastguard Worker //===-- SpillPlacement.h - Optimal Spill Code Placement --------*- C++ -*--===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This analysis computes the optimal spill code placement between basic blocks. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker // The runOnMachineFunction() method only precomputes some profiling information 13*9880d681SAndroid Build Coastguard Worker // about the CFG. The real work is done by prepare(), addConstraints(), and 14*9880d681SAndroid Build Coastguard Worker // finish() which are called by the register allocator. 15*9880d681SAndroid Build Coastguard Worker // 16*9880d681SAndroid Build Coastguard Worker // Given a variable that is live across multiple basic blocks, and given 17*9880d681SAndroid Build Coastguard Worker // constraints on the basic blocks where the variable is live, determine which 18*9880d681SAndroid Build Coastguard Worker // edge bundles should have the variable in a register and which edge bundles 19*9880d681SAndroid Build Coastguard Worker // should have the variable in a stack slot. 20*9880d681SAndroid Build Coastguard Worker // 21*9880d681SAndroid Build Coastguard Worker // The returned bit vector can be used to place optimal spill code at basic 22*9880d681SAndroid Build Coastguard Worker // block entries and exits. Spill code placement inside a basic block is not 23*9880d681SAndroid Build Coastguard Worker // considered. 24*9880d681SAndroid Build Coastguard Worker // 25*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_SPILLPLACEMENT_H 28*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_SPILLPLACEMENT_H 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h" 31*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SparseSet.h" 33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h" 34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/BlockFrequency.h" 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker namespace llvm { 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker class BitVector; 39*9880d681SAndroid Build Coastguard Worker class EdgeBundles; 40*9880d681SAndroid Build Coastguard Worker class MachineBasicBlock; 41*9880d681SAndroid Build Coastguard Worker class MachineLoopInfo; 42*9880d681SAndroid Build Coastguard Worker class MachineBlockFrequencyInfo; 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker class SpillPlacement : public MachineFunctionPass { 45*9880d681SAndroid Build Coastguard Worker struct Node; 46*9880d681SAndroid Build Coastguard Worker const MachineFunction *MF; 47*9880d681SAndroid Build Coastguard Worker const EdgeBundles *bundles; 48*9880d681SAndroid Build Coastguard Worker const MachineLoopInfo *loops; 49*9880d681SAndroid Build Coastguard Worker const MachineBlockFrequencyInfo *MBFI; 50*9880d681SAndroid Build Coastguard Worker Node *nodes; 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker // Nodes that are active in the current computation. Owned by the prepare() 53*9880d681SAndroid Build Coastguard Worker // caller. 54*9880d681SAndroid Build Coastguard Worker BitVector *ActiveNodes; 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker // Nodes with active links. Populated by scanActiveBundles. 57*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 8> Linked; 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker // Nodes that went positive during the last call to scanActiveBundles or 60*9880d681SAndroid Build Coastguard Worker // iterate. 61*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 8> RecentPositive; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker // Block frequencies are computed once. Indexed by block number. 64*9880d681SAndroid Build Coastguard Worker SmallVector<BlockFrequency, 8> BlockFrequencies; 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker /// Decision threshold. A node gets the output value 0 if the weighted sum of 67*9880d681SAndroid Build Coastguard Worker /// its inputs falls in the open interval (-Threshold;Threshold). 68*9880d681SAndroid Build Coastguard Worker BlockFrequency Threshold; 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker /// List of nodes that need to be updated in ::iterate. 71*9880d681SAndroid Build Coastguard Worker SparseSet<unsigned> TodoList; 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker public: 74*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification, replacement for typeid. 75*9880d681SAndroid Build Coastguard Worker SpillPlacement()76*9880d681SAndroid Build Coastguard Worker SpillPlacement() : MachineFunctionPass(ID), nodes(nullptr) {} ~SpillPlacement()77*9880d681SAndroid Build Coastguard Worker ~SpillPlacement() override { releaseMemory(); } 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker /// BorderConstraint - A basic block has separate constraints for entry and 80*9880d681SAndroid Build Coastguard Worker /// exit. 81*9880d681SAndroid Build Coastguard Worker enum BorderConstraint { 82*9880d681SAndroid Build Coastguard Worker DontCare, ///< Block doesn't care / variable not live. 83*9880d681SAndroid Build Coastguard Worker PrefReg, ///< Block entry/exit prefers a register. 84*9880d681SAndroid Build Coastguard Worker PrefSpill, ///< Block entry/exit prefers a stack slot. 85*9880d681SAndroid Build Coastguard Worker PrefBoth, ///< Block entry prefers both register and stack. 86*9880d681SAndroid Build Coastguard Worker MustSpill ///< A register is impossible, variable must be spilled. 87*9880d681SAndroid Build Coastguard Worker }; 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker /// BlockConstraint - Entry and exit constraints for a basic block. 90*9880d681SAndroid Build Coastguard Worker struct BlockConstraint { 91*9880d681SAndroid Build Coastguard Worker unsigned Number; ///< Basic block number (from MBB::getNumber()). 92*9880d681SAndroid Build Coastguard Worker BorderConstraint Entry : 8; ///< Constraint on block entry. 93*9880d681SAndroid Build Coastguard Worker BorderConstraint Exit : 8; ///< Constraint on block exit. 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker /// True when this block changes the value of the live range. This means 96*9880d681SAndroid Build Coastguard Worker /// the block has a non-PHI def. When this is false, a live-in value on 97*9880d681SAndroid Build Coastguard Worker /// the stack can be live-out on the stack without inserting a spill. 98*9880d681SAndroid Build Coastguard Worker bool ChangesValue; 99*9880d681SAndroid Build Coastguard Worker }; 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker /// prepare - Reset state and prepare for a new spill placement computation. 102*9880d681SAndroid Build Coastguard Worker /// @param RegBundles Bit vector to receive the edge bundles where the 103*9880d681SAndroid Build Coastguard Worker /// variable should be kept in a register. Each bit 104*9880d681SAndroid Build Coastguard Worker /// corresponds to an edge bundle, a set bit means the 105*9880d681SAndroid Build Coastguard Worker /// variable should be kept in a register through the 106*9880d681SAndroid Build Coastguard Worker /// bundle. A clear bit means the variable should be 107*9880d681SAndroid Build Coastguard Worker /// spilled. This vector is retained. 108*9880d681SAndroid Build Coastguard Worker void prepare(BitVector &RegBundles); 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker /// addConstraints - Add constraints and biases. This method may be called 111*9880d681SAndroid Build Coastguard Worker /// more than once to accumulate constraints. 112*9880d681SAndroid Build Coastguard Worker /// @param LiveBlocks Constraints for blocks that have the variable live in or 113*9880d681SAndroid Build Coastguard Worker /// live out. 114*9880d681SAndroid Build Coastguard Worker void addConstraints(ArrayRef<BlockConstraint> LiveBlocks); 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker /// addPrefSpill - Add PrefSpill constraints to all blocks listed. This is 117*9880d681SAndroid Build Coastguard Worker /// equivalent to calling addConstraint with identical BlockConstraints with 118*9880d681SAndroid Build Coastguard Worker /// Entry = Exit = PrefSpill, and ChangesValue = false. 119*9880d681SAndroid Build Coastguard Worker /// 120*9880d681SAndroid Build Coastguard Worker /// @param Blocks Array of block numbers that prefer to spill in and out. 121*9880d681SAndroid Build Coastguard Worker /// @param Strong When true, double the negative bias for these blocks. 122*9880d681SAndroid Build Coastguard Worker void addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong); 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker /// addLinks - Add transparent blocks with the given numbers. 125*9880d681SAndroid Build Coastguard Worker void addLinks(ArrayRef<unsigned> Links); 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker /// scanActiveBundles - Perform an initial scan of all bundles activated by 128*9880d681SAndroid Build Coastguard Worker /// addConstraints and addLinks, updating their state. Add all the bundles 129*9880d681SAndroid Build Coastguard Worker /// that now prefer a register to RecentPositive. 130*9880d681SAndroid Build Coastguard Worker /// Prepare internal data structures for iterate. 131*9880d681SAndroid Build Coastguard Worker /// Return true is there are any positive nodes. 132*9880d681SAndroid Build Coastguard Worker bool scanActiveBundles(); 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker /// iterate - Update the network iteratively until convergence, or new bundles 135*9880d681SAndroid Build Coastguard Worker /// are found. 136*9880d681SAndroid Build Coastguard Worker void iterate(); 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker /// getRecentPositive - Return an array of bundles that became positive during 139*9880d681SAndroid Build Coastguard Worker /// the previous call to scanActiveBundles or iterate. getRecentPositive()140*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> getRecentPositive() { return RecentPositive; } 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker /// finish - Compute the optimal spill code placement given the 143*9880d681SAndroid Build Coastguard Worker /// constraints. No MustSpill constraints will be violated, and the smallest 144*9880d681SAndroid Build Coastguard Worker /// possible number of PrefX constraints will be violated, weighted by 145*9880d681SAndroid Build Coastguard Worker /// expected execution frequencies. 146*9880d681SAndroid Build Coastguard Worker /// The selected bundles are returned in the bitvector passed to prepare(). 147*9880d681SAndroid Build Coastguard Worker /// @return True if a perfect solution was found, allowing the variable to be 148*9880d681SAndroid Build Coastguard Worker /// in a register through all relevant bundles. 149*9880d681SAndroid Build Coastguard Worker bool finish(); 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker /// getBlockFrequency - Return the estimated block execution frequency per 152*9880d681SAndroid Build Coastguard Worker /// function invocation. getBlockFrequency(unsigned Number)153*9880d681SAndroid Build Coastguard Worker BlockFrequency getBlockFrequency(unsigned Number) const { 154*9880d681SAndroid Build Coastguard Worker return BlockFrequencies[Number]; 155*9880d681SAndroid Build Coastguard Worker } 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker private: 158*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction&) override; 159*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage&) const override; 160*9880d681SAndroid Build Coastguard Worker void releaseMemory() override; 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker void activate(unsigned); 163*9880d681SAndroid Build Coastguard Worker void setThreshold(const BlockFrequency &Entry); 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker bool update(unsigned); 166*9880d681SAndroid Build Coastguard Worker }; 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker #endif 171