1 //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements flattening of CFG.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Analysis/AliasAnalysis.h"
14 #include "llvm/IR/PassManager.h"
15 #include "llvm/IR/ValueHandle.h"
16 #include "llvm/InitializePasses.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Transforms/Scalar.h"
19 #include "llvm/Transforms/Scalar/FlattenCFG.h"
20 #include "llvm/Transforms/Utils/Local.h"
24 #define DEBUG_TYPE "flatten-cfg"
27 struct FlattenCFGLegacyPass
: public FunctionPass
{
28 static char ID
; // Pass identification, replacement for typeid
30 FlattenCFGLegacyPass() : FunctionPass(ID
) {
31 initializeFlattenCFGLegacyPassPass(*PassRegistry::getPassRegistry());
33 bool runOnFunction(Function
&F
) override
;
35 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
36 AU
.addRequired
<AAResultsWrapperPass
>();
43 /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,
44 /// iterating until no more changes are made.
45 bool iterativelyFlattenCFG(Function
&F
, AliasAnalysis
*AA
) {
47 bool LocalChange
= true;
49 // Use block handles instead of iterating over function blocks directly
50 // to avoid using iterators invalidated by erasing blocks.
51 std::vector
<WeakVH
> Blocks
;
52 Blocks
.reserve(F
.size());
54 Blocks
.push_back(&BB
);
59 // Loop over all of the basic blocks and try to flatten them.
60 for (WeakVH
&BlockHandle
: Blocks
) {
61 // Skip blocks erased by FlattenCFG.
62 if (auto *BB
= cast_or_null
<BasicBlock
>(BlockHandle
))
63 if (FlattenCFG(BB
, AA
))
66 Changed
|= LocalChange
;
72 char FlattenCFGLegacyPass::ID
= 0;
74 INITIALIZE_PASS_BEGIN(FlattenCFGLegacyPass
, "flattencfg", "Flatten the CFG",
76 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass
)
77 INITIALIZE_PASS_END(FlattenCFGLegacyPass
, "flattencfg", "Flatten the CFG",
80 // Public interface to the FlattenCFG pass
81 FunctionPass
*llvm::createFlattenCFGPass() {
82 return new FlattenCFGLegacyPass();
85 bool FlattenCFGLegacyPass::runOnFunction(Function
&F
) {
86 AA
= &getAnalysis
<AAResultsWrapperPass
>().getAAResults();
87 bool EverChanged
= false;
88 // iterativelyFlattenCFG can make some blocks dead.
89 while (iterativelyFlattenCFG(F
, AA
)) {
90 removeUnreachableBlocks(F
);
96 PreservedAnalyses
FlattenCFGPass::run(Function
&F
,
97 FunctionAnalysisManager
&AM
) {
98 bool EverChanged
= false;
99 AliasAnalysis
*AA
= &AM
.getResult
<AAManager
>(F
);
100 // iterativelyFlattenCFG can make some blocks dead.
101 while (iterativelyFlattenCFG(F
, AA
)) {
102 removeUnreachableBlocks(F
);
105 return EverChanged
? PreservedAnalyses::none() : PreservedAnalyses::all();