SpillPlacement.cpp revision 74d2a3e1a014b93e9037a7b04e85dc92bfb54fa7
1//===-- 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
30#define DEBUG_TYPE "spillplacement"
31#include "SpillPlacement.h"
32#include "llvm/ADT/BitVector.h"
33#include "llvm/CodeGen/EdgeBundles.h"
34#include "llvm/CodeGen/MachineBasicBlock.h"
35#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
36#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();
56  AU.addRequired<MachineBlockFrequencyInfo>();
57  AU.addRequiredTransitive<EdgeBundles>();
58  AU.addRequiredTransitive<MachineLoopInfo>();
59  MachineFunctionPass::getAnalysisUsage(AU);
60}
61
62/// 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
66/// 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 {
76  /// BiasN - Sum of blocks that prefer a spill.
77  BlockFrequency BiasN;
78  /// BiasP - Sum of blocks that prefer a register.
79  BlockFrequency BiasP;
80
81  /// Value - Output value of this node computed from the Bias and links.
82  /// This is always in the range [-1;1]. A positive number means the variable
83  /// should go in a register through this bundle.
84  int Value;
85
86  typedef SmallVector<std::pair<BlockFrequency, unsigned>, 4> LinkVector;
87
88  /// Links - (Weight, BundleNo) for all transparent blocks connecting to other
89  /// bundles. The weights are all positive and add up to at most 2, weights
90  /// from ingoing and outgoing nodes separately add up to a most 1. The weight
91  /// sum can be less than 2 when the variable is not live into / out of some
92  /// connected basic blocks.
93  LinkVector Links;
94
95  /// SumLinkWeights - Cached sum of the weights of all links + ThresHold.
96  BlockFrequency SumLinkWeights;
97
98  /// preferReg - Return true when this node prefers to be in a register.
99  bool preferReg() const {
100    // Undecided nodes (Value==0) go on the stack.
101    return Value > 0;
102  }
103
104  /// mustSpill - Return True if this node is so biased that it must spill.
105  bool mustSpill() const {
106    // We must spill if Bias < -sum(weights) or the MustSpill flag was set.
107    // BiasN is saturated when MustSpill is set, make sure this still returns
108    // true when the RHS saturates. Note that SumLinkWeights includes Threshold.
109    return BiasN >= BiasP + SumLinkWeights;
110  }
111
112  /// clear - Reset per-query data, but preserve frequencies that only depend on
113  // the CFG.
114  void clear() {
115    BiasN = BiasP = Value = 0;
116    SumLinkWeights = Threshold;
117    Links.clear();
118  }
119
120  /// addLink - Add a link to bundle b with weight w.
121  void addLink(unsigned b, BlockFrequency w) {
122    // Update cached sum.
123    SumLinkWeights += w;
124
125    // There can be multiple links to the same bundle, add them up.
126    for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I)
127      if (I->second == b) {
128        I->first += w;
129        return;
130      }
131    // This must be the first link to b.
132    Links.push_back(std::make_pair(w, b));
133  }
134
135  /// addBias - Bias this node.
136  void addBias(BlockFrequency freq, BorderConstraint direction) {
137    switch (direction) {
138    default:
139      break;
140    case PrefReg:
141      BiasP += freq;
142      break;
143    case PrefSpill:
144      BiasN += freq;
145      break;
146    case MustSpill:
147      BiasN = BlockFrequency::getMaxFrequency();
148      break;
149    }
150  }
151
152  /// update - Recompute Value from Bias and Links. Return true when node
153  /// preference changes.
154  bool update(const Node nodes[]) {
155    // Compute the weighted sum of inputs.
156    BlockFrequency SumN = BiasN;
157    BlockFrequency SumP = BiasP;
158    for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I) {
159      if (nodes[I->second].Value == -1)
160        SumN += I->first;
161      else if (nodes[I->second].Value == 1)
162        SumP += I->first;
163    }
164
165    // The weighted sum is going to be in the range [-2;2]. Ideally, we should
166    // simply set Value = sign(Sum), but we will add a dead zone around 0 for
167    // two reasons:
168    //  1. It avoids arbitrary bias when all links are 0 as is possible during
169    //     initial iterations.
170    //  2. It helps tame rounding errors when the links nominally sum to 0.
171    bool Before = preferReg();
172    if (SumN >= SumP + Threshold)
173      Value = -1;
174    else if (SumP >= SumN + Threshold)
175      Value = 1;
176    else
177      Value = 0;
178    return Before != preferReg();
179  }
180};
181
182bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {
183  MF = &mf;
184  bundles = &getAnalysis<EdgeBundles>();
185  loops = &getAnalysis<MachineLoopInfo>();
186
187  assert(!nodes && "Leaking node array");
188  nodes = new Node[bundles->getNumBundles()];
189
190  // Compute total ingoing and outgoing block frequencies for all bundles.
191  BlockFrequencies.resize(mf.getNumBlockIDs());
192  MachineBlockFrequencyInfo &MBFI = getAnalysis<MachineBlockFrequencyInfo>();
193  for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) {
194    unsigned Num = I->getNumber();
195    BlockFrequencies[Num] = MBFI.getBlockFreq(I);
196  }
197
198  // We never change the function.
199  return false;
200}
201
202void SpillPlacement::releaseMemory() {
203  delete[] nodes;
204  nodes = 0;
205}
206
207/// activate - mark node n as active if it wasn't already.
208void SpillPlacement::activate(unsigned n) {
209  if (ActiveNodes->test(n))
210    return;
211  ActiveNodes->set(n);
212  nodes[n].clear();
213
214  // Very large bundles usually come from big switches, indirect branches,
215  // landing pads, or loops with many 'continue' statements. It is difficult to
216  // allocate registers when so many different blocks are involved.
217  //
218  // Give a small negative bias to large bundles such that 1/32 of the
219  // connected blocks need to be interested before we consider expanding the
220  // region through the bundle. This helps compile time by limiting the number
221  // of blocks visited and the number of links in the Hopfield network.
222  if (bundles->getBlocks(n).size() > 100) {
223    nodes[n].BiasP = 0;
224    nodes[n].BiasN = (BlockFrequency::getEntryFrequency() / 16);
225  }
226}
227
228
229/// addConstraints - Compute node biases and weights from a set of constraints.
230/// Set a bit in NodeMask for each active node.
231void SpillPlacement::addConstraints(ArrayRef<BlockConstraint> LiveBlocks) {
232  for (ArrayRef<BlockConstraint>::iterator I = LiveBlocks.begin(),
233       E = LiveBlocks.end(); I != E; ++I) {
234    BlockFrequency Freq = BlockFrequencies[I->Number];
235
236    // Live-in to block?
237    if (I->Entry != DontCare) {
238      unsigned ib = bundles->getBundle(I->Number, 0);
239      activate(ib);
240      nodes[ib].addBias(Freq, I->Entry);
241    }
242
243    // Live-out from block?
244    if (I->Exit != DontCare) {
245      unsigned ob = bundles->getBundle(I->Number, 1);
246      activate(ob);
247      nodes[ob].addBias(Freq, I->Exit);
248    }
249  }
250}
251
252/// addPrefSpill - Same as addConstraints(PrefSpill)
253void SpillPlacement::addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong) {
254  for (ArrayRef<unsigned>::iterator I = Blocks.begin(), E = Blocks.end();
255       I != E; ++I) {
256    BlockFrequency Freq = BlockFrequencies[*I];
257    if (Strong)
258      Freq += Freq;
259    unsigned ib = bundles->getBundle(*I, 0);
260    unsigned ob = bundles->getBundle(*I, 1);
261    activate(ib);
262    activate(ob);
263    nodes[ib].addBias(Freq, PrefSpill);
264    nodes[ob].addBias(Freq, PrefSpill);
265  }
266}
267
268void 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);
280    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);
284    BlockFrequency Freq = BlockFrequencies[Number];
285    nodes[ib].addLink(ob, Freq);
286    nodes[ob].addLink(ib, Freq);
287  }
288}
289
290bool 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
307/// 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.
310void 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
316  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) {
326    // Scan backwards, skipping the last node which was just updated.
327    bool Changed = false;
328    for (SmallVectorImpl<unsigned>::const_reverse_iterator I =
329           llvm::next(Linked.rbegin()), E = Linked.rend(); I != E; ++I) {
330      unsigned n = *I;
331      if (nodes[n].update(nodes)) {
332        Changed = true;
333        if (nodes[n].preferReg())
334          RecentPositive.push_back(n);
335      }
336    }
337    if (!Changed || !RecentPositive.empty())
338      return;
339
340    // Scan forwards, skipping the first node which was just updated.
341    Changed = false;
342    for (SmallVectorImpl<unsigned>::const_iterator I =
343           llvm::next(Linked.begin()), E = Linked.end(); I != E; ++I) {
344      unsigned n = *I;
345      if (nodes[n].update(nodes)) {
346        Changed = true;
347        if (nodes[n].preferReg())
348          RecentPositive.push_back(n);
349      }
350    }
351    if (!Changed || !RecentPositive.empty())
352      return;
353  }
354}
355
356void SpillPlacement::prepare(BitVector &RegBundles) {
357  Linked.clear();
358  RecentPositive.clear();
359  // Reuse RegBundles as our ActiveNodes vector.
360  ActiveNodes = &RegBundles;
361  ActiveNodes->clear();
362  ActiveNodes->resize(bundles->getNumBundles());
363}
364
365bool
366SpillPlacement::finish() {
367  assert(ActiveNodes && "Call prepare() first");
368
369  // Write preferences back to ActiveNodes.
370  bool Perfect = true;
371  for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n))
372    if (!nodes[n].preferReg()) {
373      ActiveNodes->reset(n);
374      Perfect = false;
375    }
376  ActiveNodes = 0;
377  return Perfect;
378}
379