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