Unique Naming Mechanisms in LLVM

References:

ValueSymbolTable

ValueSymbolTable: 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 ValueSymbolTable {
    ...

private:
  ValueName *makeUniqueName(Value *V, SmallString<256> &UniqueName);

  /// 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.
  void removeValueName(ValueName *V);

  /// @}
  /// @name Internal Data
  /// @{

  ValueMap vmap;                    ///< The map that holds the symbol table.
  mutable uint32_t LastUnique = 0;  ///< Counter for tracking unique names

};

// makeUniqueName(..) in llvm/lib/IR/ValueSymbolTable.cpp

ValueName *ValueSymbolTable::makeUniqueName(Value *V,
                                            SmallString<256> &UniqueName) {
  unsigned BaseSize = UniqueName.size();
  while (true) {
    // Trim any suffix off and append the next number.
    UniqueName.resize(BaseSize);
    raw_svector_ostream S(UniqueName);
    if (auto *GV = dyn_cast<GlobalValue>(V)) {
      // A dot is appended to mark it as clone during ABI demangling so that
      // for example "_Z1fv" and "_Z1fv.1" both demangle to "f()", the second
      // one being a clone.
      // On NVPTX we cannot use a dot because PTX only allows [A-Za-z0-9_$] for
      // identifiers. This breaks ABI demangling but at least ptxas accepts and
      // compiles the program.
      const Module *M = GV->getParent();
      if (!(M && Triple(M->getTargetTriple()).isNVPTX()))
        S << ".";
    }
    S << ++LastUnique;

    // Try insert the vmap entry with this suffix.
    auto IterBool = vmap.insert(std::make_pair(UniqueName, V));
    if (IterBool.second)
      return &*IterBool.first;
  }
}

This table is created in multiple places:

  • Function (include/llvm/IR/Function.h): std::unique_ptr<ValueSymbolTable> SymTab;
    • symbol table of args/instructions
  • Module (include/llvm/IR/Module.h): std::unique_ptr<ValueSymbolTable> ValSymTab;
    • symbol table of global variable and function identifiers

More

Created Aug 29, 2020 // Last Updated Aug 29, 2020

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?