LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SpillPlacement.cpp
Go to the documentation of this file.
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"
38 #include "llvm/CodeGen/Passes.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/Format.h"
41 
42 using namespace llvm;
43 
44 char SpillPlacement::ID = 0;
45 INITIALIZE_PASS_BEGIN(SpillPlacement, "spill-code-placement",
46  "Spill Code Placement Analysis", true, true)
50  "Spill Code Placement Analysis", true, true)
51 
52 char &llvm::SpillPlacementID = SpillPlacement::ID;
53 
54 void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
55  AU.setPreservesAll();
56  AU.addRequired<MachineBlockFrequencyInfo>();
57  AU.addRequiredTransitive<EdgeBundles>();
58  AU.addRequiredTransitive<MachineLoopInfo>();
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).
64 static 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 ///
76  /// BiasN - Sum of blocks that prefer a spill.
78  /// BiasP - Sum of blocks that prefer a register.
80 
81  /// Value - Output value of this node computed from the Bias and links.
82  /// 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;
85 
87 
88  /// Links - (Weight, BundleNo) for all transparent blocks connecting to other
89  /// bundles. The weights are all positive block frequencies.
91 
92  /// SumLinkWeights - Cached sum of the weights of all links + ThresHold.
94 
95  /// 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 {
103  // 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;
107  }
108 
109  /// clear - Reset per-query data, but preserve frequencies that only depend on
110  // the CFG.
111  void clear() {
112  BiasN = BiasP = Value = 0;
114  Links.clear();
115  }
116 
117  /// addLink - Add a link to bundle b with weight w.
118  void addLink(unsigned b, BlockFrequency w) {
119  // Update cached sum.
120  SumLinkWeights += w;
121 
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 
132  /// addBias - Bias this node.
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:
145  break;
146  }
147  }
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.
153  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  }
161 
162  // 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  //
166  // 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.
169  //
170  bool Before = preferReg();
171  if (SumN >= SumP + Threshold)
172  Value = -1;
173  else if (SumP >= SumN + Threshold)
174  Value = 1;
175  else
176  Value = 0;
177  return Before != preferReg();
178  }
179 };
180 
181 bool 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.
190  BlockFrequencies.resize(mf.getNumBlockIDs());
191  MachineBlockFrequencyInfo &MBFI = getAnalysis<MachineBlockFrequencyInfo>();
192  for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) {
193  unsigned Num = I->getNumber();
194  BlockFrequencies[Num] = MBFI.getBlockFreq(I);
195  }
196 
197  // We never change the function.
198  return false;
199 }
200 
201 void SpillPlacement::releaseMemory() {
202  delete[] nodes;
203  nodes = 0;
204 }
205 
206 /// activate - mark node n as active if it wasn't already.
207 void SpillPlacement::activate(unsigned n) {
208  if (ActiveNodes->test(n))
209  return;
210  ActiveNodes->set(n);
211  nodes[n].clear();
212 
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  //
217  // 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;
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.
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)
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 
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 
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.
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;
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;
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 
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 
365 bool
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 }
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Definition: BitVector.h:210
void push_back(const T &Elt)
Definition: SmallVector.h:236
BitVector & set()
Definition: BitVector.h:236
spill code Spill Code Placement true
int find_first() const
Definition: BitVector.h:159
INITIALIZE_PASS_BEGIN(SpillPlacement,"spill-code-placement","Spill Code Placement Analysis", true, true) INITIALIZE_PASS_END(SpillPlacement
A register is impossible, variable must be spilled.
int find_next(unsigned Prev) const
Definition: BitVector.h:173
iterator end() const
Definition: ArrayRef.h:98
BlockFrequency BiasP
BiasP - Sum of blocks that prefer a register.
static uint64_t getEntryFrequency()
Returns the frequency of the entry block of the function.
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:167
void clear()
clear - Clear all bits.
Definition: BitVector.h:205
unsigned getNumBlockIDs() const
void addPrefSpill(ArrayRef< unsigned > Blocks, bool Strong)
addPrefSpill - Same as addConstraints(PrefSpill)
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
Definition: SmallVector.h:430
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:172
unsigned getNumBundles() const
getNumBundles - Return the total number of bundles in the CFG.
Definition: EdgeBundles.h:46
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
BlockFrequency SumLinkWeights
SumLinkWeights - Cached sum of the weights of all links + ThresHold.
void addBias(BlockFrequency freq, BorderConstraint direction)
addBias - Bias this node.
void addLinks(ArrayRef< unsigned > Links)
addLinks - Add transparent blocks with the given numbers.
Block doesn't care / variable not live.
block freq
spill code Spill Code Placement Analysis
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
BitVector & reset()
Definition: BitVector.h:275
spill code placement
iterator begin() const
Definition: ArrayRef.h:97
void clear()
clear - Reset per-query data, but preserve frequencies that only depend on
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:104
Block entry/exit prefers a register.
void addConstraints(ArrayRef< BlockConstraint > LiveBlocks)
block Branch Probability Basic Block Placement
Block entry/exit prefers a stack slot.
bool test(unsigned Idx) const
Definition: BitVector.h:337
void prepare(BitVector &RegBundles)
ArrayRef< unsigned > getBlocks(unsigned Bundle) const
getBlocks - Return an array of blocks that are connected to Bundle.
Definition: EdgeBundles.h:49
void addLink(unsigned b, BlockFrequency w)
addLink - Add a link to bundle b with weight w.
bool update(const Node nodes[])
static uint64_t getMaxFrequency()
Returns the maximum possible frequency, the saturation value.
virtual void getAnalysisUsage(AnalysisUsage &AU) const
#define I(x, y, z)
Definition: MD5.cpp:54
char & SpillPlacementID
SmallVector< std::pair< BlockFrequency, unsigned >, 4 > LinkVector
unsigned getBundle(unsigned N, bool Out) const
Definition: EdgeBundles.h:43
LLVM Value Representation.
Definition: Value.h:66
BasicBlockListType::iterator iterator
bool mustSpill() const
mustSpill - Return True if this node is so biased that it must spill.
static const BlockFrequency Threshold
BlockFrequency BiasN
BiasN - Sum of blocks that prefer a spill.
bool preferReg() const
preferReg - Return true when this node prefers to be in a register.