aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp')
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp256
1 files changed, 128 insertions, 128 deletions
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 7fdd5c659d..38e7109ead 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -25,25 +25,25 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
#include <utility>
using namespace llvm;
@@ -65,10 +65,10 @@ static cl::opt<bool> UserForwardSwitchCond(
"forward-switch-cond", cl::Hidden, cl::init(false),
cl::desc("Forward switch condition to phi ops (default = false)"));
-static cl::opt<bool> UserHoistCommonInsts(
- "hoist-common-insts", cl::Hidden, cl::init(false),
- cl::desc("hoist common instructions (default = false)"));
-
+static cl::opt<bool> UserHoistCommonInsts(
+ "hoist-common-insts", cl::Hidden, cl::init(false),
+ cl::desc("hoist common instructions (default = false)"));
+
static cl::opt<bool> UserSinkCommonInsts(
"sink-common-insts", cl::Hidden, cl::init(false),
cl::desc("Sink common instructions (default = false)"));
@@ -78,18 +78,18 @@ STATISTIC(NumSimpl, "Number of blocks simplified");
/// If we have more than one empty (other than phi node) return blocks,
/// merge them together to promote recursive block merging.
-static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
+static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
bool Changed = false;
- std::vector<DominatorTree::UpdateType> Updates;
- SmallVector<BasicBlock *, 8> DeadBlocks;
-
+ std::vector<DominatorTree::UpdateType> Updates;
+ SmallVector<BasicBlock *, 8> DeadBlocks;
+
BasicBlock *RetBlock = nullptr;
// Scan all the blocks in the function, looking for empty return blocks.
- for (BasicBlock &BB : make_early_inc_range(F)) {
- if (DTU && DTU->isBBPendingDeletion(&BB))
- continue;
+ for (BasicBlock &BB : make_early_inc_range(F)) {
+ if (DTU && DTU->isBBPendingDeletion(&BB))
+ continue;
// Only look at return blocks.
ReturnInst *Ret = dyn_cast<ReturnInst>(BB.getTerminator());
@@ -140,18 +140,18 @@ static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
if (Ret->getNumOperands() == 0 ||
Ret->getOperand(0) ==
cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0)) {
- // All predecessors of BB should now branch to RetBlock instead.
- if (DTU) {
- for (auto *Predecessor : predecessors(&BB)) {
- // But, iff Predecessor already branches to RetBlock,
- // don't (re-)add DomTree edge, because it already exists.
- if (!is_contained(successors(Predecessor), RetBlock))
- Updates.push_back({DominatorTree::Insert, Predecessor, RetBlock});
- Updates.push_back({DominatorTree::Delete, Predecessor, &BB});
- }
- }
+ // All predecessors of BB should now branch to RetBlock instead.
+ if (DTU) {
+ for (auto *Predecessor : predecessors(&BB)) {
+ // But, iff Predecessor already branches to RetBlock,
+ // don't (re-)add DomTree edge, because it already exists.
+ if (!is_contained(successors(Predecessor), RetBlock))
+ Updates.push_back({DominatorTree::Insert, Predecessor, RetBlock});
+ Updates.push_back({DominatorTree::Delete, Predecessor, &BB});
+ }
+ }
BB.replaceAllUsesWith(RetBlock);
- DeadBlocks.emplace_back(&BB);
+ DeadBlocks.emplace_back(&BB);
continue;
}
@@ -175,55 +175,55 @@ static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
RetBlockPHI->addIncoming(Ret->getOperand(0), &BB);
BB.getTerminator()->eraseFromParent();
BranchInst::Create(RetBlock, &BB);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, &BB, RetBlock});
+ if (DTU)
+ Updates.push_back({DominatorTree::Insert, &BB, RetBlock});
+ }
+
+ if (DTU) {
+ DTU->applyUpdates(Updates);
+ for (auto *BB : DeadBlocks)
+ DTU->deleteBB(BB);
+ } else {
+ for (auto *BB : DeadBlocks)
+ BB->eraseFromParent();
}
- if (DTU) {
- DTU->applyUpdates(Updates);
- for (auto *BB : DeadBlocks)
- DTU->deleteBB(BB);
- } else {
- for (auto *BB : DeadBlocks)
- BB->eraseFromParent();
- }
-
return Changed;
}
/// Call SimplifyCFG on all the blocks in the function,
/// iterating until no more changes are made.
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
- DomTreeUpdater *DTU,
+ DomTreeUpdater *DTU,
const SimplifyCFGOptions &Options) {
bool Changed = false;
bool LocalChange = true;
SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32> Edges;
FindFunctionBackedges(F, Edges);
- SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
+ SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
for (unsigned i = 0, e = Edges.size(); i != e; ++i)
- UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
+ UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
+
+ SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
+ UniqueLoopHeaders.end());
- SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
- UniqueLoopHeaders.end());
-
while (LocalChange) {
LocalChange = false;
// Loop over all of the basic blocks and remove them if they are unneeded.
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
- BasicBlock &BB = *BBIt++;
- if (DTU) {
- assert(
- !DTU->isBBPendingDeletion(&BB) &&
- "Should not end up trying to simplify blocks marked for removal.");
- // Make sure that the advanced iterator does not point at the blocks
- // that are marked for removal, skip over all such blocks.
- while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
- ++BBIt;
- }
- if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
+ BasicBlock &BB = *BBIt++;
+ if (DTU) {
+ assert(
+ !DTU->isBBPendingDeletion(&BB) &&
+ "Should not end up trying to simplify blocks marked for removal.");
+ // Make sure that the advanced iterator does not point at the blocks
+ // that are marked for removal, skip over all such blocks.
+ while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
+ ++BBIt;
+ }
+ if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
LocalChange = true;
++NumSimpl;
}
@@ -233,15 +233,15 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
return Changed;
}
-static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
- DominatorTree *DT,
- const SimplifyCFGOptions &Options) {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
+ DominatorTree *DT,
+ const SimplifyCFGOptions &Options) {
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
+ EverChanged |= mergeEmptyReturnBlocks(F, DT ? &DTU : nullptr);
+ EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
- bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
- EverChanged |= mergeEmptyReturnBlocks(F, DT ? &DTU : nullptr);
- EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
-
// If neither pass changed anything, we're done.
if (!EverChanged) return false;
@@ -250,75 +250,75 @@ static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
// iterate between the two optimizations. We structure the code like this to
// avoid rerunning iterativelySimplifyCFG if the second pass of
// removeUnreachableBlocks doesn't do anything.
- if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
+ if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
return true;
do {
- EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
- EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
+ EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
+ EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
} while (EverChanged);
return true;
}
-static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
- DominatorTree *DT,
- const SimplifyCFGOptions &Options) {
- assert((!RequireAndPreserveDomTree ||
- (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
- "Original domtree is invalid?");
-
- bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
-
- assert((!RequireAndPreserveDomTree ||
- (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
- "Failed to maintain validity of domtree!");
-
- return Changed;
-}
-
+static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
+ DominatorTree *DT,
+ const SimplifyCFGOptions &Options) {
+ assert((!RequireAndPreserveDomTree ||
+ (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
+ bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
+
+ assert((!RequireAndPreserveDomTree ||
+ (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
+ "Failed to maintain validity of domtree!");
+
+ return Changed;
+}
+
// Command-line settings override compile-time settings.
-static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
- if (UserBonusInstThreshold.getNumOccurrences())
- Options.BonusInstThreshold = UserBonusInstThreshold;
- if (UserForwardSwitchCond.getNumOccurrences())
- Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
- if (UserSwitchToLookup.getNumOccurrences())
- Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
- if (UserKeepLoops.getNumOccurrences())
- Options.NeedCanonicalLoop = UserKeepLoops;
- if (UserHoistCommonInsts.getNumOccurrences())
- Options.HoistCommonInsts = UserHoistCommonInsts;
- if (UserSinkCommonInsts.getNumOccurrences())
- Options.SinkCommonInsts = UserSinkCommonInsts;
+static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
+ if (UserBonusInstThreshold.getNumOccurrences())
+ Options.BonusInstThreshold = UserBonusInstThreshold;
+ if (UserForwardSwitchCond.getNumOccurrences())
+ Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
+ if (UserSwitchToLookup.getNumOccurrences())
+ Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
+ if (UserKeepLoops.getNumOccurrences())
+ Options.NeedCanonicalLoop = UserKeepLoops;
+ if (UserHoistCommonInsts.getNumOccurrences())
+ Options.HoistCommonInsts = UserHoistCommonInsts;
+ if (UserSinkCommonInsts.getNumOccurrences())
+ Options.SinkCommonInsts = UserSinkCommonInsts;
+}
+
+SimplifyCFGPass::SimplifyCFGPass() : Options() {
+ applyCommandLineOverridesToOptions(Options);
+}
+
+SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
+ : Options(Opts) {
+ applyCommandLineOverridesToOptions(Options);
}
-SimplifyCFGPass::SimplifyCFGPass() : Options() {
- applyCommandLineOverridesToOptions(Options);
-}
-
-SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
- : Options(Opts) {
- applyCommandLineOverridesToOptions(Options);
-}
-
PreservedAnalyses SimplifyCFGPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
Options.AC = &AM.getResult<AssumptionAnalysis>(F);
- DominatorTree *DT = nullptr;
- if (RequireAndPreserveDomTree)
- DT = &AM.getResult<DominatorTreeAnalysis>(F);
- if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
- Options.setSimplifyCondBranch(false).setFoldTwoEntryPHINode(false);
- } else {
- Options.setSimplifyCondBranch(true).setFoldTwoEntryPHINode(true);
- }
- if (!simplifyFunctionCFG(F, TTI, DT, Options))
+ DominatorTree *DT = nullptr;
+ if (RequireAndPreserveDomTree)
+ DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
+ Options.setSimplifyCondBranch(false).setFoldTwoEntryPHINode(false);
+ } else {
+ Options.setSimplifyCondBranch(true).setFoldTwoEntryPHINode(true);
+ }
+ if (!simplifyFunctionCFG(F, TTI, DT, Options))
return PreservedAnalyses::all();
PreservedAnalyses PA;
- if (RequireAndPreserveDomTree)
- PA.preserve<DominatorTreeAnalysis>();
+ if (RequireAndPreserveDomTree)
+ PA.preserve<DominatorTreeAnalysis>();
PA.preserve<GlobalsAA>();
return PA;
}
@@ -329,14 +329,14 @@ struct CFGSimplifyPass : public FunctionPass {
SimplifyCFGOptions Options;
std::function<bool(const Function &)> PredicateFtor;
- CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
+ CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
std::function<bool(const Function &)> Ftor = nullptr)
- : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
+ : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
// Check for command-line overrides of options for debug/customization.
- applyCommandLineOverridesToOptions(Options);
+ applyCommandLineOverridesToOptions(Options);
}
bool runOnFunction(Function &F) override {
@@ -344,9 +344,9 @@ struct CFGSimplifyPass : public FunctionPass {
return false;
Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- DominatorTree *DT = nullptr;
- if (RequireAndPreserveDomTree)
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ DominatorTree *DT = nullptr;
+ if (RequireAndPreserveDomTree)
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
Options.setSimplifyCondBranch(false)
.setFoldTwoEntryPHINode(false);
@@ -356,15 +356,15 @@ struct CFGSimplifyPass : public FunctionPass {
}
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return simplifyFunctionCFG(F, TTI, DT, Options);
+ return simplifyFunctionCFG(F, TTI, DT, Options);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AssumptionCacheTracker>();
- if (RequireAndPreserveDomTree)
- AU.addRequired<DominatorTreeWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
- if (RequireAndPreserveDomTree)
- AU.addPreserved<DominatorTreeWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addPreserved<DominatorTreeWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
}
};
@@ -375,13 +375,13 @@ INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
false)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
false)
// Public interface to the CFGSimplification pass
FunctionPass *
-llvm::createCFGSimplificationPass(SimplifyCFGOptions Options,
+llvm::createCFGSimplificationPass(SimplifyCFGOptions Options,
std::function<bool(const Function &)> Ftor) {
- return new CFGSimplifyPass(Options, std::move(Ftor));
+ return new CFGSimplifyPass(Options, std::move(Ftor));
}