From: Reid Spencer Date: Tue, 25 May 2004 08:52:42 +0000 (+0000) Subject: Completely rewrote the class. SymbolTable now separates Type* from Value* in preparation\ X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b870c5f7c50a2e8e21329f10ab9105588adc773f;p=oota-llvm.git Completely rewrote the class. SymbolTable now separates Type* from Value* in preparation\ for making Type not derive from Value. There are now separate interfaces \ for looking up, finding, and inserting Types and Values. There are also \ three separate iterator interfaces, one for type planes, one for the types \ (type type plane), and one for values within a type plane. See the \ documentation in the Header file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13752 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/VMCore/SymbolTable.cpp b/lib/VMCore/SymbolTable.cpp index be1459e70b7..dc2900ef9ab 100644 --- a/lib/VMCore/SymbolTable.cpp +++ b/lib/VMCore/SymbolTable.cpp @@ -2,8 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// 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. // //===----------------------------------------------------------------------===// // @@ -16,6 +17,7 @@ #include "llvm/Module.h" #include "Support/StringExtras.h" #include + using namespace llvm; #define DEBUG_SYMBOL_TABLE 0 @@ -23,27 +25,22 @@ using namespace llvm; SymbolTable::~SymbolTable() { // Drop all abstract type references in the type plane... - iterator TyPlane = find(Type::TypeTy); - if (TyPlane != end()) { - VarMap &TyP = TyPlane->second; - for (VarMap::iterator I = TyP.begin(), E = TyP.end(); I != E; ++I) { - const Type *Ty = cast(I->second); - if (Ty->isAbstract()) // If abstract, drop the reference... - cast(Ty)->removeAbstractTypeUser(this); - } + for (type_iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { + if (TI->second->isAbstract()) // If abstract, drop the reference... + cast(TI->second)->removeAbstractTypeUser(this); } - // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the planes - // that could still have entries! + // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the + // planes that could still have entries! #ifndef NDEBUG // Only do this in -g mode... bool LeftoverValues = true; - for (iterator i = begin(); i != end(); ++i) { - for (type_iterator I = i->second.begin(); I != i->second.end(); ++I) - if (!isa(I->second) && !isa(I->second)) { + for (plane_iterator PI = pmap.begin(); PI != pmap.end(); ++PI) { + for (value_iterator VI = PI->second.begin(); VI != PI->second.end(); ++VI) + if (!isa(VI->second) ) { std::cerr << "Value still in symbol table! Type = '" - << i->first->getDescription() << "' Name = '" - << I->first << "'\n"; + << PI->first->getDescription() << "' Name = '" + << VI->first << "'\n"; LeftoverValues = false; } } @@ -57,47 +54,58 @@ SymbolTable::~SymbolTable() { // the specified type. // std::string SymbolTable::getUniqueName(const Type *Ty, - const std::string &BaseName) { - iterator I = find(Ty); - if (I == end()) return BaseName; + const std::string &BaseName) const { + // Find the plane + plane_const_iterator PI = pmap.find(Ty); + if (PI == pmap.end()) return BaseName; std::string TryName = BaseName; - type_iterator End = I->second.end(); + const ValueMap& vmap = PI->second; + value_const_iterator End = vmap.end(); - while (I->second.find(TryName) != End) // Loop until we find a free + // 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 - Returns null on failure... +// lookup a value - Returns null on failure... Value *SymbolTable::lookup(const Type *Ty, const std::string &Name) const { - const_iterator I = find(Ty); - if (I != end()) { // We have symbols in that plane... - type_const_iterator J = I->second.find(Name); - if (J != I->second.end()) // and the name is in our hash table... - return J->second; + plane_const_iterator PI = pmap.find(Ty); + if (PI != pmap.end()) { // We have symbols in that plane... + value_const_iterator VI = PI->second.find(Name); + if (VI != PI->second.end()) // and the name is in our hash table... + return VI->second; } + return 0; +} + +// lookup a type by name - returns null on failure +Type* SymbolTable::lookupType( const std::string& Name ) const { + type_const_iterator TI = tmap.find( Name ); + if ( TI != tmap.end() ) + return TI->second; return 0; } +// Remove a value void SymbolTable::remove(Value *N) { assert(N->hasName() && "Value doesn't have name!"); if (InternallyInconsistent) return; - iterator I = find(N->getType()); - assert(I != end() && - "Trying to remove a type that doesn't have a plane yet!"); - removeEntry(I, I->second.find(N->getName())); + plane_iterator PI = pmap.find(N->getType()); + assert(PI != pmap.end() && + "Trying to remove a value that doesn't have a type plane yet!"); + removeEntry(PI, PI->second.find(N->getName())); } + // removeEntry - Remove a value from the symbol table... -// -Value *SymbolTable::removeEntry(iterator Plane, type_iterator Entry) { +Value *SymbolTable::removeEntry(plane_iterator Plane, value_iterator Entry) { if (InternallyInconsistent) return 0; - assert(Plane != super::end() && + assert(Plane != pmap.end() && Entry != Plane->second.end() && "Invalid entry to remove!"); Value *Result = Entry->second; @@ -123,34 +131,60 @@ Value *SymbolTable::removeEntry(iterator Plane, type_iterator Entry) { cast(Plane->first)->removeAbstractTypeUser(this); } - erase(Plane); + pmap.erase(Plane); } + return Result; +} + + +// remove - Remove a type +void SymbolTable::remove(Type* Ty ) { + type_iterator TI = this->type_begin(); + type_iterator TE = this->type_end(); + + // Search for the entry + while ( TI != TE && TI->second != Ty ) + ++TI; + + if ( TI != TE ) + this->removeEntry( TI ); +} + + +// removeEntry - Remove a type from the symbol table... +Type* SymbolTable::removeEntry(type_iterator Entry) { + if (InternallyInconsistent) return 0; + assert( Entry != tmap.end() && "Invalid entry to remove!"); + + 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 (Ty == Type::TypeTy) { - const Type *T = cast(Result); - if (T->isAbstract()) { + if (Result->isAbstract()) { #if DEBUG_ABSTYPE - std::cerr << "Removing abs type from symtab" << T->getDescription()<<"\n"; + std::cerr << "Removing abstract type from symtab" << Result->getDescription()<<"\n"; #endif - cast(T)->removeAbstractTypeUser(this); - } + cast(Result)->removeAbstractTypeUser(this); } return Result; } -// insertEntry - Insert a value into the symbol table with the specified -// name... -// + +// insertEntry - Insert a value into the symbol table with the specified name. void SymbolTable::insertEntry(const std::string &Name, const Type *VTy, Value *V) { - // Check to see if there is a naming conflict. If so, rename this value! if (lookup(VTy, Name)) { std::string UniqueName = getUniqueName(VTy, Name); - assert(InternallyInconsistent == false && "Infinite loop inserting entry!"); + assert(InternallyInconsistent == false && "Infinite loop inserting value!"); InternallyInconsistent = true; V->setName(UniqueName, this); InternallyInconsistent = false; @@ -163,11 +197,11 @@ void SymbolTable::insertEntry(const std::string &Name, const Type *VTy, << VTy->getDescription() << "\n"; #endif - iterator I = find(VTy); - if (I == end()) { // Not in collection yet... insert dummy entry + plane_iterator PI = pmap.find(VTy); + if (PI == pmap.end()) { // Not in collection yet... insert dummy entry // Insert a new empty element. I points to the new elements. - I = super::insert(make_pair(VTy, VarMap())).first; - assert(I != end() && "How did insert fail?"); + PI = pmap.insert(make_pair(VTy, ValueMap())).first; + assert(PI != pmap.end() && "How did insert fail?"); // Check to see if the type is abstract. If so, it might be refined in the // future, which would cause the plane of the old type to get merged into @@ -182,31 +216,126 @@ void SymbolTable::insertEntry(const std::string &Name, const Type *VTy, } } - I->second.insert(make_pair(Name, V)); + PI->second.insert(make_pair(Name, V)); +} + + +// insertEntry - Insert a value into the symbol table with the specified +// name... +// +void SymbolTable::insertEntry(const std::string& Name, Type* T) { + + // Check to see if there is a naming conflict. If so, rename this type! + std::string UniqueName = Name; + if (lookupType(Name)) + UniqueName = getUniqueName(T, 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 (VTy == Type::TypeTy) { - const Type *T = cast(V); - if (T->isAbstract()) { - cast(T)->addAbstractTypeUser(this); + if (T->isAbstract()) { + cast(T)->addAbstractTypeUser(this); #if DEBUG_ABSTYPE - std::cerr << "Added abstract type to ST: " << T->getDescription() << "\n"; + std::cerr << "Added abstract type to ST: " << T->getDescription() << "\n"; #endif + } +} + + +// Determine how many entries for a given type. +unsigned SymbolTable::type_size(const Type *Ty) const { + plane_const_iterator PI = pmap.find(Ty); + if ( PI == pmap.end() ) return 0; + return PI->second.size(); +} + + +// Get the name of a value +std::string SymbolTable::get_name( const Value* V ) const { + value_const_iterator VI = this->value_begin( V->getType() ); + value_const_iterator VE = this->value_end( V->getType() ); + + // Search for the entry + while ( VI != VE && VI->second != V ) + ++VI; + + if ( VI != VE ) + return VI->first; + + return ""; +} + + +// Get the name of a type +std::string SymbolTable::get_name( const Type* T ) const { + if (tmap.empty()) return ""; // No types at all. + + type_const_iterator TI = tmap.begin(); + type_const_iterator TE = tmap.end(); + + // Search for the entry + while (TI != TE && TI->second != T ) + ++TI; + + if (TI != TE) // Must have found an entry! + return TI->first; + return ""; // Must not have found anything... +} + + +// Strip the symbol table of its names. +bool SymbolTable::strip( void ) { + bool RemovedSymbol = false; + for (plane_iterator I = pmap.begin(); I != pmap.end();) { + // Removing items from the plane can cause the plane itself to get deleted. + // If this happens, make sure we incremented our plane iterator already! + ValueMap &Plane = (I++)->second; + value_iterator B = Plane.begin(), Bend = Plane.end(); + while (B != Bend) { // Found nonempty type plane! + Value *V = B->second; + if (isa(V)) { + remove(V); + RemovedSymbol = true; + } else { + if (!isa(V) || cast(V)->hasInternalLinkage()){ + // Set name to "", removing from symbol table! + V->setName("", this); + RemovedSymbol = true; + } + } + ++B; } } + + for (type_iterator TI = tmap.begin(); TI != tmap.end(); ) { + Type* T = (TI++)->second; + remove(T); + RemovedSymbol = true; + } + + return RemovedSymbol; } + // This function is called when one of the types in the type plane are refined void SymbolTable::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - // Search to see if we have any values of the type oldtype. If so, we need to + + // Search to see if we have any values of the type Oldtype. If so, we need to // move them into the newtype plane... - iterator TPI = find(OldType); - if (TPI != end()) { + plane_iterator PI = pmap.find(OldType); + if (PI != pmap.end()) { // Get a handle to the new type plane... - iterator NewTypeIt = find(NewType); - if (NewTypeIt == super::end()) { // If no plane exists, add one - NewTypeIt = super::insert(make_pair(NewType, VarMap())).first; + plane_iterator NewTypeIt = pmap.find(NewType); + if (NewTypeIt == pmap.end()) { // If no plane exists, add one + NewTypeIt = pmap.insert(make_pair(NewType, ValueMap())).first; if (NewType->isAbstract()) { cast(NewType)->addAbstractTypeUser(this); @@ -217,22 +346,22 @@ void SymbolTable::refineAbstractType(const DerivedType *OldType, } } - VarMap &NewPlane = NewTypeIt->second; - VarMap &OldPlane = TPI->second; + ValueMap &NewPlane = NewTypeIt->second; + ValueMap &OldPlane = PI->second; while (!OldPlane.empty()) { std::pair V = *OldPlane.begin(); // Check to see if there is already a value in the symbol table that this // would collide with. - type_iterator TI = NewPlane.find(V.first); - if (TI != NewPlane.end() && TI->second == V.second) { + value_iterator VI = NewPlane.find(V.first); + if (VI != NewPlane.end() && VI->second == V.second) { // No action - } else if (TI != NewPlane.end()) { + } else if (VI != NewPlane.end()) { // The only thing we are allowing for now is two external global values // folded into one. // - GlobalValue *ExistGV = dyn_cast(TI->second); + GlobalValue *ExistGV = dyn_cast(VI->second); GlobalValue *NewGV = dyn_cast(V.second); if (ExistGV && NewGV) { @@ -294,71 +423,74 @@ void SymbolTable::refineAbstractType(const DerivedType *OldType, OldType->removeAbstractTypeUser(this); // Remove the plane that is no longer used - erase(TPI); + pmap.erase(PI); } - TPI = find(Type::TypeTy); - if (TPI != end()) { - // 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. - // - VarMap &TyPlane = TPI->second; - for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I) - if (I->second == (Value*)OldType) { // FIXME when Types aren't const. + // 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 (type_iterator I = type_begin(), E = type_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"; + std::cerr << "Removing type " << OldType->getDescription() << "\n"; #endif - OldType->removeAbstractTypeUser(this); + OldType->removeAbstractTypeUser(this); - I->second = (Value*)NewType; // TODO FIXME when types aren't const - if (NewType->isAbstract()) { + I->second = (Type*)NewType; // TODO FIXME when types aren't const + if (NewType->isAbstract()) { #if DEBUG_ABSTYPE - std::cerr << "Added type " << NewType->getDescription() << "\n"; + std::cerr << "Added type " << NewType->getDescription() << "\n"; #endif - cast(NewType)->addAbstractTypeUser(this); - } + cast(NewType)->addAbstractTypeUser(this); } + } } } + +// Handle situation where type becomes Concreate from Abstract void SymbolTable::typeBecameConcrete(const DerivedType *AbsTy) { - iterator TPI = find(AbsTy); + plane_iterator PI = pmap.find(AbsTy); // If there are any values in the symbol table of this type, then the type - // plan is a use of the abstract type which must be dropped. - if (TPI != end()) + // plane is a use of the abstract type which must be dropped. + if (PI != pmap.end()) AbsTy->removeAbstractTypeUser(this); - TPI = find(Type::TypeTy); - if (TPI != end()) { - // 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. - // - VarMap &TyPlane = TPI->second; - for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I) - if (I->second == (Value*)AbsTy) // FIXME when Types aren't const. - AbsTy->removeAbstractTypeUser(this); - } + // 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 (type_iterator TI = type_begin(), TE = type_end(); TI != TE; ++TI) + if (TI->second == (Type*)AbsTy) // FIXME when Types aren't const. + AbsTy->removeAbstractTypeUser(this); } static void DumpVal(const std::pair &V) { - std::cout << " '" << V.first << "' = "; + std::cerr << " '" << V.first << "' = "; V.second->dump(); - std::cout << "\n"; + std::cerr << "\n"; } static void DumpPlane(const std::pair >&P){ - std::cout << " Plane: "; P.first->dump(); - std::cout << "\n"; + std::cerr << "\n"; for_each(P.second.begin(), P.second.end(), DumpVal); } +static void DumpTypes(const std::pair& T ) { + std::cerr << " '" << T.first << "' = "; + T.second->dump(); + std::cerr << "\n"; +} + void SymbolTable::dump() const { - std::cout << "Symbol table dump:\n"; - for_each(begin(), end(), DumpPlane); + std::cerr << "Symbol table dump:\n Plane:"; + for_each(pmap.begin(), pmap.end(), DumpPlane); + std::cerr << " Types: "; + for_each(tmap.begin(), tmap.end(), DumpTypes); } + +// vim: sw=2 ai