Skip to content

Commit c791eaa

Browse files
committed
[CodeGen][NewPM] Port SpillPlacement analysis to NPM
1 parent 8a5db30 commit c791eaa

File tree

4 files changed

+104
-47
lines changed

4 files changed

+104
-47
lines changed

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ void initializeSinkingLegacyPassPass(PassRegistry &);
289289
void initializeSjLjEHPreparePass(PassRegistry &);
290290
void initializeSlotIndexesWrapperPassPass(PassRegistry &);
291291
void initializeSpeculativeExecutionLegacyPassPass(PassRegistry &);
292-
void initializeSpillPlacementPass(PassRegistry &);
292+
void initializeSpillPlacementWrapperLegacyPass(PassRegistry &);
293293
void initializeStackColoringLegacyPass(PassRegistry &);
294294
void initializeStackFrameLayoutAnalysisPassPass(PassRegistry &);
295295
void initializeStackMapLivenessPass(PassRegistry &);

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
162162
INITIALIZE_PASS_DEPENDENCY(VirtRegMapWrapperLegacy)
163163
INITIALIZE_PASS_DEPENDENCY(LiveRegMatrixWrapperLegacy)
164164
INITIALIZE_PASS_DEPENDENCY(EdgeBundlesWrapperLegacy)
165-
INITIALIZE_PASS_DEPENDENCY(SpillPlacement)
165+
INITIALIZE_PASS_DEPENDENCY(SpillPlacementWrapperLegacy)
166166
INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
167167
INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysis)
168168
INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysis)
@@ -217,7 +217,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
217217
AU.addRequired<LiveRegMatrixWrapperLegacy>();
218218
AU.addPreserved<LiveRegMatrixWrapperLegacy>();
219219
AU.addRequired<EdgeBundlesWrapperLegacy>();
220-
AU.addRequired<SpillPlacement>();
220+
AU.addRequired<SpillPlacementWrapperLegacy>();
221221
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
222222
AU.addRequired<RegAllocEvictionAdvisorAnalysis>();
223223
AU.addRequired<RegAllocPriorityAdvisorAnalysis>();
@@ -2731,7 +2731,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
27312731
ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
27322732
Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
27332733
Bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
2734-
SpillPlacer = &getAnalysis<SpillPlacement>();
2734+
SpillPlacer = &getAnalysis<SpillPlacementWrapperLegacy>().getResult();
27352735
DebugVars = &getAnalysis<LiveDebugVariables>();
27362736

27372737
initializeCSRCost();

llvm/lib/CodeGen/SpillPlacement.cpp

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@ using namespace llvm;
4444

4545
#define DEBUG_TYPE "spill-code-placement"
4646

47-
char SpillPlacement::ID = 0;
47+
char SpillPlacementWrapperLegacy::ID = 0;
4848

49-
char &llvm::SpillPlacementID = SpillPlacement::ID;
49+
char &llvm::SpillPlacementID = SpillPlacementWrapperLegacy::ID;
5050

