diff --git a/llvm/include/llvm/IR/LocalValueSymbolTable.h b/llvm/include/llvm/IR/LocalValueSymbolTable.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/IR/LocalValueSymbolTable.h @@ -0,0 +1,51 @@ +//===- llvm/LocalValueSymbolTable.h - Implement a Value Symtab -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the name/Value symbol table for LLVM. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_LOCALVALUESYMBOLTABLE_H +#define LLVM_IR_LOCALVALUESYMBOLTABLE_H + +#include "llvm/IR/ValueSymbolTable.h" + +namespace llvm { + +/// This class provides a symbol table of name/value pairs. It is essentially +/// a std::map but has a controlled interface provided by +/// LLVM as well as ensuring uniqueness of names. +/// +class LocalValueSymbolTable : public ValueSymbolTable { +/// @name Types +/// @{ +public: +/// @} +/// @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 override; + + /// @} + /// @name Mutators + /// @{ +private: + /// 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) override; +/// @} +}; + +} // end namespace llvm + +#endif // LLVM_IR_LOCALVALUESYMBOLTABLE_H 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 @@ -61,7 +61,7 @@ /// @{ ValueSymbolTable() : vmap(0) {} - ~ValueSymbolTable(); + virtual ~ValueSymbolTable(); /// @} /// @name Accessors @@ -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); } + virtual Value *lookup(StringRef Name) const; /// @returns true iff the symbol table is empty /// Determine if the symbol table is empty @@ -104,6 +104,12 @@ /// @} /// @name Mutators /// @{ +protected: + /// 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. + virtual ValueName *createValueName(StringRef Name, Value *V); + private: ValueName *makeUniqueName(Value *V, SmallString<256> &UniqueName); @@ -113,11 +119,6 @@ /// 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. diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -32,6 +32,7 @@ LLVMContext.cpp LLVMContextImpl.cpp LLVMRemarkStreamer.cpp + LocalValueSymbolTable.cpp LegacyPassManager.cpp MDBuilder.cpp Mangler.cpp 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 @@ -58,7 +58,7 @@ #include "llvm/IR/Use.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" -#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/IR/LocalValueSymbolTable.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(); // If the function has arguments, mark them as lazily built. if (Ty->getNumParams()) diff --git a/llvm/lib/IR/LocalValueSymbolTable.cpp b/llvm/lib/IR/LocalValueSymbolTable.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/IR/LocalValueSymbolTable.cpp @@ -0,0 +1,42 @@ +//===- LocalValueSymbolTable.cpp - Implement the LocalValueSymbolTable class --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the LocalValueSymbolTable class for the IR library. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/LocalValueSymbolTable.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +#define DEBUG_TYPE "localvaluesymtab" + +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; +} + +//===----------------------------------------------------------------------===// +// LocalValueSymbolTable Class +//===----------------------------------------------------------------------===// + +Value *LocalValueSymbolTable::lookup(StringRef Name) const { + // Ensure that the name is capped according to the value of non-global-value-max-name-size + return ValueSymbolTable::lookup(capLocalValueName(Name)); +} + +ValueName *LocalValueSymbolTable::createValueName(StringRef Name, Value *V) { + // Ensure that the name is capped according to the value of non-global-value-max-name-size + return ValueSymbolTable::createValueName(capLocalValueName(Name), 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 @@ -29,6 +29,10 @@ #define DEBUG_TYPE "valuesymtab" +//===----------------------------------------------------------------------===// +// ValueSymbolTable Class +//===----------------------------------------------------------------------===// + // Class destructor ValueSymbolTable::~ValueSymbolTable() { #ifndef NDEBUG // Only do this in -g mode... @@ -40,6 +44,10 @@ #endif } +Value *ValueSymbolTable::lookup(StringRef Name) const { + return vmap.lookup(Name); +} + ValueName *ValueSymbolTable::makeUniqueName(Value *V, SmallString<256> &UniqueName) { unsigned BaseSize = UniqueName.size(); 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 +}