diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LICM.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 273 |
1 files changed, 61 insertions, 212 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 8c33045c23802..1a22edaf87266 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -46,6 +46,7 @@ #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" +#include "llvm/Analysis/MustExecute.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" @@ -69,6 +70,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" +#include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" @@ -151,11 +153,11 @@ static bool isSafeToExecuteUnconditionally(Instruction &Inst, const Instruction *CtxI = nullptr); static bool pointerInvalidatedByLoop(MemoryLocation MemLoc, AliasSetTracker *CurAST, Loop *CurLoop, - AliasAnalysis *AA); + AAResults *AA); static bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU, Loop *CurLoop, SinkAndHoistLICMFlags &Flags); -static Instruction *CloneInstructionInExitBlock( +static Instruction *cloneInstructionInExitBlock( Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU); @@ -168,27 +170,24 @@ static void moveInstructionBefore(Instruction &I, Instruction &Dest, namespace { struct LoopInvariantCodeMotion { - using ASTrackerMapTy = DenseMap<Loop *, std::unique_ptr<AliasSetTracker>>; - bool runOnLoop(Loop *L, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT, + bool runOnLoop(Loop *L, AAResults *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; std::unique_ptr<AliasSetTracker> - collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AliasAnalysis *AA); + collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AAResults *AA); std::unique_ptr<AliasSetTracker> - collectAliasInfoForLoopWithMSSA(Loop *L, AliasAnalysis *AA, + collectAliasInfoForLoopWithMSSA(Loop *L, AAResults *AA, MemorySSAUpdater *MSSAU); }; @@ -202,13 +201,8 @@ struct LegacyLICMPass : public LoopPass { } 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 @@ -226,7 +220,7 @@ struct LegacyLICMPass : public LoopPass { *L->getHeader()->getParent()), &getAnalysis<TargetTransformInfoWrapperPass>().getTTI( *L->getHeader()->getParent()), - SE ? &SE->getSE() : nullptr, MSSA, &ORE, false); + SE ? &SE->getSE() : nullptr, MSSA, &ORE); } /// This transformation requires natural loop information & requires that @@ -244,53 +238,21 @@ struct LegacyLICMPass : public LoopPass { 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 PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { - const auto &FAM = - AM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR).getManager(); - Function *F = L.getHeader()->getParent(); - - auto *ORE = FAM.getCachedResult<OptimizationRemarkEmitterAnalysis>(*F); - // FIXME: This should probably be optional rather than required. - if (!ORE) - report_fatal_error("LICM: OptimizationRemarkEmitterAnalysis not " - "cached at a higher level"); + // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis + // pass. Function analyses need to be preserved across loop transformations + // but ORE cannot be preserved (see comment before the pass definition). + OptimizationRemarkEmitter ORE(L.getHeader()->getParent()); 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(); @@ -322,13 +284,10 @@ Pass *llvm::createLICMPass(unsigned LicmMssaOptCap, /// 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, + Loop *L, AAResults *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."); @@ -372,7 +331,7 @@ bool LoopInvariantCodeMotion::runOnLoop( BasicBlock *Preheader = L->getLoopPreheader(); // Compute loop safety information. - ICFLoopSafetyInfo SafetyInfo(DT); + ICFLoopSafetyInfo SafetyInfo; SafetyInfo.computeLoopSafetyInfo(L); // We want to visit all of the instructions in this loop... that are not parts @@ -476,11 +435,6 @@ bool LoopInvariantCodeMotion::runOnLoop( 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(); @@ -494,7 +448,7 @@ bool LoopInvariantCodeMotion::runOnLoop( /// first order w.r.t the DominatorTree. This allows us to visit uses before /// definitions, allowing us to sink a loop body in one pass without iteration. /// -bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, +bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT, TargetLibraryInfo *TLI, TargetTransformInfo *TTI, Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, @@ -529,6 +483,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, // used in the loop, instead, just delete it. if (isInstructionTriviallyDead(&I, TLI)) { LLVM_DEBUG(dbgs() << "LICM deleting dead inst: " << I << '\n'); + salvageKnowledge(&I); salvageDebugInfo(I); ++II; eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); @@ -542,13 +497,14 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, // operands of the instruction are loop invariant. // bool FreeInLoop = false; - if (isNotUsedOrFreeInLoop(I, CurLoop, SafetyInfo, TTI, FreeInLoop) && + if (!I.mayHaveSideEffects() && + isNotUsedOrFreeInLoop(I, CurLoop, SafetyInfo, TTI, FreeInLoop) && canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags, - ORE) && - !I.mayHaveSideEffects()) { + ORE)) { if (sink(I, LI, DT, CurLoop, SafetyInfo, MSSAU, ORE)) { if (!FreeInLoop) { ++II; + salvageDebugInfo(I); eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); } Changed = true; @@ -790,47 +746,12 @@ public: }; } // namespace - -/// Return true if we know how to rewrite all uses of the given alloca after -/// hoisting it out of the loop. The main concerns are a) potential captures -/// and b) invariant.start markers which don't capture, but are no longer -/// valid w/o a corresponding invariant.end. -static bool canRewriteUsesOfAlloca(AllocaInst &AI) { - // TODO: This looks a lot like capture tracking, but we need to remove any - // invariant starts if we extend the lifetime of the alloca by hoisting it. - // We should probably refactor capture tracking into a form which allows us - // to reuse the relevant bits and remove the duplicated logic here. - - SmallVector<Use *, 16> Worklist; - for (Use &U : AI.uses()) - Worklist.push_back(&U); - - unsigned NumUsesExplored = 0; - while (!Worklist.empty()) { - Use *U = Worklist.pop_back_val(); - Instruction *I = cast<Instruction>(U->getUser()); - NumUsesExplored++; - if (NumUsesExplored > DefaultMaxUsesToExplore) - return false; - // Non capturing, terminating uses - if (isa<LoadInst>(I) || - (isa<StoreInst>(I) && U->getOperandNo() == 1)) - continue; - // Non capturing, non-terminating - if (!isa<BitCastInst>(I) && !isa<GetElementPtrInst>(I)) - return false; - for (Use &U : I->uses()) - Worklist.push_back(&U); - } - return true; -} - /// Walk the specified region of the CFG (defined by all blocks dominated by /// the specified block, and that are in the current loop) in depth first /// order w.r.t the DominatorTree. This allows us to visit definitions before /// uses, allowing us to hoist a loop body in one pass without iteration. /// -bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, +bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo, @@ -901,9 +822,8 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, // Attempt to remove floating point division out of the loop by // converting it to a reciprocal multiplication. - if (I.getOpcode() == Instruction::FDiv && - CurLoop->isLoopInvariant(I.getOperand(1)) && - I.hasAllowReciprocal()) { + if (I.getOpcode() == Instruction::FDiv && I.hasAllowReciprocal() && + CurLoop->isLoopInvariant(I.getOperand(1))) { auto Divisor = I.getOperand(1); auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0); auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor); @@ -945,16 +865,6 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, continue; } - if (isa<AllocaInst>(&I) && - SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop) && - canRewriteUsesOfAlloca(cast<AllocaInst>(I))) { - hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo, - MSSAU, SE, ORE); - HoistedInstructions.push_back(&I); - Changed = true; - continue; - } - if (PHINode *PN = dyn_cast<PHINode>(&I)) { if (CFH.canHoistPHI(PN)) { // Redirect incoming blocks first to ensure that we create hoisted @@ -1081,12 +991,12 @@ namespace { bool isHoistableAndSinkableInst(Instruction &I) { // Only these instructions are hoistable/sinkable. return (isa<LoadInst>(I) || isa<StoreInst>(I) || isa<CallInst>(I) || - isa<FenceInst>(I) || isa<CastInst>(I) || - isa<UnaryOperator>(I) || isa<BinaryOperator>(I) || - isa<SelectInst>(I) || isa<GetElementPtrInst>(I) || isa<CmpInst>(I) || + isa<FenceInst>(I) || isa<CastInst>(I) || isa<UnaryOperator>(I) || + isa<BinaryOperator>(I) || isa<SelectInst>(I) || + isa<GetElementPtrInst>(I) || isa<CmpInst>(I) || isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) || isa<ShuffleVectorInst>(I) || isa<ExtractValueInst>(I) || - isa<InsertValueInst>(I)); + isa<InsertValueInst>(I) || isa<FreezeInst>(I)); } /// Return true if all of the alias sets within this AST are known not to /// contain a Mod, or if MSSA knows thare are no MemoryDefs in the loop. @@ -1198,11 +1108,11 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, FunctionModRefBehavior Behavior = AA->getModRefBehavior(CI); if (Behavior == FMRB_DoesNotAccessMemory) return true; - if (AliasAnalysis::onlyReadsMemory(Behavior)) { + if (AAResults::onlyReadsMemory(Behavior)) { // A readonly argmemonly function only reads from memory pointed to by // it's arguments with arbitrary offsets. If we can prove there are no // writes to this memory in the loop, we can hoist or sink. - if (AliasAnalysis::onlyAccessesArgPointees(Behavior)) { + if (AAResults::onlyAccessesArgPointees(Behavior)) { // TODO: expand to writeable arguments for (Value *Op : CI->arg_operands()) if (Op->getType()->isPointerTy()) { @@ -1351,7 +1261,8 @@ static bool isFreeInLoop(const Instruction &I, const Loop *CurLoop, const TargetTransformInfo *TTI) { if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) { - if (TTI->getUserCost(GEP) != TargetTransformInfo::TCC_Free) + if (TTI->getUserCost(GEP, TargetTransformInfo::TCK_SizeAndLatency) != + TargetTransformInfo::TCC_Free) return false; // For a GEP, we cannot simply use getUserCost because currently it // optimistically assume that a GEP will fold into addressing mode @@ -1366,7 +1277,8 @@ static bool isFreeInLoop(const Instruction &I, const Loop *CurLoop, } return true; } else - return TTI->getUserCost(&I) == TargetTransformInfo::TCC_Free; + return TTI->getUserCost(&I, TargetTransformInfo::TCK_SizeAndLatency) == + TargetTransformInfo::TCC_Free; } /// Return true if the only users of this instruction are outside of @@ -1407,7 +1319,7 @@ static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop, return true; } -static Instruction *CloneInstructionInExitBlock( +static Instruction *cloneInstructionInExitBlock( Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU) { Instruction *New; @@ -1520,7 +1432,7 @@ static Instruction *sinkThroughTriviallyReplaceablePHI( if (It != SunkCopies.end()) New = It->second; else - New = SunkCopies[ExitBlock] = CloneInstructionInExitBlock( + New = SunkCopies[ExitBlock] = cloneInstructionInExitBlock( *I, *ExitBlock, *TPN, LI, SafetyInfo, MSSAU); return New; } @@ -1537,7 +1449,8 @@ static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo) { return false; for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { BasicBlock *BBPred = *PI; - if (isa<IndirectBrInst>(BBPred->getTerminator())) + if (isa<IndirectBrInst>(BBPred->getTerminator()) || + isa<CallBrInst>(BBPred->getTerminator())) return false; } return true; @@ -1857,7 +1770,7 @@ public: StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos); if (UnorderedAtomic) NewSI->setOrdering(AtomicOrdering::Unordered); - NewSI->setAlignment(MaybeAlign(Alignment)); + NewSI->setAlignment(Align(Alignment)); NewSI->setDebugLoc(DL); if (AATags) NewSI->setAAMetadata(AATags); @@ -1981,7 +1894,7 @@ bool llvm::promoteLoopAccessesToScalars( // We start with an alignment of one and try to find instructions that allow // us to prove better alignment. - unsigned Alignment = 1; + Align Alignment; // Keep track of which types of access we see bool SawUnorderedAtomic = false; bool SawNotAtomic = false; @@ -2029,10 +1942,7 @@ bool llvm::promoteLoopAccessesToScalars( SawUnorderedAtomic |= Load->isAtomic(); SawNotAtomic |= !Load->isAtomic(); - unsigned InstAlignment = Load->getAlignment(); - if (!InstAlignment) - InstAlignment = - MDL.getABITypeAlignment(Load->getType()); + Align InstAlignment = Load->getAlign(); // Note that proving a load safe to speculate requires proving // sufficient alignment at the target location. Proving it guaranteed @@ -2060,10 +1970,7 @@ bool llvm::promoteLoopAccessesToScalars( // already know that promotion is safe, since it may have higher // alignment than any other guaranteed stores, in which case we can // raise the alignment on the promoted store. - unsigned InstAlignment = Store->getAlignment(); - if (!InstAlignment) - InstAlignment = - MDL.getABITypeAlignment(Store->getValueOperand()->getType()); + Align InstAlignment = Store->getAlign(); if (!DereferenceableInPH || !SafeToInsertStore || (InstAlignment > Alignment)) { @@ -2090,8 +1997,7 @@ bool llvm::promoteLoopAccessesToScalars( if (!DereferenceableInPH) { DereferenceableInPH = isDereferenceableAndAlignedPointer( Store->getPointerOperand(), Store->getValueOperand()->getType(), - MaybeAlign(Store->getAlignment()), MDL, - Preheader->getTerminator(), DT); + Store->getAlign(), MDL, Preheader->getTerminator(), DT); } } else return false; // Not a load or store. @@ -2156,18 +2062,19 @@ bool llvm::promoteLoopAccessesToScalars( }); ++NumPromoted; - // Grab a debug location for the inserted loads/stores; given that the - // inserted loads/stores have little relation to the original loads/stores, - // this code just arbitrarily picks a location from one, since any debug - // location is better than none. - DebugLoc DL = LoopUses[0]->getDebugLoc(); + // Look at all the loop uses, and try to merge their locations. + std::vector<const DILocation *> LoopUsesLocs; + for (auto U : LoopUses) + LoopUsesLocs.push_back(U->getDebugLoc().get()); + auto DL = DebugLoc(DILocation::getMergedLocations(LoopUsesLocs)); // We use the SSAUpdater interface to insert phi nodes as required. SmallVector<PHINode *, 16> NewPHIs; SSAUpdater SSA(&NewPHIs); LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, *CurAST, MSSAU, *LI, DL, - Alignment, SawUnorderedAtomic, AATags, *SafetyInfo); + Alignment.value(), SawUnorderedAtomic, AATags, + *SafetyInfo); // Set up the preheader to have a definition of the value. It is the live-out // value from the preheader that uses in the loop will use. @@ -2176,8 +2083,8 @@ bool llvm::promoteLoopAccessesToScalars( SomePtr->getName() + ".promoted", Preheader->getTerminator()); if (SawUnorderedAtomic) PreheaderLoad->setOrdering(AtomicOrdering::Unordered); - PreheaderLoad->setAlignment(MaybeAlign(Alignment)); - PreheaderLoad->setDebugLoc(DL); + PreheaderLoad->setAlignment(Alignment); + PreheaderLoad->setDebugLoc(DebugLoc()); if (AATags) PreheaderLoad->setAAMetadata(AATags); SSA.AddAvailableValue(Preheader, PreheaderLoad); @@ -2206,41 +2113,13 @@ bool llvm::promoteLoopAccessesToScalars( /// 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); + AAResults *AA) { + 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); @@ -2254,46 +2133,16 @@ LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI, std::unique_ptr<AliasSetTracker> LoopInvariantCodeMotion::collectAliasInfoForLoopWithMSSA( - Loop *L, AliasAnalysis *AA, MemorySSAUpdater *MSSAU) { + Loop *L, AAResults *AA, MemorySSAUpdater *MSSAU) { auto *MSSA = MSSAU->getMemorySSA(); auto CurAST = std::make_unique<AliasSetTracker>(*AA, MSSA, L); CurAST->addAllInstructionsInLoopUsingMSSA(); 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) { + AAResults *AA) { // First check to see if any of the basic blocks in CurLoop invalidate *V. bool isInvalidatedAccordingToAST = CurAST->getAliasSetFor(MemLoc).isMod(); |