LLVM: lib/CodeGen/SpillPlacement.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
38#include
39#include
40#include
41#include
42
43using namespace llvm;
44
45#define DEBUG_TYPE "spill-code-placement"
46
48
50
52 "Spill Code Placement Analysis", true, true)
55 "Spill Code Placement Analysis", true, true)
56
58 AU.setPreservesAll();
62}
63
64
65
66
67
68
69
70
71
73
75
76
78
79
80
81
83
85
86
87
89
90
92
93
98
99
106
107
108
116
117
119
121
122
123 for (std::pair<BlockFrequency, unsigned> &L : Links)
124 if (L.second == b) {
125 L.first += w;
126 return;
127 }
128
129 Links.push_back(std::make_pair(w, b));
130 }
131
132
134 switch (direction) {
135 default:
136 break;
139 break;
142 break;
145 break;
146 }
147 }
148
149
150
152
155 for (std::pair<BlockFrequency, unsigned> &L : Links) {
156 if (nodes[L.second].Value == -1)
157 SumN += L.first;
158 else if (nodes[L.second].Value == 1)
159 SumP += L.first;
160 }
161
162
163
164
165
166
167
168
169
171 if (SumN >= SumP + Threshold)
173 else if (SumP >= SumN + Threshold)
175 else
178 }
179
181 const Node nodes[]) const {
182 for (const auto &Elt : Links) {
183 unsigned n = Elt.second;
184
185
187 List.insert(n);
188 }
189 }
190};
191
192bool SpillPlacementWrapperLegacy::runOnMachineFunction(MachineFunction &MF) {
195
196 Impl.run(MF, Bundles, MBFI);
197 return false;
198}
199
201
208 Impl.run(MF, Bundles, MBFI);
209 return Impl;
210}
211
214 MachineFunctionAnalysisManager::Invalidator &Inv) {
217 return true;
218
221}
222
226
227void SpillPlacement::releaseMemory() {
229 TodoList.clear();
230}
231
234 MF = &mf;
235 this->bundles = Bundles;
236 this->MBFI = MBFI;
237
240 TodoList.clear();
242
243
246 for (auto &I : mf) {
247 unsigned Num = I.getNumber();
249 }
250}
251
252
253void SpillPlacement::activate(unsigned n) {
254 TodoList.insert(n);
255 if (ActiveNodes->test(n))
256 return;
257 ActiveNodes->set(n);
258 nodes[n].clear(Threshold);
259
260
261
262
263
264
265
266
267
268
269 if (bundles->getBlocks(n).size() > 100) {
270 nodes[n].BiasP = BlockFrequency(0);
271 BlockFrequency BiasN = MBFI->getEntryFreq();
272 BiasN >>= 4;
273 nodes[n].BiasN = BiasN;
274 }
275}
276
277
278
279
280
281
282void SpillPlacement::setThreshold(BlockFrequency Entry) {
283
284
285 uint64_t Freq = Entry.getFrequency();
286 uint64_t Scaled = (Freq >> 13) + bool(Freq & (1 << 12));
287 Threshold = BlockFrequency(std::max(UINT64_C(1), Scaled));
288}
289
290
291
295
296
298 unsigned ib = bundles->getBundle(LB.Number, false);
299 activate(ib);
300 nodes[ib].addBias(Freq, LB.Entry);
301 }
302
303
305 unsigned ob = bundles->getBundle(LB.Number, true);
306 activate(ob);
307 nodes[ob].addBias(Freq, LB.Exit);
308 }
309 }
310}
311
312
314 for (unsigned B : Blocks) {
316 if (Strong)
317 Freq += Freq;
318 unsigned ib = bundles->getBundle(B, false);
319 unsigned ob = bundles->getBundle(B, true);
320 activate(ib);
321 activate(ob);
322 nodes[ib].addBias(Freq, PrefSpill);
323 nodes[ob].addBias(Freq, PrefSpill);
324 }
325}
326
328 for (unsigned Number : Links) {
329 unsigned ib = bundles->getBundle(Number, false);
330 unsigned ob = bundles->getBundle(Number, true);
331
332
333 if (ib == ob)
334 continue;
335 activate(ib);
336 activate(ob);
338 nodes[ib].addLink(ob, Freq);
339 nodes[ob].addLink(ib, Freq);
340 }
341}
342
344 RecentPositive.clear();
345 for (unsigned n : ActiveNodes->set_bits()) {
346 update(n);
347
348
349 if (nodes[n].mustSpill())
350 continue;
351 if (nodes[n].preferReg())
352 RecentPositive.push_back(n);
353 }
354 return !RecentPositive.empty();
355}
356
357bool SpillPlacement::update(unsigned n) {
358 if ([n].update(nodes.get(), Threshold))
359 return false;
360 nodes[n].getDissentingNeighbors(TodoList, nodes.get());
361 return true;
362}
363
364
365
367
368
369 RecentPositive.clear();
370
371
372
373
374
375 unsigned Limit = bundles->getNumBundles() * 10;
376 while(Limit-- > 0 && !TodoList.empty()) {
377 unsigned n = TodoList.pop_back_val();
378 if (!update(n))
379 continue;
380 if (nodes[n].preferReg())
381 RecentPositive.push_back(n);
382 }
383}
384
386 RecentPositive.clear();
387 TodoList.clear();
388
389 ActiveNodes = &RegBundles;
390 ActiveNodes->clear();
391 ActiveNodes->resize(bundles->getNumBundles());
392}
393
394bool
396 assert(ActiveNodes && "Call prepare() first");
397
398
399 bool Perfect = true;
400 for (unsigned n : ActiveNodes->set_bits())
401 if (!nodes[n].preferReg()) {
402 ActiveNodes->reset(n);
403 Perfect = false;
404 }
405 ActiveNodes = nullptr;
406 return Perfect;
407}
408
411 switch(C) {
412 case DontCare: return "DontCare";
413 case PrefReg: return "PrefReg";
414 case PrefSpill: return "PrefSpill";
415 case PrefBoth: return "PrefBoth";
416 case MustSpill: return "MustSpill";
417 };
419 };
420
424 << (ChangesValue ? "changes" : "no change") << "}";
425}
426
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This templated class represents "all analyses that operate over " (e....
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void clear()
clear - Removes all bits from the bitvector.
static BlockFrequency max()
Returns the maximum possible frequency, the saturation value.
unsigned getNumBundles() const
getNumBundles - Return the total number of bundles in the CFG.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI BlockFrequency getEntryFreq() const
Divide a block's BlockFrequency::getFrequency() value by this value to obtain the entry block - relat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseSet - Fast set implementation for objects that can be identified by small unsigned keys.
void clear()
clear - Clears the set.
void setUniverse(unsigned U)
setUniverse - Set the universe size which determines the largest key the set can hold.
SpillPlacement run(MachineFunction &, MachineFunctionAnalysisManager &)
Definition SpillPlacement.cpp:203
void addConstraints(ArrayRef< BlockConstraint > LiveBlocks)
addConstraints - Add constraints and biases.
Definition SpillPlacement.cpp:292
bool finish()
finish - Compute the optimal spill code placement given the constraints.
Definition SpillPlacement.cpp:395
void addPrefSpill(ArrayRef< unsigned > Blocks, bool Strong)
addPrefSpill - Add PrefSpill constraints to all blocks listed.
Definition SpillPlacement.cpp:313
void prepare(BitVector &RegBundles)
prepare - Reset state and prepare for a new spill placement computation.
Definition SpillPlacement.cpp:385
bool scanActiveBundles()
scanActiveBundles - Perform an initial scan of all bundles activated by addConstraints and addLinks,...
Definition SpillPlacement.cpp:343
bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &Inv)
Definition SpillPlacement.cpp:212
friend class SpillPlacementAnalysis
void addLinks(ArrayRef< unsigned > Links)
addLinks - Add transparent blocks with the given numbers.
Definition SpillPlacement.cpp:327
void iterate()
iterate - Update the network iteratively until convergence, or new bundles are found.
Definition SpillPlacement.cpp:366
BorderConstraint
BorderConstraint - A basic block has separate constraints for entry and exit.
@ MustSpill
A register is impossible, variable must be spilled.
@ DontCare
Block doesn't care / variable not live.
@ PrefBoth
Block entry prefers both register and stack.
@ PrefReg
Block entry/exit prefers a register.
@ PrefSpill
Block entry/exit prefers a stack slot.
SpillPlacement(SpillPlacement &&)
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
iterator_range< typename GraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI char & SpillPlacementID
SpillPlacement analysis.
Definition SpillPlacement.cpp:49
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
Node - Each edge bundle corresponds to a Hopfield node.
Definition SpillPlacement.cpp:72
void addBias(BlockFrequency freq, BorderConstraint direction)
addBias - Bias this node.
Definition SpillPlacement.cpp:133
bool preferReg() const
preferReg - Return true when this node prefers to be in a register.
Definition SpillPlacement.cpp:94
bool update(const Node nodes[], BlockFrequency Threshold)
update - Recompute Value from Bias and Links.
Definition SpillPlacement.cpp:151
BlockFrequency SumLinkWeights
SumLinkWeights - Cached sum of the weights of all links + ThresHold.
Definition SpillPlacement.cpp:91
BlockFrequency BiasN
BiasN - Sum of blocks that prefer a spill.
Definition SpillPlacement.cpp:74
void addLink(unsigned b, BlockFrequency w)
addLink - Add a link to bundle b with weight w.
Definition SpillPlacement.cpp:118
LinkVector Links
Links - (Weight, BundleNo) for all transparent blocks connecting to other bundles.
Definition SpillPlacement.cpp:88
int Value
Value - Output value of this node computed from the Bias and links.
Definition SpillPlacement.cpp:82
BlockFrequency BiasP
BiasP - Sum of blocks that prefer a register.
Definition SpillPlacement.cpp:77
SmallVector< std::pair< BlockFrequency, unsigned >, 4 > LinkVector
Definition SpillPlacement.cpp:84
void clear(BlockFrequency Threshold)
clear - Reset per-query data, but preserve frequencies that only depend on the CFG.
Definition SpillPlacement.cpp:109
bool mustSpill() const
mustSpill - Return True if this node is so biased that it must spill.
Definition SpillPlacement.cpp:100
void getDissentingNeighbors(SparseSet< unsigned > &List, const Node nodes[]) const
Definition SpillPlacement.cpp:180
A special type used by analysis passes to provide an address that identifies that particular analysis...
BlockConstraint - Entry and exit constraints for a basic block.
BorderConstraint Exit
Constraint on block exit.
void dump() const
Definition SpillPlacement.cpp:427
void print(raw_ostream &OS) const
Definition SpillPlacement.cpp:409
bool ChangesValue
True when this block changes the value of the live range.
BorderConstraint Entry
Constraint on block entry.
unsigned Number
Basic block number (from MBB::getNumber()).