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