123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements flattening of CFG.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Analysis/AliasAnalysis.h"
- #include "llvm/IR/PassManager.h"
- #include "llvm/IR/ValueHandle.h"
- #include "llvm/InitializePasses.h"
- #include "llvm/Pass.h"
- #include "llvm/Transforms/Scalar.h"
- #include "llvm/Transforms/Scalar/FlattenCFG.h"
- #include "llvm/Transforms/Utils/Local.h"
- using namespace llvm;
- #define DEBUG_TYPE "flattencfg"
- namespace {
- struct FlattenCFGLegacyPass : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- public:
- FlattenCFGLegacyPass() : FunctionPass(ID) {
- initializeFlattenCFGLegacyPassPass(*PassRegistry::getPassRegistry());
- }
- bool runOnFunction(Function &F) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<AAResultsWrapperPass>();
- }
- private:
- AliasAnalysis *AA;
- };
- /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,
- /// iterating until no more changes are made.
- bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {
- bool Changed = false;
- bool LocalChange = true;
- // Use block handles instead of iterating over function blocks directly
- // to avoid using iterators invalidated by erasing blocks.
- std::vector<WeakVH> Blocks;
- Blocks.reserve(F.size());
- for (auto &BB : F)
- Blocks.push_back(&BB);
- while (LocalChange) {
- LocalChange = false;
- // Loop over all of the basic blocks and try to flatten them.
- for (WeakVH &BlockHandle : Blocks) {
- // Skip blocks erased by FlattenCFG.
- if (auto *BB = cast_or_null<BasicBlock>(BlockHandle))
- if (FlattenCFG(BB, AA))
- LocalChange = true;
- }
- Changed |= LocalChange;
- }
- return Changed;
- }
- } // namespace
- char FlattenCFGLegacyPass::ID = 0;
- INITIALIZE_PASS_BEGIN(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",
- false, false)
- INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
- INITIALIZE_PASS_END(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",
- false, false)
- // Public interface to the FlattenCFG pass
- FunctionPass *llvm::createFlattenCFGPass() {
- return new FlattenCFGLegacyPass();
- }
- bool FlattenCFGLegacyPass::runOnFunction(Function &F) {
- AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- bool EverChanged = false;
- // iterativelyFlattenCFG can make some blocks dead.
- while (iterativelyFlattenCFG(F, AA)) {
- removeUnreachableBlocks(F);
- EverChanged = true;
- }
- return EverChanged;
- }
- PreservedAnalyses FlattenCFGPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- bool EverChanged = false;
- AliasAnalysis *AA = &AM.getResult<AAManager>(F);
- // iterativelyFlattenCFG can make some blocks dead.
- while (iterativelyFlattenCFG(F, AA)) {
- removeUnreachableBlocks(F);
- EverChanged = true;
- }
- return EverChanged ? PreservedAnalyses::none() : PreservedAnalyses::all();
- }
|