llvm.org GIT mirror llvm / 8bfe508
Add the SpillPlacement analysis pass. This pass precomputes CFG block frequency information that can be used by the register allocator to find optimal spill code placement. Given an interference pattern, placeSpills() will compute which basic blocks should have the current variable enter or exit in a register, and which blocks prefer the stack. The algorithm is ready to consume block frequencies from profiling data, but for now it gets by with the static estimates used for spill weights. This is a work in progress and still not hooked up to RegAllocGreedy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122938 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
5 changed file(s) with 466 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
8787 /// register allocators.
8888 extern char &TwoAddressInstructionPassID;
8989
90 /// SpillPlacement analysis. Suggest optimal placement of spill code between
91 /// basic blocks.
92 ///
93 extern char &SpillPlacementID;
94
9095 /// UnreachableMachineBlockElimination pass - This pass removes unreachable
9196 /// machine basic blocks.
9297 extern char &UnreachableMachineBlockElimID;
202202 void initializeSingleLoopExtractorPass(PassRegistry&);
203203 void initializeSinkingPass(PassRegistry&);
204204 void initializeSlotIndexesPass(PassRegistry&);
205 void initializeSpillPlacementPass(PassRegistry&);
205206 void initializeStackProtectorPass(PassRegistry&);
206207 void initializeStackSlotColoringPass(PassRegistry&);
207208 void initializeStripDeadDebugInfoPass(PassRegistry&);
7979 SjLjEHPrepare.cpp
8080 SlotIndexes.cpp
8181 Spiller.cpp
82 SpillPlacement.cpp
8283 SplitKit.cpp
8384 Splitter.cpp
8485 StackProtector.cpp
0 //===-- SpillPlacement.cpp - Optimal Spill Code Placement -----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the spill code placement analysis.
10 //
11 // Each edge bundle corresponds to a node in a Hopfield network. Constraints on
12 // basic blocks are weighted by the block frequency and added to become the node
13 // bias.
14 //
15 // Transparent basic blocks have the variable live through, but don't care if it
16 // is spilled or in a register. These blocks become connections in the Hopfield
17 // network, again weighted by block frequency.
18 //
19 // The Hopfield network minimizes (possibly locally) its energy function:
20 //
21 // E = -sum_n V_n * ( B_n + sum_{n, m linked by b} V_m * F_b )
22 //
23 // The energy function represents the expected spill code execution frequency,
24 // or the cost of spilling. This is a Lyapunov function which never increases
25 // when a node is updated. It is guaranteed to converge to a local minimum.
26 //
27 //===----------------------------------------------------------------------===//
28
29 #include "SpillPlacement.h"
30 #include "llvm/CodeGen/EdgeBundles.h"
31 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
32 #include "llvm/CodeGen/MachineBasicBlock.h"
33 #include "llvm/CodeGen/MachineFunction.h"
34 #include "llvm/CodeGen/MachineLoopInfo.h"
35 #include "llvm/CodeGen/Passes.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/Format.h"
38
39 using namespace llvm;
40
41 char SpillPlacement::ID = 0;
42 INITIALIZE_PASS_BEGIN(SpillPlacement, "spill-code-placement",
43 "Spill Code Placement Analysis", true, true)
44 INITIALIZE_PASS_DEPENDENCY(EdgeBundles)
45 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
46 INITIALIZE_PASS_END(SpillPlacement, "spill-code-placement",
47 "Spill Code Placement Analysis", true, true)
48
49 char &llvm::SpillPlacementID = SpillPlacement::ID;
50
51 void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
52 AU.setPreservesAll();
53 AU.addRequiredTransitive();
54 AU.addRequiredTransitive();
55 MachineFunctionPass::getAnalysisUsage(AU);
56 }
57
58 /// Node - Each edge bundle corresponds to a Hopfield node.
59 ///
60 /// The node contains precomputed frequency data that only depends on the CFG,
61 /// but Bias and Links are computed each time placeSpills is called.
62 ///
63 /// The node Value is positive when the variable should be in a register. The
64 /// value can change when linked nodes change, but convergence is very fast
65 /// because all weights are positive.
66 ///
67 struct SpillPlacement::Node {
68 /// Frequency - Total block frequency feeding into[0] or out of[1] the bundle.
69 /// Ideally, these two numbers should be identical, but inaccuracies in the
70 /// block frequency estimates means that we need to normalize ingoing and
71 /// outgoing frequencies separately so they are commensurate.
72 float Frequency[2];
73
74 /// Bias - Normalized contributions from non-transparent blocks.
75 /// A bundle connected to a MustSpill block has a huge negative bias,
76 /// otherwise it is a number in the range [-2;2].
77 float Bias;
78
79 /// Value - Output value of this node computed from the Bias and links.
80 /// This is always in the range [-1;1]. A positive number means the variable
81 /// should go in a register through this bundle.
82 float Value;
83
84 typedef SmallVector, 4> LinkVector;
85
86 /// Links - (Weight, BundleNo) for all transparent blocks connecting to other
87 /// bundles. The weights are all positive and add up to at most 2, weights
88 /// from ingoing and outgoing nodes separately add up to a most 1. The weight
89 /// sum can be less than 2 when the variable is not live into / out of some
90 /// connected basic blocks.
91 LinkVector Links;
92
93 /// preferReg - Return true when this node prefers to be in a register.
94 bool preferReg() const {
95 // Undecided nodes (Value==0) go on the stack.
96 return Value > 0;
97 }
98
99 /// mustSpill - Return True if this node is so biased that it must spill.
100 bool mustSpill() const {
101 // Actually, we must spill if Bias < sum(weights).
102 // It may be worth it to compute the weight sum here?
103 return Bias < -2.0f;
104 }
105
106 /// Node - Create a blank Node.
107 Node() {
108 Frequency[0] = Frequency[1] = 0;
109 }
110
111 /// clear - Reset per-query data, but preserve frequencies that only depend on
112 // the CFG.
113 void clear() {
114 Bias = Value = 0;
115 Links.clear();
116 }
117
118 /// addLink - Add a link to bundle b with weight w.
119 /// out=0 for an ingoing link, and 1 for an outgoing link.
120 void addLink(unsigned b, float w, bool out) {
121 // Normalize w relative to all connected blocks from that direction.
122 w /= Frequency[out];
123
124 // There can be multiple links to the same bundle, add them up.
125 for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I)
126 if (I->second == b) {
127 I->first += w;
128 return;
129 }
130 // This must be the first link to b.
131 Links.push_back(std::make_pair(w, b));
132 }
133
134 /// addBias - Bias this node from an ingoing[0] or outgoing[1] link.
135 void addBias(float w, bool out) {
136 // Normalize w relative to all connected blocks from that direction.
137 w /= Frequency[out];
138 Bias += w;
139 }
140
141 /// update - Recompute Value from Bias and Links. Return true when node
142 /// preference changes.
143 bool update(const Node nodes[]) {
144 // Compute the weighted sum of inputs.
145 float Sum = Bias;
146 for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I)
147 Sum += I->first * nodes[I->second].Value;
148
149 // The weighted sum is going to be in the range [-2;2]. Ideally, we should
150 // simply set Value = sign(Sum), but we will add a dead zone around 0 for
151 // two reasons:
152 // 1. It avoids arbitrary bias when all links are 0 as is possible during
153 // initial iterations.
154 // 2. It helps tame rounding errors when the links nominally sum to 0.
155 const float Thres = 1e-4;
156 bool Before = preferReg();
157 if (Sum < -Thres)
158 Value = -1;
159 else if (Sum > Thres)
160 Value = 1;
161 else
162 Value = 0;
163 return Before != preferReg();
164 }
165 };
166
167 bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {
168 MF = &mf;
169 bundles = &getAnalysis();
170 loops = &getAnalysis();
171
172 assert(!nodes && "Leaking node array");
173 nodes = new Node[bundles->getNumBundles()];
174
175 // Compute total ingoing and outgoing block frequencies for all bundles.
176 for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) {
177 float Freq = getBlockFrequency(I);
178 unsigned Num = I->getNumber();
179 nodes[bundles->getBundle(Num, 1)].Frequency[0] += Freq;
180 nodes[bundles->getBundle(Num, 0)].Frequency[1] += Freq;
181 }
182
183 // We never change the function.
184 return false;
185 }
186
187 void SpillPlacement::releaseMemory() {
188 delete[] nodes;
189 nodes = 0;
190 }
191
192 /// activate - mark node n as active if it wasn't already.
193 void SpillPlacement::activate(unsigned n) {
194 if (ActiveNodes->test(n))
195 return;
196 ActiveNodes->set(n);
197 nodes[n].clear();
198 }
199
200
201 /// prepareNodes - Compute node biases and weights from a set of constraints.
202 /// Set a bit in NodeMask for each active node.
203 void SpillPlacement::
204 prepareNodes(const SmallVectorImpl &LiveBlocks) {
205 DEBUG(dbgs() << "Building Hopfield network from " << LiveBlocks.size()
206 << " constraint blocks:\n");
207 for (SmallVectorImpl::const_iterator I = LiveBlocks.begin(),
208 E = LiveBlocks.end(); I != E; ++I) {
209 MachineBasicBlock *MBB = MF->getBlockNumbered(I->Number);
210 float Freq = getBlockFrequency(MBB);
211 DEBUG(dbgs() << " BB#" << I->Number << format(", Freq = %.1f", Freq));
212
213 // Is this a transparent block? Link ingoing and outgoing bundles.
214 if (I->Entry == DontCare && I->Exit == DontCare) {
215 unsigned ib = bundles->getBundle(I->Number, 0);
216 unsigned ob = bundles->getBundle(I->Number, 1);
217 DEBUG(dbgs() << ", transparent EB#" << ib << " -> EB#" << ob << '\n');
218
219 // Ignore self-loops.
220 if (ib == ob)
221 continue;
222 activate(ib);
223 activate(ob);
224 nodes[ib].addLink(ob, Freq, 1);
225 nodes[ob].addLink(ib, Freq, 0);
226 continue;
227 }
228
229 // This block is not transparent, but it can still add bias.
230 const float Bias[] = {
231 0, // DontCare,
232 1, // PrefReg,
233 -1, // PrefSpill
234 -HUGE_VALF // MustSpill
235 };
236
237 // Live-in to block?
238 if (I->Entry != DontCare) {
239 unsigned ib = bundles->getBundle(I->Number, 0);
240 activate(ib);
241 nodes[ib].addBias(Freq * Bias[I->Entry], 1);
242 DEBUG(dbgs() << format(", entry EB#%u %+.1f", ib, Freq * Bias[I->Entry]));
243 }
244
245 // Live-out from block?
246 if (I->Exit != DontCare) {
247 unsigned ob = bundles->getBundle(I->Number, 1);
248 activate(ob);
249 nodes[ob].addBias(Freq * Bias[I->Exit], 0);
250 DEBUG(dbgs() << format(", exit EB#%u %+.1f", ob, Freq * Bias[I->Exit]));
251 }
252
253 DEBUG(dbgs() << '\n');
254 }
255 }
256
257 /// iterate - Repeatedly update the Hopfield nodes until stability or the
258 /// maximum number of iterations is reached.
259 /// @param Linked - Numbers of linked nodes that need updating.
260 void SpillPlacement::iterate(const SmallVectorImpl &Linked) {
261 DEBUG(dbgs() << "Iterating over " << Linked.size() << " linked nodes:\n");
262 if (Linked.empty())
263 return;
264
265 // Run up to 10 iterations. The edge bundle numbering is closely related to
266 // basic block numbering, so there is a strong tendency towards chains of
267 // linked nodes with sequential numbers. By scanning the linked nodes
268 // backwards and forwards, we make it very likely that a single node can
269 // affect the entire network in a single iteration. That means very fast
270 // convergence, usually in a single iteration.
271 for (unsigned iteration = 0; iteration != 10; ++iteration) {
272 // Scan backwards, skipping the last node which was just updated.
273 bool Changed = false;
274 for (SmallVectorImpl::const_reverse_iterator I =
275 llvm::next(Linked.rbegin()), E = Linked.rend(); I != E; ++I) {
276 unsigned n = *I;
277 bool C = nodes[n].update(nodes);
278 Changed |= C;
279 DEBUG(dbgs() << " \\EB#" << n << format(" = %+2.0f", nodes[n].Value)
280 << (C ? " *\n" : "\n"));
281 }
282 if (!Changed)
283 return;
284
285 // Scan forwards, skipping the first node which was just updated.
286 Changed = false;
287 for (SmallVectorImpl::const_iterator I =
288 llvm::next(Linked.begin()), E = Linked.end(); I != E; ++I) {
289 unsigned n = *I;
290 bool C = nodes[n].update(nodes);
291 Changed |= C;
292 DEBUG(dbgs() << " /EB#" << n << format(" = %+2.0f", nodes[n].Value)
293 << (C ? " *\n" : "\n"));
294 }
295 if (!Changed)
296 return;
297 }
298 }
299
300 bool
301 SpillPlacement::placeSpills(const SmallVectorImpl &LiveBlocks,
302 BitVector &RegBundles) {
303 // Reuse RegBundles as our ActiveNodes vector.
304 ActiveNodes = &RegBundles;
305 ActiveNodes->clear();
306 ActiveNodes->resize(bundles->getNumBundles());
307
308 // Compute active nodes, links and biases.
309 prepareNodes(LiveBlocks);
310
311 // Update all active nodes, and find the ones that are actually linked to
312 // something so their value may change when iterating.
313 DEBUG(dbgs() << "Network has " << RegBundles.count() << " active nodes:\n");
314 SmallVector Linked;
315 for (int n = RegBundles.find_first(); n>=0; n = RegBundles.find_next(n)) {
316 nodes[n].update(nodes);
317 // A node that must spill, or a node without any links is not going to
318 // change its value ever again, so exclude it from iterations.
319 if (!nodes[n].Links.empty() && !nodes[n].mustSpill())
320 Linked.push_back(n);
321
322 DEBUG({
323 dbgs() << " EB#" << n << format(" = %+2.0f", nodes[n].Value)
324 << format(", Bias %+.2f", nodes[n].Bias)
325 << format(", Freq %.1f/%.1f", nodes[n].Frequency[0],
326 nodes[n].Frequency[1]);
327 for (unsigned i = 0, e = nodes[n].Links.size(); i != e; ++i)
328 dbgs() << format(", %.2f -> EB#%u", nodes[n].Links[i].first,
329 nodes[n].Links[i].second);
330 dbgs() << '\n';
331 });
332 }
333
334 // Iterate the network to convergence.
335 iterate(Linked);
336
337 // Write preferences back to RegBundles.
338 bool Perfect = true;
339 for (int n = RegBundles.find_first(); n>=0; n = RegBundles.find_next(n))
340 if (!nodes[n].preferReg()) {
341 RegBundles.reset(n);
342 Perfect = false;
343 }
344 return Perfect;
345 }
346
347 /// getBlockFrequency - Return our best estimate of the block frequency which is
348 /// the expected number of block executions per function invocation.
349 float SpillPlacement::getBlockFrequency(const MachineBasicBlock *MBB) {
350 // Use the unnormalized spill weight for real block frequencies.
351 return LiveIntervals::getSpillWeight(true, false, loops->getLoopDepth(MBB));
352 }
353
0 //===-- SpillPlacement.h - Optimal Spill Code Placement --------*- C++ -*--===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This analysis computes the optimal spill code placement between basic blocks.
10 //
11 // The runOnMachineFunction() method only precomputes some profiling information
12 // about the CFG. The real work is done by placeSpills() which is called by the
13 // register allocator.
14 //
15 // Given a variable that is live across multiple basic blocks, and given
16 // constraints on the basic blocks where the variable is live, determine which
17 // edge bundles should have the variable in a register and which edge bundles
18 // should have the variable in a stack slot.
19 //
20 // The returned bit vector can be used to place optimal spill code at basic
21 // block entries and exits. Spill code placement inside a basic block is not
22 // considered.
23 //
24 //===----------------------------------------------------------------------===//
25
26 #ifndef LLVM_CODEGEN_SPILLPLACEMENT_H
27 #define LLVM_CODEGEN_SPILLPLACEMENT_H
28
29 #include "llvm/CodeGen/MachineFunctionPass.h"
30
31 namespace llvm {
32
33 class BitVector;
34 class EdgeBundles;
35 class MachineBasicBlock;
36 class MachineLoopInfo;
37 template class SmallVectorImpl;
38
39 class SpillPlacement : public MachineFunctionPass {
40 struct Node;
41 const MachineFunction *MF;
42 const EdgeBundles *bundles;
43 const MachineLoopInfo *loops;
44 Node *nodes;
45
46 // Nodes that are active in the current computation. Owned by the placeSpills
47 // caller.
48 BitVector *ActiveNodes;
49
50 public:
51 static char ID; // Pass identification, replacement for typeid.
52
53 SpillPlacement() : MachineFunctionPass(ID), nodes(0) {}
54 ~SpillPlacement() { releaseMemory(); }
55
56 /// BorderConstraint - A basic block has separate constraints for entry and
57 /// exit.
58 enum BorderConstraint {
59 DontCare, ///< Block doesn't care / variable not live.
60 PrefReg, ///< Block entry/exit prefers a register.
61 PrefSpill, ///< Block entry/exit prefers a stack slot.
62 MustSpill ///< A register is impossible, variable must be spilled.
63 };
64
65 /// BlockConstraint - Entry and exit constraints for a basic block.
66 struct BlockConstraint {
67 unsigned Number; ///< Basic block number (from MBB::getNumber()).
68 BorderConstraint Entry : 8; ///< Constraint on block entry.
69 BorderConstraint Exit : 8; ///< Constraint on block exit.
70 };
71
72 /// placeSpills - Compute the optimal spill code placement given the
73 /// constraints. No MustSpill constraints will be violated, and the smallest
74 /// possible number of PrefX constraints will be violated, weighted by
75 /// expected execution frequencies.
76 /// @param LiveBlocks Constraints for blocks that have the variable live in or
77 /// live out. DontCare/DontCare means the variable is live
78 /// through the block. DontCare/X means the variable is live
79 /// out, but not live in.
80 /// @param RegBundles Bit vector to receive the edge bundles where the
81 /// variable should be kept in a register. Each bit
82 /// corresponds to an edge bundle, a set bit means the
83 /// variable should be kept in a register through the
84 /// bundle. A clear bit means the variable should be
85 /// spilled.
86 /// @return True if a perfect solution was found, allowing the variable to be
87 /// in a register through all relevant bundles.
88 bool placeSpills(const SmallVectorImpl &LiveBlocks,
89 BitVector &RegBundles);
90
91 private:
92 virtual bool runOnMachineFunction(MachineFunction&);
93 virtual void getAnalysisUsage(AnalysisUsage&) const;
94 virtual void releaseMemory();
95
96 void activate(unsigned);
97 float getBlockFrequency(const MachineBasicBlock*);
98 void prepareNodes(const SmallVectorImpl&);
99 void iterate(const SmallVectorImpl&);
100 };
101
102 } // end namespace llvm
103
104 #endif