1b417d464SFiona Glaser //===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===// 2b417d464SFiona Glaser // 3b417d464SFiona Glaser // The LLVM Compiler Infrastructure 4b417d464SFiona Glaser // 5b417d464SFiona Glaser // This file is distributed under the University of Illinois Open Source 6b417d464SFiona Glaser // License. See LICENSE.TXT for details. 7b417d464SFiona Glaser // 8b417d464SFiona Glaser //===----------------------------------------------------------------------===// 9b417d464SFiona Glaser // 10b417d464SFiona Glaser // This file implements the Loop SimplifyCFG Pass. This pass is responsible for 11b417d464SFiona Glaser // basic loop CFG cleanup, primarily to assist other loop passes. If you 12b417d464SFiona Glaser // encounter a noncanonical CFG construct that causes another loop pass to 13b417d464SFiona Glaser // perform suboptimally, this is the place to fix it up. 14b417d464SFiona Glaser // 15b417d464SFiona Glaser //===----------------------------------------------------------------------===// 16b417d464SFiona Glaser 17ab6a513bSJustin Bogner #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" 18b417d464SFiona Glaser #include "llvm/ADT/SmallVector.h" 19b417d464SFiona Glaser #include "llvm/ADT/Statistic.h" 20b417d464SFiona Glaser #include "llvm/Analysis/AliasAnalysis.h" 21b417d464SFiona Glaser #include "llvm/Analysis/BasicAliasAnalysis.h" 22*aec2fa35SDaniel Jasper #include "llvm/Analysis/AssumptionCache.h" 23b417d464SFiona Glaser #include "llvm/Analysis/DependenceAnalysis.h" 24b417d464SFiona Glaser #include "llvm/Analysis/GlobalsModRef.h" 25b417d464SFiona Glaser #include "llvm/Analysis/LoopInfo.h" 26b417d464SFiona Glaser #include "llvm/Analysis/LoopPass.h" 27ab6a513bSJustin Bogner #include "llvm/Analysis/LoopPassManager.h" 28b417d464SFiona Glaser #include "llvm/Analysis/ScalarEvolution.h" 29b417d464SFiona Glaser #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 30b417d464SFiona Glaser #include "llvm/Analysis/TargetTransformInfo.h" 31b417d464SFiona Glaser #include "llvm/IR/Dominators.h" 32ab6a513bSJustin Bogner #include "llvm/Transforms/Scalar.h" 33b417d464SFiona Glaser #include "llvm/Transforms/Utils/Local.h" 3431088a9dSChandler Carruth #include "llvm/Transforms/Utils/LoopUtils.h" 35b417d464SFiona Glaser using namespace llvm; 36b417d464SFiona Glaser 37b417d464SFiona Glaser #define DEBUG_TYPE "loop-simplifycfg" 38b417d464SFiona Glaser 39ab6a513bSJustin Bogner static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI) { 40b417d464SFiona Glaser bool Changed = false; 41b417d464SFiona Glaser // Copy blocks into a temporary array to avoid iterator invalidation issues 42b417d464SFiona Glaser // as we remove them. 43ab6a513bSJustin Bogner SmallVector<WeakVH, 16> Blocks(L.blocks()); 44b417d464SFiona Glaser 45b417d464SFiona Glaser for (auto &Block : Blocks) { 46b417d464SFiona Glaser // Attempt to merge blocks in the trivial case. Don't modify blocks which 47b417d464SFiona Glaser // belong to other loops. 4836e8230dSFiona Glaser BasicBlock *Succ = cast_or_null<BasicBlock>(Block); 49b417d464SFiona Glaser if (!Succ) 50b417d464SFiona Glaser continue; 51b417d464SFiona Glaser 52b417d464SFiona Glaser BasicBlock *Pred = Succ->getSinglePredecessor(); 53ab6a513bSJustin Bogner if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) 54b417d464SFiona Glaser continue; 55b417d464SFiona Glaser 56b417d464SFiona Glaser // Pred is going to disappear, so we need to update the loop info. 57ab6a513bSJustin Bogner if (L.getHeader() == Pred) 58ab6a513bSJustin Bogner L.moveToHeader(Succ); 59ab6a513bSJustin Bogner LI.removeBlock(Pred); 60ab6a513bSJustin Bogner MergeBasicBlockIntoOnlyPred(Succ, &DT); 61b417d464SFiona Glaser Changed = true; 62b417d464SFiona Glaser } 63b417d464SFiona Glaser 64b417d464SFiona Glaser return Changed; 65b417d464SFiona Glaser } 66b417d464SFiona Glaser 670746f3bfSSean Silva PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM) { 6878eebe77SJustin Bogner const auto &FAM = 6978eebe77SJustin Bogner AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager(); 70ab6a513bSJustin Bogner Function *F = L.getHeader()->getParent(); 71ab6a513bSJustin Bogner 72ab6a513bSJustin Bogner auto *LI = FAM.getCachedResult<LoopAnalysis>(*F); 73ab6a513bSJustin Bogner auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F); 74ab6a513bSJustin Bogner assert((LI && DT) && "Analyses for LoopSimplifyCFG not available"); 75ab6a513bSJustin Bogner 76ab6a513bSJustin Bogner if (!simplifyLoopCFG(L, *DT, *LI)) 77ab6a513bSJustin Bogner return PreservedAnalyses::all(); 78ab6a513bSJustin Bogner return getLoopPassPreservedAnalyses(); 79ab6a513bSJustin Bogner } 80ab6a513bSJustin Bogner 81ab6a513bSJustin Bogner namespace { 82ab6a513bSJustin Bogner class LoopSimplifyCFGLegacyPass : public LoopPass { 83ab6a513bSJustin Bogner public: 84ab6a513bSJustin Bogner static char ID; // Pass ID, replacement for typeid 85ab6a513bSJustin Bogner LoopSimplifyCFGLegacyPass() : LoopPass(ID) { 86ab6a513bSJustin Bogner initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry()); 87ab6a513bSJustin Bogner } 88ab6a513bSJustin Bogner 89ab6a513bSJustin Bogner bool runOnLoop(Loop *L, LPPassManager &) override { 90aa641a51SAndrew Kaylor if (skipLoop(L)) 91b417d464SFiona Glaser return false; 92b417d464SFiona Glaser 93ab6a513bSJustin Bogner DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 94ab6a513bSJustin Bogner LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 95ab6a513bSJustin Bogner return simplifyLoopCFG(*L, DT, LI); 96ab6a513bSJustin Bogner } 97ab6a513bSJustin Bogner 98ab6a513bSJustin Bogner void getAnalysisUsage(AnalysisUsage &AU) const override { 9949c22190SChandler Carruth AU.addPreserved<DependenceAnalysisWrapperPass>(); 100ab6a513bSJustin Bogner getLoopAnalysisUsage(AU); 101ab6a513bSJustin Bogner } 102ab6a513bSJustin Bogner }; 103ab6a513bSJustin Bogner } 104ab6a513bSJustin Bogner 105ab6a513bSJustin Bogner char LoopSimplifyCFGLegacyPass::ID = 0; 106ab6a513bSJustin Bogner INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 107ab6a513bSJustin Bogner "Simplify loop CFG", false, false) 108ab6a513bSJustin Bogner INITIALIZE_PASS_DEPENDENCY(LoopPass) 109ab6a513bSJustin Bogner INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 110ab6a513bSJustin Bogner "Simplify loop CFG", false, false) 111ab6a513bSJustin Bogner 112ab6a513bSJustin Bogner Pass *llvm::createLoopSimplifyCFGPass() { 113ab6a513bSJustin Bogner return new LoopSimplifyCFGLegacyPass(); 114b417d464SFiona Glaser } 115