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