diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 0d9ba26aa14..5fd9cc3312b 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -125,6 +125,7 @@ namespace { (void) llvm::createMergeFunctionsPass(); (void) llvm::createPrintModulePass(0); (void) llvm::createPrintFunctionPass("", 0); + (void) llvm::createRemoveDbgInfoPass(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 887614074c5..8c92cffa560 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -200,6 +200,13 @@ Pass *createAddReadAttrsPass(); /// ModulePass *createMergeFunctionsPass(); +//===----------------------------------------------------------------------===// +// +// RemoveDbgInfoPass - This pass removes debug info. intrinsics. +// +ModulePass *createRemoveDbgInfoPass(); + + } // End llvm namespace #endif diff --git a/lib/Transforms/Utils/DbgInfoRemover.cpp b/lib/Transforms/Utils/DbgInfoRemover.cpp new file mode 100644 index 00000000000..484354d7317 --- /dev/null +++ b/lib/Transforms/Utils/DbgInfoRemover.cpp @@ -0,0 +1,97 @@ +//===- DbgInforemover.cpp - Remove Debug Info Intrinsics ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is utility pass removes all debug information intrinsics from a +// function. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/IPO.h" +#include "llvm/Module.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/Pass.h" +#include "llvm/ADT/SmallPtrSet.h" +using namespace llvm; + +namespace { + // Remove dbg intrinsics and related globals from this module. + struct RemoveDbgInfoPass : public ModulePass { + static char ID; // Pass identification, replacement for typeid + RemoveDbgInfoPass() : ModulePass(&ID) {} + + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesCFG(); + } + + bool runOnModule(Module &M) { + bool Changed = false; + DbgGlobals.clear(); + + for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { + Function *F = I++; + Changed |= cleanupFunction(*F); + if (F->hasName() && !strncmp(F->getNameStart(), "llvm.dbg", 8)) + M.getFunctionList().erase(F); + } + + for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); + GVI != E; ) { + GlobalVariable *GV = GVI++; + if (GV->hasName() && !strncmp(GV->getNameStart(), "llvm.dbg", 8)) { + if (GV->hasInitializer()) + CollectDbgGlobals(GV->getInitializer()); + GV->replaceAllUsesWith(UndefValue::get(GV->getType())); + GV->removeDeadConstantUsers(); + M.getGlobalList().erase(GV); + } + } + + for (SmallPtrSet::iterator CI = DbgGlobals.begin(), + CE = DbgGlobals.end(); CI != CE; ) { + GlobalVariable *GV = *CI++; + GV->removeDeadConstantUsers(); + if (GV->use_empty()) + M.getGlobalList().erase(GV); + } + return Changed; + } + + void CollectDbgGlobals(Constant *C) { + if (GlobalVariable *GV = dyn_cast(C)) + DbgGlobals.insert(GV); + for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) + CollectDbgGlobals(cast(*I)); + } + + bool cleanupFunction(Function &F) { + SmallVector WorkList; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + if (isa(I)) + WorkList.push_back(I); + + for (SmallVector::iterator WI = WorkList.begin(), + WE = WorkList.end(); WI != WE; ++WI) + (*WI)->eraseFromParent(); + + return !WorkList.empty(); + } + + private: + SmallPtrSet DbgGlobals; + }; + + char RemoveDbgInfoPass::ID = 0; + static RegisterPass X("remove-dbginfo", + "Remove Debugging Information"); +} + +ModulePass *llvm::createRemoveDbgInfoPass() { + return new RemoveDbgInfoPass(); +}