namespace {
struct LoopInvariantCodeMotion {
- using ASTrackerMapTy = DenseMap<Loop *, std::unique_ptr<AliasSetTracker>>;
bool runOnLoop(Loop *L, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT,
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
ScalarEvolution *SE, MemorySSA *MSSA,
- OptimizationRemarkEmitter *ORE, bool DeleteAST);
+ OptimizationRemarkEmitter *ORE);
- ASTrackerMapTy &getLoopToAliasSetMap() { return LoopToAliasSetMap; }
LoopInvariantCodeMotion(unsigned LicmMssaOptCap,
unsigned LicmMssaNoAccForPromotionCap)
: LicmMssaOptCap(LicmMssaOptCap),
LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap) {}
private:
- ASTrackerMapTy LoopToAliasSetMap;
unsigned LicmMssaOptCap;
unsigned LicmMssaNoAccForPromotionCap;
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
- if (skipLoop(L)) {
- // If we have run LICM on a previous loop but now we are skipping
- // (because we've hit the opt-bisect limit), we need to clear the
- // loop alias information.
- LICM.getLoopToAliasSetMap().clear();
+ if (skipLoop(L))
return false;
- }
auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
MemorySSA *MSSA = EnableMSSALoopDependency
*L->getHeader()->getParent()),
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
*L->getHeader()->getParent()),
- SE ? &SE->getSE() : nullptr, MSSA, &ORE, true);
+ SE ? &SE->getSE() : nullptr, MSSA, &ORE);
}
/// This transformation requires natural loop information & requires that
getLoopAnalysisUsage(AU);
}
- using llvm::Pass::doFinalization;
-
- bool doFinalization() override {
- auto &AliasSetMap = LICM.getLoopToAliasSetMap();
- // All loops in the AliasSetMap should be cleaned up already. The only case
- // where we fail to do so is if an outer loop gets deleted before LICM
- // visits it.
- assert(all_of(AliasSetMap,
- [](LoopInvariantCodeMotion::ASTrackerMapTy::value_type &KV) {
- return !KV.first->getParentLoop();
- }) &&
- "Didn't free loop alias sets");
- AliasSetMap.clear();
- return false;
- }
-
private:
LoopInvariantCodeMotion LICM;
-
- /// cloneBasicBlockAnalysis - Simple Analysis hook. Clone alias set info.
- void cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To,
- Loop *L) override;
-
- /// deleteAnalysisValue - Simple Analysis hook. Delete value V from alias
- /// set.
- void deleteAnalysisValue(Value *V, Loop *L) override;
-
- /// Simple Analysis hook. Delete loop L from alias set map.
- void deleteAnalysisLoop(Loop *L) override;
};
} // namespace
LoopInvariantCodeMotion LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap);
if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, &AR.TLI, &AR.TTI, &AR.SE,
- AR.MSSA, ORE, true))
+ AR.MSSA, ORE))
return PreservedAnalyses::all();
auto PA = getLoopPassPreservedAnalyses();
/// Hoist expressions out of the specified loop. Note, alias info for inner
/// loop is not preserved so it is not a good idea to run LICM multiple
/// times on one loop.
-/// We should delete AST for inner loops in the new pass manager to avoid
-/// memory leak.
-///
bool LoopInvariantCodeMotion::runOnLoop(
Loop *L, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT,
TargetLibraryInfo *TLI, TargetTransformInfo *TTI, ScalarEvolution *SE,
- MemorySSA *MSSA, OptimizationRemarkEmitter *ORE, bool DeleteAST) {
+ MemorySSA *MSSA, OptimizationRemarkEmitter *ORE) {
bool Changed = false;
assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form.");
assert((!L->getParentLoop() || L->getParentLoop()->isLCSSAForm(*DT)) &&
"Parent loop not left in LCSSA form after LICM!");
- // If this loop is nested inside of another one, save the alias information
- // for when we process the outer loop.
- if (!MSSAU.get() && CurAST.get() && L->getParentLoop() && !DeleteAST)
- LoopToAliasSetMap[L] = std::move(CurAST);
-
if (MSSAU.get() && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
/// Returns an owning pointer to an alias set which incorporates aliasing info
/// from L and all subloops of L.
-/// FIXME: In new pass manager, there is no helper function to handle loop
-/// analysis such as cloneBasicBlockAnalysis, so the AST needs to be recomputed
-/// from scratch for every loop. Hook up with the helper functions when
-/// available in the new pass manager to avoid redundant computation.
std::unique_ptr<AliasSetTracker>
LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI,
AliasAnalysis *AA) {
- std::unique_ptr<AliasSetTracker> CurAST;
- SmallVector<Loop *, 4> RecomputeLoops;
- for (Loop *InnerL : L->getSubLoops()) {
- auto MapI = LoopToAliasSetMap.find(InnerL);
- // If the AST for this inner loop is missing it may have been merged into
- // some other loop's AST and then that loop unrolled, and so we need to
- // recompute it.
- if (MapI == LoopToAliasSetMap.end()) {
- RecomputeLoops.push_back(InnerL);
- continue;
- }
- std::unique_ptr<AliasSetTracker> InnerAST = std::move(MapI->second);
+ auto CurAST = std::make_unique<AliasSetTracker>(*AA);
- if (CurAST) {
- // What if InnerLoop was modified by other passes ?
- // Once we've incorporated the inner loop's AST into ours, we don't need
- // the subloop's anymore.
- CurAST->add(*InnerAST);
- } else {
- CurAST = std::move(InnerAST);
- }
- LoopToAliasSetMap.erase(MapI);
- }
- if (!CurAST)
- CurAST = std::make_unique<AliasSetTracker>(*AA);
-
- // Add everything from the sub loops that are no longer directly available.
- for (Loop *InnerL : RecomputeLoops)
+ // Add everything from all the sub loops.
+ for (Loop *InnerL : L->getSubLoops())
for (BasicBlock *BB : InnerL->blocks())
CurAST->add(*BB);
return CurAST;
}
-/// Simple analysis hook. Clone alias set info.
-///
-void LegacyLICMPass::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To,
- Loop *L) {
- auto ASTIt = LICM.getLoopToAliasSetMap().find(L);
- if (ASTIt == LICM.getLoopToAliasSetMap().end())
- return;
-
- ASTIt->second->copyValue(From, To);
-}
-
-/// Simple Analysis hook. Delete value V from alias set
-///
-void LegacyLICMPass::deleteAnalysisValue(Value *V, Loop *L) {
- auto ASTIt = LICM.getLoopToAliasSetMap().find(L);
- if (ASTIt == LICM.getLoopToAliasSetMap().end())
- return;
-
- ASTIt->second->deleteValue(V);
-}
-
-/// Simple Analysis hook. Delete value L from alias set map.
-///
-void LegacyLICMPass::deleteAnalysisLoop(Loop *L) {
- if (!LICM.getLoopToAliasSetMap().count(L))
- return;
-
- LICM.getLoopToAliasSetMap().erase(L);
-}
-
static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
AliasSetTracker *CurAST, Loop *CurLoop,
AliasAnalysis *AA) {