Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / Transforms / Scalar / SimplifyCFG.cpp
1 //===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements dead code elimination and basic block merging.
11 //
12 // Specifically, this:
13 //   * removes basic blocks with no predecessors
14 //   * merges a basic block into its predecessor if there is only one and the
15 //     predecessor only has one successor.
16 //   * Eliminates PHI nodes for basic blocks with a single predecessor
17 //   * Eliminates a basic block that only contains an unconditional branch
18 //
19 //===----------------------------------------------------------------------===//
20
21 #include "llvm/Transforms/Scalar.h"
22 #include "llvm/Transforms/Utils/Local.h"
23 #include "llvm/Module.h"
24 #include "llvm/Support/CFG.h"
25 #include "llvm/Pass.h"
26 #include "Support/Statistic.h"
27 #include <set>
28
29 namespace {
30   Statistic<> NumSimpl("cfgsimplify", "Number of blocks simplified");
31
32   struct CFGSimplifyPass : public FunctionPass {
33     virtual bool runOnFunction(Function &F);
34   };
35   RegisterOpt<CFGSimplifyPass> X("simplifycfg", "Simplify the CFG");
36 }
37
38 FunctionPass *createCFGSimplificationPass() {
39   return new CFGSimplifyPass();
40 }
41
42 static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
43   if (Reachable.count(BB)) return false;
44   Reachable.insert(BB);
45
46   bool Changed = ConstantFoldTerminator(BB);
47   for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
48     MarkAliveBlocks(*SI, Reachable);
49
50   return Changed;
51 }
52
53
54 // It is possible that we may require multiple passes over the code to fully
55 // simplify the CFG.
56 //
57 bool CFGSimplifyPass::runOnFunction(Function &F) {
58   std::set<BasicBlock*> Reachable;
59   bool Changed = MarkAliveBlocks(F.begin(), Reachable);
60
61   // If there are unreachable blocks in the CFG...
62   if (Reachable.size() != F.size()) {
63     assert(Reachable.size() < F.size());
64     NumSimpl += F.size()-Reachable.size();
65
66     // Loop over all of the basic blocks that are not reachable, dropping all of
67     // their internal references...
68     for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
69       if (!Reachable.count(BB)) {
70         for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
71           if (Reachable.count(*SI))
72             (*SI)->removePredecessor(BB);
73         BB->dropAllReferences();
74       }
75     
76     for (Function::iterator I = ++F.begin(); I != F.end();)
77       if (!Reachable.count(I))
78         I = F.getBasicBlockList().erase(I);
79       else
80         ++I;
81
82     Changed = true;
83   }
84
85   bool LocalChange = true;
86   while (LocalChange) {
87     LocalChange = false;
88
89     // Loop over all of the basic blocks (except the first one) and remove them
90     // if they are unneeded...
91     //
92     for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
93       if (SimplifyCFG(BBIt++)) {
94         LocalChange = true;
95         ++NumSimpl;
96       }
97     }
98     Changed |= LocalChange;
99   }
100
101   return Changed;
102 }