//===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the Loop SimplifyCFG Pass. This pass is responsible for // basic loop CFG cleanup, primarily to assist other loop passes. If you // encounter a noncanonical CFG construct that causes another loop pass to // perform suboptimally, this is the place to fix it up. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/DependenceAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" using namespace llvm; #define DEBUG_TYPE "loop-simplifycfg" static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI) { bool Changed = false; // Copy blocks into a temporary array to avoid iterator invalidation issues // as we remove them. SmallVector Blocks(L.blocks()); for (auto &Block : Blocks) { // Attempt to merge blocks in the trivial case. Don't modify blocks which // belong to other loops. BasicBlock *Succ = cast_or_null(Block); if (!Succ) continue; BasicBlock *Pred = Succ->getSinglePredecessor(); if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) continue; // Pred is going to disappear, so we need to update the loop info. if (L.getHeader() == Pred) L.moveToHeader(Succ); LI.removeBlock(Pred); MergeBasicBlockIntoOnlyPred(Succ, &DT); Changed = true; } return Changed; } PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { if (!simplifyLoopCFG(L, AR.DT, AR.LI)) return PreservedAnalyses::all(); return getLoopPassPreservedAnalyses(); } namespace { class LoopSimplifyCFGLegacyPass : public LoopPass { public: static char ID; // Pass ID, replacement for typeid LoopSimplifyCFGLegacyPass() : LoopPass(ID) { initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry()); } bool runOnLoop(Loop *L, LPPassManager &) override { if (skipLoop(L)) return false; DominatorTree &DT = getAnalysis().getDomTree(); LoopInfo &LI = getAnalysis().getLoopInfo(); return simplifyLoopCFG(*L, DT, LI); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addPreserved(); getLoopAnalysisUsage(AU); } }; } char LoopSimplifyCFGLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", "Simplify loop CFG", false, false) INITIALIZE_PASS_DEPENDENCY(LoopPass) INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", "Simplify loop CFG", false, false) Pass *llvm::createLoopSimplifyCFGPass() { return new LoopSimplifyCFGLegacyPass(); }