diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-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.cpp | 256 |
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)); } |