xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/ValueSymbolTable.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- ValueSymbolTable.cpp - Implement the ValueSymbolTable class --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the ValueSymbolTable class for the IR library.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
150b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
160b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
170b57cec5SDimitry Andric #include "llvm/IR/Module.h"
180b57cec5SDimitry Andric #include "llvm/IR/Type.h"
190b57cec5SDimitry Andric #include "llvm/IR/Value.h"
200b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
210b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
220b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
230b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
2406c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
250b57cec5SDimitry Andric #include <cassert>
260b57cec5SDimitry Andric #include <utility>
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric using namespace llvm;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric #define DEBUG_TYPE "valuesymtab"
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric // Class destructor
330b57cec5SDimitry Andric ValueSymbolTable::~ValueSymbolTable() {
340b57cec5SDimitry Andric #ifndef NDEBUG // Only do this in -g mode...
350b57cec5SDimitry Andric   for (const auto &VI : vmap)
360b57cec5SDimitry Andric     dbgs() << "Value still in symbol table! Type = '"
370b57cec5SDimitry Andric            << *VI.getValue()->getType() << "' Name = '" << VI.getKeyData()
380b57cec5SDimitry Andric            << "'\n";
390b57cec5SDimitry Andric   assert(vmap.empty() && "Values remain in symbol table!");
400b57cec5SDimitry Andric #endif
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric ValueName *ValueSymbolTable::makeUniqueName(Value *V,
440b57cec5SDimitry Andric                                             SmallString<256> &UniqueName) {
450b57cec5SDimitry Andric   unsigned BaseSize = UniqueName.size();
46*0fca6ea1SDimitry Andric   bool AppenDot = false;
470b57cec5SDimitry Andric   if (auto *GV = dyn_cast<GlobalValue>(V)) {
480b57cec5SDimitry Andric     // A dot is appended to mark it as clone during ABI demangling so that
490b57cec5SDimitry Andric     // for example "_Z1fv" and "_Z1fv.1" both demangle to "f()", the second
500b57cec5SDimitry Andric     // one being a clone.
510b57cec5SDimitry Andric     // On NVPTX we cannot use a dot because PTX only allows [A-Za-z0-9_$] for
520b57cec5SDimitry Andric     // identifiers. This breaks ABI demangling but at least ptxas accepts and
530b57cec5SDimitry Andric     // compiles the program.
540b57cec5SDimitry Andric     const Module *M = GV->getParent();
550b57cec5SDimitry Andric     if (!(M && Triple(M->getTargetTriple()).isNVPTX()))
56*0fca6ea1SDimitry Andric       AppenDot = true;
570b57cec5SDimitry Andric   }
58*0fca6ea1SDimitry Andric 
59*0fca6ea1SDimitry Andric   while (true) {
60*0fca6ea1SDimitry Andric     // Trim any suffix off and append the next number.
61*0fca6ea1SDimitry Andric     UniqueName.resize(BaseSize);
62*0fca6ea1SDimitry Andric     raw_svector_ostream S(UniqueName);
63*0fca6ea1SDimitry Andric     if (AppenDot)
64*0fca6ea1SDimitry Andric       S << ".";
650b57cec5SDimitry Andric     S << ++LastUnique;
660b57cec5SDimitry Andric 
67*0fca6ea1SDimitry Andric     // Retry if MaxNameSize has been exceeded.
68*0fca6ea1SDimitry Andric     if (MaxNameSize > -1 && UniqueName.size() > (size_t)MaxNameSize) {
69*0fca6ea1SDimitry Andric       assert(BaseSize >= UniqueName.size() - (size_t)MaxNameSize &&
70*0fca6ea1SDimitry Andric              "Can't generate unique name: MaxNameSize is too small.");
71*0fca6ea1SDimitry Andric       BaseSize -= UniqueName.size() - (size_t)MaxNameSize;
72*0fca6ea1SDimitry Andric       continue;
73*0fca6ea1SDimitry Andric     }
740b57cec5SDimitry Andric     // Try insert the vmap entry with this suffix.
75fe6060f1SDimitry Andric     auto IterBool = vmap.insert(std::make_pair(UniqueName.str(), V));
760b57cec5SDimitry Andric     if (IterBool.second)
770b57cec5SDimitry Andric       return &*IterBool.first;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric // Insert a value into the symbol table with the specified name...
820b57cec5SDimitry Andric //
830b57cec5SDimitry Andric void ValueSymbolTable::reinsertValue(Value *V) {
840b57cec5SDimitry Andric   assert(V->hasName() && "Can't insert nameless Value into symbol table");
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Try inserting the name, assuming it won't conflict.
870b57cec5SDimitry Andric   if (vmap.insert(V->getValueName())) {
880b57cec5SDimitry Andric     // LLVM_DEBUG(dbgs() << " Inserted value: " << V->getValueName() << ": " <<
890b57cec5SDimitry Andric     // *V << "\n");
900b57cec5SDimitry Andric     return;
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   // Otherwise, there is a naming conflict.  Rename this value.
940b57cec5SDimitry Andric   SmallString<256> UniqueName(V->getName().begin(), V->getName().end());
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   // The name is too already used, just free it so we can allocate a new name.
975ffd83dbSDimitry Andric   MallocAllocator Allocator;
985ffd83dbSDimitry Andric   V->getValueName()->Destroy(Allocator);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   ValueName *VN = makeUniqueName(V, UniqueName);
1010b57cec5SDimitry Andric   V->setValueName(VN);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric void ValueSymbolTable::removeValueName(ValueName *V) {
1050b57cec5SDimitry Andric   // LLVM_DEBUG(dbgs() << " Removing Value: " << V->getKeyData() << "\n");
1060b57cec5SDimitry Andric   // Remove the value from the symbol table.
1070b57cec5SDimitry Andric   vmap.remove(V);
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric /// createValueName - This method attempts to create a value name and insert
1110b57cec5SDimitry Andric /// it into the symbol table with the specified name.  If it conflicts, it
1120b57cec5SDimitry Andric /// auto-renames the name and returns that instead.
1130b57cec5SDimitry Andric ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) {
114fe6060f1SDimitry Andric   if (MaxNameSize > -1 && Name.size() > (unsigned)MaxNameSize)
115fe6060f1SDimitry Andric     Name = Name.substr(0, std::max(1u, (unsigned)MaxNameSize));
116fe6060f1SDimitry Andric 
1170b57cec5SDimitry Andric   // In the common case, the name is not already in the symbol table.
1180b57cec5SDimitry Andric   auto IterBool = vmap.insert(std::make_pair(Name, V));
1190b57cec5SDimitry Andric   if (IterBool.second) {
1200b57cec5SDimitry Andric     // LLVM_DEBUG(dbgs() << " Inserted value: " << Entry.getKeyData() << ": "
1210b57cec5SDimitry Andric     //           << *V << "\n");
1220b57cec5SDimitry Andric     return &*IterBool.first;
1230b57cec5SDimitry Andric   }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   // Otherwise, there is a naming conflict.  Rename this value.
1260b57cec5SDimitry Andric   SmallString<256> UniqueName(Name.begin(), Name.end());
1270b57cec5SDimitry Andric   return makeUniqueName(V, UniqueName);
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1310b57cec5SDimitry Andric // dump - print out the symbol table
1320b57cec5SDimitry Andric //
1330b57cec5SDimitry Andric LLVM_DUMP_METHOD void ValueSymbolTable::dump() const {
1340b57cec5SDimitry Andric   // dbgs() << "ValueSymbolTable:\n";
1350b57cec5SDimitry Andric   for (const auto &I : *this) {
1360b57cec5SDimitry Andric     // dbgs() << "  '" << I->getKeyData() << "' = ";
1370b57cec5SDimitry Andric     I.getValue()->dump();
1380b57cec5SDimitry Andric     // dbgs() << "\n";
1390b57cec5SDimitry Andric   }
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric #endif
142