ValueSymbolTable.cpp revision 0b8c9a80f20772c3793201ab5b251d3520b9cea3
1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- ValueSymbolTable.cpp - Implement the ValueSymbolTable class -------===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file implements the ValueSymbolTable class for the IR library.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
12d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany//===----------------------------------------------------------------------===//
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define DEBUG_TYPE "valuesymtab"
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "llvm/IR/ValueSymbolTable.h"
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "llvm/ADT/SmallString.h"
1705bf9a51dfeac0f84f6dbc2dacf987249c0fc612Alexander Potapenko#include "llvm/IR/GlobalValue.h"
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "llvm/IR/Type.h"
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "llvm/Support/Debug.h"
201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "llvm/Support/raw_ostream.h"
21487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonovusing namespace llvm;
221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Class destructor
244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya SerebryanyValueSymbolTable::~ValueSymbolTable() {
255b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov#ifndef NDEBUG   // Only do this in -g mode...
26c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
27c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    dbgs() << "Value still in symbol table! Type = '"
281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany           << *VI->getValue()->getType() << "' Name = '"
291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany           << VI->getKeyData() << "'\n";
301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  assert(vmap.empty() && "Values remain in symbol table!");
311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif
329f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany}
3379d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko
349f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany// Insert a value into the symbol table with the specified name...
359f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany//
369f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryanyvoid ValueSymbolTable::reinsertValue(Value* V) {
379f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany  assert(V->hasName() && "Can't insert nameless Value into symbol table");
381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // Try inserting the name, assuming it won't conflict.
401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (vmap.insert(V->Name)) {
411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    //DEBUG(dbgs() << " Inserted value: " << V->Name << ": " << *V << "\n");
421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return;
431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // Otherwise, there is a naming conflict.  Rename this value.
461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  SmallString<256> UniqueName(V->getName().begin(), V->getName().end());
471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // The name is too already used, just free it so we can allocate a new name.
493f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  V->Name->Destroy();
509f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany
519f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany  unsigned BaseSize = UniqueName.size();
521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (1) {
53e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    // Trim any suffix off and append the next number.
541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    UniqueName.resize(BaseSize);
551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    raw_svector_ostream(UniqueName) << ++LastUnique;
561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
57e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    // Try insert the vmap entry with this suffix.
581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ValueName &NewName = vmap.GetOrCreateValue(UniqueName);
591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (NewName.getValue() == 0) {
601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      // Newly inserted name.  Success!
61e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany      NewName.setValue(V);
621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      V->Name = &NewName;
631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany     //DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n");
641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      return;
651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
663f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  }
673f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany}
680985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany
691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ValueSymbolTable::removeValueName(ValueName *V) {
70c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany  //DEBUG(dbgs() << " Removing Value: " << V->getKeyData() << "\n");
711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // Remove the value from the symbol table.
721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  vmap.remove(V);
730985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany}
74487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov
75487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov/// createValueName - This method attempts to create a value name and insert
76487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov/// it into the symbol table with the specified name.  If it conflicts, it
771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany/// auto-renames the name and returns that instead.
78e130191a254064bfd1c8d373afdacf6d52979713Kostya SerebryanyValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) {
791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // In the common case, the name is not already in the symbol table.
80e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ValueName &Entry = vmap.GetOrCreateValue(Name);
81e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  if (Entry.getValue() == 0) {
82e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    Entry.setValue(V);
83e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    //DEBUG(dbgs() << " Inserted value: " << Entry.getKeyData() << ": "
84e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    //           << *V << "\n");
85e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    return &Entry;
861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
87c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
8881a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov  // Otherwise, there is a naming conflict.  Rename this value.
893f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  SmallString<256> UniqueName(Name.begin(), Name.end());
9009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov
911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (1) {
92f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov    // Trim any suffix off and append the next number.
93c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    UniqueName.resize(Name.size());
94a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany    raw_svector_ostream(UniqueName) << ++LastUnique;
951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    // Try insert the vmap entry with this suffix.
971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ValueName &NewName = vmap.GetOrCreateValue(UniqueName);
981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (NewName.getValue() == 0) {
991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      // Newly inserted name.  Success!
1001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      NewName.setValue(V);
101600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov     //DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n");
1024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany      return &NewName;
1034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany    }
1044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  }
1054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
1064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
107fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov
108b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov// dump - print out the symbol table
109b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov//
1109cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanovvoid ValueSymbolTable::dump() const {
111e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany  //DEBUG(dbgs() << "ValueSymbolTable:\n");
11255cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov  for (const_iterator I = begin(), E = end(); I != E; ++I) {
11355cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov    //DEBUG(dbgs() << "  '" << I->getKeyData() << "' = ");
11409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    I->getValue()->dump();
1154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany    //DEBUG(dbgs() << "\n");
116fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov  }
1174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
11834a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov