//===-- SymbolTable.cpp - Implement the SymbolTable 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
+// Spencer. It is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the SymbolTable class for the VMCore library.
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "Support/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <iostream>
cast<DerivedType>(TI->second)->removeAbstractTypeUser(this);
}
- // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the
+ // 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...
for (plane_iterator PI = pmap.begin(); PI != pmap.end(); ++PI) {
for (value_iterator VI = PI->second.begin(); VI != PI->second.end(); ++VI)
if (!isa<Constant>(VI->second) ) {
- std::cerr << "Value still in symbol table! Type = '"
+ std::cerr << "Value still in symbol table! Type = '"
<< PI->first->getDescription() << "' Name = '"
<< VI->first << "'\n";
- LeftoverValues = false;
+ LeftoverValues = false;
}
}
-
+
assert(LeftoverValues && "Values remain in symbol table!");
#endif
}
// lookup a value - Returns null on failure...
Value *SymbolTable::lookup(const Type *Ty, const std::string &Name) const {
plane_const_iterator PI = pmap.find(Ty);
- if (PI != pmap.end()) { // We have symbols in that plane...
+ 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...
+ 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() )
+Type* SymbolTable::lookupType(const std::string& Name) const {
+ type_const_iterator TI = tmap.find(Name);
+ if (TI != tmap.end())
return const_cast<Type*>(TI->second);
return 0;
}
+/// changeName - 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).
+void SymbolTable::changeName(Value *V, const std::string &name) {
+ assert(!V->getName().empty() && !name.empty() && V->getName() != name &&
+ "Illegal use of this method!");
+
+ plane_iterator PI = pmap.find(V->getType());
+ assert(PI != pmap.end() && "Value doesn't have an entry in this table?");
+ ValueMap &VM = PI->second;
+
+ value_iterator VI = VM.find(V->getName());
+ assert(VI != VM.end() && "Value does have an entry in this table?");
+
+ // Remove the old entry.
+ VM.erase(VI);
+
+ // See if we can insert the new name.
+ VI = VM.lower_bound(name);
+
+ // Is there a naming conflict?
+ if (VI != VM.end() && VI->first == name) {
+ V->Name = getUniqueName(V->getType(), name);
+ VM.insert(make_pair(V->Name, V));
+ } else {
+ V->Name = name;
+ VM.insert(VI, make_pair(name, V));
+ }
+}
+
// Remove a value
void SymbolTable::remove(Value *N) {
assert(N->hasName() && "Value doesn't have name!");
- if (InternallyInconsistent) return;
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(plane_iterator Plane, value_iterator Entry) {
- if (InternallyInconsistent) return 0;
- assert(Plane != pmap.end() &&
- Entry != Plane->second.end() && "Invalid entry to remove!");
+ ValueMap &VM = PI->second;
+ value_iterator Entry = VM.find(N->getName());
+ assert(Entry != VM.end() && "Invalid entry to remove!");
- Value *Result = Entry->second;
#if DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Removing Value: " << Result->getName() << "\n";
+ std::cerr << " Removing Value: " << Entry->second->getName() << "\n";
#endif
// Remove the value from the plane...
- Plane->second.erase(Entry);
+ VM.erase(Entry);
// If the plane is empty, remove it now!
- if (Plane->second.empty()) {
+ if (VM.empty()) {
// If the plane represented an abstract type that we were interested in,
// unlink ourselves from this plane.
//
- if (Plane->first->isAbstract()) {
+ if (N->getType()->isAbstract()) {
#if DEBUG_ABSTYPE
std::cerr << "Plane Empty: Removing type: "
- << Plane->first->getDescription() << "\n";
+ << N->getType()->getDescription() << "\n";
#endif
- cast<DerivedType>(Plane->first)->removeAbstractTypeUser(this);
+ cast<DerivedType>(N->getType())->removeAbstractTypeUser(this);
}
- pmap.erase(Plane);
+ pmap.erase(PI);
}
- return Result;
-}
-
-
-// remove - Remove a type
-void SymbolTable::remove(const 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!");
+// remove - Remove a type from the symbol table...
+Type* SymbolTable::remove(type_iterator Entry) {
+ assert(Entry != tmap.end() && "Invalid entry to remove!");
const Type* Result = Entry->second;
// 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 value!");
- InternallyInconsistent = true;
- V->setName(UniqueName, this);
- InternallyInconsistent = false;
- return;
- }
+ plane_iterator PI = pmap.find(VTy); // Plane iterator
+ value_iterator VI; // Actual value iterator
+ ValueMap *VM; // The plane we care about.
#if DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Inserting definition: " << Name << ": "
+ std::cerr << " Inserting definition: " << Name << ": "
<< VTy->getDescription() << "\n";
#endif
- 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.
- PI = pmap.insert(make_pair(VTy, ValueMap())).first;
- assert(PI != pmap.end() && "How did insert fail?");
+ VM = &pmap.insert(make_pair(VTy, ValueMap())).first->second;
+ VI = VM->end();
// 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
<< "\n";
#endif
}
+
+ } else {
+ // Check to see if there is a naming conflict. If so, rename this value!
+ VM = &PI->second;
+ VI = VM->lower_bound(Name);
+ if (VI != VM->end() && VI->first == Name) {
+ V->Name = getUniqueName(VTy, Name);
+ VM->insert(make_pair(V->Name, V));
+ return;
+ }
}
- PI->second.insert(make_pair(Name, V));
+ VM->insert(VI, make_pair(Name, V));
}
// insertEntry - Insert a value into the symbol table with the specified
// name...
//
-void SymbolTable::insertEntry(const std::string& Name, const Type* T) {
+void SymbolTable::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 DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Inserting type: " << UniqueName << ": "
+ std::cerr << " Inserting type: " << UniqueName << ": "
<< 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 SymbolTable::strip() {
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.
value_iterator B = Plane.begin(), Bend = Plane.end();
while (B != Bend) { // Found nonempty type plane!
Value *V = B->second;
- if (isa<Constant>(V)) {
- remove(V);
+ ++B;
+ if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
+ // Set name to "", removing from symbol table!
+ V->setName("");
RemovedSymbol = true;
- } else {
- if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()){
- // Set name to "", removing from symbol table!
- V->setName("", this);
- RemovedSymbol = true;
- }
}
- ++B;
}
}
for (type_iterator TI = tmap.begin(); TI != tmap.end(); ) {
- const Type* T = (TI++)->second;
- remove(T);
+ remove(TI++);
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) {
+ const Type *NewType) {
// Search to see if we have any values of the type Oldtype. If so, we need to
// move them into the newtype plane...
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<DerivedType>(NewType)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
// Ok we have two external global values. Make all uses of the new
// one use the old one...
NewGV->uncheckedReplaceAllUsesWith(ExistGV);
-
- // Now we just convert it to an unnamed method... which won't get
- // added to our symbol table. The problem is that if we call
- // setName on the method that it will try to remove itself from
- // the symbol table and die... because it's not in the symtab
- // right now. To fix this, we have an internally consistent flag
- // that turns remove into a noop. Thus the name will get null'd
- // out, but the symbol table won't get upset.
- //
- assert(InternallyInconsistent == false &&
- "Symbol table already inconsistent!");
- InternallyInconsistent = true;
-
- // Remove newM from the symtab
- NewGV->setName("");
- InternallyInconsistent = false;
+
+ // Update NewGV's name, we're about the remove it from the symbol
+ // table.
+ NewGV->Name = "";
// Now we can remove this global from the module entirely...
Module *M = NewGV->getParent();
}
} else {
insertEntry(V.first, NewType, V.second);
-
}
// Remove the item from the old type plane
OldPlane.erase(OldPlane.begin());
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";
+ std::cerr << "Added type " << NewType->getDescription() << "\n";
#endif
- cast<DerivedType>(NewType)->addAbstractTypeUser(this);
+ cast<DerivedType>(NewType)->addAbstractTypeUser(this);
}
}
}