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" 21aec2fa35SDaniel Jasper #include "llvm/Analysis/AssumptionCache.h" 223bab7e1aSChandler Carruth #include "llvm/Analysis/BasicAliasAnalysis.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" 27b417d464SFiona Glaser #include "llvm/Analysis/ScalarEvolution.h" 28b417d464SFiona Glaser #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 29b417d464SFiona Glaser #include "llvm/Analysis/TargetTransformInfo.h" 30b417d464SFiona Glaser #include "llvm/IR/Dominators.h" 31ab6a513bSJustin Bogner #include "llvm/Transforms/Scalar.h" 323bab7e1aSChandler Carruth #include "llvm/Transforms/Scalar/LoopPassManager.h" 33a373d18eSDavid Blaikie #include "llvm/Transforms/Utils.h" 34*dfd14adeSAlina Sbirlea #include "llvm/Transforms/Utils/BasicBlockUtils.h" 35*dfd14adeSAlina Sbirlea #include "llvm/Transforms/Utils/Local.h" 3631088a9dSChandler Carruth #include "llvm/Transforms/Utils/LoopUtils.h" 37b417d464SFiona Glaser using namespace llvm; 38b417d464SFiona Glaser 39b417d464SFiona Glaser #define DEBUG_TYPE "loop-simplifycfg" 40b417d464SFiona Glaser 41e6a9c248SDavid Green static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, 42e6a9c248SDavid Green ScalarEvolution &SE) { 43b417d464SFiona Glaser bool Changed = false; 44b417d464SFiona Glaser // Copy blocks into a temporary array to avoid iterator invalidation issues 45b417d464SFiona Glaser // as we remove them. 46e6bca0eeSSanjoy Das SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); 47b417d464SFiona Glaser 48b417d464SFiona Glaser for (auto &Block : Blocks) { 49b417d464SFiona Glaser // Attempt to merge blocks in the trivial case. Don't modify blocks which 50b417d464SFiona Glaser // belong to other loops. 5136e8230dSFiona Glaser BasicBlock *Succ = cast_or_null<BasicBlock>(Block); 52b417d464SFiona Glaser if (!Succ) 53b417d464SFiona Glaser continue; 54b417d464SFiona Glaser 55b417d464SFiona Glaser BasicBlock *Pred = Succ->getSinglePredecessor(); 56ab6a513bSJustin Bogner if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) 57b417d464SFiona Glaser continue; 58b417d464SFiona Glaser 59*dfd14adeSAlina Sbirlea // Merge Succ into Pred and delete it. 60*dfd14adeSAlina Sbirlea MergeBlockIntoPredecessor(Succ, &DT, &LI); 61e6a9c248SDavid Green 62e6a9c248SDavid Green SE.forgetLoop(&L); 63b417d464SFiona Glaser Changed = true; 64b417d464SFiona Glaser } 65b417d464SFiona Glaser 66b417d464SFiona Glaser return Changed; 67b417d464SFiona Glaser } 68b417d464SFiona Glaser 69410eaeb0SChandler Carruth PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM, 70410eaeb0SChandler Carruth LoopStandardAnalysisResults &AR, 71410eaeb0SChandler Carruth LPMUpdater &) { 72e6a9c248SDavid Green if (!simplifyLoopCFG(L, AR.DT, AR.LI, AR.SE)) 73ab6a513bSJustin Bogner return PreservedAnalyses::all(); 74ca68a3ecSChandler Carruth 75ab6a513bSJustin Bogner return getLoopPassPreservedAnalyses(); 76ab6a513bSJustin Bogner } 77ab6a513bSJustin Bogner 78ab6a513bSJustin Bogner namespace { 79ab6a513bSJustin Bogner class LoopSimplifyCFGLegacyPass : public LoopPass { 80ab6a513bSJustin Bogner public: 81ab6a513bSJustin Bogner static char ID; // Pass ID, replacement for typeid 82ab6a513bSJustin Bogner LoopSimplifyCFGLegacyPass() : LoopPass(ID) { 83ab6a513bSJustin Bogner initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry()); 84ab6a513bSJustin Bogner } 85ab6a513bSJustin Bogner 86ab6a513bSJustin Bogner bool runOnLoop(Loop *L, LPPassManager &) override { 87aa641a51SAndrew Kaylor if (skipLoop(L)) 88b417d464SFiona Glaser return false; 89b417d464SFiona Glaser 90ab6a513bSJustin Bogner DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 91ab6a513bSJustin Bogner LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 92e6a9c248SDavid Green ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 93e6a9c248SDavid Green return simplifyLoopCFG(*L, DT, LI, SE); 94ab6a513bSJustin Bogner } 95ab6a513bSJustin Bogner 96ab6a513bSJustin Bogner void getAnalysisUsage(AnalysisUsage &AU) const override { 9749c22190SChandler Carruth AU.addPreserved<DependenceAnalysisWrapperPass>(); 98ab6a513bSJustin Bogner getLoopAnalysisUsage(AU); 99ab6a513bSJustin Bogner } 100ab6a513bSJustin Bogner }; 101ab6a513bSJustin Bogner } 102ab6a513bSJustin Bogner 103ab6a513bSJustin Bogner char LoopSimplifyCFGLegacyPass::ID = 0; 104ab6a513bSJustin Bogner INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 105ab6a513bSJustin Bogner "Simplify loop CFG", false, false) 106ab6a513bSJustin Bogner INITIALIZE_PASS_DEPENDENCY(LoopPass) 107ab6a513bSJustin Bogner INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 108ab6a513bSJustin Bogner "Simplify loop CFG", false, false) 109ab6a513bSJustin Bogner 110ab6a513bSJustin Bogner Pass *llvm::createLoopSimplifyCFGPass() { 111ab6a513bSJustin Bogner return new LoopSimplifyCFGLegacyPass(); 112b417d464SFiona Glaser } 113