Changes in directory llvm/lib/VMCore:
TypeSymbolTable.cpp added (r1.1) ValueSymbolTable.cpp added (r1.1) --- Log message: For PR411: http://llvm.cs.uiuc.edu/PR411 : First step in refactoring the SymbolTable is to split it into two classes, one for a symbol table of types and one for a symbol table of Values. --- Diffs of the changes: (+360 -0) TypeSymbolTable.cpp | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ ValueSymbolTable.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 360 insertions(+) Index: llvm/lib/VMCore/TypeSymbolTable.cpp diff -c /dev/null llvm/lib/VMCore/TypeSymbolTable.cpp:1.1 *** /dev/null Tue Jan 10 03:51:58 2006 --- llvm/lib/VMCore/TypeSymbolTable.cpp Tue Jan 10 03:51:48 2006 *************** *** 0 **** --- 1,193 ---- + //===-- TypeSymbolTable.cpp - Implement the TypeSymbolTable class ---------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and revised by Reid + // Spencer. It is distributed under the University of Illinois Open Source + // License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the TypeSymbolTable class for the VMCore library. + // + //===----------------------------------------------------------------------===// + + #include "llvm/TypeSymbolTable.h" + #include "llvm/DerivedTypes.h" + #include "llvm/ADT/StringExtras.h" + #include <iostream> + + using namespace llvm; + + #define DEBUG_SYMBOL_TABLE 0 + #define DEBUG_ABSTYPE 0 + + TypeSymbolTable::~TypeSymbolTable() { + // Drop all abstract type references in the type plane... + for (iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { + if (TI->second->isAbstract()) // If abstract, drop the reference... + cast<DerivedType>(TI->second)->removeAbstractTypeUser(this); + } + } + + std::string TypeSymbolTable::getUniqueName(const std::string &BaseName) const { + std::string TryName = BaseName; + const_iterator End = tmap.end(); + + // See if the name exists + while (tmap.find(TryName) != End) // Loop until we find a free + TryName = BaseName + utostr(++LastUnique); // name in the symbol table + return TryName; + } + + // lookup a type by name - returns null on failure + Type* TypeSymbolTable::lookup(const std::string& Name) const { + const_iterator TI = tmap.find(Name); + if (TI != tmap.end()) + return const_cast<Type*>(TI->second); + return 0; + } + + // Erase a specific type from the symbol table + bool TypeSymbolTable::erase(Type *N) { + for (iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { + if (TI->second == N) { + this->erase(TI); + return true; + } + } + return false; + } + + // remove - Remove a type from the symbol table... + Type* TypeSymbolTable::erase(iterator Entry) { + assert(Entry != tmap.end() && "Invalid entry to remove!"); + + const Type* Result = Entry->second; + + #if DEBUG_SYMBOL_TABLE + dump(); + std::cerr << " Removing Value: " << Result->getName() << "\n"; + #endif + + tmap.erase(Entry); + + // If we are removing an abstract type, remove the symbol table from it's use + // list... + if (Result->isAbstract()) { + #if DEBUG_ABSTYPE + std::cerr << "Removing abstract type from symtab" << Result->getDescription()<<"\n"; + #endif + cast<DerivedType>(Result)->removeAbstractTypeUser(this); + } + + return const_cast<Type*>(Result); + } + + + // insert - Insert a type into the symbol table with the specified name... + void TypeSymbolTable::insert(const std::string& Name, const Type* T) { + assert(T && "Can't insert null type into symbol table!"); + + // Check to see if there is a naming conflict. If so, rename this type! + std::string UniqueName = Name; + if (lookup(Name)) + UniqueName = getUniqueName(Name); + + #if DEBUG_SYMBOL_TABLE + dump(); + std::cerr << " Inserting type: " << UniqueName << ": " + << T->getDescription() << "\n"; + #endif + + // Insert the tmap entry + tmap.insert(make_pair(UniqueName, T)); + + // If we are adding an abstract type, add the symbol table to it's use list. + if (T->isAbstract()) { + cast<DerivedType>(T)->addAbstractTypeUser(this); + #if DEBUG_ABSTYPE + std::cerr << "Added abstract type to ST: " << T->getDescription() << "\n"; + #endif + } + } + + // Strip the symbol table of its names. + bool TypeSymbolTable::strip() { + bool RemovedSymbol = false; + for (iterator TI = tmap.begin(); TI != tmap.end(); ) { + erase(TI++); + RemovedSymbol = true; + } + + return RemovedSymbol; + } + + /// rename - Given a value with a non-empty name, remove its existing entry + /// from the symbol table and insert a new one for Name. This is equivalent to + /// doing "remove(V), V->Name = Name, insert(V)", but is faster, and will not + /// temporarily remove the symbol table plane if V is the last value in the + /// symtab with that name (which could invalidate iterators to that plane). + bool TypeSymbolTable::rename(Type *T, const std::string &name) { + for (iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { + if (TI->second == T) { + // Remove the old entry. + tmap.erase(TI); + // Add the new entry. + this->insert(name,T); + return true; + } + } + return false; + } + + // This function is called when one of the types in the type plane are refined + void TypeSymbolTable::refineAbstractType(const DerivedType *OldType, + const Type *NewType) { + + // Loop over all of the types in the symbol table, replacing any references + // to OldType with references to NewType. Note that there may be multiple + // occurrences, and although we only need to remove one at a time, it's + // faster to remove them all in one pass. + // + for (iterator I = begin(), E = end(); I != E; ++I) { + if (I->second == (Type*)OldType) { // FIXME when Types aren't const. + #if DEBUG_ABSTYPE + std::cerr << "Removing type " << OldType->getDescription() << "\n"; + #endif + OldType->removeAbstractTypeUser(this); + + I->second = (Type*)NewType; // TODO FIXME when types aren't const + if (NewType->isAbstract()) { + #if DEBUG_ABSTYPE + std::cerr << "Added type " << NewType->getDescription() << "\n"; + #endif + cast<DerivedType>(NewType)->addAbstractTypeUser(this); + } + } + } + } + + + // Handle situation where type becomes Concreate from Abstract + void TypeSymbolTable::typeBecameConcrete(const DerivedType *AbsTy) { + // Loop over all of the types in the symbol table, dropping any abstract + // type user entries for AbsTy which occur because there are names for the + // type. + for (iterator TI = begin(), TE = end(); TI != TE; ++TI) + if (TI->second == const_cast<Type*>(static_cast<const Type*>(AbsTy))) + AbsTy->removeAbstractTypeUser(this); + } + + static void DumpTypes(const std::pair<const std::string, const Type*>& T ) { + std::cerr << " '" << T.first << "' = "; + T.second->dump(); + std::cerr << "\n"; + } + + void TypeSymbolTable::dump() const { + std::cerr << "TypeSymbolPlane: "; + for_each(tmap.begin(), tmap.end(), DumpTypes); + } + + // vim: sw=2 ai Index: llvm/lib/VMCore/ValueSymbolTable.cpp diff -c /dev/null llvm/lib/VMCore/ValueSymbolTable.cpp:1.1 *** /dev/null Tue Jan 10 03:52:01 2006 --- llvm/lib/VMCore/ValueSymbolTable.cpp Tue Jan 10 03:51:48 2006 *************** *** 0 **** --- 1,167 ---- + //===-- ValueSymbolTable.cpp - Implement the ValueSymbolTable class -------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and revised by Reid + // Spencer. It is distributed under the University of Illinois Open Source + // License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the ValueSymbolTable class for the VMCore library. + // + //===----------------------------------------------------------------------===// + + #include "llvm/GlobalValue.h" + #include "llvm/Type.h" + #include "llvm/ValueSymbolTable.h" + #include "llvm/ADT/StringExtras.h" + #include <algorithm> + #include <iostream> + + using namespace llvm; + + #define DEBUG_SYMBOL_TABLE 0 + #define DEBUG_ABSTYPE 0 + + // Class destructor + ValueSymbolTable::~ValueSymbolTable() { + #ifndef NDEBUG // Only do this in -g mode... + bool LeftoverValues = true; + for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI) + if (!isa<Constant>(VI->second) ) { + std::cerr << "Value still in symbol table! Type = '" + << VI->second->getType()->getDescription() << "' Name = '" + << VI->first << "'\n"; + LeftoverValues = false; + } + assert(LeftoverValues && "Values remain in symbol table!"); + #endif + } + + // getUniqueName - Given a base name, return a string that is either equal to + // it (or derived from it) that does not already occur in the symbol table for + // the specified type. + // + std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const { + std::string TryName = BaseName; + const_iterator End = vmap.end(); + + // See if the name exists + while (vmap.find(TryName) != End) // Loop until we find a free + TryName = BaseName + utostr(++LastUnique); // name in the symbol table + return TryName; + } + + + // lookup a value - Returns null on failure... + // + Value *ValueSymbolTable::lookup(const std::string &Name) const { + const_iterator VI = vmap.find(Name); + if (VI != vmap.end()) // We found the symbol + return const_cast<Value*>(VI->second); + return 0; + } + + // Strip the symbol table of its names. + // + bool ValueSymbolTable::strip() { + bool RemovedSymbol = false; + for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ) { + Value *V = VI->second; + ++VI; + if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) { + // Set name to "", removing from symbol table! + V->setName(""); + RemovedSymbol = true; + } + } + return RemovedSymbol; + } + + // Insert a value into the symbol table with the specified name... + // + void ValueSymbolTable::insert(Value* V) { + assert(V && "Can't insert null Value into symbol table!"); + assert(V->hasName() && "Can't insert nameless Value into symbol table"); + + // Check to see if there is a naming conflict. If so, rename this type! + std::string UniqueName = getUniqueName(V->getName()); + + #if DEBUG_SYMBOL_TABLE + dump(); + std::cerr << " Inserting value: " << UniqueName << ": " << V->dump() << "\n"; + #endif + + // Insert the vmap entry + vmap.insert(make_pair(UniqueName, V)); + } + + // Remove a value + bool ValueSymbolTable::erase(Value *V) { + assert(V->hasName() && "Value doesn't have name!"); + iterator Entry = vmap.find(V->getName()); + if (Entry == vmap.end()) + return false; + + #if DEBUG_SYMBOL_TABLE + dump(); + std::cerr << " Removing Value: " << Entry->second->getName() << "\n"; + #endif + + // Remove the value from the plane... + vmap.erase(Entry); + return true; + } + + + // rename - Given a value with a non-empty name, remove its existing entry + // from the symbol table and insert a new one for Name. This is equivalent to + // doing "remove(V), V->Name = Name, insert(V)", + // + bool ValueSymbolTable::rename(Value *V, const std::string &name) { + assert(V && "Can't rename a null Value"); + assert(V->hasName() && "Can't rename a nameless Value"); + assert(!V->getName().empty() && "Can't rename an Value with null name"); + assert(V->getName() != name && "Can't rename a Value with same name"); + assert(!name.empty() && "Can't rename a named Value with a null name"); + + // Find the name + iterator VI = vmap.find(V->getName()); + + // If we didn't find it, we're done + if (VI == vmap.end()) + return false; + + // Remove the old entry. + vmap.erase(VI); + + // See if we can insert the new name. + VI = vmap.lower_bound(name); + + // Is there a naming conflict? + if (VI != vmap.end() && VI->first == name) { + V->Name = getUniqueName( name); + vmap.insert(make_pair(V->Name, V)); + } else { + V->Name = name; + vmap.insert(VI, make_pair(name, V)); + } + + return true; + } + + // DumpVal - a std::for_each function for dumping a value + // + static void DumpVal(const std::pair<const std::string, Value *> &V) { + std::cerr << " '" << V.first << "' = "; + V.second->dump(); + std::cerr << "\n"; + } + + // dump - print out the symbol table + // + void ValueSymbolTable::dump() const { + std::cerr << "ValueSymbolTable:\n"; + for_each(vmap.begin(), vmap.end(), DumpVal); + } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits