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