xref: /minix3/external/bsd/llvm/dist/llvm/lib/CodeGen/SpillPlacement.h (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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