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/CFG.h"
15 #include "llvm/IR/ValueHandle.h"
16 #include "llvm/Pass.h"
17 #include "llvm/Transforms/Scalar.h"
18 #include "llvm/Transforms/Utils/Local.h"
22 #define DEBUG_TYPE "flattencfg"
25 struct FlattenCFGPass
: public FunctionPass
{
26 static char ID
; // Pass identification, replacement for typeid
28 FlattenCFGPass() : FunctionPass(ID
) {
29 initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry());
31 bool runOnFunction(Function
&F
) override
;
33 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
34 AU
.addRequired
<AAResultsWrapperPass
>();
42 char FlattenCFGPass::ID
= 0;
43 INITIALIZE_PASS_BEGIN(FlattenCFGPass
, "flattencfg", "Flatten the CFG", false,
45 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass
)
46 INITIALIZE_PASS_END(FlattenCFGPass
, "flattencfg", "Flatten the CFG", false,
49 // Public interface to the FlattenCFG pass
50 FunctionPass
*llvm::createFlattenCFGPass() { return new FlattenCFGPass(); }
52 /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,
53 /// iterating until no more changes are made.
54 static bool iterativelyFlattenCFG(Function
&F
, AliasAnalysis
*AA
) {
56 bool LocalChange
= true;
58 // Use block handles instead of iterating over function blocks directly
59 // to avoid using iterators invalidated by erasing blocks.
60 std::vector
<WeakVH
> Blocks
;
61 Blocks
.reserve(F
.size());
63 Blocks
.push_back(&BB
);
68 // Loop over all of the basic blocks and try to flatten them.
69 for (WeakVH
&BlockHandle
: Blocks
) {
70 // Skip blocks erased by FlattenCFG.
71 if (auto *BB
= cast_or_null
<BasicBlock
>(BlockHandle
))
72 if (FlattenCFG(BB
, AA
))
75 Changed
|= LocalChange
;
80 bool FlattenCFGPass::runOnFunction(Function
&F
) {
81 AA
= &getAnalysis
<AAResultsWrapperPass
>().getAAResults();
82 bool EverChanged
= false;
83 // iterativelyFlattenCFG can make some blocks dead.
84 while (iterativelyFlattenCFG(F
, AA
)) {
85 removeUnreachableBlocks(F
);