1e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 3e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// The LLVM Compiler Infrastructure 4e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 8e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===----------------------------------------------------------------------===// 9e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 10c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// The StripSymbols transformation implements code stripping. Specifically, it 11c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// can delete: 124920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman// 13c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// * names for virtual registers 14c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// * symbols for internal globals and functions 15c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// * debug information 16e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 17c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// Note that this transformation makes code much less readable, so it should 18c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// only be used in situations where the 'strip' utility would be used, such as 19c86b67742a3298c0a5a715b57a64f11107b8a3f2Gordon Henriksen// reducing code size or making it harder to reverse engineer code. 20e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 21e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===----------------------------------------------------------------------===// 22e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 23e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner#include "llvm/Transforms/IPO.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallPtrSet.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 304068e1af9ff68b6b5fdb3233f1304e53f1bf179aChandler Carruth#include "llvm/IR/TypeFinder.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/ValueSymbolTable.h" 32e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner#include "llvm/Pass.h" 33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Utils/Local.h" 34e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnerusing namespace llvm; 35e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 36e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnernamespace { 378aa9fba7cbc9ed58a0f5e32ad5e54c3bb984b3e4Nick Lewycky class StripSymbols : public ModulePass { 38e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner bool OnlyDebugInfo; 39e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner public: 40ecd94c804a563f2a86572dcf1d2e81f397e19daaNick Lewycky static char ID; // Pass identification, replacement for typeid 414920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman explicit StripSymbols(bool ODI = false) 42081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson : ModulePass(ID), OnlyDebugInfo(ODI) { 43081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeStripSymbolsPass(*PassRegistry::getPassRegistry()); 44081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson } 45e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 47f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 49f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel AU.setPreservesAll(); 50f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel } 51f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel }; 52229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel 538aa9fba7cbc9ed58a0f5e32ad5e54c3bb984b3e4Nick Lewycky class StripNonDebugSymbols : public ModulePass { 54f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel public: 55f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel static char ID; // Pass identification, replacement for typeid 56f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel explicit StripNonDebugSymbols() 57081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson : ModulePass(ID) { 58081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeStripNonDebugSymbolsPass(*PassRegistry::getPassRegistry()); 59081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson } 60229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 62e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 64e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner AU.setPreservesAll(); 65e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 66e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner }; 6723e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 688aa9fba7cbc9ed58a0f5e32ad5e54c3bb984b3e4Nick Lewycky class StripDebugDeclare : public ModulePass { 6923e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel public: 7023e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel static char ID; // Pass identification, replacement for typeid 7123e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel explicit StripDebugDeclare() 72081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson : ModulePass(ID) { 73081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeStripDebugDeclarePass(*PassRegistry::getPassRegistry()); 74081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson } 7523e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 7723e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 7923e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel AU.setPreservesAll(); 8023e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel } 8123e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel }; 8226d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 8326d14294de179ada3ba472d206bd25e9785f05a3Devang Patel class StripDeadDebugInfo : public ModulePass { 8426d14294de179ada3ba472d206bd25e9785f05a3Devang Patel public: 8526d14294de179ada3ba472d206bd25e9785f05a3Devang Patel static char ID; // Pass identification, replacement for typeid 8626d14294de179ada3ba472d206bd25e9785f05a3Devang Patel explicit StripDeadDebugInfo() 87081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson : ModulePass(ID) { 88081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeStripDeadDebugInfoPass(*PassRegistry::getPassRegistry()); 89081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson } 9026d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 9226d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 9426d14294de179ada3ba472d206bd25e9785f05a3Devang Patel AU.setPreservesAll(); 9526d14294de179ada3ba472d206bd25e9785f05a3Devang Patel } 9626d14294de179ada3ba472d206bd25e9785f05a3Devang Patel }; 97e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 98e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 99844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanchar StripSymbols::ID = 0; 100d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(StripSymbols, "strip", 101ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Strip all symbols from a module", false, false) 102844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 103e3ad43c828280cf11e8631f1a814a51a0b168016Chris LattnerModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 104e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner return new StripSymbols(OnlyDebugInfo); 105e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 106e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 107f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patelchar StripNonDebugSymbols::ID = 0; 108d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(StripNonDebugSymbols, "strip-nondebug", 109d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen Anderson "Strip all symbols, except dbg symbols, from a module", 110ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson false, false) 111f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel 112f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang PatelModulePass *llvm::createStripNonDebugSymbolsPass() { 113f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel return new StripNonDebugSymbols(); 114f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel} 115f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel 11623e528be8069ead5f598e4043481fa2ef122a0e6Devang Patelchar StripDebugDeclare::ID = 0; 117d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(StripDebugDeclare, "strip-debug-declare", 118ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Strip all llvm.dbg.declare intrinsics", false, false) 11923e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 12023e528be8069ead5f598e4043481fa2ef122a0e6Devang PatelModulePass *llvm::createStripDebugDeclarePass() { 12123e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel return new StripDebugDeclare(); 12223e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel} 12323e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 12426d14294de179ada3ba472d206bd25e9785f05a3Devang Patelchar StripDeadDebugInfo::ID = 0; 125d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(StripDeadDebugInfo, "strip-dead-debug-info", 126ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Strip debug info for unused symbols", false, false) 12726d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 12826d14294de179ada3ba472d206bd25e9785f05a3Devang PatelModulePass *llvm::createStripDeadDebugInfoPass() { 12926d14294de179ada3ba472d206bd25e9785f05a3Devang Patel return new StripDeadDebugInfo(); 13026d14294de179ada3ba472d206bd25e9785f05a3Devang Patel} 13126d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 132bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel/// OnlyUsedBy - Return true if V is only used by Usr. 133bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patelstatic bool OnlyUsedBy(Value *V, Value *Usr) { 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (User *U : V->users()) 135bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel if (U != Usr) 136bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel return false; 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 138bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel return true; 139bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel} 140bf5db817f4f66701f3efd7c7ae001cc36f825086Devang Patel 141dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattnerstatic void RemoveDeadConstant(Constant *C) { 142dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner assert(C->use_empty() && "Constant is not dead!"); 1430eeb913aa17a68b1f2963b02ca1d68f09dba0b78Chris Lattner SmallPtrSet<Constant*, 4> Operands; 144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (Value *Op : C->operands()) 145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (OnlyUsedBy(Op, C)) 146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Operands.insert(cast<Constant>(Op)); 147dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals. 149dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GV->eraseFromParent(); 150dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 151dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner else if (!isa<Function>(C)) 152f23de86fa3b275cabc6450349dcbbb448ee5952bDevang Patel if (isa<CompositeType>(C->getType())) 153f23de86fa3b275cabc6450349dcbbb448ee5952bDevang Patel C->destroyConstant(); 154fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 155dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // If the constant referenced anything, see if we can delete it as well. 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (Constant *O : Operands) 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RemoveDeadConstant(O); 158dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner} 159e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 1607f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner// Strip the symbol table of its names. 1617f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner// 162f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patelstatic void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 1637f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 164dec628eead87b20773c98a00830580df211acc98Chris Lattner Value *V = VI->getValue(); 1657f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner ++VI; 166bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) { 167460f656475738d1a95a6be95346908ce1597df25Daniel Dunbar if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) 168f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel // Set name to "", removing from symbol table! 169f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel V->setName(""); 1707f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner } 1717f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner } 1727f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner} 1737f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner 1741afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner// Strip any named types of their names. 1751afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattnerstatic void StripTypeNames(Module &M, bool PreserveDbgInfo) { 176573e97326766359d3a9747eed7b7d47b6c33fa0fBill Wendling TypeFinder StructTypes; 177573e97326766359d3a9747eed7b7d47b6c33fa0fBill Wendling StructTypes.run(M, false); 1781afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner 1791afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { 1801afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner StructType *STy = StructTypes[i]; 1813ebb64946bc8e7c8feba1b2044e7a47f80b3a83fChris Lattner if (STy->isLiteral() || STy->getName().empty()) continue; 1824920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman 1831afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg")) 1841afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner continue; 1851afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner 1861afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner STy->setName(""); 187f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel } 1887f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner} 1897f1444bc0aefdd924e9b231e20d4c0529311e141Chris Lattner 1904460a7e90c318857a37be386a7ebccff3020a795Devang Patel/// Find values that are marked as llvm.used. 191401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattnerstatic void findUsedValues(GlobalVariable *LLVMUsed, 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallPtrSetImpl<const GlobalValue*> &UsedValues) { 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!LLVMUsed) return; 194401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner UsedValues.insert(LLVMUsed); 195cde25b435a907e7741da0c0d18953850936277c4Rafael Espindola 196cde25b435a907e7741da0c0d18953850936277c4Rafael Espindola ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); 197cde25b435a907e7741da0c0d18953850936277c4Rafael Espindola 198401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 1994920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman if (GlobalValue *GV = 200401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 201401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner UsedValues.insert(GV); 2024460a7e90c318857a37be386a7ebccff3020a795Devang Patel} 2034460a7e90c318857a37be386a7ebccff3020a795Devang Patel 2044460a7e90c318857a37be386a7ebccff3020a795Devang Patel/// StripSymbolNames - Strip symbol names. 2057db949df789383acce98ef072f08794fdd5bd04eDan Gohmanstatic bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 2064460a7e90c318857a37be386a7ebccff3020a795Devang Patel 2074460a7e90c318857a37be386a7ebccff3020a795Devang Patel SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 208401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); 209401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); 2104460a7e90c318857a37be386a7ebccff3020a795Devang Patel 211229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 212229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel I != E; ++I) { 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I->hasLocalLinkage() && llvmUsedValues.count(&*I) == 0) 214460f656475738d1a95a6be95346908ce1597df25Daniel Dunbar if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 215f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel I->setName(""); // Internal symbols can't participate in linkage 216229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel } 2174920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman 218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (Function &I : M) { 219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (I.hasLocalLinkage() && llvmUsedValues.count(&I) == 0) 220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!PreserveDbgInfo || !I.getName().startswith("llvm.dbg")) 221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar I.setName(""); // Internal symbols can't participate in linkage 222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StripSymtab(I.getValueSymbolTable(), PreserveDbgInfo); 223229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel } 2244920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman 225229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel // Remove all names from types. 2261afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner StripTypeNames(M, PreserveDbgInfo); 2278c231e5dda26b790ff388fe2f70eeeda621c9261Devang Patel 228229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel return true; 229229de95eabb7f5350a42152eab8c4c8643cdd0bfDevang Patel} 230e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 231f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patelbool StripSymbols::runOnModule(Module &M) { 232de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipModule(M)) 233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 235f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel bool Changed = false; 236f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel Changed |= StripDebugInfo(M); 237f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel if (!OnlyDebugInfo) 238f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel Changed |= StripSymbolNames(M, false); 239f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel return Changed; 240f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel} 241f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel 242f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patelbool StripNonDebugSymbols::runOnModule(Module &M) { 243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipModule(M)) 244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 246f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel return StripSymbolNames(M, true); 247f17fc461d17f9fa85f8fbc140ded8f3c591791e2Devang Patel} 24823e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 24923e528be8069ead5f598e4043481fa2ef122a0e6Devang Patelbool StripDebugDeclare::runOnModule(Module &M) { 250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipModule(M)) 251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 25223e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 25323e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel Function *Declare = M.getFunction("llvm.dbg.declare"); 25423e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel std::vector<Constant*> DeadConstants; 25523e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 2564425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen if (Declare) { 2574425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen while (!Declare->use_empty()) { 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallInst *CI = cast<CallInst>(Declare->user_back()); 259e9af352d74d1fa670afbaf50594f899c1b12a995Gabor Greif Value *Arg1 = CI->getArgOperand(0); 260e9af352d74d1fa670afbaf50594f899c1b12a995Gabor Greif Value *Arg2 = CI->getArgOperand(1); 2614425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 2624425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen CI->eraseFromParent(); 2634425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen if (Arg1->use_empty()) { 2644920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman if (Constant *C = dyn_cast<Constant>(Arg1)) 2654425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen DeadConstants.push_back(C); 2664920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman else 267e66f6f15e6afe3d437ccdca93f2209b3d4158486Dan Gohman RecursivelyDeleteTriviallyDeadInstructions(Arg1); 2684425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen } 2694425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen if (Arg2->use_empty()) 2704920bf77be434681a4f782c80ca0ab982abfb726Michael Gottesman if (Constant *C = dyn_cast<Constant>(Arg2)) 2714425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen DeadConstants.push_back(C); 27223e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel } 2734425240dbcb6e0da24f4a9f72cfb24f529f5b7afDale Johannesen Declare->eraseFromParent(); 27423e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel } 27523e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 27623e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel while (!DeadConstants.empty()) { 27723e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel Constant *C = DeadConstants.back(); 27823e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel DeadConstants.pop_back(); 27923e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 28023e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel if (GV->hasLocalLinkage()) 28123e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel RemoveDeadConstant(GV); 2820eeb913aa17a68b1f2963b02ca1d68f09dba0b78Chris Lattner } else 28323e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel RemoveDeadConstant(C); 28423e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel } 28523e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel 28623e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel return true; 28723e528be8069ead5f598e4043481fa2ef122a0e6Devang Patel} 28826d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 289e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// Remove any debug info for global variables/functions in the given module for 290e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// which said global variable/function no longer exists (i.e. is null). 291e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// 292e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// Debugging information is encoded in llvm IR using metadata. This is designed 293e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// such a way that debug info for symbols preserved even if symbols are 294e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// optimized away by the optimizer. This special pass removes debug info for 295e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman/// such symbols. 29626d14294de179ada3ba472d206bd25e9785f05a3Devang Patelbool StripDeadDebugInfo::runOnModule(Module &M) { 297de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipModule(M)) 298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 30026d14294de179ada3ba472d206bd25e9785f05a3Devang Patel bool Changed = false; 30126d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 302e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman LLVMContext &C = M.getContext(); 303e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 304e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // Find all debug info in F. This is actually overkill in terms of what we 305442d5f6c4b2395914c5970012916ce3746a39c39Michael Gottesman // want to do, but we want to try and be as resilient as possible in the face 306e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // of potential debug info changes by using the formal interfaces given to us 307e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // as much as possible. 308e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman DebugInfoFinder F; 309e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman F.processModule(M); 310e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 311e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // For each compile unit, find the live set of global variables/functions and 312e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // replace the current list of potentially dead global variables/functions 313e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // with the live list. 314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Metadata *, 64> LiveGlobalVariables; 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Metadata *, 64> LiveSubprograms; 316e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman DenseSet<const MDNode *> VisitedSet; 317e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::set<DISubprogram *> LiveSPs; 319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (Function &F : M) { 320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DISubprogram *SP = F.getSubprogram()) 321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LiveSPs.insert(SP); 322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 3246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (DICompileUnit *DIC : F.compile_units()) { 325e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // Create our live global variable list. 326e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman bool GlobalVariableChange = false; 3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (DIGlobalVariable *DIG : DIC->getGlobalVariables()) { 328e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // Make sure we only visit each global variable only once. 329e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman if (!VisitedSet.insert(DIG).second) 330e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman continue; 331e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 332e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // If the global variable referenced by DIG is not null, the global 333e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // variable is live. 3340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (DIG->getVariable()) 335e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman LiveGlobalVariables.push_back(DIG); 33626d14294de179ada3ba472d206bd25e9785f05a3Devang Patel else 337e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman GlobalVariableChange = true; 33826d14294de179ada3ba472d206bd25e9785f05a3Devang Patel } 339e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If we found dead global variables, replace the current global 341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // variable list with our new live global variable list. 342e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman if (GlobalVariableChange) { 3430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar DIC->replaceGlobalVariables(MDTuple::get(C, LiveGlobalVariables)); 344e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman Changed = true; 345e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman } 346e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman 347e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman // Reset lists for the next iteration. 348e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman LiveSubprograms.clear(); 349e0e66b9dfaca5f9cae3bba563b05a6230d64e21dMichael Gottesman LiveGlobalVariables.clear(); 35026d14294de179ada3ba472d206bd25e9785f05a3Devang Patel } 35126d14294de179ada3ba472d206bd25e9785f05a3Devang Patel 35226d14294de179ada3ba472d206bd25e9785f05a3Devang Patel return Changed; 35326d14294de179ada3ba472d206bd25e9785f05a3Devang Patel} 354