]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file implements flattening of CFG. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
14 | #include "llvm/Transforms/Scalar.h" | |
15 | #include "llvm/Analysis/AliasAnalysis.h" | |
16 | #include "llvm/IR/CFG.h" | |
17 | #include "llvm/Pass.h" | |
18 | #include "llvm/Transforms/Utils/Local.h" | |
19 | using namespace llvm; | |
20 | ||
21 | #define DEBUG_TYPE "flattencfg" | |
22 | ||
23 | namespace { | |
24 | struct FlattenCFGPass : public FunctionPass { | |
25 | static char ID; // Pass identification, replacement for typeid | |
26 | public: | |
27 | FlattenCFGPass() : FunctionPass(ID) { | |
28 | initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry()); | |
29 | } | |
30 | bool runOnFunction(Function &F) override; | |
31 | ||
32 | void getAnalysisUsage(AnalysisUsage &AU) const override { | |
33 | AU.addRequired<AliasAnalysis>(); | |
34 | } | |
35 | ||
36 | private: | |
37 | AliasAnalysis *AA; | |
38 | }; | |
39 | } | |
40 | ||
41 | char FlattenCFGPass::ID = 0; | |
42 | INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, | |
43 | false) | |
44 | INITIALIZE_AG_DEPENDENCY(AliasAnalysis) | |
45 | INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, | |
46 | false) | |
47 | ||
48 | // Public interface to the FlattenCFG pass | |
49 | FunctionPass *llvm::createFlattenCFGPass() { return new FlattenCFGPass(); } | |
50 | ||
51 | /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function, | |
52 | /// iterating until no more changes are made. | |
53 | static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) { | |
54 | bool Changed = false; | |
55 | bool LocalChange = true; | |
56 | while (LocalChange) { | |
57 | LocalChange = false; | |
58 | ||
59 | // Loop over all of the basic blocks and remove them if they are unneeded... | |
60 | // | |
61 | for (Function::iterator BBIt = F.begin(); BBIt != F.end();) { | |
62 | if (FlattenCFG(BBIt++, AA)) { | |
63 | LocalChange = true; | |
64 | } | |
65 | } | |
66 | Changed |= LocalChange; | |
67 | } | |
68 | return Changed; | |
69 | } | |
70 | ||
71 | bool FlattenCFGPass::runOnFunction(Function &F) { | |
72 | AA = &getAnalysis<AliasAnalysis>(); | |
73 | bool EverChanged = false; | |
74 | // iterativelyFlattenCFG can make some blocks dead. | |
75 | while (iterativelyFlattenCFG(F, AA)) { | |
76 | removeUnreachableBlocks(F); | |
77 | EverChanged = true; | |
78 | } | |
79 | return EverChanged; | |
80 | } |