Use LoopAccessInfoManager directly instead of various GetLAA lambdas.
Depends on D134608.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D134609
void getAnalysisUsage(AnalysisUsage &AU) const override;
- /// Query the result of the loop access information for the loop \p L.
+ /// Return the proxy object for retrieving LoopAccessInfo for individual
+ /// loops.
///
/// If there is no cached result available run the analysis.
- const LoopAccessInfo &getInfo(Loop *L) { return LAIs->getInfo(*L); }
+ LoopAccessInfoManager &getLAIs() { return *LAIs; }
void releaseMemory() override {
// Invalidate the cache when the pass is freed.
/// induction variable and the different reduction variables.
class LoopVectorizationLegality {
public:
- LoopVectorizationLegality(
- Loop *L, PredicatedScalarEvolution &PSE, DominatorTree *DT,
- TargetTransformInfo *TTI, TargetLibraryInfo *TLI, AAResults *AA,
- Function *F, std::function<const LoopAccessInfo &(Loop &)> *GetLAA,
- LoopInfo *LI, OptimizationRemarkEmitter *ORE,
- LoopVectorizationRequirements *R, LoopVectorizeHints *H, DemandedBits *DB,
- AssumptionCache *AC, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
- : TheLoop(L), LI(LI), PSE(PSE), TTI(TTI), TLI(TLI), DT(DT),
- GetLAA(GetLAA), ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC),
- BFI(BFI), PSI(PSI) {}
+ LoopVectorizationLegality(Loop *L, PredicatedScalarEvolution &PSE,
+ DominatorTree *DT, TargetTransformInfo *TTI,
+ TargetLibraryInfo *TLI, AAResults *AA, Function *F,
+ LoopAccessInfoManager &LAIs, LoopInfo *LI,
+ OptimizationRemarkEmitter *ORE,
+ LoopVectorizationRequirements *R,
+ LoopVectorizeHints *H, DemandedBits *DB,
+ AssumptionCache *AC, BlockFrequencyInfo *BFI,
+ ProfileSummaryInfo *PSI)
+ : TheLoop(L), LI(LI), PSE(PSE), TTI(TTI), TLI(TLI), DT(DT), LAIs(LAIs),
+ ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC), BFI(BFI),
+ PSI(PSI) {}
/// ReductionList contains the reduction descriptors for all
/// of the reductions that were found in the loop.
DominatorTree *DT;
// LoopAccess analysis.
- std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
+ LoopAccessInfoManager &LAIs;
- // And the loop-accesses info corresponding to this loop. This pointer is
- // null until canVectorizeMemory sets it up.
const LoopAccessInfo *LAI = nullptr;
/// Interface to emit optimization remarks.
class DominatorTree;
class Function;
class Loop;
-class LoopAccessInfo;
+class LoopAccessInfoManager;
class LoopInfo;
class OptimizationRemarkEmitter;
class ProfileSummaryInfo;
DemandedBits *DB;
AAResults *AA;
AssumptionCache *AC;
- std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
+ LoopAccessInfoManager *LAIs;
OptimizationRemarkEmitter *ORE;
ProfileSummaryInfo *PSI;
runImpl(Function &F, ScalarEvolution &SE_, LoopInfo &LI_,
TargetTransformInfo &TTI_, DominatorTree &DT_,
BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_, DemandedBits &DB_,
- AAResults &AA_, AssumptionCache &AC_,
- std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
+ AAResults &AA_, AssumptionCache &AC_, LoopAccessInfoManager &LAIs_,
OptimizationRemarkEmitter &ORE_, ProfileSummaryInfo *PSI_);
bool processLoop(Loop *L);
class LoopDistributeForLoop {
public:
LoopDistributeForLoop(Loop *L, Function *F, LoopInfo *LI, DominatorTree *DT,
- ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)
- : L(L), F(F), LI(LI), DT(DT), SE(SE), ORE(ORE) {
+ ScalarEvolution *SE, LoopAccessInfoManager &LAIs,
+ OptimizationRemarkEmitter *ORE)
+ : L(L), F(F), LI(LI), DT(DT), SE(SE), LAIs(LAIs), ORE(ORE) {
setForced();
}
/// Try to distribute an inner-most loop.
- bool processLoop(std::function<const LoopAccessInfo &(Loop &)> &GetLAA) {
+ bool processLoop() {
assert(L->isInnermost() && "Only process inner loops.");
LLVM_DEBUG(dbgs() << "\nLDist: In \""
BasicBlock *PH = L->getLoopPreheader();
- LAI = &GetLAA(*L);
+ LAI = &LAIs.getInfo(*L);
// Currently, we only distribute to isolate the part of the loop with
// dependence cycles to enable partial vectorization.
const LoopAccessInfo *LAI = nullptr;
DominatorTree *DT;
ScalarEvolution *SE;
+ LoopAccessInfoManager &LAIs;
OptimizationRemarkEmitter *ORE;
/// Indicates whether distribution is forced to be enabled/disabled for
/// Shared implementation between new and old PMs.
static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
ScalarEvolution *SE, OptimizationRemarkEmitter *ORE,
- std::function<const LoopAccessInfo &(Loop &)> &GetLAA) {
+ LoopAccessInfoManager &LAIs) {
// Build up a worklist of inner-loops to vectorize. This is necessary as the
// act of distributing a loop creates new loops and can invalidate iterators
// across the loops.
// Now walk the identified inner loops.
bool Changed = false;
for (Loop *L : Worklist) {
- LoopDistributeForLoop LDL(L, &F, LI, DT, SE, ORE);
+ LoopDistributeForLoop LDL(L, &F, LI, DT, SE, LAIs, ORE);
// If distribution was forced for the specific loop to be
// enabled/disabled, follow that. Otherwise use the global flag.
if (LDL.isForced().value_or(EnableLoopDistribute))
- Changed |= LDL.processLoop(GetLAA);
+ Changed |= LDL.processLoop();
}
// Process each loop nest in the function.
return false;
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
- std::function<const LoopAccessInfo &(Loop &)> GetLAA =
- [&](Loop &L) -> const LoopAccessInfo & { return LAA->getInfo(&L); };
+ auto &LAIs = getAnalysis<LoopAccessLegacyAnalysis>().getLAIs();
- return runImpl(F, LI, DT, SE, ORE, GetLAA);
+ return runImpl(F, LI, DT, SE, ORE, LAIs);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
LoopAccessInfoManager &LAIs = AM.getResult<LoopAccessAnalysis>(F);
- std::function<const LoopAccessInfo &(Loop &)> GetLAA =
- [&](Loop &L) -> const LoopAccessInfo & { return LAIs.getInfo(L); };
-
- bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, GetLAA);
+ bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, LAIs);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
} // end anonymous namespace
-static bool
-eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
- ScalarEvolution *SE, AssumptionCache *AC,
- function_ref<const LoopAccessInfo &(Loop &)> GetLAI) {
+static bool eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI,
+ DominatorTree &DT,
+ BlockFrequencyInfo *BFI,
+ ProfileSummaryInfo *PSI,
+ ScalarEvolution *SE, AssumptionCache *AC,
+ LoopAccessInfoManager &LAIs) {
// Build up a worklist of inner-loops to transform to avoid iterator
// invalidation.
// FIXME: This logic comes from other passes that actually change the loop
if (!L->isRotatedForm() || !L->getExitingBlock())
continue;
// The actual work is performed by LoadEliminationForLoop.
- LoadEliminationForLoop LEL(L, &LI, GetLAI(*L), &DT, BFI, PSI);
+ LoadEliminationForLoop LEL(L, &LI, LAIs.getInfo(*L), &DT, BFI, PSI);
Changed |= LEL.processLoop();
}
return Changed;
return false;
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &LAA = getAnalysis<LoopAccessLegacyAnalysis>();
+ auto &LAIs = getAnalysis<LoopAccessLegacyAnalysis>().getLAIs();
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
auto *BFI = (PSI && PSI->hasProfileSummary()) ?
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
// Process each loop nest in the function.
- return eliminateLoadsAcrossLoops(
- F, LI, DT, BFI, PSI, SE, /*AC*/ nullptr,
- [&LAA](Loop &L) -> const LoopAccessInfo & { return LAA.getInfo(&L); });
+ return eliminateLoadsAcrossLoops(F, LI, DT, BFI, PSI, SE, /*AC*/ nullptr,
+ LAIs);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
&AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
LoopAccessInfoManager &LAIs = AM.getResult<LoopAccessAnalysis>(F);
- bool Changed = eliminateLoadsAcrossLoops(
- F, LI, DT, BFI, PSI, &SE, &AC,
- [&](Loop &L) -> const LoopAccessInfo & { return LAIs.getInfo(L); });
+ bool Changed = eliminateLoadsAcrossLoops(F, LI, DT, BFI, PSI, &SE, &AC, LAIs);
if (!Changed)
return PreservedAnalyses::all();
// LoopAccessInfo will take place only when it's necessary.
LoopVersioningLICM(AliasAnalysis *AA, ScalarEvolution *SE,
OptimizationRemarkEmitter *ORE,
- function_ref<const LoopAccessInfo &(Loop *)> GetLAI)
- : AA(AA), SE(SE), GetLAI(GetLAI),
- LoopDepthThreshold(LVLoopDepthThreshold),
+ LoopAccessInfoManager &LAIs)
+ : AA(AA), SE(SE), LAIs(LAIs), LoopDepthThreshold(LVLoopDepthThreshold),
InvariantThreshold(LVInvarThreshold), ORE(ORE) {}
bool runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT);
const LoopAccessInfo *LAI = nullptr;
// Proxy for retrieving LoopAccessInfo.
- function_ref<const LoopAccessInfo &(Loop *)> GetLAI;
+ LoopAccessInfoManager &LAIs;
// The current loop we are working on.
Loop *CurLoop = nullptr;
}
}
// Get LoopAccessInfo from current loop via the proxy.
- LAI = &GetLAI(CurLoop);
+ LAI = &LAIs.getInfo(*CurLoop);
// Check LoopAccessInfo for need of runtime check.
if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n");
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto &LAIs = getAnalysis<LoopAccessLegacyAnalysis>().getLAIs();
- auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
- return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(L);
- };
-
- return LoopVersioningLICM(AA, SE, ORE, GetLAI).runOnLoop(L, LI, DT);
+ return LoopVersioningLICM(AA, SE, ORE, LAIs).runOnLoop(L, LI, DT);
}
bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
OptimizationRemarkEmitter ORE(F);
LoopAccessInfoManager LAIs(*SE, *AA, *DT, *LI, nullptr);
- std::function<const LoopAccessInfo &(Loop *)> GetLAI =
- [&](Loop *L) -> const LoopAccessInfo & { return LAIs.getInfo(*L); };
- if (!LoopVersioningLICM(AA, SE, &ORE, GetLAI).runOnLoop(&L, LI, DT))
+ if (!LoopVersioningLICM(AA, SE, &ORE, LAIs).runOnLoop(&L, LI, DT))
return PreservedAnalyses::all();
return getLoopPassPreservedAnalyses();
}
}
namespace {
-bool runImpl(LoopInfo *LI, function_ref<const LoopAccessInfo &(Loop &)> GetLAA,
- DominatorTree *DT, ScalarEvolution *SE) {
+bool runImpl(LoopInfo *LI, LoopAccessInfoManager &LAIs, DominatorTree *DT,
+ ScalarEvolution *SE) {
// Build up a worklist of inner-loops to version. This is necessary as the
// act of versioning a loop creates new loops and can invalidate iterators
// across the loops.
if (!L->isLoopSimplifyForm() || !L->isRotatedForm() ||
!L->getExitingBlock())
continue;
- const LoopAccessInfo &LAI = GetLAA(*L);
+ const LoopAccessInfo &LAI = LAIs.getInfo(*L);
if (!LAI.hasConvergentOp() &&
(LAI.getNumRuntimePointerChecks() ||
!LAI.getPSE().getPredicate().isAlwaysTrue())) {
bool runOnFunction(Function &F) override {
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
- return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(&L);
- };
-
+ auto &LAIs = getAnalysis<LoopAccessLegacyAnalysis>().getLAIs();
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- return runImpl(LI, GetLAA, DT, SE);
+ return runImpl(LI, LAIs, DT, SE);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
FunctionAnalysisManager &AM) {
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
-
LoopAccessInfoManager &LAIs = AM.getResult<LoopAccessAnalysis>(F);
- auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
- return LAIs.getInfo(L);
- };
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- if (runImpl(&LI, GetLAA, &DT, &SE))
+ if (runImpl(&LI, LAIs, &DT, &SE))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
}
}
bool LoopVectorizationLegality::canVectorizeMemory() {
- LAI = &(*GetLAA)(*TheLoop);
+ LAI = &LAIs.getInfo(*TheLoop);
const OptimizationRemarkAnalysis *LAR = LAI->getReport();
if (LAR) {
ORE->emit([&]() {
auto *TLI = TLIP ? &TLIP->getTLI(F) : nullptr;
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
+ auto &LAIs = getAnalysis<LoopAccessLegacyAnalysis>().getLAIs();
auto *DB = &getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
- std::function<const LoopAccessInfo &(Loop &)> GetLAA =
- [&](Loop &L) -> const LoopAccessInfo & { return LAA->getInfo(&L); };
-
- return Impl.runImpl(F, *SE, *LI, *TTI, *DT, *BFI, TLI, *DB, *AA, *AC,
- GetLAA, *ORE, PSI).MadeAnyChange;
+ return Impl
+ .runImpl(F, *SE, *LI, *TTI, *DT, *BFI, TLI, *DB, *AA, *AC, LAIs, *ORE,
+ PSI)
+ .MadeAnyChange;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
// Check if it is legal to vectorize the loop.
LoopVectorizationRequirements Requirements;
- LoopVectorizationLegality LVL(L, PSE, DT, TTI, TLI, AA, F, GetLAA, LI, ORE,
+ LoopVectorizationLegality LVL(L, PSE, DT, TTI, TLI, AA, F, *LAIs, LI, ORE,
&Requirements, &Hints, DB, AC, BFI, PSI);
if (!LVL.canVectorize(EnableVPlanNativePath)) {
LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Cannot prove legality.\n");
Function &F, ScalarEvolution &SE_, LoopInfo &LI_, TargetTransformInfo &TTI_,
DominatorTree &DT_, BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_,
DemandedBits &DB_, AAResults &AA_, AssumptionCache &AC_,
- std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
- OptimizationRemarkEmitter &ORE_, ProfileSummaryInfo *PSI_) {
+ LoopAccessInfoManager &LAIs_, OptimizationRemarkEmitter &ORE_,
+ ProfileSummaryInfo *PSI_) {
SE = &SE_;
LI = &LI_;
TTI = &TTI_;
TLI = TLI_;
AA = &AA_;
AC = &AC_;
- GetLAA = &GetLAA_;
+ LAIs = &LAIs_;
DB = &DB_;
ORE = &ORE_;
PSI = PSI_;
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
LoopAccessInfoManager &LAIs = AM.getResult<LoopAccessAnalysis>(F);
- std::function<const LoopAccessInfo &(Loop &)> GetLAA =
- [&](Loop &L) -> const LoopAccessInfo & { return LAIs.getInfo(L); };
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
ProfileSummaryInfo *PSI =
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
LoopVectorizeResult Result =
- runImpl(F, SE, LI, TTI, DT, BFI, &TLI, DB, AA, AC, GetLAA, ORE, PSI);
+ runImpl(F, SE, LI, TTI, DT, BFI, &TLI, DB, AA, AC, LAIs, ORE, PSI);
if (!Result.MadeAnyChange)
return PreservedAnalyses::all();
PreservedAnalyses PA;