Add utility pass to remove dbg info.
[oota-llvm.git] / lib / Transforms / Utils / DbgInfoRemover.cpp
1 //===- DbgInforemover.cpp - Remove Debug Info Intrinsics ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is utility pass removes all debug information intrinsics from a 
11 // function.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Transforms/IPO.h"
16 #include "llvm/Module.h"
17 #include "llvm/IntrinsicInst.h"
18 #include "llvm/Pass.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 using namespace llvm;
21
22 namespace {
23   // Remove dbg intrinsics and related globals from this module.
24   struct RemoveDbgInfoPass : public ModulePass {
25     static char ID; // Pass identification, replacement for typeid
26     RemoveDbgInfoPass() : ModulePass(&ID) {}
27     
28     void getAnalysisUsage(AnalysisUsage &Info) const {
29       Info.setPreservesCFG();
30     }
31
32     bool runOnModule(Module &M) {
33       bool Changed = false;
34       DbgGlobals.clear();
35
36       for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
37         Function *F = I++;
38         Changed |= cleanupFunction(*F);
39         if (F->hasName() && !strncmp(F->getNameStart(), "llvm.dbg", 8))
40           M.getFunctionList().erase(F);
41       }
42
43       for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
44            GVI != E; ) {
45         GlobalVariable *GV = GVI++;
46         if (GV->hasName() && !strncmp(GV->getNameStart(), "llvm.dbg", 8)) {
47           if (GV->hasInitializer())
48             CollectDbgGlobals(GV->getInitializer());
49           GV->replaceAllUsesWith(UndefValue::get(GV->getType()));
50           GV->removeDeadConstantUsers();
51           M.getGlobalList().erase(GV);
52         }
53       }
54
55       for (SmallPtrSet<GlobalVariable *,8>::iterator CI = DbgGlobals.begin(),
56              CE = DbgGlobals.end(); CI != CE; ) {
57         GlobalVariable *GV = *CI++;
58         GV->removeDeadConstantUsers();
59         if (GV->use_empty())
60           M.getGlobalList().erase(GV);
61       }
62       return Changed;
63     }
64
65     void CollectDbgGlobals(Constant *C) {
66       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
67         DbgGlobals.insert(GV);
68       for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) 
69         CollectDbgGlobals(cast<Constant>(*I));
70     }
71
72     bool cleanupFunction(Function &F) {
73       SmallVector<Instruction *, 8> WorkList;
74       for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
75         for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
76           if (isa<DbgInfoIntrinsic>(I))
77             WorkList.push_back(I);
78
79       for (SmallVector<Instruction *, 8>::iterator WI = WorkList.begin(),
80              WE = WorkList.end(); WI != WE; ++WI)
81         (*WI)->eraseFromParent();
82      
83       return !WorkList.empty();
84     }
85     
86   private:
87     SmallPtrSet<GlobalVariable *, 8> DbgGlobals;
88   };
89   
90   char RemoveDbgInfoPass::ID = 0;
91   static RegisterPass<RemoveDbgInfoPass> X("remove-dbginfo",
92                                            "Remove Debugging Information");
93 }
94
95 ModulePass *llvm::createRemoveDbgInfoPass() {
96   return new RemoveDbgInfoPass();
97 }