Index: test/BugPoint/strip-names-and-types.ll =================================================================== --- /dev/null +++ test/BugPoint/strip-names-and-types.ll @@ -0,0 +1,20 @@ +; REQUIRES: loadable_module +; RUN: bugpoint %s -output-prefix %t -silence-passes -safe-run-llc +; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s +; RUN: bugpoint %s -output-prefix %t -disable-strip-symbols -silence-passes -safe-run-llc +; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck --check-prefix=DISABLE %s + +%type0 = type { i32, i64 } + +define i1 @foo(i1 %A) { + ret i1 %A +} + +; CHECK-LABEL: define i32 @test +define i32 @test() { + %A = icmp eq %type0* undef, undef +; CHECK: icmp eq %0* undef, undef +; DISABLE: icmp eq %type0* undef, undef + call i1 @foo(i1 %A) + ret i32 0 +} Index: tools/bugpoint/CrashDebugger.cpp =================================================================== --- tools/bugpoint/CrashDebugger.cpp +++ tools/bugpoint/CrashDebugger.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/IR/TypeFinder.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/IR/Verifier.h" #include "llvm/Pass.h" @@ -37,35 +38,122 @@ using namespace llvm; namespace { + +cl::OptionCategory CrashDebuggerOptions("CrashDebugger Options", ""); cl::opt KeepMain("keep-main", + cl::cat(CrashDebuggerOptions), cl::desc("Force function reduction to keep main"), cl::init(false)); cl::opt NoGlobalRM("disable-global-remove", + cl::cat(CrashDebuggerOptions), cl::desc("Do not remove global variables"), cl::init(false)); cl::opt ReplaceFuncsWithNull( "replace-funcs-with-null", + cl::cat(CrashDebuggerOptions), cl::desc("When stubbing functions, replace all uses will null"), cl::init(false)); cl::opt DontReducePassList("disable-pass-list-reduction", + cl::cat(CrashDebuggerOptions), cl::desc("Skip pass list reduction steps"), cl::init(false)); cl::opt NoNamedMDRM("disable-namedmd-remove", + cl::cat(CrashDebuggerOptions), cl::desc("Do not remove global named metadata"), cl::init(false)); cl::opt NoStripDebugInfo("disable-strip-debuginfo", + cl::cat(CrashDebuggerOptions), cl::desc("Do not strip debug info metadata"), cl::init(false)); cl::opt NoStripDebugTypeInfo("disable-strip-debug-types", - cl::desc("Do not strip debug type info metadata"), - cl::init(false)); + cl::cat(CrashDebuggerOptions), + cl::desc("Do not strip debug type info metadata"), + cl::init(false)); +cl::opt NoStripSymbols("disable-strip-symbols", + cl::cat(CrashDebuggerOptions), + cl::desc("Do not strip symbol and type names"), + cl::init(false)); cl::opt VerboseErrors("verbose-errors", + cl::cat(CrashDebuggerOptions), cl::desc("Print the output of crashing program"), cl::init(false)); } +// Strip the symbol table of its names. +// +static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { + for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { + Value *V = VI->getValue(); + ++VI; + if (!isa(V) || cast(V)->hasLocalLinkage()) { + if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) + // Set name to "", removing from symbol table! + V->setName(""); + } + } +} + +// 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. +static void findUsedValues(GlobalVariable *LLVMUsed, + SmallPtrSetImpl &UsedValues) { + if (!LLVMUsed) 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); +} + +static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { + + SmallPtrSet 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 || !I->getName().startswith("llvm.dbg")) + I->setName(""); // Internal symbols can't participate in linkage + } + + for (Function &I : M) { + if (I.hasLocalLinkage() && llvmUsedValues.count(&I) == 0) + if (!PreserveDbgInfo || !I.getName().startswith("llvm.dbg")) + I.setName(""); // Internal symbols can't participate in linkage + if (auto *Symtab = I.getValueSymbolTable()) + StripSymtab(*Symtab, PreserveDbgInfo); + } + + // Remove all names from types. + StripTypeNames(M, PreserveDbgInfo); + + return true; +} + +bool stripSymbolNames(Module &M) { return StripSymbolNames(M, true); } + namespace llvm { class ReducePassList : public ListReducer { BugDriver &BD; @@ -1127,6 +1215,10 @@ outs() << "\n*** Attempting to strip the debug type info: "; stripMetadata(stripNonLineTableDebugInfo); } + if (!NoStripSymbols && !BugpointIsInterrupted) { + outs() << "\n*** Attempting to strip symbol and type names: "; + stripMetadata(stripSymbolNames); + } if (!NoNamedMDRM) { if (!BugpointIsInterrupted) {