blob: af1663c8dbf6250412221b1e82fc283e15f821fc [file] [log] [blame]
Chris Lattnerfa7dad82002-05-21 20:49:37 +00001//===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
John Criswell482202a2003-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 Lattnerfa7dad82002-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"
Chris Lattnera67dd322004-10-18 03:00:50 +000023#include "llvm/Constants.h"
24#include "llvm/Instructions.h"
Chris Lattnerfa7dad82002-05-21 20:49:37 +000025#include "llvm/Module.h"
Chris Lattnerfa7dad82002-05-21 20:49:37 +000026#include "llvm/Support/CFG.h"
27#include "llvm/Pass.h"
Reid Spencer7c16caa2004-09-01 22:55:40 +000028#include "llvm/ADT/Statistic.h"
Chris Lattnerfa7dad82002-05-21 20:49:37 +000029#include <set>
Chris Lattner49525f82004-01-09 06:02:20 +000030using namespace llvm;
Brian Gaeke960707c2003-11-11 22:41:34 +000031
Chris Lattnerfa7dad82002-05-21 20:49:37 +000032namespace {
Chris Lattnerbf3a0992002-10-01 22:38:41 +000033 Statistic<> NumSimpl("cfgsimplify", "Number of blocks simplified");
34
Chris Lattnerfa7dad82002-05-21 20:49:37 +000035 struct CFGSimplifyPass : public FunctionPass {
Chris Lattner113f4f42002-06-25 16:13:24 +000036 virtual bool runOnFunction(Function &F);
Chris Lattnerfa7dad82002-05-21 20:49:37 +000037 };
Chris Lattnerc8b70922002-07-26 21:12:46 +000038 RegisterOpt<CFGSimplifyPass> X("simplifycfg", "Simplify the CFG");
Chris Lattnerfa7dad82002-05-21 20:49:37 +000039}
40
Brian Gaeke960707c2003-11-11 22:41:34 +000041// Public interface to the CFGSimplification pass
Chris Lattner49525f82004-01-09 06:02:20 +000042FunctionPass *llvm::createCFGSimplificationPass() {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000043 return new CFGSimplifyPass();
44}
45
46static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
47 if (Reachable.count(BB)) return false;
48 Reachable.insert(BB);
49
Chris Lattnera67dd322004-10-18 03:00:50 +000050 // Do a quick scan of the basic block, turning any obviously unreachable
51 // instructions into LLVM unreachable insts. The instruction combining pass
52 // canonnicalizes unreachable insts into stores to null or undef.
53 for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ++BBI)
54 if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
55 if (isa<ConstantPointerNull>(SI->getOperand(1)) ||
56 isa<UndefValue>(SI->getOperand(1))) {
57 // Loop over all of the successors, removing BB's entry from any PHI
58 // nodes.
59 for (succ_iterator I = succ_begin(BB), SE = succ_end(BB); I != SE; ++I)
60 (*I)->removePredecessor(BB);
61
62 new UnreachableInst(SI);
63 std::cerr << "Inserted UNREACHABLE instruction!\n";
64
65 // All instructions after this are dead.
66 for (; BBI != E; ) {
67 if (!BBI->use_empty())
68 BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
69 BB->getInstList().erase(BBI++);
70 }
71 break;
72 }
73
74
Chris Lattnerfa7dad82002-05-21 20:49:37 +000075 bool Changed = ConstantFoldTerminator(BB);
76 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
77 MarkAliveBlocks(*SI, Reachable);
78
79 return Changed;
80}
81
82
83// It is possible that we may require multiple passes over the code to fully
84// simplify the CFG.
85//
Chris Lattner113f4f42002-06-25 16:13:24 +000086bool CFGSimplifyPass::runOnFunction(Function &F) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000087 std::set<BasicBlock*> Reachable;
Chris Lattner113f4f42002-06-25 16:13:24 +000088 bool Changed = MarkAliveBlocks(F.begin(), Reachable);
Chris Lattnerfa7dad82002-05-21 20:49:37 +000089
90 // If there are unreachable blocks in the CFG...
Chris Lattner113f4f42002-06-25 16:13:24 +000091 if (Reachable.size() != F.size()) {
92 assert(Reachable.size() < F.size());
93 NumSimpl += F.size()-Reachable.size();
Chris Lattnerfa7dad82002-05-21 20:49:37 +000094
95 // Loop over all of the basic blocks that are not reachable, dropping all of
96 // their internal references...
Chris Lattner113f4f42002-06-25 16:13:24 +000097 for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
98 if (!Reachable.count(BB)) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +000099 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
100 if (Reachable.count(*SI))
101 (*SI)->removePredecessor(BB);
102 BB->dropAllReferences();
103 }
104
Chris Lattner113f4f42002-06-25 16:13:24 +0000105 for (Function::iterator I = ++F.begin(); I != F.end();)
106 if (!Reachable.count(I))
107 I = F.getBasicBlockList().erase(I);
Chris Lattnerfa7dad82002-05-21 20:49:37 +0000108 else
109 ++I;
110
111 Changed = true;
112 }
113
114 bool LocalChange = true;
115 while (LocalChange) {
116 LocalChange = false;
117
118 // Loop over all of the basic blocks (except the first one) and remove them
119 // if they are unneeded...
120 //
Chris Lattner113f4f42002-06-25 16:13:24 +0000121 for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
122 if (SimplifyCFG(BBIt++)) {
Chris Lattnerfa7dad82002-05-21 20:49:37 +0000123 LocalChange = true;
124 ++NumSimpl;
Chris Lattnerfa7dad82002-05-21 20:49:37 +0000125 }
126 }
127 Changed |= LocalChange;
128 }
129
130 return Changed;
131}