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