1 //===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Loop SimplifyCFG Pass. This pass is responsible for 11 // basic loop CFG cleanup, primarily to assist other loop passes. If you 12 // encounter a noncanonical CFG construct that causes another loop pass to 13 // perform suboptimally, this is the place to fix it up. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/Statistic.h" 20 #include "llvm/Analysis/AliasAnalysis.h" 21 #include "llvm/Analysis/AssumptionCache.h" 22 #include "llvm/Analysis/BasicAliasAnalysis.h" 23 #include "llvm/Analysis/DependenceAnalysis.h" 24 #include "llvm/Analysis/GlobalsModRef.h" 25 #include "llvm/Analysis/LoopInfo.h" 26 #include "llvm/Analysis/LoopPass.h" 27 #include "llvm/Analysis/MemorySSA.h" 28 #include "llvm/Analysis/MemorySSAUpdater.h" 29 #include "llvm/Analysis/ScalarEvolution.h" 30 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 31 #include "llvm/Analysis/TargetTransformInfo.h" 32 #include "llvm/IR/DomTreeUpdater.h" 33 #include "llvm/IR/Dominators.h" 34 #include "llvm/Transforms/Scalar.h" 35 #include "llvm/Transforms/Scalar/LoopPassManager.h" 36 #include "llvm/Transforms/Utils.h" 37 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 38 #include "llvm/Transforms/Utils/Local.h" 39 #include "llvm/Transforms/Utils/LoopUtils.h" 40 using namespace llvm; 41 42 #define DEBUG_TYPE "loop-simplifycfg" 43 44 static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT, 45 LoopInfo &LI, MemorySSAUpdater *MSSAU) { 46 bool Changed = false; 47 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); 48 // Copy blocks into a temporary array to avoid iterator invalidation issues 49 // as we remove them. 50 SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); 51 52 for (auto &Block : Blocks) { 53 // Attempt to merge blocks in the trivial case. Don't modify blocks which 54 // belong to other loops. 55 BasicBlock *Succ = cast_or_null<BasicBlock>(Block); 56 if (!Succ) 57 continue; 58 59 BasicBlock *Pred = Succ->getSinglePredecessor(); 60 if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) 61 continue; 62 63 // Merge Succ into Pred and delete it. 64 MergeBlockIntoPredecessor(Succ, &DTU, &LI, MSSAU); 65 66 Changed = true; 67 } 68 69 return Changed; 70 } 71 72 static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, 73 ScalarEvolution &SE, MemorySSAUpdater *MSSAU) { 74 bool Changed = false; 75 76 // Eliminate unconditional branches by merging blocks into their predecessors. 77 Changed |= mergeBlocksIntoPredecessors(L, DT, LI, MSSAU); 78 79 if (Changed) 80 SE.forgetTopmostLoop(&L); 81 82 return Changed; 83 } 84 85 PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM, 86 LoopStandardAnalysisResults &AR, 87 LPMUpdater &) { 88 Optional<MemorySSAUpdater> MSSAU; 89 if (EnableMSSALoopDependency && AR.MSSA) 90 MSSAU = MemorySSAUpdater(AR.MSSA); 91 if (!simplifyLoopCFG(L, AR.DT, AR.LI, AR.SE, 92 MSSAU.hasValue() ? MSSAU.getPointer() : nullptr)) 93 return PreservedAnalyses::all(); 94 95 return getLoopPassPreservedAnalyses(); 96 } 97 98 namespace { 99 class LoopSimplifyCFGLegacyPass : public LoopPass { 100 public: 101 static char ID; // Pass ID, replacement for typeid 102 LoopSimplifyCFGLegacyPass() : LoopPass(ID) { 103 initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry()); 104 } 105 106 bool runOnLoop(Loop *L, LPPassManager &) override { 107 if (skipLoop(L)) 108 return false; 109 110 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 111 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 112 ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 113 Optional<MemorySSAUpdater> MSSAU; 114 if (EnableMSSALoopDependency) { 115 MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); 116 MSSAU = MemorySSAUpdater(MSSA); 117 if (VerifyMemorySSA) 118 MSSA->verifyMemorySSA(); 119 } 120 return simplifyLoopCFG(*L, DT, LI, SE, 121 MSSAU.hasValue() ? MSSAU.getPointer() : nullptr); 122 } 123 124 void getAnalysisUsage(AnalysisUsage &AU) const override { 125 if (EnableMSSALoopDependency) { 126 AU.addRequired<MemorySSAWrapperPass>(); 127 AU.addPreserved<MemorySSAWrapperPass>(); 128 } 129 AU.addPreserved<DependenceAnalysisWrapperPass>(); 130 getLoopAnalysisUsage(AU); 131 } 132 }; 133 } 134 135 char LoopSimplifyCFGLegacyPass::ID = 0; 136 INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 137 "Simplify loop CFG", false, false) 138 INITIALIZE_PASS_DEPENDENCY(LoopPass) 139 INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) 140 INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", 141 "Simplify loop CFG", false, false) 142 143 Pass *llvm::createLoopSimplifyCFGPass() { 144 return new LoopSimplifyCFGLegacyPass(); 145 } 146