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