b377a8befe800dbfa064fe16a7d069a33a2dc50d
[oota-llvm.git] / lib / Transforms / IPO / PruneEH.cpp
1 //===- PruneEH.cpp - Pass which deletes unused exception handlers ---------===//
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 a simple interprocedural pass which walks the
11 // call-graph, turning invoke instructions into calls, iff the callee cannot
12 // throw an exception.  It implements this as a bottom-up traversal of the
13 // call-graph.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/CallGraphSCCPass.h"
18 #include "llvm/Function.h"
19 #include "llvm/Intrinsics.h"
20 #include "llvm/iTerminators.h"
21 #include "llvm/iOther.h"
22 #include "llvm/Analysis/CallGraph.h"
23 #include "Support/Statistic.h"
24 #include <set>
25
26 namespace {
27   Statistic<> NumRemoved("prune-eh", "Number of invokes removed");
28
29   struct PruneEH : public CallGraphSCCPass {
30     /// DoesNotThrow - This set contains all of the functions which we have
31     /// determined cannot throw exceptions.
32     std::set<CallGraphNode*> DoesNotThrow;
33
34     // runOnSCC - Analyze the SCC, performing the transformation if possible.
35     bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
36   };
37   RegisterOpt<PruneEH> X("prune-eh", "Remove unused exception handling info");
38 }
39
40 Pass *createPruneEHPass() { return new PruneEH(); }
41
42
43 bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
44   CallGraph &CG = getAnalysis<CallGraph>();
45
46   // First, check to see if any callees might throw or if there are any external
47   // functions in this SCC: if so, we cannot prune any functions in this SCC.
48   // If this SCC includes the unwind instruction, we KNOW it throws, so
49   // obviously the SCC might throw.
50   //
51   bool SCCMightThrow = false;
52   for (unsigned i = 0, e = SCC.size(); i != e; ++i)
53     if (!DoesNotThrow.count(SCC[i]) &&          // Calls maybe throwing fn
54         // Make sure this is not one of the fn's in the SCC.
55         std::find(SCC.begin(), SCC.end(), SCC[i]) == SCC.end()) {
56       SCCMightThrow = true; break;
57     } else if (Function *F = SCC[i]->getFunction())
58       if (F->isExternal()) {
59         SCCMightThrow = true; break;
60       } else {
61         for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
62           if (isa<UnwindInst>(I->getTerminator())) {  // Uses unwind!
63             SCCMightThrow = true; break;
64           }
65       }
66
67   bool MadeChange = false;
68
69   for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
70     // If the SCC can't throw, remember this for callers...
71     if (!SCCMightThrow)
72       DoesNotThrow.insert(SCC[i]);
73
74     // Convert any invoke instructions to non-throwing functions in this node
75     // into call instructions with a branch.  This makes the exception blocks
76     // dead.
77     if (Function *F = SCC[i]->getFunction())
78       for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
79         if (InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator()))
80           if (Function *F = II->getCalledFunction())
81             if (DoesNotThrow.count(CG[F])) {
82               // Insert a call instruction before the invoke...
83               std::string Name = II->getName();  II->setName("");
84               Value *Call = new CallInst(II->getCalledValue(),
85                                          std::vector<Value*>(II->op_begin()+3,
86                                                              II->op_end()),
87                                          Name, II);
88               
89               // Anything that used the value produced by the invoke instruction
90               // now uses the value produced by the call instruction.
91               II->replaceAllUsesWith(Call);
92           
93               // Insert a branch to the normal destination right before the
94               // invoke.
95               new BranchInst(II->getNormalDest(), II);
96               
97               // Finally, delete the invoke instruction!
98               I->getInstList().pop_back();
99               
100               ++NumRemoved;
101               MadeChange = true;
102             }
103   }
104
105   return MadeChange; 
106 }