[ThinLTO] Add code comment. NFC
[llvm-complete.git] / lib / Transforms / Scalar / FlattenCFGPass.cpp
blobe6abf1ceb026d5fad03648ae74d47a9063711a21
1 //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
20 using namespace llvm;
22 #define DEBUG_TYPE "flattencfg"
24 namespace {
25 struct FlattenCFGPass : public FunctionPass {
26 static char ID; // Pass identification, replacement for typeid
27 public:
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>();
37 private:
38 AliasAnalysis *AA;
42 char FlattenCFGPass::ID = 0;
43 INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
44 false)
45 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
46 INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
47 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) {
55 bool Changed = false;
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());
62 for (auto &BB : F)
63 Blocks.push_back(&BB);
65 while (LocalChange) {
66 LocalChange = false;
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))
73 LocalChange = true;
75 Changed |= LocalChange;
77 return Changed;
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);
86 EverChanged = true;
88 return EverChanged;