mirror of
https://github.com/RPCS3/llvm.git
synced 2026-08-27 02:51:23 -04:00
18e311ebbb
Summary: This patch is the second in a series of patches related to the [[ http://lists.llvm.org/pipermail/llvm-dev/2018-June/123883.html | RFC - A new dominator tree updater for LLVM ]]. It converts passes (e.g. adce/jump-threading) and various functions which currently accept DDT in local.cpp and BasicBlockUtils.cpp to use the new DomTreeUpdater class. These converted functions in utils can accept DomTreeUpdater with either UpdateStrategy and can deal with both DT and PDT held by the DomTreeUpdater. Reviewers: brzycki, kuhar, dmgreen, grosser, davide Reviewed By: brzycki Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48967 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338814 91177308-0d34-0410-b5e6-96231b3b80d8
115 lines
4.0 KiB
C++
115 lines
4.0 KiB
C++
//===--------- 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/DomTreeUpdater.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
|
#include "llvm/Transforms/Utils.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.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,
|
|
ScalarEvolution &SE) {
|
|
bool Changed = false;
|
|
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
|
|
// Copy blocks into a temporary array to avoid iterator invalidation issues
|
|
// as we remove them.
|
|
SmallVector<WeakTrackingVH, 16> 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<BasicBlock>(Block);
|
|
if (!Succ)
|
|
continue;
|
|
|
|
BasicBlock *Pred = Succ->getSinglePredecessor();
|
|
if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L)
|
|
continue;
|
|
|
|
// Merge Succ into Pred and delete it.
|
|
MergeBlockIntoPredecessor(Succ, &DTU, &LI);
|
|
|
|
SE.forgetLoop(&L);
|
|
Changed = true;
|
|
}
|
|
|
|
return Changed;
|
|
}
|
|
|
|
PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM,
|
|
LoopStandardAnalysisResults &AR,
|
|
LPMUpdater &) {
|
|
if (!simplifyLoopCFG(L, AR.DT, AR.LI, AR.SE))
|
|
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<DominatorTreeWrapperPass>().getDomTree();
|
|
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
|
ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
|
return simplifyLoopCFG(*L, DT, LI, SE);
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.addPreserved<DependenceAnalysisWrapperPass>();
|
|
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();
|
|
}
|