Skip to content

Commit 2948242

Browse files
committed
Revert "[LICM] Make promotion faster"
Revert 3d8f842 Revision triggers a miscompile sinking a store incorrectly outside a threading loop. Detected by tsan. Reverting while investigating. Differential Revision: https://reviews.llvm.org/D89264
1 parent e1928f0 commit 2948242

File tree

3 files changed

+54
-120
lines changed

3 files changed

+54
-120
lines changed

llvm/include/llvm/Analysis/AliasSetTracker.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "llvm/ADT/DenseMapInfo.h"
2121
#include "llvm/ADT/ilist.h"
2222
#include "llvm/ADT/ilist_node.h"
23-
#include "llvm/Analysis/AliasAnalysis.h"
2423
#include "llvm/Analysis/MemoryLocation.h"
2524
#include "llvm/IR/Instruction.h"
2625
#include "llvm/IR/Metadata.h"
@@ -39,6 +38,8 @@ class AAResults;
3938
class AliasSetTracker;
4039
class BasicBlock;
4140
class LoadInst;
41+
class Loop;
42+
class MemorySSA;
4243
class AnyMemSetInst;
4344
class AnyMemTransferInst;
4445
class raw_ostream;
@@ -342,6 +343,8 @@ class AliasSetTracker {
342343
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
343344

344345
AAResults &AA;
346+
MemorySSA *MSSA = nullptr;
347+
Loop *L = nullptr;
345348
ilist<AliasSet> AliasSets;
346349

347350
using PointerMapType = DenseMap<ASTCallbackVH, AliasSet::PointerRec *,
@@ -354,6 +357,8 @@ class AliasSetTracker {
354357
/// Create an empty collection of AliasSets, and use the specified alias
355358
/// analysis object to disambiguate load and store addresses.
356359
explicit AliasSetTracker(AAResults &AA) : AA(AA) {}
360+
explicit AliasSetTracker(AAResults &AA, MemorySSA *MSSA, Loop *L)
361+
: AA(AA), MSSA(MSSA), L(L) {}
357362
~AliasSetTracker() { clear(); }
358363

359364
/// These methods are used to add different types of instructions to the alias
@@ -378,6 +383,7 @@ class AliasSetTracker {
378383
void add(BasicBlock &BB); // Add all instructions in basic block
379384
void add(const AliasSetTracker &AST); // Add alias relations from another AST
380385
void addUnknown(Instruction *I);
386+
void addAllInstructionsInLoopUsingMSSA();
381387

382388
void clear();
383389

llvm/lib/Analysis/AliasSetTracker.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Analysis/GuardUtils.h"
1515
#include "llvm/Analysis/LoopInfo.h"
1616
#include "llvm/Analysis/MemoryLocation.h"
17+
#include "llvm/Analysis/MemorySSA.h"
1718
#include "llvm/Config/llvm-config.h"
1819
#include "llvm/IR/Constants.h"
1920
#include "llvm/IR/DataLayout.h"
@@ -534,6 +535,15 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
534535
}
535536
}
536537

538+
void AliasSetTracker::addAllInstructionsInLoopUsingMSSA() {
539+
assert(MSSA && L && "MSSA and L must be available");
540+
for (const BasicBlock *BB : L->blocks())
541+
if (auto *Accesses = MSSA->getBlockAccesses(BB))
542+
for (auto &Access : *Accesses)
543+
if (auto *MUD = dyn_cast<MemoryUseOrDef>(&Access))
544+
add(MUD->getMemoryInst());
545+
}
546+
537547
// deleteValue method - This method is used to remove a pointer value from the
538548
// AliasSetTracker entirely. It should be used when an instruction is deleted
539549
// from the program to update the AST. If you don't use this, you would have

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 37 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,6 @@ static void moveInstructionBefore(Instruction &I, Instruction &Dest,
185185
ICFLoopSafetyInfo &SafetyInfo,
186186
MemorySSAUpdater *MSSAU, ScalarEvolution *SE);
187187

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-
194188
namespace {
195189
struct LoopInvariantCodeMotion {
196190
bool runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
@@ -209,6 +203,9 @@ struct LoopInvariantCodeMotion {
209203

210204
std::unique_ptr<AliasSetTracker>
211205
collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AAResults *AA);
206+
std::unique_ptr<AliasSetTracker>
207+
collectAliasInfoForLoopWithMSSA(Loop *L, AAResults *AA,
208+
MemorySSAUpdater *MSSAU);
212209
};
213210

214211
struct LegacyLICMPass : public LoopPass {
@@ -449,48 +446,31 @@ bool LoopInvariantCodeMotion::runOnLoop(
449446
PredIteratorCache PIC;
450447

451448
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);
494474
}
495475

496476
// Once we have promoted values across the loop body we have to
@@ -2253,77 +2233,6 @@ bool llvm::promoteLoopAccessesToScalars(
22532233
return true;
22542234
}
22552235

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-
23272236
/// Returns an owning pointer to an alias set which incorporates aliasing info
23282237
/// from L and all subloops of L.
23292238
std::unique_ptr<AliasSetTracker>
@@ -2344,6 +2253,15 @@ LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI,
23442253
return CurAST;
23452254
}
23462255

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+
23472265
static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
23482266
AliasSetTracker *CurAST, Loop *CurLoop,
23492267
AAResults *AA) {

0 commit comments

Comments
 (0)