diff options
Diffstat (limited to 'gnu/llvm/lib/Transforms/Scalar/LICM.cpp')
| -rw-r--r-- | gnu/llvm/lib/Transforms/Scalar/LICM.cpp | 779 |
1 files changed, 424 insertions, 355 deletions
diff --git a/gnu/llvm/lib/Transforms/Scalar/LICM.cpp b/gnu/llvm/lib/Transforms/Scalar/LICM.cpp index 8923ff74253..cdd17fc516a 100644 --- a/gnu/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/gnu/llvm/lib/Transforms/Scalar/LICM.cpp @@ -30,15 +30,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/LICM.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/LoopPassManager.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -56,183 +60,173 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include <algorithm> +#include <utility> using namespace llvm; #define DEBUG_TYPE "licm" -STATISTIC(NumSunk , "Number of instructions sunk out of loop"); -STATISTIC(NumHoisted , "Number of instructions hoisted out of loop"); +STATISTIC(NumSunk, "Number of instructions sunk out of loop"); +STATISTIC(NumHoisted, "Number of instructions hoisted out of loop"); STATISTIC(NumMovedLoads, "Number of load insts hoisted or sunk"); STATISTIC(NumMovedCalls, "Number of call insts hoisted or sunk"); -STATISTIC(NumPromoted , "Number of memory locations promoted to registers"); +STATISTIC(NumPromoted, "Number of memory locations promoted to registers"); static cl::opt<bool> -DisablePromotion("disable-licm-promotion", cl::Hidden, - cl::desc("Disable memory promotion in LICM pass")); + DisablePromotion("disable-licm-promotion", cl::Hidden, + cl::desc("Disable memory promotion in LICM pass")); static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI); static bool isNotUsedInLoop(const Instruction &I, const Loop *CurLoop, - const LICMSafetyInfo *SafetyInfo); -static bool hoist(Instruction &I, BasicBlock *Preheader); + const LoopSafetyInfo *SafetyInfo); +static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, + const LoopSafetyInfo *SafetyInfo); static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT, const Loop *CurLoop, AliasSetTracker *CurAST, - const LICMSafetyInfo *SafetyInfo); -static bool isGuaranteedToExecute(const Instruction &Inst, - const DominatorTree *DT, - const Loop *CurLoop, - const LICMSafetyInfo *SafetyInfo); + const LoopSafetyInfo *SafetyInfo); static bool isSafeToExecuteUnconditionally(const Instruction &Inst, const DominatorTree *DT, - const TargetLibraryInfo *TLI, const Loop *CurLoop, - const LICMSafetyInfo *SafetyInfo, + const LoopSafetyInfo *SafetyInfo, const Instruction *CtxI = nullptr); static bool pointerInvalidatedByLoop(Value *V, uint64_t Size, - const AAMDNodes &AAInfo, + const AAMDNodes &AAInfo, AliasSetTracker *CurAST); static Instruction * CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, - const LICMSafetyInfo *SafetyInfo); + const LoopSafetyInfo *SafetyInfo); static bool canSinkOrHoistInst(Instruction &I, AliasAnalysis *AA, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, AliasSetTracker *CurAST, - LICMSafetyInfo *SafetyInfo); + LoopSafetyInfo *SafetyInfo); namespace { - struct LICM : public LoopPass { - static char ID; // Pass identification, replacement for typeid - LICM() : LoopPass(ID) { - initializeLICMPass(*PassRegistry::getPassRegistry()); - } +struct LoopInvariantCodeMotion { + bool runOnLoop(Loop *L, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT, + TargetLibraryInfo *TLI, ScalarEvolution *SE, bool DeleteAST); - bool runOnLoop(Loop *L, LPPassManager &LPM) override; - - /// This transformation requires natural loop information & requires that - /// loop preheaders be inserted into the CFG... - /// - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - AU.addRequired<DominatorTreeWrapperPass>(); - AU.addRequired<LoopInfoWrapperPass>(); - AU.addRequiredID(LoopSimplifyID); - AU.addPreservedID(LoopSimplifyID); - AU.addRequiredID(LCSSAID); - AU.addPreservedID(LCSSAID); - AU.addRequired<AAResultsWrapperPass>(); - AU.addPreserved<AAResultsWrapperPass>(); - AU.addPreserved<BasicAAWrapperPass>(); - AU.addPreserved<GlobalsAAWrapperPass>(); - AU.addPreserved<ScalarEvolutionWrapperPass>(); - AU.addPreserved<SCEVAAWrapperPass>(); - AU.addRequired<TargetLibraryInfoWrapperPass>(); - } + DenseMap<Loop *, AliasSetTracker *> &getLoopToAliasSetMap() { + return LoopToAliasSetMap; + } + +private: + DenseMap<Loop *, AliasSetTracker *> LoopToAliasSetMap; - using llvm::Pass::doFinalization; + AliasSetTracker *collectAliasInfoForLoop(Loop *L, LoopInfo *LI, + AliasAnalysis *AA); +}; + +struct LegacyLICMPass : public LoopPass { + static char ID; // Pass identification, replacement for typeid + LegacyLICMPass() : LoopPass(ID) { + initializeLegacyLICMPassPass(*PassRegistry::getPassRegistry()); + } - bool doFinalization() override { - assert(LoopToAliasSetMap.empty() && "Didn't free loop alias sets"); + bool runOnLoop(Loop *L, LPPassManager &LPM) override { + if (skipLoop(L)) return false; - } - private: - AliasAnalysis *AA; // Current AliasAnalysis information - LoopInfo *LI; // Current LoopInfo - DominatorTree *DT; // Dominator Tree for the current Loop. + auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>(); + return LICM.runOnLoop(L, + &getAnalysis<AAResultsWrapperPass>().getAAResults(), + &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(), + &getAnalysis<DominatorTreeWrapperPass>().getDomTree(), + &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(), + SE ? &SE->getSE() : nullptr, false); + } - TargetLibraryInfo *TLI; // TargetLibraryInfo for constant folding. + /// This transformation requires natural loop information & requires that + /// loop preheaders be inserted into the CFG... + /// + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + AU.addRequired<TargetLibraryInfoWrapperPass>(); + getLoopAnalysisUsage(AU); + } - // State that is updated as we process loops. - bool Changed; // Set to true when we change anything. - BasicBlock *Preheader; // The preheader block of the current loop... - Loop *CurLoop; // The current loop we are working on... - AliasSetTracker *CurAST; // AliasSet information for the current loop... - DenseMap<Loop*, AliasSetTracker*> LoopToAliasSetMap; + using llvm::Pass::doFinalization; - /// cloneBasicBlockAnalysis - Simple Analysis hook. Clone alias set info. - void cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, - Loop *L) override; + bool doFinalization() override { + assert(LICM.getLoopToAliasSetMap().empty() && + "Didn't free loop alias sets"); + return false; + } - /// deleteAnalysisValue - Simple Analysis hook. Delete value V from alias - /// set. - void deleteAnalysisValue(Value *V, Loop *L) override; +private: + LoopInvariantCodeMotion LICM; - /// Simple Analysis hook. Delete loop L from alias set map. - void deleteAnalysisLoop(Loop *L) override; - }; + /// 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; +}; +} + +PreservedAnalyses LICMPass::run(Loop &L, AnalysisManager<Loop> &AM) { + const auto &FAM = + AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager(); + Function *F = L.getHeader()->getParent(); + + auto *AA = FAM.getCachedResult<AAManager>(*F); + auto *LI = FAM.getCachedResult<LoopAnalysis>(*F); + auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F); + auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F); + auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F); + assert((AA && LI && DT && TLI && SE) && "Analyses for LICM not available"); + + LoopInvariantCodeMotion LICM; + + if (!LICM.runOnLoop(&L, AA, LI, DT, TLI, SE, true)) + return PreservedAnalyses::all(); + + // FIXME: There is no setPreservesCFG in the new PM. When that becomes + // available, it should be used here. + return getLoopPassPreservedAnalyses(); } -char LICM::ID = 0; -INITIALIZE_PASS_BEGIN(LICM, "licm", "Loop Invariant Code Motion", false, false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopSimplify) -INITIALIZE_PASS_DEPENDENCY(LCSSA) -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) +char LegacyLICMPass::ID = 0; +INITIALIZE_PASS_BEGIN(LegacyLICMPass, "licm", "Loop Invariant Code Motion", + false, false) +INITIALIZE_PASS_DEPENDENCY(LoopPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) -INITIALIZE_PASS_END(LICM, "licm", "Loop Invariant Code Motion", false, false) +INITIALIZE_PASS_END(LegacyLICMPass, "licm", "Loop Invariant Code Motion", false, + false) -Pass *llvm::createLICMPass() { return new LICM(); } +Pass *llvm::createLICMPass() { return new LegacyLICMPass(); } /// 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 LICM::runOnLoop(Loop *L, LPPassManager &LPM) { - if (skipOptnoneFunction(L)) - return false; - - Changed = false; - - // Get our Loop and Alias Analysis information... - LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); - DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - - TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); +bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AliasAnalysis *AA, + LoopInfo *LI, DominatorTree *DT, + TargetLibraryInfo *TLI, + ScalarEvolution *SE, bool DeleteAST) { + bool Changed = false; assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form."); - CurAST = new AliasSetTracker(*AA); - // Collect Alias info from subloops. - for (Loop *InnerL : L->getSubLoops()) { - AliasSetTracker *InnerAST = LoopToAliasSetMap[InnerL]; - assert(InnerAST && "Where is my AST?"); - - // What if InnerLoop was modified by other passes ? - CurAST->add(*InnerAST); - - // Once we've incorporated the inner loop's AST into ours, we don't need the - // subloop's anymore. - delete InnerAST; - LoopToAliasSetMap.erase(InnerL); - } - - CurLoop = L; + AliasSetTracker *CurAST = collectAliasInfoForLoop(L, LI, AA); // Get the preheader block to move instructions into... - Preheader = L->getLoopPreheader(); - - // Loop over the body of this loop, looking for calls, invokes, and stores. - // Because subloops have already been incorporated into AST, we skip blocks in - // subloops. - // - for (BasicBlock *BB : L->blocks()) { - if (LI->getLoopFor(BB) == L) // Ignore blocks in subloops. - CurAST->add(*BB); // Incorporate the specified basic block - } + BasicBlock *Preheader = L->getLoopPreheader(); // Compute loop safety information. - LICMSafetyInfo SafetyInfo; - computeLICMSafetyInfo(&SafetyInfo, CurLoop); + LoopSafetyInfo SafetyInfo; + computeLoopSafetyInfo(&SafetyInfo, L); // We want to visit all of the instructions in this loop... that are not parts // of our subloops (they have already had their invariants hoisted out of @@ -245,11 +239,11 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { // instructions, we perform another pass to hoist them out of the loop. // if (L->hasDedicatedExits()) - Changed |= sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, CurLoop, + Changed |= sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, L, CurAST, &SafetyInfo); if (Preheader) - Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, - CurLoop, CurAST, &SafetyInfo); + Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, L, + CurAST, &SafetyInfo); // Now that all loop invariants have been removed from the loop, promote any // memory references to scalars that we can. @@ -260,9 +254,8 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { // Loop over all of the alias sets in the tracker object. for (AliasSet &AS : *CurAST) - Changed |= promoteLoopAccessesToScalars(AS, ExitBlocks, InsertPts, - PIC, LI, DT, CurLoop, - CurAST, &SafetyInfo); + Changed |= promoteLoopAccessesToScalars( + AS, ExitBlocks, InsertPts, PIC, LI, DT, TLI, L, CurAST, &SafetyInfo); // Once we have promoted values across the loop body we have to recursively // reform LCSSA as any nested loop may now have values defined within the @@ -271,8 +264,7 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { // SSAUpdater strategy during promotion that was LCSSA aware and reformed // it as it went. if (Changed) { - auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>(); - formLCSSARecursively(*L, *DT, LI, SEWP ? &SEWP->getSE() : nullptr); + formLCSSARecursively(*L, *DT, LI, SE); } } @@ -283,50 +275,49 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { assert((!L->getParentLoop() || L->getParentLoop()->isLCSSAForm(*DT)) && "Parent loop not left in LCSSA form after LICM!"); - // Clear out loops state information for the next iteration - CurLoop = nullptr; - Preheader = nullptr; - // If this loop is nested inside of another one, save the alias information // for when we process the outer loop. - if (L->getParentLoop()) + if (L->getParentLoop() && !DeleteAST) LoopToAliasSetMap[L] = CurAST; else delete CurAST; + + if (Changed && SE) + SE->forgetLoopDispositions(L); return Changed; } /// Walk the specified region of the CFG (defined by all blocks dominated by -/// the specified block, and that are in the current loop) in reverse depth +/// the specified block, and that are in the current loop) in reverse depth /// 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, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, - AliasSetTracker *CurAST, LICMSafetyInfo *SafetyInfo) { + AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo) { // Verify inputs. - assert(N != nullptr && AA != nullptr && LI != nullptr && - DT != nullptr && CurLoop != nullptr && CurAST != nullptr && - SafetyInfo != nullptr && "Unexpected input to sinkRegion"); + assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr && + CurLoop != nullptr && CurAST != nullptr && SafetyInfo != nullptr && + "Unexpected input to sinkRegion"); - // Set changed as false. - bool Changed = false; - // Get basic block BasicBlock *BB = N->getBlock(); // If this subregion is not in the top level loop at all, exit. - if (!CurLoop->contains(BB)) return Changed; + if (!CurLoop->contains(BB)) + return false; // We are processing blocks in reverse dfo, so process children first. - const std::vector<DomTreeNode*> &Children = N->getChildren(); + bool Changed = false; + const std::vector<DomTreeNode *> &Children = N->getChildren(); for (DomTreeNode *Child : Children) Changed |= sinkRegion(Child, AA, LI, DT, TLI, CurLoop, CurAST, SafetyInfo); // Only need to process the contents of this block if it is not part of a // subloop (which would already have been processed). - if (inSubLoop(BB,CurLoop,LI)) return Changed; + if (inSubLoop(BB, CurLoop, LI)) + return Changed; - for (BasicBlock::iterator II = BB->end(); II != BB->begin(); ) { + for (BasicBlock::iterator II = BB->end(); II != BB->begin();) { Instruction &I = *--II; // If the instruction is dead, we would try to sink it because it isn't used @@ -361,21 +352,23 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, /// bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, - AliasSetTracker *CurAST, LICMSafetyInfo *SafetyInfo) { + AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo) { // Verify inputs. - assert(N != nullptr && AA != nullptr && LI != nullptr && - DT != nullptr && CurLoop != nullptr && CurAST != nullptr && - SafetyInfo != nullptr && "Unexpected input to hoistRegion"); - // Set changed as false. - bool Changed = false; - // Get basic block + assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr && + CurLoop != nullptr && CurAST != nullptr && SafetyInfo != nullptr && + "Unexpected input to hoistRegion"); + BasicBlock *BB = N->getBlock(); + // If this subregion is not in the top level loop at all, exit. - if (!CurLoop->contains(BB)) return Changed; + if (!CurLoop->contains(BB)) + return false; + // Only need to process the contents of this block if it is not part of a // subloop (which would already have been processed). + bool Changed = false; if (!inSubLoop(BB, CurLoop, LI)) - for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ) { + for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) { Instruction &I = *II++; // Try constant folding this instruction. If all the operands are // constants, it is technically hoistable, but it would be better to just @@ -384,9 +377,11 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, &I, I.getModule()->getDataLayout(), TLI)) { DEBUG(dbgs() << "LICM folding inst: " << I << " --> " << *C << '\n'); CurAST->copyValue(&I, C); - CurAST->deleteValue(&I); I.replaceAllUsesWith(C); - I.eraseFromParent(); + if (isInstructionTriviallyDead(&I, TLI)) { + CurAST->deleteValue(&I); + I.eraseFromParent(); + } continue; } @@ -396,12 +391,13 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, // if (CurLoop->hasLoopInvariantOperands(&I) && canSinkOrHoistInst(I, AA, DT, TLI, CurLoop, CurAST, SafetyInfo) && - isSafeToExecuteUnconditionally(I, DT, TLI, CurLoop, SafetyInfo, - CurLoop->getLoopPreheader()->getTerminator())) - Changed |= hoist(I, CurLoop->getLoopPreheader()); + isSafeToExecuteUnconditionally( + I, DT, CurLoop, SafetyInfo, + CurLoop->getLoopPreheader()->getTerminator())) + Changed |= hoist(I, DT, CurLoop, SafetyInfo); } - const std::vector<DomTreeNode*> &Children = N->getChildren(); + const std::vector<DomTreeNode *> &Children = N->getChildren(); for (DomTreeNode *Child : Children) Changed |= hoistRegion(Child, AA, LI, DT, TLI, CurLoop, CurAST, SafetyInfo); return Changed; @@ -410,7 +406,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, /// Computes loop safety information, checks loop body & header /// for the possibility of may throw exception. /// -void llvm::computeLICMSafetyInfo(LICMSafetyInfo * SafetyInfo, Loop * CurLoop) { +void llvm::computeLoopSafetyInfo(LoopSafetyInfo *SafetyInfo, Loop *CurLoop) { assert(CurLoop != nullptr && "CurLoop cant be null"); BasicBlock *Header = CurLoop->getHeader(); // Setting default safety values. @@ -419,15 +415,17 @@ void llvm::computeLICMSafetyInfo(LICMSafetyInfo * SafetyInfo, Loop * CurLoop) { // Iterate over header and compute safety info. for (BasicBlock::iterator I = Header->begin(), E = Header->end(); (I != E) && !SafetyInfo->HeaderMayThrow; ++I) - SafetyInfo->HeaderMayThrow |= I->mayThrow(); - + SafetyInfo->HeaderMayThrow |= + !isGuaranteedToTransferExecutionToSuccessor(&*I); + SafetyInfo->MayThrow = SafetyInfo->HeaderMayThrow; - // Iterate over loop instructions and compute safety info. - for (Loop::block_iterator BB = CurLoop->block_begin(), - BBE = CurLoop->block_end(); (BB != BBE) && !SafetyInfo->MayThrow ; ++BB) + // Iterate over loop instructions and compute safety info. + for (Loop::block_iterator BB = CurLoop->block_begin(), + BBE = CurLoop->block_end(); + (BB != BBE) && !SafetyInfo->MayThrow; ++BB) for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); (I != E) && !SafetyInfo->MayThrow; ++I) - SafetyInfo->MayThrow |= I->mayThrow(); + SafetyInfo->MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(&*I); // Compute funclet colors if we might sink/hoist in a function with a funclet // personality routine. @@ -443,11 +441,11 @@ void llvm::computeLICMSafetyInfo(LICMSafetyInfo * SafetyInfo, Loop * CurLoop) { /// bool canSinkOrHoistInst(Instruction &I, AliasAnalysis *AA, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, - AliasSetTracker *CurAST, LICMSafetyInfo *SafetyInfo) { + AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo) { // Loads have extra constraints we have to verify before we can hoist them. if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { if (!LI->isUnordered()) - return false; // Don't hoist volatile/atomic loads! + return false; // Don't hoist volatile/atomic loads! // Loads from constant memory are always safe to move, even if they end up // in the same alias set as something that ends up being modified. @@ -499,7 +497,8 @@ bool canSinkOrHoistInst(Instruction &I, AliasAnalysis *AA, DominatorTree *DT, break; } } - if (!FoundMod) return true; + if (!FoundMod) + return true; } // FIXME: This should use mod/ref information to see if we can hoist or @@ -518,9 +517,8 @@ bool canSinkOrHoistInst(Instruction &I, AliasAnalysis *AA, DominatorTree *DT, // TODO: Plumb the context instruction through to make hoisting and sinking // more powerful. Hoisting of loads already works due to the special casing - // above. - return isSafeToExecuteUnconditionally(I, DT, TLI, CurLoop, SafetyInfo, - nullptr); + // above. + return isSafeToExecuteUnconditionally(I, DT, CurLoop, SafetyInfo, nullptr); } /// Returns true if a PHINode is a trivially replaceable with an @@ -541,7 +539,7 @@ static bool isTriviallyReplacablePHI(const PHINode &PN, const Instruction &I) { /// blocks of the loop. /// static bool isNotUsedInLoop(const Instruction &I, const Loop *CurLoop, - const LICMSafetyInfo *SafetyInfo) { + const LoopSafetyInfo *SafetyInfo) { const auto &BlockColors = SafetyInfo->BlockColors; for (const User *U : I.users()) { const Instruction *UI = cast<Instruction>(U); @@ -588,7 +586,7 @@ static bool isNotUsedInLoop(const Instruction &I, const Loop *CurLoop, static Instruction * CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, - const LICMSafetyInfo *SafetyInfo) { + const LoopSafetyInfo *SafetyInfo) { Instruction *New; if (auto *CI = dyn_cast<CallInst>(&I)) { const auto &BlockColors = SafetyInfo->BlockColors; @@ -621,7 +619,8 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, } ExitBlock.getInstList().insert(ExitBlock.getFirstInsertionPt(), New); - if (!I.getName().empty()) New->setName(I.getName() + ".le"); + if (!I.getName().empty()) + New->setName(I.getName() + ".le"); // Build LCSSA PHI nodes for any in-loop operands. Note that this is // particularly cheap because we can rip off the PHI node that we're @@ -652,18 +651,20 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, /// static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT, const Loop *CurLoop, AliasSetTracker *CurAST, - const LICMSafetyInfo *SafetyInfo) { + const LoopSafetyInfo *SafetyInfo) { DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n"); bool Changed = false; - if (isa<LoadInst>(I)) ++NumMovedLoads; - else if (isa<CallInst>(I)) ++NumMovedCalls; + if (isa<LoadInst>(I)) + ++NumMovedLoads; + else if (isa<CallInst>(I)) + ++NumMovedCalls; ++NumSunk; Changed = true; #ifndef NDEBUG SmallVector<BasicBlock *, 32> ExitBlocks; CurLoop->getUniqueExitBlocks(ExitBlocks); - SmallPtrSet<BasicBlock *, 32> ExitBlockSet(ExitBlocks.begin(), + SmallPtrSet<BasicBlock *, 32> ExitBlockSet(ExitBlocks.begin(), ExitBlocks.end()); #endif @@ -717,18 +718,30 @@ static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT, /// When an instruction is found to only use loop invariant operands that /// is safe to hoist, this instruction is called to do the dirty work. /// -static bool hoist(Instruction &I, BasicBlock *Preheader) { - DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": " - << I << "\n"); +static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, + const LoopSafetyInfo *SafetyInfo) { + auto *Preheader = CurLoop->getLoopPreheader(); + DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": " << I + << "\n"); + + // Metadata can be dependent on conditions we are hoisting above. + // Conservatively strip all metadata on the instruction unless we were + // guaranteed to execute I if we entered the loop, in which case the metadata + // is valid in the loop preheader. + if (I.hasMetadataOtherThanDebugLoc() && + // The check on hasMetadataOtherThanDebugLoc is to prevent us from burning + // time in isGuaranteedToExecute if we don't actually have anything to + // drop. It is a compile time optimization, not required for correctness. + !isGuaranteedToExecute(I, DT, CurLoop, SafetyInfo)) + I.dropUnknownNonDebugMetadata(); + // Move the new node to the Preheader, before its terminator. I.moveBefore(Preheader->getTerminator()); - // Metadata can be dependent on the condition we are hoisting above. - // Conservatively strip all metadata on the instruction. - I.dropUnknownNonDebugMetadata(); - - if (isa<LoadInst>(I)) ++NumMovedLoads; - else if (isa<CallInst>(I)) ++NumMovedCalls; + if (isa<LoadInst>(I)) + ++NumMovedLoads; + else if (isa<CallInst>(I)) + ++NumMovedCalls; ++NumHoisted; return true; } @@ -736,134 +749,91 @@ static bool hoist(Instruction &I, BasicBlock *Preheader) { /// Only sink or hoist an instruction if it is not a trapping instruction, /// or if the instruction is known not to trap when moved to the preheader. /// or if it is a trapping instruction and is guaranteed to execute. -static bool isSafeToExecuteUnconditionally(const Instruction &Inst, +static bool isSafeToExecuteUnconditionally(const Instruction &Inst, const DominatorTree *DT, - const TargetLibraryInfo *TLI, const Loop *CurLoop, - const LICMSafetyInfo *SafetyInfo, + const LoopSafetyInfo *SafetyInfo, const Instruction *CtxI) { - if (isSafeToSpeculativelyExecute(&Inst, CtxI, DT, TLI)) + if (isSafeToSpeculativelyExecute(&Inst, CtxI, DT)) return true; return isGuaranteedToExecute(Inst, DT, CurLoop, SafetyInfo); } -static bool isGuaranteedToExecute(const Instruction &Inst, - const DominatorTree *DT, - const Loop *CurLoop, - const LICMSafetyInfo * SafetyInfo) { - - // We have to check to make sure that the instruction dominates all - // of the exit blocks. If it doesn't, then there is a path out of the loop - // which does not execute this instruction, so we can't hoist it. - - // If the instruction is in the header block for the loop (which is very - // common), it is always guaranteed to dominate the exit blocks. Since this - // is a common case, and can save some work, check it now. - if (Inst.getParent() == CurLoop->getHeader()) - // If there's a throw in the header block, we can't guarantee we'll reach - // Inst. - return !SafetyInfo->HeaderMayThrow; - - // Somewhere in this loop there is an instruction which may throw and make us - // exit the loop. - if (SafetyInfo->MayThrow) - return false; - - // Get the exit blocks for the current loop. - SmallVector<BasicBlock*, 8> ExitBlocks; - CurLoop->getExitBlocks(ExitBlocks); - - // Verify that the block dominates each of the exit blocks of the loop. - for (BasicBlock *ExitBlock : ExitBlocks) - if (!DT->dominates(Inst.getParent(), ExitBlock)) - return false; - - // As a degenerate case, if the loop is statically infinite then we haven't - // proven anything since there are no exit blocks. - if (ExitBlocks.empty()) - return false; - - return true; -} - namespace { - class LoopPromoter : public LoadAndStorePromoter { - Value *SomePtr; // Designated pointer to store to. - SmallPtrSetImpl<Value*> &PointerMustAliases; - SmallVectorImpl<BasicBlock*> &LoopExitBlocks; - SmallVectorImpl<Instruction*> &LoopInsertPts; - PredIteratorCache &PredCache; - AliasSetTracker &AST; - LoopInfo &LI; - DebugLoc DL; - int Alignment; - AAMDNodes AATags; - - Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const { - if (Instruction *I = dyn_cast<Instruction>(V)) - if (Loop *L = LI.getLoopFor(I->getParent())) - if (!L->contains(BB)) { - // We need to create an LCSSA PHI node for the incoming value and - // store that. - PHINode *PN = - PHINode::Create(I->getType(), PredCache.size(BB), - I->getName() + ".lcssa", &BB->front()); - for (BasicBlock *Pred : PredCache.get(BB)) - PN->addIncoming(I, Pred); - return PN; - } - return V; - } +class LoopPromoter : public LoadAndStorePromoter { + Value *SomePtr; // Designated pointer to store to. + SmallPtrSetImpl<Value *> &PointerMustAliases; + SmallVectorImpl<BasicBlock *> &LoopExitBlocks; + SmallVectorImpl<Instruction *> &LoopInsertPts; + PredIteratorCache &PredCache; + AliasSetTracker &AST; + LoopInfo &LI; + DebugLoc DL; + int Alignment; + AAMDNodes AATags; - public: - LoopPromoter(Value *SP, - ArrayRef<const Instruction *> Insts, - SSAUpdater &S, SmallPtrSetImpl<Value *> &PMA, - SmallVectorImpl<BasicBlock *> &LEB, - SmallVectorImpl<Instruction *> &LIP, PredIteratorCache &PIC, - AliasSetTracker &ast, LoopInfo &li, DebugLoc dl, int alignment, - const AAMDNodes &AATags) - : LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA), - LoopExitBlocks(LEB), LoopInsertPts(LIP), PredCache(PIC), AST(ast), - LI(li), DL(dl), Alignment(alignment), AATags(AATags) {} - - bool isInstInList(Instruction *I, - const SmallVectorImpl<Instruction*> &) const override { - Value *Ptr; - if (LoadInst *LI = dyn_cast<LoadInst>(I)) - Ptr = LI->getOperand(0); - else - Ptr = cast<StoreInst>(I)->getPointerOperand(); - return PointerMustAliases.count(Ptr); - } + Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const { + if (Instruction *I = dyn_cast<Instruction>(V)) + if (Loop *L = LI.getLoopFor(I->getParent())) + if (!L->contains(BB)) { + // We need to create an LCSSA PHI node for the incoming value and + // store that. + PHINode *PN = PHINode::Create(I->getType(), PredCache.size(BB), + I->getName() + ".lcssa", &BB->front()); + for (BasicBlock *Pred : PredCache.get(BB)) + PN->addIncoming(I, Pred); + return PN; + } + return V; + } - void doExtraRewritesBeforeFinalDeletion() const override { - // Insert stores after in the loop exit blocks. Each exit block gets a - // store of the live-out values that feed them. Since we've already told - // the SSA updater about the defs in the loop and the preheader - // definition, it is all set and we can start using it. - for (unsigned i = 0, e = LoopExitBlocks.size(); i != e; ++i) { - BasicBlock *ExitBlock = LoopExitBlocks[i]; - Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock); - LiveInValue = maybeInsertLCSSAPHI(LiveInValue, ExitBlock); - Value *Ptr = maybeInsertLCSSAPHI(SomePtr, ExitBlock); - Instruction *InsertPos = LoopInsertPts[i]; - StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos); - NewSI->setAlignment(Alignment); - NewSI->setDebugLoc(DL); - if (AATags) NewSI->setAAMetadata(AATags); - } - } +public: + LoopPromoter(Value *SP, ArrayRef<const Instruction *> Insts, SSAUpdater &S, + SmallPtrSetImpl<Value *> &PMA, + SmallVectorImpl<BasicBlock *> &LEB, + SmallVectorImpl<Instruction *> &LIP, PredIteratorCache &PIC, + AliasSetTracker &ast, LoopInfo &li, DebugLoc dl, int alignment, + const AAMDNodes &AATags) + : LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA), + LoopExitBlocks(LEB), LoopInsertPts(LIP), PredCache(PIC), AST(ast), + LI(li), DL(std::move(dl)), Alignment(alignment), AATags(AATags) {} + + bool isInstInList(Instruction *I, + const SmallVectorImpl<Instruction *> &) const override { + Value *Ptr; + if (LoadInst *LI = dyn_cast<LoadInst>(I)) + Ptr = LI->getOperand(0); + else + Ptr = cast<StoreInst>(I)->getPointerOperand(); + return PointerMustAliases.count(Ptr); + } - void replaceLoadWithValue(LoadInst *LI, Value *V) const override { - // Update alias analysis. - AST.copyValue(LI, V); + void doExtraRewritesBeforeFinalDeletion() const override { + // Insert stores after in the loop exit blocks. Each exit block gets a + // store of the live-out values that feed them. Since we've already told + // the SSA updater about the defs in the loop and the preheader + // definition, it is all set and we can start using it. + for (unsigned i = 0, e = LoopExitBlocks.size(); i != e; ++i) { + BasicBlock *ExitBlock = LoopExitBlocks[i]; + Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock); + LiveInValue = maybeInsertLCSSAPHI(LiveInValue, ExitBlock); + Value *Ptr = maybeInsertLCSSAPHI(SomePtr, ExitBlock); + Instruction *InsertPos = LoopInsertPts[i]; + StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos); + NewSI->setAlignment(Alignment); + NewSI->setDebugLoc(DL); + if (AATags) + NewSI->setAAMetadata(AATags); } - void instructionDeleted(Instruction *I) const override { - AST.deleteValue(I); - } - }; + } + + void replaceLoadWithValue(LoadInst *LI, Value *V) const override { + // Update alias analysis. + AST.copyValue(LI, V); + } + void instructionDeleted(Instruction *I) const override { AST.deleteValue(I); } +}; } // end anon namespace /// Try to promote memory values to scalars by sinking stores out of the @@ -871,32 +841,28 @@ namespace { /// the stores in the loop, looking for stores to Must pointers which are /// loop invariant. /// -bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, - SmallVectorImpl<BasicBlock*>&ExitBlocks, - SmallVectorImpl<Instruction*>&InsertPts, - PredIteratorCache &PIC, LoopInfo *LI, - DominatorTree *DT, Loop *CurLoop, - AliasSetTracker *CurAST, - LICMSafetyInfo * SafetyInfo) { +bool llvm::promoteLoopAccessesToScalars( + AliasSet &AS, SmallVectorImpl<BasicBlock *> &ExitBlocks, + SmallVectorImpl<Instruction *> &InsertPts, PredIteratorCache &PIC, + LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, + Loop *CurLoop, AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo) { // Verify inputs. - assert(LI != nullptr && DT != nullptr && - CurLoop != nullptr && CurAST != nullptr && - SafetyInfo != nullptr && + assert(LI != nullptr && DT != nullptr && CurLoop != nullptr && + CurAST != nullptr && SafetyInfo != nullptr && "Unexpected Input to promoteLoopAccessesToScalars"); - // Initially set Changed status to false. - bool Changed = false; + // We can promote this alias set if it has a store, if it is a "Must" alias // set, if the pointer is loop invariant, and if we are not eliminating any // volatile loads or stores. if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() || AS.isVolatile() || !CurLoop->isLoopInvariant(AS.begin()->getValue())) - return Changed; + return false; assert(!AS.empty() && "Must alias set should have at least one pointer element in it!"); Value *SomePtr = AS.begin()->getValue(); - BasicBlock * Preheader = CurLoop->getLoopPreheader(); + BasicBlock *Preheader = CurLoop->getLoopPreheader(); // It isn't safe to promote a load/store from the loop if the load/store is // conditional. For example, turning: @@ -909,12 +875,27 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, // // is not safe, because *P may only be valid to access if 'c' is true. // + // The safety property divides into two parts: + // 1) The memory may not be dereferenceable on entry to the loop. In this + // case, we can't insert the required load in the preheader. + // 2) The memory model does not allow us to insert a store along any dynamic + // path which did not originally have one. + // // It is safe to promote P if all uses are direct load/stores and if at // least one is guaranteed to be executed. bool GuaranteedToExecute = false; - SmallVector<Instruction*, 64> LoopUses; - SmallPtrSet<Value*, 4> PointerMustAliases; + // It is also safe to promote P if we can prove that speculating a load into + // the preheader is safe (i.e. proving dereferenceability on all + // paths through the loop), and that the memory can be proven thread local + // (so that the memory model requirement doesn't apply.) We first establish + // the former, and then run a capture analysis below to establish the later. + // We can use any access within the alias set to prove dereferenceability + // since they're all must alias. + bool CanSpeculateLoad = false; + + SmallVector<Instruction *, 64> LoopUses; + SmallPtrSet<Value *, 4> PointerMustAliases; // We start with an alignment of one and try to find instructions that allow // us to prove better alignment. @@ -922,11 +903,32 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, AAMDNodes AATags; bool HasDedicatedExits = CurLoop->hasDedicatedExits(); + // Don't sink stores from loops without dedicated block exits. Exits + // containing indirect branches are not transformed by loop simplify, + // make sure we catch that. An additional load may be generated in the + // preheader for SSA updater, so also avoid sinking when no preheader + // is available. + if (!HasDedicatedExits || !Preheader) + return false; + + const DataLayout &MDL = Preheader->getModule()->getDataLayout(); + + if (SafetyInfo->MayThrow) { + // If a loop can throw, we have to insert a store along each unwind edge. + // That said, we can't actually make the unwind edge explicit. Therefore, + // we have to prove that the store is dead along the unwind edge. + // + // Currently, this code just special-cases alloca instructions. + if (!isa<AllocaInst>(GetUnderlyingObject(SomePtr, MDL))) + return false; + } + // Check that all of the pointers in the alias set have the same type. We // cannot (yet) promote a memory location that is loaded and stored in // different sizes. While we are at it, collect alignment and AA info. - for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) { - Value *ASIV = ASI->getValue(); + bool Changed = false; + for (const auto &ASI : AS) { + Value *ASIV = ASI.getValue(); PointerMustAliases.insert(ASIV); // Check that all of the pointers in the alias set have the same type. We @@ -947,6 +949,10 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, assert(!Load->isVolatile() && "AST broken"); if (!Load->isSimple()) return Changed; + + if (!GuaranteedToExecute && !CanSpeculateLoad) + CanSpeculateLoad = isSafeToExecuteUnconditionally( + *Load, DT, CurLoop, SafetyInfo, Preheader->getTerminator()); } else if (const StoreInst *Store = dyn_cast<StoreInst>(UI)) { // Stores *of* the pointer are not interesting, only stores *to* the // pointer. @@ -955,13 +961,6 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, assert(!Store->isVolatile() && "AST broken"); if (!Store->isSimple()) return Changed; - // Don't sink stores from loops without dedicated block exits. Exits - // containing indirect branches are not transformed by loop simplify, - // make sure we catch that. An additional load may be generated in the - // preheader for SSA updater, so also avoid sinking when no preheader - // is available. - if (!HasDedicatedExits || !Preheader) - return Changed; // Note that we only check GuaranteedToExecute inside the store case // so that we do not introduce stores where they did not exist before @@ -972,16 +971,22 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, // instruction will be executed, update the alignment. // Larger is better, with the exception of 0 being the best alignment. unsigned InstAlignment = Store->getAlignment(); - if ((InstAlignment > Alignment || InstAlignment == 0) && Alignment != 0) + if ((InstAlignment > Alignment || InstAlignment == 0) && + Alignment != 0) { if (isGuaranteedToExecute(*UI, DT, CurLoop, SafetyInfo)) { GuaranteedToExecute = true; Alignment = InstAlignment; } + } else if (!GuaranteedToExecute) { + GuaranteedToExecute = + isGuaranteedToExecute(*UI, DT, CurLoop, SafetyInfo); + } - if (!GuaranteedToExecute) - GuaranteedToExecute = isGuaranteedToExecute(*UI, DT, - CurLoop, SafetyInfo); - + if (!GuaranteedToExecute && !CanSpeculateLoad) { + CanSpeculateLoad = isDereferenceableAndAlignedPointer( + Store->getPointerOperand(), Store->getAlignment(), MDL, + Preheader->getTerminator(), DT); + } } else return Changed; // Not a load or store. @@ -997,8 +1002,17 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, } } - // If there isn't a guaranteed-to-execute instruction, we can't promote. - if (!GuaranteedToExecute) + // Check legality per comment above. Otherwise, we can't promote. + bool PromotionIsLegal = GuaranteedToExecute; + if (!PromotionIsLegal && CanSpeculateLoad) { + // If this is a thread local location, then we can insert stores along + // paths which originally didn't have them without violating the memory + // model. + Value *Object = GetUnderlyingObject(SomePtr, MDL); + PromotionIsLegal = + isAllocLikeFn(Object, TLI) && !PointerMayBeCaptured(Object, true, true); + } + if (!PromotionIsLegal) return Changed; // Figure out the loop exits and their insertion points, if this is the @@ -1017,7 +1031,8 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, return Changed; // Otherwise, this is safe to promote, lets do it! - DEBUG(dbgs() << "LICM: Promoting value stored to in loop: " <<*SomePtr<<'\n'); + DEBUG(dbgs() << "LICM: Promoting value stored to in loop: " << *SomePtr + << '\n'); Changed = true; ++NumPromoted; @@ -1028,20 +1043,19 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, DebugLoc DL = LoopUses[0]->getDebugLoc(); // We use the SSAUpdater interface to insert phi nodes as required. - SmallVector<PHINode*, 16> NewPHIs; + SmallVector<PHINode *, 16> NewPHIs; SSAUpdater SSA(&NewPHIs); - LoopPromoter Promoter(SomePtr, LoopUses, SSA, - PointerMustAliases, ExitBlocks, + LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks, InsertPts, PIC, *CurAST, *LI, DL, Alignment, AATags); // 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. - LoadInst *PreheaderLoad = - new LoadInst(SomePtr, SomePtr->getName()+".promoted", - Preheader->getTerminator()); + LoadInst *PreheaderLoad = new LoadInst( + SomePtr, SomePtr->getName() + ".promoted", Preheader->getTerminator()); PreheaderLoad->setAlignment(Alignment); PreheaderLoad->setDebugLoc(DL); - if (AATags) PreheaderLoad->setAAMetadata(AATags); + if (AATags) + PreheaderLoad->setAAMetadata(AATags); SSA.AddAvailableValue(Preheader, PreheaderLoad); // Rewrite all the loads in the loop and remember all the definitions from @@ -1055,10 +1069,67 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS, return Changed; } +/// 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 functions to handle loop +/// analysis such as cloneBasicBlockAnalysis. So the AST needs to be recompute +/// from scratch for every loop. Hook up with the helper functions when +/// available in the new pass manager to avoid redundant computation. +AliasSetTracker * +LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI, + AliasAnalysis *AA) { + AliasSetTracker *CurAST = nullptr; + 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; + } + AliasSetTracker *InnerAST = MapI->second; + + if (CurAST != nullptr) { + // What if InnerLoop was modified by other passes ? + CurAST->add(*InnerAST); + + // Once we've incorporated the inner loop's AST into ours, we don't need + // the subloop's anymore. + delete InnerAST; + } else { + CurAST = InnerAST; + } + LoopToAliasSetMap.erase(MapI); + } + if (CurAST == nullptr) + CurAST = new AliasSetTracker(*AA); + + auto mergeLoop = [&](Loop *L) { + // Loop over the body of this loop, looking for calls, invokes, and stores. + // Because subloops have already been incorporated into AST, we skip blocks + // in subloops. + for (BasicBlock *BB : L->blocks()) + if (LI->getLoopFor(BB) == L) // Ignore blocks in subloops. + CurAST->add(*BB); // Incorporate the specified basic block + }; + + // Add everything from the sub loops that are no longer directly available. + for (Loop *InnerL : RecomputeLoops) + mergeLoop(InnerL); + + // And merge in this loop. + mergeLoop(L); + + return CurAST; +} + /// Simple analysis hook. Clone alias set info. /// -void LICM::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) { - AliasSetTracker *AST = LoopToAliasSetMap.lookup(L); +void LegacyLICMPass::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, + Loop *L) { + AliasSetTracker *AST = LICM.getLoopToAliasSetMap().lookup(L); if (!AST) return; @@ -1067,8 +1138,8 @@ void LICM::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) { /// Simple Analysis hook. Delete value V from alias set /// -void LICM::deleteAnalysisValue(Value *V, Loop *L) { - AliasSetTracker *AST = LoopToAliasSetMap.lookup(L); +void LegacyLICMPass::deleteAnalysisValue(Value *V, Loop *L) { + AliasSetTracker *AST = LICM.getLoopToAliasSetMap().lookup(L); if (!AST) return; @@ -1077,21 +1148,20 @@ void LICM::deleteAnalysisValue(Value *V, Loop *L) { /// Simple Analysis hook. Delete value L from alias set map. /// -void LICM::deleteAnalysisLoop(Loop *L) { - AliasSetTracker *AST = LoopToAliasSetMap.lookup(L); +void LegacyLICMPass::deleteAnalysisLoop(Loop *L) { + AliasSetTracker *AST = LICM.getLoopToAliasSetMap().lookup(L); if (!AST) return; delete AST; - LoopToAliasSetMap.erase(L); + LICM.getLoopToAliasSetMap().erase(L); } - /// Return true if the body of this loop may store into the memory /// location pointed to by V. /// static bool pointerInvalidatedByLoop(Value *V, uint64_t Size, - const AAMDNodes &AAInfo, + const AAMDNodes &AAInfo, AliasSetTracker *CurAST) { // Check to see if any of the basic blocks in CurLoop invalidate *V. return CurAST->getAliasSetForPointer(V, Size, AAInfo).isMod(); @@ -1104,4 +1174,3 @@ static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI) { assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop"); return LI->getLoopFor(BB) != CurLoop; } - |
