blob: 1fa41ec5c2260e8e9a361724d1a56384f854afa1 [file] [log] [blame]
Tom Stellardaa664d92013-08-06 02:43:45 +00001//===- 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#define DEBUG_TYPE "flattencfg"
15#include "llvm/Transforms/Scalar.h"
16#include "llvm/Analysis/AliasAnalysis.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000017#include "llvm/IR/CFG.h"
Tom Stellardaa664d92013-08-06 02:43:45 +000018#include "llvm/Pass.h"
Tom Stellardaa664d92013-08-06 02:43:45 +000019#include "llvm/Transforms/Utils/Local.h"
20using namespace llvm;
21
22namespace {
23struct FlattenCFGPass : public FunctionPass {
24 static char ID; // Pass identification, replacement for typeid
25public:
26 FlattenCFGPass() : FunctionPass(ID) {
27 initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry());
28 }
29 bool runOnFunction(Function &F);
30
31 void getAnalysisUsage(AnalysisUsage &AU) const {
32 AU.addRequired<AliasAnalysis>();
33 }
34
35private:
36 AliasAnalysis *AA;
37};
38}
39
40char FlattenCFGPass::ID = 0;
41INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
42 false)
43INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
44INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
45 false)
46
47// Public interface to the FlattenCFG pass
48FunctionPass *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.
52static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {
53 bool Changed = false;
54 bool LocalChange = true;
55 while (LocalChange) {
56 LocalChange = false;
57
58 // Loop over all of the basic blocks and remove them if they are unneeded...
59 //
60 for (Function::iterator BBIt = F.begin(); BBIt != F.end();) {
61 if (FlattenCFG(BBIt++, AA)) {
62 LocalChange = true;
63 }
64 }
65 Changed |= LocalChange;
66 }
67 return Changed;
68}
69
70bool FlattenCFGPass::runOnFunction(Function &F) {
71 AA = &getAnalysis<AliasAnalysis>();
72 bool EverChanged = false;
73 // iterativelyFlattenCFG can make some blocks dead.
74 while (iterativelyFlattenCFG(F, AA)) {
75 removeUnreachableBlocks(F);
76 EverChanged = true;
77 }
78 return EverChanged;
79}