StripSymbols.cpp revision 210299
1205407Srdivacky//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 2205407Srdivacky// 3205407Srdivacky// The LLVM Compiler Infrastructure 4205407Srdivacky// 5205407Srdivacky// This file is distributed under the University of Illinois Open Source 6205407Srdivacky// License. See LICENSE.TXT for details. 7205407Srdivacky// 8205407Srdivacky//===----------------------------------------------------------------------===// 9205407Srdivacky// 10218893Sdim// The StripSymbols transformation implements code stripping. Specifically, it 11205407Srdivacky// can delete: 12205407Srdivacky// 13205407Srdivacky// * names for virtual registers 14226633Sdim// * symbols for internal globals and functions 15206083Srdivacky// * debug information 16205407Srdivacky// 17234353Sdim// Note that this transformation makes code much less readable, so it should 18205407Srdivacky// only be used in situations where the 'strip' utility would be used, such as 19205407Srdivacky// reducing code size or making it harder to reverse engineer code. 20205407Srdivacky// 21208599Srdivacky//===----------------------------------------------------------------------===// 22205407Srdivacky 23218893Sdim#include "llvm/Transforms/IPO.h" 24239462Sdim#include "llvm/Constants.h" 25205407Srdivacky#include "llvm/DerivedTypes.h" 26205407Srdivacky#include "llvm/Instructions.h" 27205407Srdivacky#include "llvm/Module.h" 28205407Srdivacky#include "llvm/Pass.h" 29218893Sdim#include "llvm/Analysis/DebugInfo.h" 30205407Srdivacky#include "llvm/ValueSymbolTable.h" 31224145Sdim#include "llvm/TypeSymbolTable.h" 32224145Sdim#include "llvm/Transforms/Utils/Local.h" 33208599Srdivacky#include "llvm/ADT/SmallPtrSet.h" 34208599Srdivackyusing namespace llvm; 35208599Srdivacky 36208599Srdivackynamespace { 37208599Srdivacky class StripSymbols : public ModulePass { 38208599Srdivacky bool OnlyDebugInfo; 39208599Srdivacky public: 40208599Srdivacky static char ID; // Pass identification, replacement for typeid 41208599Srdivacky explicit StripSymbols(bool ODI = false) 42208599Srdivacky : ModulePass(&ID), OnlyDebugInfo(ODI) {} 43208599Srdivacky 44208599Srdivacky virtual bool runOnModule(Module &M); 45208599Srdivacky 46224145Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const { 47224145Sdim AU.setPreservesAll(); 48224145Sdim } 49224145Sdim }; 50224145Sdim 51205407Srdivacky class StripNonDebugSymbols : public ModulePass { 52224145Sdim public: 53224145Sdim static char ID; // Pass identification, replacement for typeid 54224145Sdim explicit StripNonDebugSymbols() 55205407Srdivacky : ModulePass(&ID) {} 56224145Sdim 57224145Sdim virtual bool runOnModule(Module &M); 58205407Srdivacky 59224145Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const { 60224145Sdim AU.setPreservesAll(); 61224145Sdim } 62224145Sdim }; 63224145Sdim 64218893Sdim class StripDebugDeclare : public ModulePass { 65224145Sdim public: 66224145Sdim static char ID; // Pass identification, replacement for typeid 67224145Sdim explicit StripDebugDeclare() 68205407Srdivacky : ModulePass(&ID) {} 69224145Sdim 70224145Sdim virtual bool runOnModule(Module &M); 71243830Sdim 72243830Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const { 73243830Sdim AU.setPreservesAll(); 74243830Sdim } 75243830Sdim }; 76224145Sdim 77224145Sdim class StripDeadDebugInfo : public ModulePass { 78224145Sdim public: 79224145Sdim static char ID; // Pass identification, replacement for typeid 80205407Srdivacky explicit StripDeadDebugInfo() 81224145Sdim : ModulePass(&ID) {} 82224145Sdim 83224145Sdim virtual bool runOnModule(Module &M); 84224145Sdim 85224145Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const { 86224145Sdim AU.setPreservesAll(); 87224145Sdim } 88205407Srdivacky }; 89224145Sdim} 90224145Sdim 91224145Sdimchar StripSymbols::ID = 0; 92224145Sdimstatic RegisterPass<StripSymbols> 93224145SdimX("strip", "Strip all symbols from a module"); 94224145Sdim 95224145SdimModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 96224145Sdim return new StripSymbols(OnlyDebugInfo); 97218893Sdim} 98205407Srdivacky 99224145Sdimchar StripNonDebugSymbols::ID = 0; 100224145Sdimstatic RegisterPass<StripNonDebugSymbols> 101224145SdimY("strip-nondebug", "Strip all symbols, except dbg symbols, from a module"); 102218893Sdim 103224145SdimModulePass *llvm::createStripNonDebugSymbolsPass() { 104224145Sdim return new StripNonDebugSymbols(); 105224145Sdim} 106224145Sdim 107224145Sdimchar StripDebugDeclare::ID = 0; 108224145Sdimstatic RegisterPass<StripDebugDeclare> 109221345SdimZ("strip-debug-declare", "Strip all llvm.dbg.declare intrinsics"); 110224145Sdim 111224145SdimModulePass *llvm::createStripDebugDeclarePass() { 112224145Sdim return new StripDebugDeclare(); 113224145Sdim} 114224145Sdim 115221345Sdimchar StripDeadDebugInfo::ID = 0; 116224145Sdimstatic RegisterPass<StripDeadDebugInfo> 117224145SdimA("strip-dead-debug-info", "Strip debug info for unused symbols"); 118224145Sdim 119224145SdimModulePass *llvm::createStripDeadDebugInfoPass() { 120221345Sdim return new StripDeadDebugInfo(); 121224145Sdim} 122224145Sdim 123221345Sdim/// OnlyUsedBy - Return true if V is only used by Usr. 124224145Sdimstatic bool OnlyUsedBy(Value *V, Value *Usr) { 125224145Sdim for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { 126218893Sdim User *U = *I; 127224145Sdim if (U != Usr) 128224145Sdim return false; 129218893Sdim } 130224145Sdim return true; 131218893Sdim} 132224145Sdim 133224145Sdimstatic void RemoveDeadConstant(Constant *C) { 134205407Srdivacky assert(C->use_empty() && "Constant is not dead!"); 135224145Sdim SmallPtrSet<Constant*, 4> Operands; 136224145Sdim for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 137224145Sdim if (isa<DerivedType>(C->getOperand(i)->getType()) && 138224145Sdim OnlyUsedBy(C->getOperand(i), C)) 139224145Sdim Operands.insert(cast<Constant>(C->getOperand(i))); 140224145Sdim if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 141218893Sdim if (!GV->hasLocalLinkage()) return; // Don't delete non static globals. 142224145Sdim GV->eraseFromParent(); 143224145Sdim } 144224145Sdim else if (!isa<Function>(C)) 145205407Srdivacky if (isa<CompositeType>(C->getType())) 146224145Sdim C->destroyConstant(); 147224145Sdim 148243830Sdim // If the constant referenced anything, see if we can delete it as well. 149243830Sdim for (SmallPtrSet<Constant*, 4>::iterator OI = Operands.begin(), 150224145Sdim OE = Operands.end(); OI != OE; ++OI) 151224145Sdim RemoveDeadConstant(*OI); 152224145Sdim} 153224145Sdim 154224145Sdim// Strip the symbol table of its names. 155224145Sdim// 156218893Sdimstatic void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 157224145Sdim for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 158224145Sdim Value *V = VI->getValue(); 159205407Srdivacky ++VI; 160224145Sdim if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) { 161224145Sdim if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) 162224145Sdim // Set name to "", removing from symbol table! 163224145Sdim V->setName(""); 164224145Sdim } 165224145Sdim } 166224145Sdim} 167205407Srdivacky 168224145Sdim// Strip the symbol table of its names. 169224145Sdimstatic void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { 170224145Sdim for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { 171224145Sdim if (PreserveDbgInfo && StringRef(TI->first).startswith("llvm.dbg")) 172224145Sdim ++TI; 173224145Sdim else 174224145Sdim ST.remove(TI++); 175224145Sdim } 176224145Sdim} 177224145Sdim 178224145Sdim/// Find values that are marked as llvm.used. 179205407Srdivackystatic void findUsedValues(GlobalVariable *LLVMUsed, 180224145Sdim SmallPtrSet<const GlobalValue*, 8> &UsedValues) { 181224145Sdim if (LLVMUsed == 0) return; 182224145Sdim UsedValues.insert(LLVMUsed); 183224145Sdim 184205407Srdivacky ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer()); 185224145Sdim if (Inits == 0) return; 186224145Sdim 187205407Srdivacky for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 188224145Sdim if (GlobalValue *GV = 189224145Sdim dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 190224145Sdim UsedValues.insert(GV); 191224145Sdim} 192224145Sdim 193224145Sdim/// StripSymbolNames - Strip symbol names. 194224145Sdimstatic bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 195205407Srdivacky 196224145Sdim SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 197224145Sdim findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); 198224145Sdim findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); 199224145Sdim 200205407Srdivacky for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 201205407Srdivacky I != E; ++I) { 202224145Sdim if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 203224145Sdim if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 204206083Srdivacky I->setName(""); // Internal symbols can't participate in linkage 205224145Sdim } 206224145Sdim 207205407Srdivacky for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 208224145Sdim if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 209224145Sdim if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 210224145Sdim I->setName(""); // Internal symbols can't participate in linkage 211224145Sdim StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); 212224145Sdim } 213224145Sdim 214224145Sdim // Remove all names from types. 215224145Sdim StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); 216224145Sdim 217205407Srdivacky return true; 218224145Sdim} 219205407Srdivacky 220224145Sdim// StripDebugInfo - Strip debug info in the module if it exists. 221224145Sdim// To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and 222224145Sdim// llvm.dbg.region.end calls, and any globals they point to if now dead. 223205407Srdivackystatic bool StripDebugInfo(Module &M) { 224224145Sdim 225224145Sdim bool Changed = false; 226224145Sdim 227224145Sdim // Remove all of the calls to the debugger intrinsics, and remove them from 228224145Sdim // the module. 229224145Sdim if (Function *Declare = M.getFunction("llvm.dbg.declare")) { 230224145Sdim while (!Declare->use_empty()) { 231224145Sdim CallInst *CI = cast<CallInst>(Declare->use_back()); 232224145Sdim CI->eraseFromParent(); 233205407Srdivacky } 234224145Sdim Declare->eraseFromParent(); 235224145Sdim Changed = true; 236224145Sdim } 237205407Srdivacky 238224145Sdim if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { 239224145Sdim while (!DbgVal->use_empty()) { 240224145Sdim CallInst *CI = cast<CallInst>(DbgVal->use_back()); 241224145Sdim CI->eraseFromParent(); 242224145Sdim } 243205407Srdivacky DbgVal->eraseFromParent(); 244224145Sdim Changed = true; 245224145Sdim } 246205407Srdivacky 247224145Sdim for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), 248224145Sdim NME = M.named_metadata_end(); NMI != NME;) { 249224145Sdim NamedMDNode *NMD = NMI; 250224145Sdim ++NMI; 251224145Sdim if (NMD->getName().startswith("llvm.dbg.")) { 252224145Sdim NMD->eraseFromParent(); 253205407Srdivacky Changed = true; 254224145Sdim } 255224145Sdim } 256205407Srdivacky 257224145Sdim unsigned MDDbgKind = M.getMDKindID("dbg"); 258224145Sdim for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) 259224145Sdim for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; 260224145Sdim ++FI) 261224145Sdim for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; 262224145Sdim ++BI) { 263224145Sdim Changed = true; // FIXME: Only set if there was debug metadata. 264224145Sdim BI->setMetadata(MDDbgKind, 0); 265224145Sdim } 266205407Srdivacky 267224145Sdim return Changed; 268224145Sdim} 269205407Srdivacky 270224145Sdimbool StripSymbols::runOnModule(Module &M) { 271224145Sdim bool Changed = false; 272224145Sdim Changed |= StripDebugInfo(M); 273224145Sdim if (!OnlyDebugInfo) 274224145Sdim Changed |= StripSymbolNames(M, false); 275224145Sdim return Changed; 276224145Sdim} 277224145Sdim 278224145Sdimbool StripNonDebugSymbols::runOnModule(Module &M) { 279224145Sdim return StripSymbolNames(M, true); 280224145Sdim} 281224145Sdim 282224145Sdimbool StripDebugDeclare::runOnModule(Module &M) { 283224145Sdim 284224145Sdim Function *Declare = M.getFunction("llvm.dbg.declare"); 285224145Sdim std::vector<Constant*> DeadConstants; 286224145Sdim 287224145Sdim if (Declare) { 288224145Sdim while (!Declare->use_empty()) { 289224145Sdim CallInst *CI = cast<CallInst>(Declare->use_back()); 290205407Srdivacky Value *Arg1 = CI->getArgOperand(0); 291224145Sdim Value *Arg2 = CI->getArgOperand(1); 292224145Sdim assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 293205407Srdivacky CI->eraseFromParent(); 294224145Sdim if (Arg1->use_empty()) { 295224145Sdim if (Constant *C = dyn_cast<Constant>(Arg1)) 296224145Sdim DeadConstants.push_back(C); 297224145Sdim else 298224145Sdim RecursivelyDeleteTriviallyDeadInstructions(Arg1); 299224145Sdim } 300226633Sdim if (Arg2->use_empty()) 301205407Srdivacky if (Constant *C = dyn_cast<Constant>(Arg2)) 302224145Sdim DeadConstants.push_back(C); 303206083Srdivacky } 304224145Sdim Declare->eraseFromParent(); 305224145Sdim } 306224145Sdim 307224145Sdim while (!DeadConstants.empty()) { 308224145Sdim Constant *C = DeadConstants.back(); 309224145Sdim DeadConstants.pop_back(); 310224145Sdim if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 311206083Srdivacky if (GV->hasLocalLinkage()) 312224145Sdim RemoveDeadConstant(GV); 313205407Srdivacky } else 314224145Sdim RemoveDeadConstant(C); 315224145Sdim } 316205407Srdivacky 317224145Sdim return true; 318224145Sdim} 319224145Sdim 320205407Srdivacky/// getRealLinkageName - If special LLVM prefix that is used to inform the asm 321224145Sdim/// printer to not emit usual symbol prefix before the symbol name is used then 322224145Sdim/// return linkage name after skipping this special LLVM prefix. 323243830Sdimstatic StringRef getRealLinkageName(StringRef LinkageName) { 324224145Sdim char One = '\1'; 325224145Sdim if (LinkageName.startswith(StringRef(&One, 1))) 326224145Sdim return LinkageName.substr(1); 327224145Sdim return LinkageName; 328205407Srdivacky} 329224145Sdim 330224145Sdimbool StripDeadDebugInfo::runOnModule(Module &M) { 331224145Sdim bool Changed = false; 332224145Sdim 333224145Sdim // Debugging infomration is encoded in llvm IR using metadata. This is designed 334224145Sdim // such a way that debug info for symbols preserved even if symbols are 335224145Sdim // optimized away by the optimizer. This special pass removes debug info for 336224145Sdim // such symbols. 337224145Sdim 338205407Srdivacky // llvm.dbg.gv keeps track of debug info for global variables. 339205407Srdivacky if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { 340205407Srdivacky SmallVector<MDNode *, 8> MDs; 341224145Sdim for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) 342205407Srdivacky if (DIGlobalVariable(NMD->getOperand(i)).Verify()) 343224145Sdim MDs.push_back(NMD->getOperand(i)); 344224145Sdim else 345224145Sdim Changed = true; 346205407Srdivacky NMD->eraseFromParent(); 347224145Sdim NMD = NULL; 348224145Sdim 349224145Sdim for (SmallVector<MDNode *, 8>::iterator I = MDs.begin(), 350224145Sdim E = MDs.end(); I != E; ++I) { 351224145Sdim if (M.getGlobalVariable(DIGlobalVariable(*I).getGlobal()->getName(), 352224145Sdim true)) { 353224145Sdim if (!NMD) 354224145Sdim NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); 355205407Srdivacky NMD->addOperand(*I); 356239462Sdim } 357239462Sdim else 358239462Sdim Changed = true; 359239462Sdim } 360239462Sdim } 361239462Sdim 362239462Sdim // llvm.dbg.sp keeps track of debug info for subprograms. 363239462Sdim if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) { 364239462Sdim SmallVector<MDNode *, 8> MDs; 365239462Sdim for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) 366239462Sdim if (DISubprogram(NMD->getOperand(i)).Verify()) 367239462Sdim MDs.push_back(NMD->getOperand(i)); 368239462Sdim else 369239462Sdim Changed = true; 370239462Sdim NMD->eraseFromParent(); 371224145Sdim NMD = NULL; 372224145Sdim 373224145Sdim for (SmallVector<MDNode *, 8>::iterator I = MDs.begin(), 374224145Sdim E = MDs.end(); I != E; ++I) { 375224145Sdim bool FnIsLive = false; 376224145Sdim if (Function *F = DISubprogram(*I).getFunction()) 377224145Sdim if (M.getFunction(F->getName())) 378224145Sdim FnIsLive = true; 379224145Sdim if (FnIsLive) { 380205407Srdivacky if (!NMD) 381224145Sdim NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); 382224145Sdim NMD->addOperand(*I); 383224145Sdim } else { 384224145Sdim // Remove llvm.dbg.lv.fnname named mdnode which may have been used 385224145Sdim // to hold debug info for dead function's local variables. 386224145Sdim StringRef FName = DISubprogram(*I).getLinkageName(); 387224145Sdim if (FName.empty()) 388205407Srdivacky FName = DISubprogram(*I).getName(); 389224145Sdim if (NamedMDNode *LVNMD = 390224145Sdim M.getNamedMetadata(Twine("llvm.dbg.lv.", 391224145Sdim getRealLinkageName(FName)))) 392224145Sdim LVNMD->eraseFromParent(); 393224145Sdim } 394224145Sdim } 395205407Srdivacky } 396224145Sdim 397224145Sdim return Changed; 398205407Srdivacky} 399224145Sdim