51-
INITIALIZE_PASS_BEGIN(SpillPlacement, DEBUG_TYPE,
51+
INITIALIZE_PASS_BEGIN(SpillPlacementWrapperLegacy, DEBUG_TYPE,
5252
"Spill Code Placement Analysis", true, true)
5353
INITIALIZE_PASS_DEPENDENCY(EdgeBundlesWrapperLegacy)
54-
INITIALIZE_PASS_END(SpillPlacement, DEBUG_TYPE,
54+
INITIALIZE_PASS_END(SpillPlacementWrapperLegacy, DEBUG_TYPE,
5555
"Spill Code Placement Analysis", true, true)
5656

57-
void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
57+
void SpillPlacementWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
5858
AU.setPreservesAll();
5959
AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
6060
AU.addRequiredTransitive<EdgeBundlesWrapperLegacy>();
@@ -189,32 +189,57 @@ struct SpillPlacement::Node {
189189
}
190190
};
191191

192-
bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {
192+
bool SpillPlacementWrapperLegacy::runOnMachineFunction(MachineFunction &MF) {
193+
auto *Bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
194+
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
195+
196+
Impl.reset(new SpillPlacement(Bundles, MBFI));
197+
Impl->run(MF);
198+
return false;
199+
}
200+
201+
AnalysisKey SpillPlacementAnalysis::Key;
202+
203+
SpillPlacement
204+
SpillPlacementAnalysis::run(MachineFunction &MF,
205+
MachineFunctionAnalysisManager &MFAM) {
206+
auto *Bundles = &MFAM.getResult<EdgeBundlesAnalysis>(MF);
207+
auto *MBFI = &MFAM.getResult<MachineBlockFrequencyAnalysis>(MF);
208+
SpillPlacement Impl(Bundles, MBFI);
209+
Impl.run(MF);
210+
return Impl;
211+
}
212+
213+
bool SpillPlacementAnalysis::Result::invalidate(
214+
MachineFunction &MF, const PreservedAnalyses &PA,
215+
MachineFunctionAnalysisManager::Invalidator &Inv) {
216+
auto PAC = PA.getChecker<SpillPlacementAnalysis>();
217+
return !(PAC.preserved() ||
218+
PAC.preservedSet<AllAnalysesOn<MachineFunction>>()) ||
219+
Inv.invalidate<EdgeBundlesAnalysis>(MF, PA) ||
220+
Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA);
221+
}
222+
223+
void SpillPlacement::arrayDeleter(Node *N) {
224+
if (N)
225+
delete[] N;
226+
}
227+
228+
void SpillPlacement::run(MachineFunction &mf) {
193229
MF = &mf;
194-
bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
195230

196231
assert(!nodes && "Leaking node array");
197-
nodes = new Node[bundles->getNumBundles()];
232+
nodes.reset(new Node[bundles->getNumBundles()]);
198233
TodoList.clear();
199234
TodoList.setUniverse(bundles->getNumBundles());
200235

201236
// Compute total ingoing and outgoing block frequencies for all bundles.
202237
BlockFrequencies.resize(mf.getNumBlockIDs());
203-
MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
204238
setThreshold(MBFI->getEntryFreq());
205239
for (auto &I : mf) {
206240
unsigned Num = I.getNumber();
207241
BlockFrequencies[Num] = MBFI->getBlockFreq(&I);
208242
}
209-
210-
// We never change the function.
211-
return false;
212-
}
213-
214-
void SpillPlacement::releaseMemory() {
215-
delete[] nodes;
216-
nodes = nullptr;
217-
TodoList.clear();
218243
}
219244

220245
/// activate - mark node n as active if it wasn't already.
@@ -223,7 +248,7 @@ void SpillPlacement::activate(unsigned n) {
223248
if (ActiveNodes->test(n))
224249
return;
225250
ActiveNodes->set(n);
226-
nodes[n].clear(Threshold);
251+
nodes.get()[n].clear(Threshold);
227252

228253
// Very large bundles usually come from big switches, indirect branches,
229254
// landing pads, or loops with many 'continue' statements. It is difficult to
@@ -235,10 +260,10 @@ void SpillPlacement::activate(unsigned n) {
235260
// limiting the number of blocks visited and the number of links in the
236261
// Hopfield network.
237262
if (bundles->getBlocks(n).size() > 100) {
238-
nodes[n].BiasP = BlockFrequency(0);
263+
nodes.get()[n].BiasP = BlockFrequency(0);
239264
BlockFrequency BiasN = MBFI->getEntryFreq();
240265
BiasN >>= 4;
241-
nodes[n].BiasN = BiasN;
266+
nodes.get()[n].BiasN = BiasN;
242267
}
243268
}
244269

@@ -265,14 +290,14 @@ void SpillPlacement::addConstraints(ArrayRef<BlockConstraint> LiveBlocks) {
265290
if (LB.Entry != DontCare) {
266291
unsigned ib = bundles->getBundle(LB.Number, false);
267292
activate(ib);
268-
nodes[ib].addBias(Freq, LB.Entry);
293+
nodes.get()[ib].addBias(Freq, LB.Entry);
269294
}
270295

271296
// Live-out from block?
272297
if (LB.Exit != DontCare) {
273298
unsigned ob = bundles->getBundle(LB.Number, true);
274299
activate(ob);
275-
nodes[ob].addBias(Freq, LB.Exit);
300+
nodes.get()[ob].addBias(Freq, LB.Exit);
276301
}
277302
}
278303
}
@@ -287,8 +312,8 @@ void SpillPlacement::addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong) {
287312
unsigned ob = bundles->getBundle(B, true);
288313
activate(ib);
289314
activate(ob);
290-
nodes[ib].addBias(Freq, PrefSpill);
291-
nodes[ob].addBias(Freq, PrefSpill);
315+
nodes.get()[ib].addBias(Freq, PrefSpill);
316+
nodes.get()[ob].addBias(Freq, PrefSpill);
292317
}
293318
}
294319

@@ -303,8 +328,8 @@ void SpillPlacement::addLinks(ArrayRef<unsigned> Links) {
303328
activate(ib);
304329
activate(ob);
305330
BlockFrequency Freq = BlockFrequencies[Number];
306-
nodes[ib].addLink(ob, Freq);
307-
nodes[ob].addLink(ib, Freq);
331+
nodes.get()[ib].addLink(ob, Freq);
332+
nodes.get()[ob].addLink(ib, Freq);
308333
}
309334
}
310335

@@ -314,18 +339,18 @@ bool SpillPlacement::scanActiveBundles() {
314339
update(n);
315340
// A node that must spill, or a node without any links is not going to
316341
// change its value ever again, so exclude it from iterations.
317-
if (nodes[n].mustSpill())
342+
if (nodes.get()[n].mustSpill())
318343
continue;
319-
if (nodes[n].preferReg())
344+
if (nodes.get()[n].preferReg())
320345
RecentPositive.push_back(n);
321346
}
322347
return !RecentPositive.empty();
323348
}
324349

