X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FStripSymbols.cpp;h=3396f7929e68dcf0876324023904dbde788ee3fa;hb=cde25b435a907e7741da0c0d18953850936277c4;hp=066487fe15929025c83484f03b307191cf70c2fe;hpb=23e528be8069ead5f598e4043481fa2ef122a0e6;p=oota-llvm.git diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index 066487fe159..3396f7929e6 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -21,25 +21,28 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/DebugInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Pass.h" -#include "llvm/ValueSymbolTable.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/Transforms/Utils/Local.h" -#include "llvm/Support/Compiler.h" -#include "llvm/ADT/SmallPtrSet.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN StripSymbols : public ModulePass { + class StripSymbols : public ModulePass { bool OnlyDebugInfo; public: static char ID; // Pass identification, replacement for typeid explicit StripSymbols(bool ODI = false) - : ModulePass(&ID), OnlyDebugInfo(ODI) {} + : ModulePass(ID), OnlyDebugInfo(ODI) { + initializeStripSymbolsPass(*PassRegistry::getPassRegistry()); + } virtual bool runOnModule(Module &M); @@ -48,11 +51,13 @@ namespace { } }; - class VISIBILITY_HIDDEN StripNonDebugSymbols : public ModulePass { + class StripNonDebugSymbols : public ModulePass { public: static char ID; // Pass identification, replacement for typeid explicit StripNonDebugSymbols() - : ModulePass(&ID) {} + : ModulePass(ID) { + initializeStripNonDebugSymbolsPass(*PassRegistry::getPassRegistry()); + } virtual bool runOnModule(Module &M); @@ -61,11 +66,28 @@ namespace { } }; - class VISIBILITY_HIDDEN StripDebugDeclare : public ModulePass { + class StripDebugDeclare : public ModulePass { public: static char ID; // Pass identification, replacement for typeid explicit StripDebugDeclare() - : ModulePass(&ID) {} + : ModulePass(ID) { + initializeStripDebugDeclarePass(*PassRegistry::getPassRegistry()); + } + + virtual bool runOnModule(Module &M); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + }; + + class StripDeadDebugInfo : public ModulePass { + public: + static char ID; // Pass identification, replacement for typeid + explicit StripDeadDebugInfo() + : ModulePass(ID) { + initializeStripDeadDebugInfoPass(*PassRegistry::getPassRegistry()); + } virtual bool runOnModule(Module &M); @@ -76,29 +98,38 @@ namespace { } char StripSymbols::ID = 0; -static RegisterPass -X("strip", "Strip all symbols from a module"); +INITIALIZE_PASS(StripSymbols, "strip", + "Strip all symbols from a module", false, false) ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { return new StripSymbols(OnlyDebugInfo); } char StripNonDebugSymbols::ID = 0; -static RegisterPass -Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module"); +INITIALIZE_PASS(StripNonDebugSymbols, "strip-nondebug", + "Strip all symbols, except dbg symbols, from a module", + false, false) ModulePass *llvm::createStripNonDebugSymbolsPass() { return new StripNonDebugSymbols(); } char StripDebugDeclare::ID = 0; -static RegisterPass -Z("strip-debug-declare", "Strip all llvm.dbg.declare intrinsics"); +INITIALIZE_PASS(StripDebugDeclare, "strip-debug-declare", + "Strip all llvm.dbg.declare intrinsics", false, false) ModulePass *llvm::createStripDebugDeclarePass() { return new StripDebugDeclare(); } +char StripDeadDebugInfo::ID = 0; +INITIALIZE_PASS(StripDeadDebugInfo, "strip-dead-debug-info", + "Strip debug info for unused symbols", false, false) + +ModulePass *llvm::createStripDeadDebugInfoPass() { + return new StripDeadDebugInfo(); +} + /// OnlyUsedBy - Return true if V is only used by Usr. static bool OnlyUsedBy(Value *V, Value *Usr) { for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { @@ -111,11 +142,10 @@ static bool OnlyUsedBy(Value *V, Value *Usr) { static void RemoveDeadConstant(Constant *C) { assert(C->use_empty() && "Constant is not dead!"); - SmallPtrSet Operands; + SmallPtrSet Operands; for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) - if (isa(C->getOperand(i)->getType()) && - OnlyUsedBy(C->getOperand(i), C)) - Operands.insert(C->getOperand(i)); + if (OnlyUsedBy(C->getOperand(i), C)) + Operands.insert(cast(C->getOperand(i))); if (GlobalVariable *GV = dyn_cast(C)) { if (!GV->hasLocalLinkage()) return; // Don't delete non static globals. GV->eraseFromParent(); @@ -125,7 +155,7 @@ static void RemoveDeadConstant(Constant *C) { C->destroyConstant(); // If the constant referenced anything, see if we can delete it as well. - for (SmallPtrSet::iterator OI = Operands.begin(), + for (SmallPtrSet::iterator OI = Operands.begin(), OE = Operands.end(); OI != OE; ++OI) RemoveDeadConstant(*OI); } @@ -137,67 +167,66 @@ static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { Value *V = VI->getValue(); ++VI; if (!isa(V) || cast(V)->hasLocalLinkage()) { - if (!PreserveDbgInfo || strncmp(V->getNameStart(), "llvm.dbg", 8)) + if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) // Set name to "", removing from symbol table! V->setName(""); } } } -// Strip the symbol table of its names. -static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { - for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { - if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0) - ++TI; - else - ST.remove(TI++); +// Strip any named types of their names. +static void StripTypeNames(Module &M, bool PreserveDbgInfo) { + TypeFinder StructTypes; + StructTypes.run(M, false); + + for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { + StructType *STy = StructTypes[i]; + if (STy->isLiteral() || STy->getName().empty()) continue; + + if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg")) + continue; + + STy->setName(""); } } /// Find values that are marked as llvm.used. -void findUsedValues(Module &M, - SmallPtrSet& llvmUsedValues) { - if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) { - llvmUsedValues.insert(LLVMUsed); - // Collect values that are preserved as per explicit request. - // llvm.used is used to list these values. - if (ConstantArray *Inits = - dyn_cast(LLVMUsed->getInitializer())) { - for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) { - if (GlobalValue *GV = dyn_cast(Inits->getOperand(i))) - llvmUsedValues.insert(GV); - else if (ConstantExpr *CE = - dyn_cast(Inits->getOperand(i))) - if (CE->getOpcode() == Instruction::BitCast) - if (GlobalValue *GV = dyn_cast(CE->getOperand(0))) - llvmUsedValues.insert(GV); - } - } - } +static void findUsedValues(GlobalVariable *LLVMUsed, + SmallPtrSet &UsedValues) { + if (LLVMUsed == 0) return; + UsedValues.insert(LLVMUsed); + + ConstantArray *Inits = cast(LLVMUsed->getInitializer()); + + for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) + if (GlobalValue *GV = + dyn_cast(Inits->getOperand(i)->stripPointerCasts())) + UsedValues.insert(GV); } /// StripSymbolNames - Strip symbol names. -bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { +static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { SmallPtrSet llvmUsedValues; - findUsedValues(M, llvmUsedValues); + findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); + findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) - if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) + if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage } for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) - if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) + if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); } // Remove all names from types. - StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); + StripTypeNames(M, PreserveDbgInfo); return true; } @@ -205,93 +234,83 @@ bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { // StripDebugInfo - Strip debug info in the module if it exists. // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and // llvm.dbg.region.end calls, and any globals they point to if now dead. -bool StripDebugInfo(Module &M) { - - SmallPtrSet llvmUsedValues; - findUsedValues(M, llvmUsedValues); +static bool StripDebugInfo(Module &M) { - // Delete all dbg variables. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - GlobalVariable *GV = dyn_cast(I); - if (!GV) continue; - if (!GV->use_empty() && llvmUsedValues.count(I) == 0) { - if (strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0) { - GV->replaceAllUsesWith(UndefValue::get(GV->getType())); - } - } - } - - Function *FuncStart = M.getFunction("llvm.dbg.func.start"); - Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); - Function *RegionStart = M.getFunction("llvm.dbg.region.start"); - Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); - Function *Declare = M.getFunction("llvm.dbg.declare"); - - std::vector DeadConstants; + bool Changed = false; // Remove all of the calls to the debugger intrinsics, and remove them from // the module. - if (FuncStart) { - while (!FuncStart->use_empty()) { - CallInst *CI = cast(FuncStart->use_back()); - Value *Arg = CI->getOperand(1); - assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); - CI->eraseFromParent(); - if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) - DeadConstants.push_back(C); - } - FuncStart->eraseFromParent(); - } - if (StopPoint) { - while (!StopPoint->use_empty()) { - CallInst *CI = cast(StopPoint->use_back()); - Value *Arg = CI->getOperand(3); - assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); + if (Function *Declare = M.getFunction("llvm.dbg.declare")) { + while (!Declare->use_empty()) { + CallInst *CI = cast(Declare->use_back()); CI->eraseFromParent(); - if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) - DeadConstants.push_back(C); } - StopPoint->eraseFromParent(); + Declare->eraseFromParent(); + Changed = true; } - if (RegionStart) { - while (!RegionStart->use_empty()) { - CallInst *CI = cast(RegionStart->use_back()); - Value *Arg = CI->getOperand(1); - assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); + + if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { + while (!DbgVal->use_empty()) { + CallInst *CI = cast(DbgVal->use_back()); CI->eraseFromParent(); - if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) - DeadConstants.push_back(C); } - RegionStart->eraseFromParent(); + DbgVal->eraseFromParent(); + Changed = true; } - if (RegionEnd) { - while (!RegionEnd->use_empty()) { - CallInst *CI = cast(RegionEnd->use_back()); - Value *Arg = CI->getOperand(1); - assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); - CI->eraseFromParent(); - if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) - DeadConstants.push_back(C); + + for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), + NME = M.named_metadata_end(); NMI != NME;) { + NamedMDNode *NMD = NMI; + ++NMI; + if (NMD->getName().startswith("llvm.dbg.")) { + NMD->eraseFromParent(); + Changed = true; } - RegionEnd->eraseFromParent(); } + + for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) + for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; + ++FI) + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; + ++BI) { + if (!BI->getDebugLoc().isUnknown()) { + Changed = true; + BI->setDebugLoc(DebugLoc()); + } + } + + return Changed; +} + +bool StripSymbols::runOnModule(Module &M) { + bool Changed = false; + Changed |= StripDebugInfo(M); + if (!OnlyDebugInfo) + Changed |= StripSymbolNames(M, false); + return Changed; +} + +bool StripNonDebugSymbols::runOnModule(Module &M) { + return StripSymbolNames(M, true); +} + +bool StripDebugDeclare::runOnModule(Module &M) { + + Function *Declare = M.getFunction("llvm.dbg.declare"); + std::vector DeadConstants; + if (Declare) { while (!Declare->use_empty()) { CallInst *CI = cast(Declare->use_back()); - Value *Arg1 = CI->getOperand(1); - Value *Arg2 = CI->getOperand(2); + Value *Arg1 = CI->getArgOperand(0); + Value *Arg2 = CI->getArgOperand(1); assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg1->use_empty()) { if (Constant *C = dyn_cast(Arg1)) DeadConstants.push_back(C); else - RecursivelyDeleteTriviallyDeadInstructions(Arg1, NULL); + RecursivelyDeleteTriviallyDeadInstructions(Arg1); } if (Arg2->use_empty()) if (Constant *C = dyn_cast(Arg2)) @@ -300,108 +319,95 @@ bool StripDebugInfo(Module &M) { Declare->eraseFromParent(); } - // llvm.dbg.compile_units and llvm.dbg.subprograms are marked as linkonce - // but since we are removing all debug information, make them internal now. - // FIXME: Use private linkage maybe? - if (Constant *C = M.getNamedGlobal("llvm.dbg.compile_units")) - if (GlobalVariable *GV = dyn_cast(C)) - GV->setLinkage(GlobalValue::InternalLinkage); - - if (Constant *C = M.getNamedGlobal("llvm.dbg.subprograms")) - if (GlobalVariable *GV = dyn_cast(C)) - GV->setLinkage(GlobalValue::InternalLinkage); - - if (Constant *C = M.getNamedGlobal("llvm.dbg.global_variables")) - if (GlobalVariable *GV = dyn_cast(C)) - GV->setLinkage(GlobalValue::InternalLinkage); - - // Delete all dbg variables. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - GlobalVariable *GV = dyn_cast(I); - if (!GV) continue; - if (GV->use_empty() && llvmUsedValues.count(I) == 0 - && (!GV->hasSection() - || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) - DeadConstants.push_back(GV); - } - - if (DeadConstants.empty()) - return false; - - // Delete any internal globals that were only used by the debugger intrinsics. while (!DeadConstants.empty()) { Constant *C = DeadConstants.back(); DeadConstants.pop_back(); if (GlobalVariable *GV = dyn_cast(C)) { if (GV->hasLocalLinkage()) RemoveDeadConstant(GV); - } - else + } else RemoveDeadConstant(C); } - // Remove all llvm.dbg types. - TypeSymbolTable &ST = M.getTypeSymbolTable(); - for (TypeSymbolTable::iterator TI = ST.begin(), TE = ST.end(); TI != TE; ) { - if (!strncmp(TI->first.c_str(), "llvm.dbg.", 9)) - ST.remove(TI++); - else - ++TI; - } - return true; } -bool StripSymbols::runOnModule(Module &M) { - bool Changed = false; - Changed |= StripDebugInfo(M); - if (!OnlyDebugInfo) - Changed |= StripSymbolNames(M, false); - return Changed; -} - -bool StripNonDebugSymbols::runOnModule(Module &M) { - return StripSymbolNames(M, true); +/// getRealLinkageName - If special LLVM prefix that is used to inform the asm +/// printer to not emit usual symbol prefix before the symbol name is used then +/// return linkage name after skipping this special LLVM prefix. +static StringRef getRealLinkageName(StringRef LinkageName) { + char One = '\1'; + if (LinkageName.startswith(StringRef(&One, 1))) + return LinkageName.substr(1); + return LinkageName; } -bool StripDebugDeclare::runOnModule(Module &M) { - - Function *Declare = M.getFunction("llvm.dbg.declare"); - - if (!Declare) - return false; - - std::vector DeadConstants; +bool StripDeadDebugInfo::runOnModule(Module &M) { + bool Changed = false; - while (!Declare->use_empty()) { - CallInst *CI = cast(Declare->use_back()); - Value *Arg1 = CI->getOperand(1); - Value *Arg2 = CI->getOperand(2); - assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); - CI->eraseFromParent(); - if (Arg1->use_empty()) { - if (Constant *C = dyn_cast(Arg1)) - DeadConstants.push_back(C); - else - RecursivelyDeleteTriviallyDeadInstructions(Arg1, NULL); + // Debugging infomration is encoded in llvm IR using metadata. This is designed + // such a way that debug info for symbols preserved even if symbols are + // optimized away by the optimizer. This special pass removes debug info for + // such symbols. + + // llvm.dbg.gv keeps track of debug info for global variables. + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { + SmallVector MDs; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + if (DIGlobalVariable(NMD->getOperand(i)).Verify()) + MDs.push_back(NMD->getOperand(i)); + else + Changed = true; + NMD->eraseFromParent(); + NMD = NULL; + + for (SmallVector::iterator I = MDs.begin(), + E = MDs.end(); I != E; ++I) { + GlobalVariable *GV = DIGlobalVariable(*I).getGlobal(); + if (GV && M.getGlobalVariable(GV->getName(), true)) { + if (!NMD) + NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); + NMD->addOperand(*I); + } + else + Changed = true; } - if (Arg2->use_empty()) - if (Constant *C = dyn_cast(Arg2)) - DeadConstants.push_back(C); } - Declare->eraseFromParent(); - while (!DeadConstants.empty()) { - Constant *C = DeadConstants.back(); - DeadConstants.pop_back(); - if (GlobalVariable *GV = dyn_cast(C)) { - if (GV->hasLocalLinkage()) - RemoveDeadConstant(GV); + // llvm.dbg.sp keeps track of debug info for subprograms. + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) { + SmallVector MDs; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + if (DISubprogram(NMD->getOperand(i)).Verify()) + MDs.push_back(NMD->getOperand(i)); + else + Changed = true; + NMD->eraseFromParent(); + NMD = NULL; + + for (SmallVector::iterator I = MDs.begin(), + E = MDs.end(); I != E; ++I) { + bool FnIsLive = false; + if (Function *F = DISubprogram(*I).getFunction()) + if (M.getFunction(F->getName())) + FnIsLive = true; + if (FnIsLive) { + if (!NMD) + NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); + NMD->addOperand(*I); + } else { + // Remove llvm.dbg.lv.fnname named mdnode which may have been used + // to hold debug info for dead function's local variables. + StringRef FName = DISubprogram(*I).getLinkageName(); + if (FName.empty()) + FName = DISubprogram(*I).getName(); + if (NamedMDNode *LVNMD = + M.getNamedMetadata(Twine("llvm.dbg.lv.", + getRealLinkageName(FName)))) + LVNMD->eraseFromParent(); + } } - else - RemoveDeadConstant(C); } - return true; + return Changed; }