blob: 08611d2349a65f6d666f35df6f2b70ef88dae977 [file] [log] [blame]
Chris Lattnerfa7dad82002-05-21 20:49:37 +00001//===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
2//
3// This file implements dead code elimination and basic block merging.
4//
5// Specifically, this:
6// * removes basic blocks with no predecessors
7// * merges a basic block into its predecessor if there is only one and the
8// predecessor only has one successor.
9// * Eliminates PHI nodes for basic blocks with a single predecessor
10// * Eliminates a basic block that only contains an unconditional branch
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Scalar.h"
15#include "llvm/Transforms/Utils/Local.h"
16#include "llvm/Module.h"
17#include "llvm/GlobalVariable.h"
18#include "llvm/Support/CFG.h"
19#include "llvm/Pass.h"
20#include "Support/StatisticReporter.h"
21#include <set>
22
23static Statistic<> NumSimpl("cfgsimplify\t- Number of blocks simplified");
24
25namespace {
26 struct CFGSimplifyPass : public FunctionPass {
27 const char *getPassName() const { return "Simplify CFG"; }
28
Chris Lattner113f4f42002-06-25 16:13:24 +000029 virtual bool runOnFunction(Function &F);
Chris Lattnerfa7dad82002-05-21 20:49:37 +000030 };
31}
32
33Pass *createCFGSimplificationPass() {
34 return new CFGSimplifyPass();
35}
36
37static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
38 if (Reachable.count(BB)) return false;
39 Reachable.insert(BB);
40
41 bool Changed = ConstantFoldTerminator(BB);
42 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
43 MarkAliveBlocks(*SI, Reachable);
44
45 return Changed;
46}
47
48
49// It is possible that we may require multiple passes over the code to fully
50// simplify the CFG.
51//
Chris Lattner113f4f42002-06-25 16:13:24 +000052bool CFGSimplifyPass::runOnFunction(Function &F) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000053 std::set<BasicBlock*> Reachable;
Chris Lattner113f4f42002-06-25 16:13:24 +000054 bool Changed = MarkAliveBlocks(F.begin(), Reachable);
Chris Lattnerfa7dad82002-05-21 20:49:37 +000055
56 // If there are unreachable blocks in the CFG...
Chris Lattner113f4f42002-06-25 16:13:24 +000057 if (Reachable.size() != F.size()) {
58 assert(Reachable.size() < F.size());
59 NumSimpl += F.size()-Reachable.size();
Chris Lattnerfa7dad82002-05-21 20:49:37 +000060
61 // Loop over all of the basic blocks that are not reachable, dropping all of
62 // their internal references...
Chris Lattner113f4f42002-06-25 16:13:24 +000063 for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
64 if (!Reachable.count(BB)) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000065 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
66 if (Reachable.count(*SI))
67 (*SI)->removePredecessor(BB);
68 BB->dropAllReferences();
69 }
70
Chris Lattner113f4f42002-06-25 16:13:24 +000071 for (Function::iterator I = ++F.begin(); I != F.end();)
72 if (!Reachable.count(I))
73 I = F.getBasicBlockList().erase(I);
Chris Lattnerfa7dad82002-05-21 20:49:37 +000074 else
75 ++I;
76
77 Changed = true;
78 }
79
80 bool LocalChange = true;
81 while (LocalChange) {
82 LocalChange = false;
83
84 // Loop over all of the basic blocks (except the first one) and remove them
85 // if they are unneeded...
86 //
Chris Lattner113f4f42002-06-25 16:13:24 +000087 for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
88 if (SimplifyCFG(BBIt++)) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000089 LocalChange = true;
90 ++NumSimpl;
Chris Lattnerfa7dad82002-05-21 20:49:37 +000091 }
92 }
93 Changed |= LocalChange;
94 }
95
96 return Changed;
97}