Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
35294 views
//===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements flattening of CFG.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Analysis/AliasAnalysis.h"13#include "llvm/IR/PassManager.h"14#include "llvm/IR/ValueHandle.h"15#include "llvm/InitializePasses.h"16#include "llvm/Pass.h"17#include "llvm/Transforms/Scalar.h"18#include "llvm/Transforms/Scalar/FlattenCFG.h"19#include "llvm/Transforms/Utils/Local.h"2021using namespace llvm;2223#define DEBUG_TYPE "flatten-cfg"2425namespace {26struct FlattenCFGLegacyPass : public FunctionPass {27static char ID; // Pass identification, replacement for typeid28public:29FlattenCFGLegacyPass() : FunctionPass(ID) {30initializeFlattenCFGLegacyPassPass(*PassRegistry::getPassRegistry());31}32bool runOnFunction(Function &F) override;3334void getAnalysisUsage(AnalysisUsage &AU) const override {35AU.addRequired<AAResultsWrapperPass>();36}3738private:39AliasAnalysis *AA;40};4142/// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,43/// iterating until no more changes are made.44bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {45bool Changed = false;46bool LocalChange = true;4748// Use block handles instead of iterating over function blocks directly49// to avoid using iterators invalidated by erasing blocks.50std::vector<WeakVH> Blocks;51Blocks.reserve(F.size());52for (auto &BB : F)53Blocks.push_back(&BB);5455while (LocalChange) {56LocalChange = false;5758// Loop over all of the basic blocks and try to flatten them.59for (WeakVH &BlockHandle : Blocks) {60// Skip blocks erased by FlattenCFG.61if (auto *BB = cast_or_null<BasicBlock>(BlockHandle))62if (FlattenCFG(BB, AA))63LocalChange = true;64}65Changed |= LocalChange;66}67return Changed;68}69} // namespace7071char FlattenCFGLegacyPass::ID = 0;7273INITIALIZE_PASS_BEGIN(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",74false, false)75INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)76INITIALIZE_PASS_END(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",77false, false)7879// Public interface to the FlattenCFG pass80FunctionPass *llvm::createFlattenCFGPass() {81return new FlattenCFGLegacyPass();82}8384bool FlattenCFGLegacyPass::runOnFunction(Function &F) {85AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();86bool EverChanged = false;87// iterativelyFlattenCFG can make some blocks dead.88while (iterativelyFlattenCFG(F, AA)) {89removeUnreachableBlocks(F);90EverChanged = true;91}92return EverChanged;93}9495PreservedAnalyses FlattenCFGPass::run(Function &F,96FunctionAnalysisManager &AM) {97bool EverChanged = false;98AliasAnalysis *AA = &AM.getResult<AAManager>(F);99// iterativelyFlattenCFG can make some blocks dead.100while (iterativelyFlattenCFG(F, AA)) {101removeUnreachableBlocks(F);102EverChanged = true;103}104return EverChanged ? PreservedAnalyses::none() : PreservedAnalyses::all();105}106107108