325350
bool SpillPlacement::update(unsigned n) {
326-
if (!nodes[n].update(nodes, Threshold))
351+
if (!nodes.get()[n].update(nodes.get(), Threshold))
327352
return false;
328-
nodes[n].getDissentingNeighbors(TodoList, nodes);
353+
nodes.get()[n].getDissentingNeighbors(TodoList, nodes.get());
329354
return true;
330355
}
331356

@@ -345,7 +370,7 @@ void SpillPlacement::iterate() {
345370
unsigned n = TodoList.pop_back_val();
346371
if (!update(n))
347372
continue;
348-
if (nodes[n].preferReg())
373+
if (nodes.get()[n].preferReg())
349374
RecentPositive.push_back(n);
350375
}
351376
}
@@ -366,7 +391,7 @@ SpillPlacement::finish() {
366391
// Write preferences back to ActiveNodes.
367392
bool Perfect = true;
368393
for (unsigned n : ActiveNodes->set_bits())
369-
if (!nodes[n].preferReg()) {
394+
if (!nodes.get()[n].preferReg()) {
370395
ActiveNodes->reset(n);
371396
Perfect = false;
372397
}

llvm/lib/CodeGen/SpillPlacement.h

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/ADT/ArrayRef.h"
3030
#include "llvm/ADT/SmallVector.h"
3131
#include "llvm/ADT/SparseSet.h"
32+
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
3233
#include "llvm/CodeGen/MachineFunctionPass.h"
3334
#include "llvm/Support/BlockFrequency.h"
3435

@@ -38,13 +39,21 @@ class BitVector;
3839
class EdgeBundles;
3940
class MachineBlockFrequencyInfo;
4041
class MachineFunction;
42+
class SpillPlacementWrapperLegacy;
43+
class SpillPlacementAnalysis;
44+
45+
class SpillPlacement {
46+
friend class SpillPlacementWrapperLegacy;
47+
friend class SpillPlacementAnalysis;
4148

42-
class SpillPlacement : public MachineFunctionPass {
4349
struct Node;
50+
4451
const MachineFunction *MF = nullptr;
4552
const EdgeBundles *bundles = nullptr;
4653
const MachineBlockFrequencyInfo *MBFI = nullptr;
47-
Node *nodes = nullptr;
54+
55+
static void arrayDeleter(Node *N);
56+
std::unique_ptr<Node, decltype(&arrayDeleter)> nodes;
4857

4958
// Nodes that are active in the current computation. Owned by the prepare()
5059
// caller.
@@ -68,11 +77,6 @@ class SpillPlacement : public MachineFunctionPass {
6877
SparseSet<unsigned> TodoList;
6978

7079
public:
71-
static char ID; // Pass identification, replacement for typeid.
72-
73-
SpillPlacement() : MachineFunctionPass(ID) {}
74-
~SpillPlacement() override { releaseMemory(); }
75-
7680
/// BorderConstraint - A basic block has separate constraints for entry and
7781
/// exit.
7882
enum BorderConstraint {
@@ -154,17 +158,45 @@ class SpillPlacement : public MachineFunctionPass {
154158
return BlockFrequencies[Number];
155159
}
156160

161+
bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
162+
MachineFunctionAnalysisManager::Invalidator &Inv);
163+
157164
private:
158-
bool runOnMachineFunction(MachineFunction &mf) override;
159-
void getAnalysisUsage(AnalysisUsage &AU) const override;
160-
void releaseMemory() override;
165+
SpillPlacement(EdgeBundles *Bundles, MachineBlockFrequencyInfo *MBFI)
166+
: bundles(Bundles), MBFI(MBFI), nodes(nullptr, &arrayDeleter) {}
161167

168+
void run(MachineFunction &MF);
162169
void activate(unsigned n);
163170
void setThreshold(BlockFrequency Entry);
164171

165172
bool update(unsigned n);
166173
};
167174

175+
class SpillPlacementWrapperLegacy : public MachineFunctionPass {
176+
public:
177+
static char ID;
178+
SpillPlacementWrapperLegacy() : MachineFunctionPass(ID) {}
179+
180+
SpillPlacement &getResult() { return *Impl; }
181+
const SpillPlacement &getResult() const { return *Impl; }
182+
183+
private:
184+
std::unique_ptr<SpillPlacement> Impl;
185+
bool runOnMachineFunction(MachineFunction &MF) override;
186+
void getAnalysisUsage(AnalysisUsage &AU) const override;
187+
void releaseMemory() override { Impl.reset(); }
188+
};
189+
190+
class SpillPlacementAnalysis
191+
: public AnalysisInfoMixin<SpillPlacementAnalysis> {
192+
friend AnalysisInfoMixin<SpillPlacementAnalysis>;
193+
static AnalysisKey Key;
194+
195+
public:
196+
using Result = SpillPlacement;
197+
SpillPlacement run(MachineFunction &, MachineFunctionAnalysisManager &);
198+
};
199+
168200
} // end namespace llvm
169201

170202
#endif // LLVM_LIB_CODEGEN_SPILLPLACEMENT_H

0 commit comments

Comments
 (0)