Index: include/llvm/IR/LLVMContext.h =================================================================== --- include/llvm/IR/LLVMContext.h +++ include/llvm/IR/LLVMContext.h @@ -103,6 +103,15 @@ /// Remove the GC for a function void deleteGC(const Function &Fn); + /// Return true if the Context runtime configuration is set to preserve all + /// value name. When false, only GlobalValue names will be available in the + /// IR. + bool preserveNonGlobalValueNames(); + + /// Set the Context runtime configuration to preserve all value name (true, + /// default) or only GlobalValue names (false). Clients can use this flag to + /// save memory and runtime, especially in release mode. + void setPreserveNonGlobalValueNames(bool Preserve); typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context, unsigned LocCookie); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -45,6 +45,11 @@ // Prime the lexer. Lex.Lex(); + if (!Context.preserveNonGlobalValueNames()) + return Error( + Lex.getLoc(), + "Can read textual IR with a Context that doesn't support named Values"); + return ParseTopLevelEntities() || ValidateEndOfModule(); } Index: lib/IR/LLVMContext.cpp =================================================================== --- lib/IR/LLVMContext.cpp +++ lib/IR/LLVMContext.cpp @@ -320,3 +320,9 @@ void LLVMContext::deleteGC(const Function &Fn) { pImpl->GCNames.erase(&Fn); } + +bool LLVMContext::preserveNonGlobalValueNames() { return pImpl->PreserveNames; } + +void LLVMContext::setPreserveNonGlobalValueNames(bool Preserve) { + pImpl->PreserveNames = Preserve; +} Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -1034,6 +1034,10 @@ /// clients which do use GC. DenseMap GCNames; + /// Flag to indicate if Value (other than GlobalValue) retains their name or + /// not. + bool PreserveNames = true; + LLVMContextImpl(LLVMContext &C); ~LLVMContextImpl(); Index: lib/IR/Value.cpp =================================================================== --- lib/IR/Value.cpp +++ lib/IR/Value.cpp @@ -195,6 +195,10 @@ } void Value::setNameImpl(const Twine &NewName) { + // Fast-path: LLVMContext can be set to strip out non-GlobalValue names + if (!getContext().preserveNonGlobalValueNames() && !isa(this)) + return; + // Fast path for common IRBuilder case of setName("") when there is no name. if (NewName.isTriviallyEmpty() && !hasName()) return; Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -76,6 +76,9 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) : Context(&Context), MergedModule(new Module("ld-temp.o", Context)), TheLinker(new Linker(*MergedModule)) { +#ifdef NDEBUG + Context.setPreserveNonGlobalValueNames(false); +#endif initializeLTOPasses(); } Index: test/Feature/strip_names.ll =================================================================== --- /dev/null +++ test/Feature/strip_names.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -S | FileCheck %s +; RUN: opt < %s | opt -S -disable-named-value | FileCheck --check-prefix=NONAME %s + + +; CHECK: @GlobalValueName +; CHECK: @foo(i32 %in) +; CHECK: somelabel: +; CHECK: %GV = load i32, i32* @GlobalValueName +; CHECK: %add = add i32 %in, %GV +; CHECK: ret i32 %add + +; NONAME: @GlobalValueName +; NONAME: @foo(i32) +; NONAME-NOT: somelabel: +; NONAME: %2 = load i32, i32* @GlobalValueName +; NONAME: %3 = add i32 %0, %2 +; NONAME: ret i32 %3 + +@GlobalValueName = global i32 0 + +define i32 @foo(i32 %in) { +somelabel: + %GV = load i32, i32* @GlobalValueName + %add = add i32 %in, %GV + ret i32 %add +} Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -103,6 +103,11 @@ "manager and verify the result is the same."), cl::init(false)); +static cl::opt DisableNamedValue( + "disable-named-value", + cl::desc("Strip name from Value (other than GlobalValue)."), + cl::init(false), cl::Hidden); + static int compileModule(char **, LLVMContext &); static std::unique_ptr @@ -205,6 +210,9 @@ cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); + // Honor "-disable-named-value" command line option + Context.setPreserveNonGlobalValueNames(!DisableNamedValue); + // Compile the module TimeCompilations times to give better compile time // metrics. for (unsigned I = TimeCompilations; I; --I) Index: tools/opt/opt.cpp =================================================================== --- tools/opt/opt.cpp +++ tools/opt/opt.cpp @@ -196,6 +196,11 @@ cl::desc("Run all passes twice, re-using the same pass manager."), cl::init(false), cl::Hidden); +static cl::opt DisableNamedValue( + "disable-named-value", + cl::desc("Strip name from Value (other than GlobalValue)."), + cl::init(false), cl::Hidden); + static inline void addPass(legacy::PassManagerBase &PM, Pass *P) { // Add the pass to the pass manager... PM.add(P); @@ -345,6 +350,9 @@ SMDiagnostic Err; + // Honor "-disable-named-value" command line option + Context.setPreserveNonGlobalValueNames(!DisableNamedValue); + // Load the input module... std::unique_ptr M = parseIRFile(InputFilename, Err, Context);