blob: 8e0f7d33073644ef71717239760ff3ea6652156a [file] [log] [blame]
Chris Lattner573527b2002-05-21 20:49:37 +00001//===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
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//===----------------------------------------------------------------------===//
Chris Lattner573527b2002-05-21 20:49:37 +00009//
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"
Chris Lattner573527b2002-05-21 20:49:37 +000024#include "llvm/Support/CFG.h"
25#include "llvm/Pass.h"
Chris Lattnera92f6962002-10-01 22:38:41 +000026#include "Support/Statistic.h"
Chris Lattner573527b2002-05-21 20:49:37 +000027#include <set>
Chris Lattnerd7456022004-01-09 06:02:20 +000028using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000029
Chris Lattner573527b2002-05-21 20:49:37 +000030namespace {
Chris Lattnera92f6962002-10-01 22:38:41 +000031 Statistic<> NumSimpl("cfgsimplify", "Number of blocks simplified");
32
Chris Lattner573527b2002-05-21 20:49:37 +000033 struct CFGSimplifyPass : public FunctionPass {
Chris Lattner7e708292002-06-25 16:13:24 +000034 virtual bool runOnFunction(Function &F);
Chris Lattner573527b2002-05-21 20:49:37 +000035 };
Chris Lattnera6275cc2002-07-26 21:12:46 +000036 RegisterOpt<CFGSimplifyPass> X("simplifycfg", "Simplify the CFG");
Chris Lattner573527b2002-05-21 20:49:37 +000037}
38
Brian Gaeked0fde302003-11-11 22:41:34 +000039// Public interface to the CFGSimplification pass
Chris Lattnerd7456022004-01-09 06:02:20 +000040FunctionPass *llvm::createCFGSimplificationPass() {
Chris Lattner573527b2002-05-21 20:49:37 +000041 return new CFGSimplifyPass();
42}
43
44static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
45 if (Reachable.count(BB)) return false;
46 Reachable.insert(BB);
47
48 bool Changed = ConstantFoldTerminator(BB);
49 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
50 MarkAliveBlocks(*SI, Reachable);
51
52 return Changed;
53}
54
55
56// It is possible that we may require multiple passes over the code to fully
57// simplify the CFG.
58//
Chris Lattner7e708292002-06-25 16:13:24 +000059bool CFGSimplifyPass::runOnFunction(Function &F) {
Chris Lattner573527b2002-05-21 20:49:37 +000060 std::set<BasicBlock*> Reachable;
Chris Lattner7e708292002-06-25 16:13:24 +000061 bool Changed = MarkAliveBlocks(F.begin(), Reachable);
Chris Lattner573527b2002-05-21 20:49:37 +000062
63 // If there are unreachable blocks in the CFG...
Chris Lattner7e708292002-06-25 16:13:24 +000064 if (Reachable.size() != F.size()) {
65 assert(Reachable.size() < F.size());
66 NumSimpl += F.size()-Reachable.size();
Chris Lattner573527b2002-05-21 20:49:37 +000067
68 // Loop over all of the basic blocks that are not reachable, dropping all of
69 // their internal references...
Chris Lattner7e708292002-06-25 16:13:24 +000070 for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
71 if (!Reachable.count(BB)) {
Chris Lattner573527b2002-05-21 20:49:37 +000072 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
73 if (Reachable.count(*SI))
74 (*SI)->removePredecessor(BB);
75 BB->dropAllReferences();
76 }
77
Chris Lattner7e708292002-06-25 16:13:24 +000078 for (Function::iterator I = ++F.begin(); I != F.end();)
79 if (!Reachable.count(I))
80 I = F.getBasicBlockList().erase(I);
Chris Lattner573527b2002-05-21 20:49:37 +000081 else
82 ++I;
83
84 Changed = true;
85 }
86
87 bool LocalChange = true;
88 while (LocalChange) {
89 LocalChange = false;
90
91 // Loop over all of the basic blocks (except the first one) and remove them
92 // if they are unneeded...
93 //
Chris Lattner7e708292002-06-25 16:13:24 +000094 for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
95 if (SimplifyCFG(BBIt++)) {
Chris Lattner573527b2002-05-21 20:49:37 +000096 LocalChange = true;
97 ++NumSimpl;
Chris Lattner573527b2002-05-21 20:49:37 +000098 }
99 }
100 Changed |= LocalChange;
101 }
102
103 return Changed;
104}