blob: 5f734697067f57e1726794172ecddd636c4c8f79 [file] [log] [blame]
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +00001//===-- SpillPlacement.cpp - Optimal Spill Code Placement -----------------===//
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 file implements the spill code placement analysis.
11//
12// Each edge bundle corresponds to a node in a Hopfield network. Constraints on
13// basic blocks are weighted by the block frequency and added to become the node
14// bias.
15//
16// Transparent basic blocks have the variable live through, but don't care if it
17// is spilled or in a register. These blocks become connections in the Hopfield
18// network, again weighted by block frequency.
19//
20// The Hopfield network minimizes (possibly locally) its energy function:
21//
22// E = -sum_n V_n * ( B_n + sum_{n, m linked by b} V_m * F_b )
23//
24// The energy function represents the expected spill code execution frequency,
25// or the cost of spilling. This is a Lyapunov function which never increases
26// when a node is updated. It is guaranteed to converge to a local minimum.
27//
28//===----------------------------------------------------------------------===//
29
Jakob Stoklund Olesenfc7d7752011-01-19 23:14:59 +000030#define DEBUG_TYPE "spillplacement"
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000031#include "SpillPlacement.h"
Jakub Staszakf31034d2013-03-18 23:45:45 +000032#include "llvm/ADT/BitVector.h"
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000033#include "llvm/CodeGen/EdgeBundles.h"
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000034#include "llvm/CodeGen/MachineBasicBlock.h"
Benjamin Kramer4eed7562013-06-17 19:00:36 +000035#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000036#include "llvm/CodeGen/MachineFunction.h"
37#include "llvm/CodeGen/MachineLoopInfo.h"
38#include "llvm/CodeGen/Passes.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/Format.h"
41
42using namespace llvm;
43
44char SpillPlacement::ID = 0;
45INITIALIZE_PASS_BEGIN(SpillPlacement, "spill-code-placement",
46 "Spill Code Placement Analysis", true, true)
47INITIALIZE_PASS_DEPENDENCY(EdgeBundles)
48INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
49INITIALIZE_PASS_END(SpillPlacement, "spill-code-placement",
50 "Spill Code Placement Analysis", true, true)
51
52char &llvm::SpillPlacementID = SpillPlacement::ID;
53
54void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
55 AU.setPreservesAll();
Benjamin Kramer4eed7562013-06-17 19:00:36 +000056 AU.addRequired<MachineBlockFrequencyInfo>();
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000057 AU.addRequiredTransitive<EdgeBundles>();
58 AU.addRequiredTransitive<MachineLoopInfo>();
59 MachineFunctionPass::getAnalysisUsage(AU);
60}
61
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000062/// Decision threshold. A node gets the output value 0 if the weighted sum of
63/// its inputs falls in the open interval (-Threshold;Threshold).
64static const BlockFrequency Threshold = 2;
65
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000066/// Node - Each edge bundle corresponds to a Hopfield node.
67///
68/// The node contains precomputed frequency data that only depends on the CFG,
69/// but Bias and Links are computed each time placeSpills is called.
70///
71/// The node Value is positive when the variable should be in a register. The
72/// value can change when linked nodes change, but convergence is very fast
73/// because all weights are positive.
74///
75struct SpillPlacement::Node {
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000076 /// BiasN - Sum of blocks that prefer a spill.
77 BlockFrequency BiasN;
78 /// BiasP - Sum of blocks that prefer a register.
79 BlockFrequency BiasP;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000080
81 /// Value - Output value of this node computed from the Bias and links.
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000082 /// This is always on of the values {-1, 0, 1}. A positive number means the
83 /// variable should go in a register through this bundle.
84 int Value;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000085
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000086 typedef SmallVector<std::pair<BlockFrequency, unsigned>, 4> LinkVector;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000087
88 /// Links - (Weight, BundleNo) for all transparent blocks connecting to other
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000089 /// bundles. The weights are all positive block frequencies.
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000090 LinkVector Links;
91
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +000092 /// SumLinkWeights - Cached sum of the weights of all links + ThresHold.
93 BlockFrequency SumLinkWeights;
94
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +000095 /// preferReg - Return true when this node prefers to be in a register.
96 bool preferReg() const {
97 // Undecided nodes (Value==0) go on the stack.
98 return Value > 0;
99 }
100
101 /// mustSpill - Return True if this node is so biased that it must spill.
102 bool mustSpill() const {
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000103 // We must spill if Bias < -sum(weights) or the MustSpill flag was set.
104 // BiasN is saturated when MustSpill is set, make sure this still returns
105 // true when the RHS saturates. Note that SumLinkWeights includes Threshold.
106 return BiasN >= BiasP + SumLinkWeights;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000107 }
108
109 /// clear - Reset per-query data, but preserve frequencies that only depend on
110 // the CFG.
111 void clear() {
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000112 BiasN = BiasP = Value = 0;
113 SumLinkWeights = Threshold;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000114 Links.clear();
115 }
116
117 /// addLink - Add a link to bundle b with weight w.
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000118 void addLink(unsigned b, BlockFrequency w) {
119 // Update cached sum.
120 SumLinkWeights += w;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000121
122 // There can be multiple links to the same bundle, add them up.
123 for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I)
124 if (I->second == b) {
125 I->first += w;
126 return;
127 }
128 // This must be the first link to b.
129 Links.push_back(std::make_pair(w, b));
130 }
131
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000132 /// addBias - Bias this node.
133 void addBias(BlockFrequency freq, BorderConstraint direction) {
134 switch (direction) {
135 default:
136 break;
137 case PrefReg:
138 BiasP += freq;
139 break;
140 case PrefSpill:
141 BiasN += freq;
142 break;
143 case MustSpill:
144 BiasN = BlockFrequency::getMaxFrequency();
145 break;
146 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000147 }
148
149 /// update - Recompute Value from Bias and Links. Return true when node
150 /// preference changes.
151 bool update(const Node nodes[]) {
152 // Compute the weighted sum of inputs.
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000153 BlockFrequency SumN = BiasN;
154 BlockFrequency SumP = BiasP;
155 for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I) {
156 if (nodes[I->second].Value == -1)
157 SumN += I->first;
158 else if (nodes[I->second].Value == 1)
159 SumP += I->first;
160 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000161
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000162 // Each weighted sum is going to be less than the total frequency of the
163 // bundle. Ideally, we should simply set Value = sign(SumP - SumN), but we
164 // will add a dead zone around 0 for two reasons:
165 //
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000166 // 1. It avoids arbitrary bias when all links are 0 as is possible during
167 // initial iterations.
168 // 2. It helps tame rounding errors when the links nominally sum to 0.
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000169 //
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000170 bool Before = preferReg();
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000171 if (SumN >= SumP + Threshold)
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000172 Value = -1;
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000173 else if (SumP >= SumN + Threshold)
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000174 Value = 1;
175 else
176 Value = 0;
177 return Before != preferReg();
178 }
179};
180
181bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {
182 MF = &mf;
183 bundles = &getAnalysis<EdgeBundles>();
184 loops = &getAnalysis<MachineLoopInfo>();
185
186 assert(!nodes && "Leaking node array");
187 nodes = new Node[bundles->getNumBundles()];
188
189 // Compute total ingoing and outgoing block frequencies for all bundles.
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000190 BlockFrequencies.resize(mf.getNumBlockIDs());
Stephen Hines36b56882014-04-23 16:57:46 -0700191 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000192 for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) {
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000193 unsigned Num = I->getNumber();
Stephen Hines36b56882014-04-23 16:57:46 -0700194 BlockFrequencies[Num] = MBFI->getBlockFreq(I);
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000195 }
196
197 // We never change the function.
198 return false;
199}
200
201void SpillPlacement::releaseMemory() {
202 delete[] nodes;
203 nodes = 0;
204}
205
206/// activate - mark node n as active if it wasn't already.
207void SpillPlacement::activate(unsigned n) {
208 if (ActiveNodes->test(n))
209 return;
210 ActiveNodes->set(n);
211 nodes[n].clear();
Jakob Stoklund Olesen1dc12aa2012-05-21 03:11:23 +0000212
213 // Very large bundles usually come from big switches, indirect branches,
214 // landing pads, or loops with many 'continue' statements. It is difficult to
215 // allocate registers when so many different blocks are involved.
216 //
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000217 // Give a small negative bias to large bundles such that a substantial
218 // fraction of the connected blocks need to be interested before we consider
219 // expanding the region through the bundle. This helps compile time by
220 // limiting the number of blocks visited and the number of links in the
221 // Hopfield network.
222 if (bundles->getBlocks(n).size() > 100) {
223 nodes[n].BiasP = 0;
Stephen Hines36b56882014-04-23 16:57:46 -0700224 nodes[n].BiasN = (MBFI->getEntryFreq() / 16);
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000225 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000226}
227
228
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000229/// addConstraints - Compute node biases and weights from a set of constraints.
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000230/// Set a bit in NodeMask for each active node.
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000231void SpillPlacement::addConstraints(ArrayRef<BlockConstraint> LiveBlocks) {
232 for (ArrayRef<BlockConstraint>::iterator I = LiveBlocks.begin(),
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000233 E = LiveBlocks.end(); I != E; ++I) {
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000234 BlockFrequency Freq = BlockFrequencies[I->Number];
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000235
236 // Live-in to block?
237 if (I->Entry != DontCare) {
238 unsigned ib = bundles->getBundle(I->Number, 0);
239 activate(ib);
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000240 nodes[ib].addBias(Freq, I->Entry);
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000241 }
242
243 // Live-out from block?
244 if (I->Exit != DontCare) {
245 unsigned ob = bundles->getBundle(I->Number, 1);
246 activate(ob);
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000247 nodes[ob].addBias(Freq, I->Exit);
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000248 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000249 }
250}
251
Jakob Stoklund Olesene60f1032011-07-23 03:10:19 +0000252/// addPrefSpill - Same as addConstraints(PrefSpill)
Jakob Stoklund Olesenb87f91b2011-08-03 23:09:38 +0000253void SpillPlacement::addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong) {
Jakob Stoklund Olesene60f1032011-07-23 03:10:19 +0000254 for (ArrayRef<unsigned>::iterator I = Blocks.begin(), E = Blocks.end();
255 I != E; ++I) {
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000256 BlockFrequency Freq = BlockFrequencies[*I];
Jakob Stoklund Olesenb87f91b2011-08-03 23:09:38 +0000257 if (Strong)
258 Freq += Freq;
Jakob Stoklund Olesene60f1032011-07-23 03:10:19 +0000259 unsigned ib = bundles->getBundle(*I, 0);
260 unsigned ob = bundles->getBundle(*I, 1);
261 activate(ib);
262 activate(ob);
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000263 nodes[ib].addBias(Freq, PrefSpill);
264 nodes[ob].addBias(Freq, PrefSpill);
Jakob Stoklund Olesene60f1032011-07-23 03:10:19 +0000265 }
266}
267
Jakob Stoklund Olesen7b41fbe2011-04-07 17:27:46 +0000268void SpillPlacement::addLinks(ArrayRef<unsigned> Links) {
269 for (ArrayRef<unsigned>::iterator I = Links.begin(), E = Links.end(); I != E;
270 ++I) {
271 unsigned Number = *I;
272 unsigned ib = bundles->getBundle(Number, 0);
273 unsigned ob = bundles->getBundle(Number, 1);
274
275 // Ignore self-loops.
276 if (ib == ob)
277 continue;
278 activate(ib);
279 activate(ob);
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000280 if (nodes[ib].Links.empty() && !nodes[ib].mustSpill())
281 Linked.push_back(ib);
282 if (nodes[ob].Links.empty() && !nodes[ob].mustSpill())
283 Linked.push_back(ob);
Jakob Stoklund Olesen6d9fe792013-07-16 18:26:15 +0000284 BlockFrequency Freq = BlockFrequencies[Number];
285 nodes[ib].addLink(ob, Freq);
286 nodes[ob].addLink(ib, Freq);
Jakob Stoklund Olesen7b41fbe2011-04-07 17:27:46 +0000287 }
288}
289
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000290bool SpillPlacement::scanActiveBundles() {
291 Linked.clear();
292 RecentPositive.clear();
293 for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n)) {
294 nodes[n].update(nodes);
295 // A node that must spill, or a node without any links is not going to
296 // change its value ever again, so exclude it from iterations.
297 if (nodes[n].mustSpill())
298 continue;
299 if (!nodes[n].Links.empty())
300 Linked.push_back(n);
301 if (nodes[n].preferReg())
302 RecentPositive.push_back(n);
303 }
304 return !RecentPositive.empty();
305}
306
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000307/// iterate - Repeatedly update the Hopfield nodes until stability or the
308/// maximum number of iterations is reached.
309/// @param Linked - Numbers of linked nodes that need updating.
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000310void SpillPlacement::iterate() {
311 // First update the recently positive nodes. They have likely received new
312 // negative bias that will turn them off.
313 while (!RecentPositive.empty())
314 nodes[RecentPositive.pop_back_val()].update(nodes);
315
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000316 if (Linked.empty())
317 return;
318
319 // Run up to 10 iterations. The edge bundle numbering is closely related to
320 // basic block numbering, so there is a strong tendency towards chains of
321 // linked nodes with sequential numbers. By scanning the linked nodes
322 // backwards and forwards, we make it very likely that a single node can
323 // affect the entire network in a single iteration. That means very fast
324 // convergence, usually in a single iteration.
325 for (unsigned iteration = 0; iteration != 10; ++iteration) {
Stephen Hines36b56882014-04-23 16:57:46 -0700326 // Scan backwards, skipping the last node when iteration is not zero. When
327 // iteration is not zero, the last node was just updated.
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000328 bool Changed = false;
329 for (SmallVectorImpl<unsigned>::const_reverse_iterator I =
Stephen Hines36b56882014-04-23 16:57:46 -0700330 iteration == 0 ? Linked.rbegin() : std::next(Linked.rbegin()),
331 E = Linked.rend(); I != E; ++I) {
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000332 unsigned n = *I;
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000333 if (nodes[n].update(nodes)) {
334 Changed = true;
335 if (nodes[n].preferReg())
336 RecentPositive.push_back(n);
337 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000338 }
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000339 if (!Changed || !RecentPositive.empty())
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000340 return;
341
342 // Scan forwards, skipping the first node which was just updated.
343 Changed = false;
344 for (SmallVectorImpl<unsigned>::const_iterator I =
Stephen Hines36b56882014-04-23 16:57:46 -0700345 std::next(Linked.begin()), E = Linked.end(); I != E; ++I) {
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000346 unsigned n = *I;
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000347 if (nodes[n].update(nodes)) {
348 Changed = true;
349 if (nodes[n].preferReg())
350 RecentPositive.push_back(n);
351 }
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000352 }
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000353 if (!Changed || !RecentPositive.empty())
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000354 return;
355 }
356}
357
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000358void SpillPlacement::prepare(BitVector &RegBundles) {
Jakob Stoklund Olesenf4afdfc2011-04-09 02:59:09 +0000359 Linked.clear();
360 RecentPositive.clear();
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000361 // Reuse RegBundles as our ActiveNodes vector.
362 ActiveNodes = &RegBundles;
363 ActiveNodes->clear();
364 ActiveNodes->resize(bundles->getNumBundles());
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000365}
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000366
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000367bool
368SpillPlacement::finish() {
369 assert(ActiveNodes && "Call prepare() first");
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000370
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000371 // Write preferences back to ActiveNodes.
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000372 bool Perfect = true;
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000373 for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n))
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000374 if (!nodes[n].preferReg()) {
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000375 ActiveNodes->reset(n);
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000376 Perfect = false;
377 }
Jakob Stoklund Olesen9efa2a22011-04-06 19:13:57 +0000378 ActiveNodes = 0;
Jakob Stoklund Olesen8bfe5082011-01-06 01:21:53 +0000379 return Perfect;
380}