/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
Line | Count | Source |
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. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "llvm/Analysis/AliasAnalysis.h" |
14 | | #include "llvm/Transforms/Utils/Local.h" |
15 | | #include "llvm/IR/CFG.h" |
16 | | #include "llvm/Pass.h" |
17 | | #include "llvm/Transforms/Scalar.h" |
18 | | using namespace llvm; |
19 | | |
20 | | #define DEBUG_TYPE "flattencfg" |
21 | | |
22 | | namespace { |
23 | | struct FlattenCFGPass : public FunctionPass { |
24 | | static char ID; // Pass identification, replacement for typeid |
25 | | public: |
26 | 2.72k | FlattenCFGPass() : FunctionPass(ID) { |
27 | 2.72k | initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry()); |
28 | 2.72k | } |
29 | | bool runOnFunction(Function &F) override; |
30 | | |
31 | 2.70k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
32 | 2.70k | AU.addRequired<AAResultsWrapperPass>(); |
33 | 2.70k | } |
34 | | |
35 | | private: |
36 | | AliasAnalysis *AA; |
37 | | }; |
38 | | } |
39 | | |
40 | | char FlattenCFGPass::ID = 0; |
41 | 36.0k | INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, |
42 | 36.0k | false) |
43 | 36.0k | INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) |
44 | 36.0k | INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, |
45 | | false) |
46 | | |
47 | | // Public interface to the FlattenCFG pass |
48 | 2.72k | FunctionPass *llvm::createFlattenCFGPass() { return new FlattenCFGPass(); } |
49 | | |
50 | | /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function, |
51 | | /// iterating until no more changes are made. |
52 | 27.4k | static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) { |
53 | 27.4k | bool Changed = false; |
54 | 27.4k | bool LocalChange = true; |
55 | 55.0k | while (LocalChange) { |
56 | 27.5k | LocalChange = false; |
57 | 27.5k | |
58 | 27.5k | // Loop over all of the basic blocks and remove them if they are unneeded... |
59 | 27.5k | // |
60 | 57.9k | for (Function::iterator BBIt = F.begin(); BBIt != F.end();) { |
61 | 30.4k | if (FlattenCFG(&*BBIt++, AA)) { |
62 | 8 | LocalChange = true; |
63 | 8 | } |
64 | 30.4k | } |
65 | 27.5k | Changed |= LocalChange; |
66 | 27.5k | } |
67 | 27.4k | return Changed; |
68 | 27.4k | } |
69 | | |
70 | 27.4k | bool FlattenCFGPass::runOnFunction(Function &F) { |
71 | 27.4k | AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); |
72 | 27.4k | bool EverChanged = false; |
73 | 27.4k | // iterativelyFlattenCFG can make some blocks dead. |
74 | 27.4k | while (iterativelyFlattenCFG(F, AA)) { |
75 | 6 | removeUnreachableBlocks(F); |
76 | 6 | EverChanged = true; |
77 | 6 | } |
78 | 27.4k | return EverChanged; |
79 | 27.4k | } |