diff --git a/llvm/include/llvm/IR/ValueSymbolTable.h b/llvm/include/llvm/IR/ValueSymbolTable.h --- a/llvm/include/llvm/IR/ValueSymbolTable.h +++ b/llvm/include/llvm/IR/ValueSymbolTable.h @@ -71,7 +71,7 @@ /// the symbol table. /// @returns the value associated with the \p Name /// Lookup a named Value. - Value *lookup(StringRef Name) const { return vmap.lookup(Name); } + Value *lookup(StringRef Name, bool isLocal = false) const; /// @returns true iff the symbol table is empty /// Determine if the symbol table is empty diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3116,7 +3116,7 @@ Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty, LocTy Loc, bool IsCall) { // Look this name up in the normal function symbol table. - Value *Val = F.getValueSymbolTable()->lookup(Name); + Value *Val = F.getValueSymbolTable()->lookup(Name, true); // If this is a forward reference for the value, see if we already created a // forward ref record. @@ -3542,7 +3542,7 @@ return error(Label.Loc, "cannot take address of numeric label after " "the function is defined"); BB = dyn_cast_or_null( - F->getValueSymbolTable()->lookup(Label.StrVal)); + F->getValueSymbolTable()->lookup(Label.StrVal, true)); if (!BB) return error(Label.Loc, "referenced value is not a basic block"); } @@ -7981,7 +7981,7 @@ return error(Label.Loc, "invalid numeric label in uselistorder_bb"); if (Label.Kind != ValID::t_LocalName) return error(Label.Loc, "expected basic block name in uselistorder_bb"); - Value *V = F->getValueSymbolTable()->lookup(Label.StrVal); + Value *V = F->getValueSymbolTable()->lookup(Label.StrVal, true); if (!V) return error(Label.Loc, "invalid basic block in uselistorder_bb"); if (!isa(V)) diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -42,11 +42,6 @@ "use-dereferenceable-at-point-semantics", cl::Hidden, cl::init(false), cl::desc("Deref attributes and metadata infer facts at definition only")); - -static cl::opt NonGlobalValueMaxNameSize( - "non-global-value-max-name-size", cl::Hidden, cl::init(1024), - cl::desc("Maximum size for the name of non-global values.")); - //===----------------------------------------------------------------------===// // Value Class //===----------------------------------------------------------------------===// @@ -323,11 +318,6 @@ if (getName() == NameRef) return; - // Cap the size of non-GlobalValue names. - if (NameRef.size() > NonGlobalValueMaxNameSize && !isa(this)) - NameRef = - NameRef.substr(0, std::max(1u, (unsigned)NonGlobalValueMaxNameSize)); - assert(!getType()->isVoidTy() && "Cannot assign a name to void values!"); // Get the symbol table to update for this object. diff --git a/llvm/lib/IR/ValueSymbolTable.cpp b/llvm/lib/IR/ValueSymbolTable.cpp --- a/llvm/lib/IR/ValueSymbolTable.cpp +++ b/llvm/lib/IR/ValueSymbolTable.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -29,6 +30,20 @@ #define DEBUG_TYPE "valuesymtab" +static cl::opt NonGlobalValueMaxNameSize( + "non-global-value-max-name-size", cl::Hidden, cl::init(1024), + cl::desc("Maximum size for the name of non-global values.")); + +StringRef capLocalValueName(StringRef NameRef) { + if (NameRef.size() > NonGlobalValueMaxNameSize) + return NameRef.substr(0, std::max(1u, (unsigned)NonGlobalValueMaxNameSize)); + return NameRef; +} + +//===----------------------------------------------------------------------===// +// ValueSymbolTable Class +//===----------------------------------------------------------------------===// + // Class destructor ValueSymbolTable::~ValueSymbolTable() { #ifndef NDEBUG // Only do this in -g mode... @@ -40,6 +55,16 @@ #endif } +Value *ValueSymbolTable::lookup(StringRef Name, bool IsLocal) const { + // Ensure that the name is capped according to the value of + // non-global-value-max-name-size, otherwise symbol table + // lookup will fail if Name exceeds the size cap. + if (IsLocal) + Name = capLocalValueName(Name); + + return vmap.lookup(Name); +} + ValueName *ValueSymbolTable::makeUniqueName(Value *V, SmallString<256> &UniqueName) { unsigned BaseSize = UniqueName.size(); @@ -100,6 +125,10 @@ /// it into the symbol table with the specified name. If it conflicts, it /// auto-renames the name and returns that instead. ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) { + // Cap the size of non-GlobalValue names. + if (!isa(V)) + Name = capLocalValueName(Name); + // In the common case, the name is not already in the symbol table. auto IterBool = vmap.insert(std::make_pair(Name, V)); if (IterBool.second) { diff --git a/llvm/test/Assembler/non-global-value-max-name-size.ll b/llvm/test/Assembler/non-global-value-max-name-size.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/non-global-value-max-name-size.ll @@ -0,0 +1,10 @@ +; RUN: opt < %s -S -non-global-value-max-name-size=4 +; Test that local value name lookup works if the name is capped + +define void @f() { +bb0: + br label %testz + +testz: + br label %testz +}