39
39
#include " llvm/Analysis/Loads.h"
40
40
#include " llvm/Analysis/LoopInfo.h"
41
41
#include " llvm/Analysis/LoopPass.h"
42
+ #include " llvm/Analysis/MemorySSA.h"
43
+ #include " llvm/Analysis/MemorySSAUpdater.h"
42
44
#include " llvm/Analysis/ScalarEvolution.h"
43
45
#include " llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
44
46
#include " llvm/IR/Dominators.h"
@@ -67,6 +69,14 @@ static cl::opt<unsigned> MaxNumberOfUseBBsForSinking(
67
69
" max-uses-for-sinking" , cl::Hidden, cl::init(30 ),
68
70
cl::desc(" Do not sink instructions that have too many uses." ));
69
71
72
+ static cl::opt<bool > EnableMSSAInLoopSink (
73
+ " enable-mssa-in-loop-sink" , cl::Hidden, cl::init(false ),
74
+ cl::desc(" Enable MemorySSA for LoopSink in new pass manager" ));
75
+
76
+ static cl::opt<bool > EnableMSSAInLegacyLoopSink (
77
+ " enable-mssa-in-legacy-loop-sink" , cl::Hidden, cl::init(false ),
78
+ cl::desc(" Enable MemorySSA for LoopSink in legacy pass manager" ));
79
+
70
80
// / Return adjusted total frequency of \p BBs.
71
81
// /
72
82
// / * If there is only one BB, sinking instruction will not introduce code
@@ -172,11 +182,10 @@ findBBsToSinkInto(const Loop &L, const SmallPtrSetImpl<BasicBlock *> &UseBBs,
172
182
// sinking is successful.
173
183
// \p LoopBlockNumber is used to sort the insertion blocks to ensure
174
184
// determinism.
175
- static bool sinkInstruction (Loop &L, Instruction &I,
176
- const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
177
- const SmallDenseMap<BasicBlock *, int , 16 > &LoopBlockNumber,
178
- LoopInfo &LI, DominatorTree &DT,
179
- BlockFrequencyInfo &BFI) {
185
+ static bool sinkInstruction (
186
+ Loop &L, Instruction &I, const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
187
+ const SmallDenseMap<BasicBlock *, int , 16 > &LoopBlockNumber, LoopInfo &LI,
188
+ DominatorTree &DT, BlockFrequencyInfo &BFI, MemorySSAUpdater *MSSAU) {
180
189
// Compute the set of blocks in loop L which contain a use of I.
181
190
SmallPtrSet<BasicBlock *, 2 > BBs;
182
191
for (auto &U : I.uses ()) {
@@ -230,6 +239,21 @@ static bool sinkInstruction(Loop &L, Instruction &I,
230
239
Instruction *IC = I.clone ();
231
240
IC->setName (I.getName ());
232
241
IC->insertBefore (&*N->getFirstInsertionPt ());
242
+
243
+ if (MSSAU && MSSAU->getMemorySSA ()->getMemoryAccess (&I)) {
244
+ // Create a new MemoryAccess and let MemorySSA set its defining access.
245
+ MemoryAccess *NewMemAcc =
246
+ MSSAU->createMemoryAccessInBB (IC, nullptr , N, MemorySSA::Beginning);
247
+ if (NewMemAcc) {
248
+ if (auto *MemDef = dyn_cast<MemoryDef>(NewMemAcc))
249
+ MSSAU->insertDef (MemDef, /* RenameUses=*/ true );
250
+ else {
251
+ auto *MemUse = cast<MemoryUse>(NewMemAcc);
252
+ MSSAU->insertUse (MemUse, /* RenameUses=*/ true );
253
+ }
254
+ }
255
+ }
256
+
233
257
// Replaces uses of I with IC in N
234
258
I.replaceUsesWithIf (IC, [N](Use &U) {
235
259
return cast<Instruction>(U.getUser ())->getParent () == N;
@@ -244,6 +268,11 @@ static bool sinkInstruction(Loop &L, Instruction &I,
244
268
NumLoopSunk++;
245
269
I.moveBefore (&*MoveBB->getFirstInsertionPt ());
246
270
271
+ if (MSSAU)
272
+ if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
273
+ MSSAU->getMemorySSA ()->getMemoryAccess (&I)))
274
+ MSSAU->moveToPlace (OldMemAcc, MoveBB, MemorySSA::Beginning);
275
+
247
276
return true ;
248
277
}
249
278
@@ -252,15 +281,14 @@ static bool sinkInstruction(Loop &L, Instruction &I,
252
281
static bool sinkLoopInvariantInstructions (Loop &L, AAResults &AA, LoopInfo &LI,
253
282
DominatorTree &DT,
254
283
BlockFrequencyInfo &BFI,
255
- ScalarEvolution *SE) {
284
+ ScalarEvolution *SE,
285
+ AliasSetTracker *CurAST,
286
+ MemorySSA *MSSA) {
256
287
BasicBlock *Preheader = L.getLoopPreheader ();
257
- if (!Preheader)
258
- return false ;
288
+ assert (Preheader && " Expected loop to have preheader" );
259
289
260
- // Enable LoopSink only when runtime profile is available.
261
- // With static profile, the sinking decision may be sub-optimal.
262
- if (!Preheader->getParent ()->hasProfileData ())
263
- return false ;
290
+ assert (Preheader->getParent ()->hasProfileData () &&
291
+ " Unexpected call when profile data unavailable." );
264
292
265
293
const BlockFrequency PreheaderFreq = BFI.getBlockFreq (Preheader);
266
294
// If there are no basic blocks with lower frequency than the preheader then
@@ -271,13 +299,15 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
271
299
}))
272
300
return false ;
273
301
274
- bool Changed = false ;
275
- AliasSetTracker CurAST (AA);
302
+ std::unique_ptr<MemorySSAUpdater> MSSAU;
303
+ std::unique_ptr<SinkAndHoistLICMFlags> LICMFlags;
304
+ if (MSSA) {
305
+ MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
306
+ LICMFlags =
307
+ std::make_unique<SinkAndHoistLICMFlags>(/* IsSink=*/ true , &L, MSSA);
308
+ }
276
309
277
- // Compute alias set.
278
- for (BasicBlock *BB : L.blocks ())
279
- CurAST.add (*BB);
280
- CurAST.add (*Preheader);
310
+ bool Changed = false ;
281
311
282
312
// Sort loop's basic blocks by frequency
283
313
SmallVector<BasicBlock *, 10 > ColdLoopBBs;
@@ -300,9 +330,11 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
300
330
// No need to check for instruction's operands are loop invariant.
301
331
assert (L.hasLoopInvariantOperands (I) &&
302
332
" Insts in a loop's preheader should have loop invariant operands!" );
303
- if (!canSinkOrHoistInst (*I, &AA, &DT, &L, &CurAST, nullptr , false ))
333
+ if (!canSinkOrHoistInst (*I, &AA, &DT, &L, CurAST, MSSAU.get (), false ,
334
+ LICMFlags.get ()))
304
335
continue ;
305
- if (sinkInstruction (L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI))
336
+ if (sinkInstruction (L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI,
337
+ MSSAU.get ()))
306
338
Changed = true ;
307
339
}
308
340
@@ -311,6 +343,13 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
311
343
return Changed;
312
344
}
313
345
346
+ static void computeAliasSet (Loop &L, BasicBlock &Preheader,
347
+ AliasSetTracker &CurAST) {
348
+ for (BasicBlock *BB : L.blocks ())
349
+ CurAST.add (*BB);
350
+ CurAST.add (Preheader);
351
+ }
352
+
314
353
PreservedAnalyses LoopSinkPass::run (Function &F, FunctionAnalysisManager &FAM) {
315
354
LoopInfo &LI = FAM.getResult <LoopAnalysis>(F);
316
355
// Nothing to do if there are no loops.
@@ -321,6 +360,10 @@ PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
321
360
DominatorTree &DT = FAM.getResult <DominatorTreeAnalysis>(F);
322
361
BlockFrequencyInfo &BFI = FAM.getResult <BlockFrequencyAnalysis>(F);
323
362
363
+ MemorySSA *MSSA = EnableMSSAInLoopSink
364
+ ? &FAM.getResult <MemorySSAAnalysis>(F).getMSSA ()
365
+ : nullptr ;
366
+
324
367
// We want to do a postorder walk over the loops. Since loops are a tree this
325
368
// is equivalent to a reversed preorder walk and preorder is easy to compute
326
369
// without recursion. Since we reverse the preorder, we will visit siblings
@@ -332,18 +375,42 @@ PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
332
375
do {
333
376
Loop &L = *PreorderLoops.pop_back_val ();
334
377
378
+ BasicBlock *Preheader = L.getLoopPreheader ();
379
+ if (!Preheader)
380
+ continue ;
381
+
382
+ // Enable LoopSink only when runtime profile is available.
383
+ // With static profile, the sinking decision may be sub-optimal.
384
+ if (!Preheader->getParent ()->hasProfileData ())
385
+ continue ;
386
+
387
+ std::unique_ptr<AliasSetTracker> CurAST;
388
+ if (!EnableMSSAInLoopSink) {
389
+ CurAST = std::make_unique<AliasSetTracker>(AA);
390
+ computeAliasSet (L, *Preheader, *CurAST.get ());
391
+ }
392
+
335
393
// Note that we don't pass SCEV here because it is only used to invalidate
336
394
// loops in SCEV and we don't preserve (or request) SCEV at all making that
337
395
// unnecessary.
338
396
Changed |= sinkLoopInvariantInstructions (L, AA, LI, DT, BFI,
339
- /* ScalarEvolution*/ nullptr );
397
+ /* ScalarEvolution*/ nullptr ,
398
+ CurAST.get (), MSSA);
340
399
} while (!PreorderLoops.empty ());
341
400
342
401
if (!Changed)
343
402
return PreservedAnalyses::all ();
344
403
345
404
PreservedAnalyses PA;
346
405
PA.preserveSet <CFGAnalyses>();
406
+
407
+ if (MSSA) {
408
+ PA.preserve <MemorySSAAnalysis>();
409
+
410
+ if (VerifyMemorySSA)
411
+ MSSA->verifyMemorySSA ();
412
+ }
413
+
347
414
return PA;
348
415
}
349
416
@@ -358,19 +425,46 @@ struct LegacyLoopSinkPass : public LoopPass {
358
425
if (skipLoop (L))
359
426
return false ;
360
427
428
+ BasicBlock *Preheader = L->getLoopPreheader ();
429
+ if (!Preheader)
430
+ return false ;
431
+
432
+ // Enable LoopSink only when runtime profile is available.
433
+ // With static profile, the sinking decision may be sub-optimal.
434
+ if (!Preheader->getParent ()->hasProfileData ())
435
+ return false ;
436
+
437
+ AAResults &AA = getAnalysis<AAResultsWrapperPass>().getAAResults ();
361
438
auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
362
- return sinkLoopInvariantInstructions (
363
- *L, getAnalysis<AAResultsWrapperPass>().getAAResults (),
364
- getAnalysis<LoopInfoWrapperPass>().getLoopInfo (),
439
+ std::unique_ptr<AliasSetTracker> CurAST;
440
+ MemorySSA *MSSA = nullptr ;
441
+ if (EnableMSSAInLegacyLoopSink)
442
+ MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA ();
443
+ else {
444
+ CurAST = std::make_unique<AliasSetTracker>(AA);
445
+ computeAliasSet (*L, *Preheader, *CurAST.get ());
446
+ }
447
+
448
+ bool Changed = sinkLoopInvariantInstructions (
449
+ *L, AA, getAnalysis<LoopInfoWrapperPass>().getLoopInfo (),
365
450
getAnalysis<DominatorTreeWrapperPass>().getDomTree (),
366
451
getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI (),
367
- SE ? &SE->getSE () : nullptr );
452
+ SE ? &SE->getSE () : nullptr , CurAST.get (), MSSA);
453
+
454
+ if (MSSA && VerifyMemorySSA)
455
+ MSSA->verifyMemorySSA ();
456
+
457
+ return Changed;
368
458
}
369
459
370
460
void getAnalysisUsage (AnalysisUsage &AU) const override {
371
461
AU.setPreservesCFG ();
372
462
AU.addRequired <BlockFrequencyInfoWrapperPass>();
373
463
getLoopAnalysisUsage (AU);
464
+ if (EnableMSSAInLegacyLoopSink) {
465
+ AU.addRequired <MemorySSAWrapperPass>();
466
+ AU.addPreserved <MemorySSAWrapperPass>();
467
+ }
374
468
}
375
469
};
376
470
}
@@ -380,6 +474,7 @@ INITIALIZE_PASS_BEGIN(LegacyLoopSinkPass, "loop-sink", "Loop Sink", false,
380
474
false )
381
475
INITIALIZE_PASS_DEPENDENCY(LoopPass)
382
476
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
477
+ INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
383
478
INITIALIZE_PASS_END(LegacyLoopSinkPass, " loop-sink" , " Loop Sink" , false , false )
384
479
385
480
Pass *llvm::createLoopSinkPass() { return new LegacyLoopSinkPass (); }
0 commit comments