@@ -185,12 +185,6 @@ static void moveInstructionBefore(Instruction &I, Instruction &Dest,
185
185
ICFLoopSafetyInfo &SafetyInfo,
186
186
MemorySSAUpdater *MSSAU, ScalarEvolution *SE);
187
187
188
- static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
189
- function_ref<void (Instruction *)> Fn);
190
- static SmallVector<SmallSetVector<Value *, 8 >, 0 >
191
- collectPromotionCandidates (MemorySSA *MSSA, AliasAnalysis *AA, Loop *L,
192
- SmallVectorImpl<Instruction *> &MaybePromotable);
193
-
194
188
namespace {
195
189
struct LoopInvariantCodeMotion {
196
190
bool runOnLoop (Loop *L, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
@@ -209,6 +203,9 @@ struct LoopInvariantCodeMotion {
209
203
210
204
std::unique_ptr<AliasSetTracker>
211
205
collectAliasInfoForLoop (Loop *L, LoopInfo *LI, AAResults *AA);
206
+ std::unique_ptr<AliasSetTracker>
207
+ collectAliasInfoForLoopWithMSSA (Loop *L, AAResults *AA,
208
+ MemorySSAUpdater *MSSAU);
212
209
};
213
210
214
211
struct LegacyLICMPass : public LoopPass {
@@ -449,48 +446,31 @@ bool LoopInvariantCodeMotion::runOnLoop(
449
446
PredIteratorCache PIC;
450
447
451
448
bool Promoted = false ;
452
- if (CurAST.get ()) {
453
- // Loop over all of the alias sets in the tracker object.
454
- for (AliasSet &AS : *CurAST) {
455
- // We can promote this alias set if it has a store, if it is a "Must"
456
- // alias set, if the pointer is loop invariant, and if we are not
457
- // eliminating any volatile loads or stores.
458
- if (AS.isForwardingAliasSet () || !AS.isMod () || !AS.isMustAlias () ||
459
- !L->isLoopInvariant (AS.begin ()->getValue ()))
460
- continue ;
461
-
462
- assert (
463
- !AS.empty () &&
464
- " Must alias set should have at least one pointer element in it!" );
465
-
466
- SmallSetVector<Value *, 8 > PointerMustAliases;
467
- for (const auto &ASI : AS)
468
- PointerMustAliases.insert (ASI.getValue ());
469
-
470
- Promoted |= promoteLoopAccessesToScalars (
471
- PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, LI,
472
- DT, TLI, L, CurAST.get (), MSSAU.get (), &SafetyInfo, ORE);
473
- }
474
- } else {
475
- SmallVector<Instruction *, 16 > MaybePromotable;
476
- foreachMemoryAccess (MSSA, L, [&](Instruction *I) {
477
- MaybePromotable.push_back (I);
478
- });
479
-
480
- // Promoting one set of accesses may make the pointers for another set
481
- // loop invariant, so run this in a loop (with the MaybePromotable set
482
- // decreasing in size over time).
483
- bool LocalPromoted;
484
- do {
485
- LocalPromoted = false ;
486
- for (const SmallSetVector<Value *, 8 > &PointerMustAliases :
487
- collectPromotionCandidates (MSSA, AA, L, MaybePromotable)) {
488
- LocalPromoted |= promoteLoopAccessesToScalars (
489
- PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC,
490
- LI, DT, TLI, L, /* AST*/ nullptr , MSSAU.get (), &SafetyInfo, ORE);
491
- }
492
- Promoted |= LocalPromoted;
493
- } while (LocalPromoted);
449
+
450
+ // Build an AST using MSSA.
451
+ if (!CurAST.get ())
452
+ CurAST = collectAliasInfoForLoopWithMSSA (L, AA, MSSAU.get ());
453
+
454
+ // Loop over all of the alias sets in the tracker object.
455
+ for (AliasSet &AS : *CurAST) {
456
+ // We can promote this alias set if it has a store, if it is a "Must"
457
+ // alias set, if the pointer is loop invariant, and if we are not
458
+ // eliminating any volatile loads or stores.
459
+ if (AS.isForwardingAliasSet () || !AS.isMod () || !AS.isMustAlias () ||
460
+ !L->isLoopInvariant (AS.begin ()->getValue ()))
461
+ continue ;
462
+
463
+ assert (
464
+ !AS.empty () &&
465
+ " Must alias set should have at least one pointer element in it!" );
466
+
467
+ SmallSetVector<Value *, 8 > PointerMustAliases;
468
+ for (const auto &ASI : AS)
469
+ PointerMustAliases.insert (ASI.getValue ());
470
+
471
+ Promoted |= promoteLoopAccessesToScalars (
472
+ PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, LI,
473
+ DT, TLI, L, CurAST.get (), MSSAU.get (), &SafetyInfo, ORE);
494
474
}
495
475
496
476
// Once we have promoted values across the loop body we have to
@@ -2253,77 +2233,6 @@ bool llvm::promoteLoopAccessesToScalars(
2253
2233
return true ;
2254
2234
}
2255
2235
2256
- static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
2257
- function_ref<void (Instruction *)> Fn) {
2258
- for (const BasicBlock *BB : L->blocks ())
2259
- if (const auto *Accesses = MSSA->getBlockAccesses (BB))
2260
- for (const auto &Access : *Accesses)
2261
- if (const auto *MUD = dyn_cast<MemoryUseOrDef>(&Access))
2262
- Fn (MUD->getMemoryInst ());
2263
- }
2264
-
2265
- static SmallVector<SmallSetVector<Value *, 8 >, 0 >
2266
- collectPromotionCandidates (MemorySSA *MSSA, AliasAnalysis *AA, Loop *L,
2267
- SmallVectorImpl<Instruction *> &MaybePromotable) {
2268
- AliasSetTracker AST (*AA);
2269
-
2270
- auto IsPotentiallyPromotable = [L](const Instruction *I) {
2271
- if (const auto *SI = dyn_cast<StoreInst>(I))
2272
- return L->isLoopInvariant (SI->getPointerOperand ());
2273
- if (const auto *LI = dyn_cast<LoadInst>(I))
2274
- return L->isLoopInvariant (LI->getPointerOperand ());
2275
- return false ;
2276
- };
2277
-
2278
- // Populate AST with potentially promotable accesses and remove them from
2279
- // MaybePromotable, so they will not be checked again on the next iteration.
2280
- SmallPtrSet<Value *, 16 > AttemptingPromotion;
2281
- llvm::erase_if (MaybePromotable, [&](Instruction *I) {
2282
- if (IsPotentiallyPromotable (I)) {
2283
- AttemptingPromotion.insert (I);
2284
- AST.add (I);
2285
- return true ;
2286
- }
2287
- return false ;
2288
- });
2289
-
2290
- // We're only interested in must-alias sets that contain a mod.
2291
- SmallVector<const AliasSet *, 8 > Sets;
2292
- for (AliasSet &AS : AST)
2293
- if (!AS.isForwardingAliasSet () && AS.isMod () && AS.isMustAlias ())
2294
- Sets.push_back (&AS);
2295
-
2296
- if (Sets.empty ())
2297
- return {}; // Nothing to promote...
2298
-
2299
- // Discard any sets for which there is an aliasing non-promotable access.
2300
- foreachMemoryAccess (MSSA, L, [&](Instruction *I) {
2301
- if (AttemptingPromotion.contains (I))
2302
- return ;
2303
-
2304
- if (Optional<MemoryLocation> Loc = MemoryLocation::getOrNone (I)) {
2305
- llvm::erase_if (Sets, [&](const AliasSet *AS) {
2306
- return AS->aliasesPointer (Loc->Ptr , Loc->Size , Loc->AATags , *AA)
2307
- != NoAlias;
2308
- });
2309
- } else {
2310
- llvm::erase_if (Sets, [&](const AliasSet *AS) {
2311
- return AS->aliasesUnknownInst (I, *AA);
2312
- });
2313
- }
2314
- });
2315
-
2316
- SmallVector<SmallSetVector<Value *, 8 >, 0 > Result;
2317
- for (const AliasSet *Set : Sets) {
2318
- SmallSetVector<Value *, 8 > PointerMustAliases;
2319
- for (const auto &ASI : *Set)
2320
- PointerMustAliases.insert (ASI.getValue ());
2321
- Result.push_back (std::move (PointerMustAliases));
2322
- }
2323
-
2324
- return Result;
2325
- }
2326
-
2327
2236
// / Returns an owning pointer to an alias set which incorporates aliasing info
2328
2237
// / from L and all subloops of L.
2329
2238
std::unique_ptr<AliasSetTracker>
@@ -2344,6 +2253,15 @@ LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI,
2344
2253
return CurAST;
2345
2254
}
2346
2255
2256
+ std::unique_ptr<AliasSetTracker>
2257
+ LoopInvariantCodeMotion::collectAliasInfoForLoopWithMSSA (
2258
+ Loop *L, AAResults *AA, MemorySSAUpdater *MSSAU) {
2259
+ auto *MSSA = MSSAU->getMemorySSA ();
2260
+ auto CurAST = std::make_unique<AliasSetTracker>(*AA, MSSA, L);
2261
+ CurAST->addAllInstructionsInLoopUsingMSSA ();
2262
+ return CurAST;
2263
+ }
2264
+
2347
2265
static bool pointerInvalidatedByLoop (MemoryLocation MemLoc,
2348
2266
AliasSetTracker *CurAST, Loop *CurLoop,
2349
2267
AAResults *AA) {
0 commit comments