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 @@ -60,18 +60,18 @@ /// @name Constructors /// @{ - ValueSymbolTable() : vmap(0) {} + ValueSymbolTable(bool IsLocal) : vmap(0), isLocal(IsLocal) {} ~ValueSymbolTable(); -/// @} -/// @name Accessors -/// @{ + /// @} + /// @name Accessors + /// @{ /// This method finds the value with the given \p Name in the /// 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) const; /// @returns true iff the symbol table is empty /// Determine if the symbol table is empty @@ -107,17 +107,17 @@ private: ValueName *makeUniqueName(Value *V, SmallString<256> &UniqueName); + /// createValueName - This method attempts to create a value name and insert + /// it into the symbol table with the specified name. If it conflicts, it + /// auto-renames the name and returns that instead. + ValueName *createValueName(StringRef Name, Value *V); + /// This method adds the provided value \p N to the symbol table. The Value /// must have a name which is used to place the value in the symbol table. /// If the inserted name conflicts, this renames the value. /// Add a named value to the symbol table void reinsertValue(Value *V); - /// createValueName - This method attempts to create a value name and insert - /// it into the symbol table with the specified name. If it conflicts, it - /// auto-renames the name and returns that instead. - ValueName *createValueName(StringRef Name, Value *V); - /// This method removes a value from the symbol table. It leaves the /// ValueName attached to the value, but it is no longer inserted in the /// symtab. @@ -128,6 +128,8 @@ /// @{ ValueMap vmap; ///< The map that holds the symbol table. + bool isLocal; ///< If true, this symbol table holds local values instead of + ///< global values. mutable uint32_t LastUnique = 0; ///< Counter for tracking unique names /// @} diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -49,6 +49,7 @@ #include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/IntrinsicsXCore.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -58,7 +59,6 @@ #include "llvm/IR/Use.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" -#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -385,7 +385,7 @@ // We only need a symbol table for a function if the context keeps value names if (!getContext().shouldDiscardValueNames()) - SymTab = std::make_unique(); + SymTab = std::make_unique(true); // If the function has arguments, mark them as lazily built. if (Ty->getNumParams()) diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -72,7 +72,7 @@ // Module::Module(StringRef MID, LLVMContext &C) - : Context(C), ValSymTab(std::make_unique()), + : Context(C), ValSymTab(std::make_unique(false)), Materializer(), ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL("") { Context.addModule(this); 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... @@ -96,10 +111,24 @@ vmap.remove(V); } +Value *ValueSymbolTable::lookup(StringRef Name) const { + if (isLocal) { + // Ensure that the name is capped according to the value of + // non-global-value-max-name-size + Name = capLocalValueName(Name); + } + + return vmap.lookup(Name); +} + /// createValueName - This method attempts to create a value name and insert /// 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) { + if (isLocal) { + 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 +}