LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

PruneEH.cpp

Go to the documentation of this file.
00001 //===- PruneEH.cpp - Pass which deletes unused exception handlers ---------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements a simple interprocedural pass which walks the
00011 // call-graph, turning invoke instructions into calls, iff the callee cannot
00012 // throw an exception.  It implements this as a bottom-up traversal of the
00013 // call-graph.
00014 //
00015 //===----------------------------------------------------------------------===//
00016 
00017 #include "llvm/Transforms/IPO.h"
00018 #include "llvm/CallGraphSCCPass.h"
00019 #include "llvm/Function.h"
00020 #include "llvm/Intrinsics.h"
00021 #include "llvm/Instructions.h"
00022 #include "llvm/Analysis/CallGraph.h"
00023 #include "llvm/ADT/Statistic.h"
00024 #include <set>
00025 #include <algorithm>
00026 using namespace llvm;
00027 
00028 namespace {
00029   Statistic<> NumRemoved("prune-eh", "Number of invokes removed");
00030 
00031   struct PruneEH : public CallGraphSCCPass {
00032     /// DoesNotThrow - This set contains all of the functions which we have
00033     /// determined cannot throw exceptions.
00034     std::set<CallGraphNode*> DoesNotThrow;
00035 
00036     // runOnSCC - Analyze the SCC, performing the transformation if possible.
00037     bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
00038   };
00039   RegisterOpt<PruneEH> X("prune-eh", "Remove unused exception handling info");
00040 }
00041 
00042 ModulePass *llvm::createPruneEHPass() { return new PruneEH(); }
00043 
00044 
00045 bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
00046   CallGraph &CG = getAnalysis<CallGraph>();
00047 
00048   // First, check to see if any callees might throw or if there are any external
00049   // functions in this SCC: if so, we cannot prune any functions in this SCC.
00050   // If this SCC includes the unwind instruction, we KNOW it throws, so
00051   // obviously the SCC might throw.
00052   //
00053   bool SCCMightThrow = false;
00054   for (unsigned i = 0, e = SCC.size(); !SCCMightThrow && i != e; ++i) {
00055     Function *F = SCC[i]->getFunction();
00056     if (F == 0 || (F->isExternal() && !F->getIntrinsicID())) {
00057       SCCMightThrow = true;
00058     } else {
00059       // Check to see if this function performs an unwind or calls an
00060       // unwinding function.
00061       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00062         if (isa<UnwindInst>(BB->getTerminator())) {  // Uses unwind!
00063           SCCMightThrow = true;
00064           break;
00065         }
00066 
00067         // Invoke instructions don't allow unwinding to continue, so we are
00068         // only interested in call instructions.
00069         for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
00070           if (CallInst *CI = dyn_cast<CallInst>(I)) {
00071             if (Function *Callee = CI->getCalledFunction()) {
00072               CallGraphNode *CalleeNode = CG[Callee];
00073               // If the callee is outside our current SCC, or if it is not
00074               // known to throw, then we might throw also.
00075               if (std::find(SCC.begin(), SCC.end(), CalleeNode) == SCC.end()&&
00076                   !DoesNotThrow.count(CalleeNode)) {
00077                 SCCMightThrow = true;
00078                 break;
00079               }
00080                 
00081             } else {
00082               // Indirect call, it might throw.
00083               SCCMightThrow = true;
00084               break;
00085             }
00086           }
00087         if (SCCMightThrow) break;
00088       }
00089     }
00090   }
00091   bool MadeChange = false;
00092 
00093   for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
00094     // If the SCC can't throw, remember this for callers...
00095     if (!SCCMightThrow)
00096       DoesNotThrow.insert(SCC[i]);
00097 
00098     // Convert any invoke instructions to non-throwing functions in this node
00099     // into call instructions with a branch.  This makes the exception blocks
00100     // dead.
00101     if (Function *F = SCC[i]->getFunction())
00102       for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
00103         if (InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator()))
00104           if (Function *F = II->getCalledFunction())
00105             if (DoesNotThrow.count(CG[F])) {
00106               // Insert a call instruction before the invoke...
00107               std::string Name = II->getName();  II->setName("");
00108               Value *Call = new CallInst(II->getCalledValue(),
00109                                          std::vector<Value*>(II->op_begin()+3,
00110                                                              II->op_end()),
00111                                          Name, II);
00112               
00113               // Anything that used the value produced by the invoke instruction
00114               // now uses the value produced by the call instruction.
00115               II->replaceAllUsesWith(Call);
00116               II->getUnwindDest()->removePredecessor(II->getParent());
00117           
00118               // Insert a branch to the normal destination right before the
00119               // invoke.
00120               new BranchInst(II->getNormalDest(), II);
00121               
00122               // Finally, delete the invoke instruction!
00123               I->getInstList().pop_back();
00124               
00125               ++NumRemoved;
00126               MadeChange = true;
00127             }
00128   }
00129 
00130   return MadeChange; 
00131 }
00132