Refactor SymbolTableListTraits to only have a single pointer in it, instead

of two.  This shrinkifies Function by 8 bytes (104->96) and Module by 8
bytes (68->60).  On a testcase of mine, this reduces the memory used to
read a module header from 565680b to 561024, a little over 4K.

llvm-svn: 36188
This commit is contained in:
Chris Lattner 2007-04-17 03:26:42 +00:00
parent 0ed36f4078
commit b47aa543bb
13 changed files with 138 additions and 113 deletions

View File

@ -18,9 +18,8 @@
namespace llvm { namespace llvm {
template<typename SC> struct ilist_traits; template<typename ValueSubClass, typename ItemParentClass>
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, class SymbolTableListTraits;
typename SubClass> class SymbolTableListTraits;
/// A class to represent an incoming formal argument to a Function. An argument /// A class to represent an incoming formal argument to a Function. An argument
/// is a very simple Value. It is essentially a named (optional) type. When used /// is a very simple Value. It is essentially a named (optional) type. When used
@ -33,8 +32,7 @@ class Argument : public Value { // Defined in the Function.cpp file
Argument *Prev, *Next; // Next and Prev links for our intrusive linked list Argument *Prev, *Next; // Next and Prev links for our intrusive linked list
void setNext(Argument *N) { Next = N; } void setNext(Argument *N) { Next = N; }
void setPrev(Argument *N) { Prev = N; } void setPrev(Argument *N) { Prev = N; }
friend class SymbolTableListTraits<Argument, Function, Function, friend class SymbolTableListTraits<Argument, Function>;
ilist_traits<Argument> >;
void setParent(Function *parent); void setParent(Function *parent);
public: public:

View File

@ -25,11 +25,12 @@ template <class Term, class BB> class SuccIterator; // Successor Iterator
template <class Ptr, class USE_iterator> class PredIterator; template <class Ptr, class USE_iterator> class PredIterator;
template<> struct ilist_traits<Instruction> template<> struct ilist_traits<Instruction>
: public SymbolTableListTraits<Instruction, BasicBlock, Function> { : public SymbolTableListTraits<Instruction, BasicBlock> {
// createSentinel is used to create a node that marks the end of the list... // createSentinel is used to create a node that marks the end of the list...
static Instruction *createSentinel(); static Instruction *createSentinel();
static void destroySentinel(Instruction *I) { delete I; } static void destroySentinel(Instruction *I) { delete I; }
static iplist<Instruction> &getList(BasicBlock *BB); static iplist<Instruction> &getList(BasicBlock *BB);
static ValueSymbolTable *getSymTab(BasicBlock *ItemParent);
}; };
/// This represents a single basic block in LLVM. A basic block is simply a /// This represents a single basic block in LLVM. A basic block is simply a
@ -52,11 +53,12 @@ public:
private : private :
InstListType InstList; InstListType InstList;
BasicBlock *Prev, *Next; // Next and Prev links for our intrusive linked list BasicBlock *Prev, *Next; // Next and Prev links for our intrusive linked list
Function *Parent;
void setParent(Function *parent); void setParent(Function *parent);
void setNext(BasicBlock *N) { Next = N; } void setNext(BasicBlock *N) { Next = N; }
void setPrev(BasicBlock *N) { Prev = N; } void setPrev(BasicBlock *N) { Prev = N; }
friend class SymbolTableListTraits<BasicBlock, Function, Function>; friend class SymbolTableListTraits<BasicBlock, Function>;
BasicBlock(const BasicBlock &); // Do not implement BasicBlock(const BasicBlock &); // Do not implement
void operator=(const BasicBlock &); // Do not implement void operator=(const BasicBlock &); // Do not implement
@ -76,8 +78,8 @@ public:
/// getParent - Return the enclosing method, or null if none /// getParent - Return the enclosing method, or null if none
/// ///
const Function *getParent() const { return InstList.getParent(); } const Function *getParent() const { return Parent; }
Function *getParent() { return InstList.getParent(); } Function *getParent() { return Parent; }
// getNext/Prev - Return the next or previous basic block in the list. // getNext/Prev - Return the next or previous basic block in the list.
BasicBlock *getNext() { return Next; } BasicBlock *getNext() { return Next; }

View File

@ -30,21 +30,23 @@ class ParamAttrsList;
// Traits for intrusive list of instructions... // Traits for intrusive list of instructions...
template<> struct ilist_traits<BasicBlock> template<> struct ilist_traits<BasicBlock>
: public SymbolTableListTraits<BasicBlock, Function, Function> { : public SymbolTableListTraits<BasicBlock, Function> {
// createSentinel is used to create a node that marks the end of the list... // createSentinel is used to create a node that marks the end of the list...
static BasicBlock *createSentinel(); static BasicBlock *createSentinel();
static void destroySentinel(BasicBlock *BB) { delete BB; } static void destroySentinel(BasicBlock *BB) { delete BB; }
static iplist<BasicBlock> &getList(Function *F); static iplist<BasicBlock> &getList(Function *F);
static ValueSymbolTable *getSymTab(Function *ItemParent);
}; };
template<> struct ilist_traits<Argument> template<> struct ilist_traits<Argument>
: public SymbolTableListTraits<Argument, Function, Function> { : public SymbolTableListTraits<Argument, Function> {
// createSentinel is used to create a node that marks the end of the list... // createSentinel is used to create a node that marks the end of the list...
static Argument *createSentinel(); static Argument *createSentinel();
static void destroySentinel(Argument *A) { delete A; } static void destroySentinel(Argument *A) { delete A; }
static iplist<Argument> &getList(Function *F); static iplist<Argument> &getList(Function *F);
static ValueSymbolTable *getSymTab(Function *ItemParent);
}; };
class Function : public GlobalValue, public Annotable { class Function : public GlobalValue, public Annotable {
@ -67,7 +69,7 @@ private:
ParamAttrsList *ParamAttrs; ///< Parameter attributes ParamAttrsList *ParamAttrs; ///< Parameter attributes
unsigned CallingConvention; ///< Calling convention to use unsigned CallingConvention; ///< Calling convention to use
friend class SymbolTableListTraits<Function, Module, Module>; friend class SymbolTableListTraits<Function, Module>;
void setParent(Module *parent); void setParent(Module *parent);
Function *Prev, *Next; Function *Prev, *Next;
@ -238,6 +240,16 @@ public:
void dropAllReferences(); void dropAllReferences();
}; };
inline ValueSymbolTable *
ilist_traits<BasicBlock>::getSymTab(Function *F) {
return F ? &F->getValueSymbolTable() : 0;
}
inline ValueSymbolTable *
ilist_traits<Argument>::getSymTab(Function *F) {
return F ? &F->getValueSymbolTable() : 0;
}
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -27,13 +27,11 @@ namespace llvm {
class Module; class Module;
class Constant; class Constant;
class PointerType; class PointerType;
template<typename SC> struct ilist_traits; template<typename ValueSubClass, typename ItemParentClass>
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, class SymbolTableListTraits;
typename SubClass> class SymbolTableListTraits;
class GlobalVariable : public GlobalValue { class GlobalVariable : public GlobalValue {
friend class SymbolTableListTraits<GlobalVariable, Module, Module, friend class SymbolTableListTraits<GlobalVariable, Module>;
ilist_traits<GlobalVariable> >;
void operator=(const GlobalVariable &); // Do not implement void operator=(const GlobalVariable &); // Do not implement
GlobalVariable(const GlobalVariable &); // Do not implement GlobalVariable(const GlobalVariable &); // Do not implement

View File

@ -22,9 +22,8 @@ namespace llvm {
struct AssemblyAnnotationWriter; struct AssemblyAnnotationWriter;
class BinaryOperator; class BinaryOperator;
template<typename SC> struct ilist_traits; template<typename ValueSubClass, typename ItemParentClass>
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, class SymbolTableListTraits;
typename SubClass> class SymbolTableListTraits;
class Instruction : public User { class Instruction : public User {
void operator=(const Instruction &); // Do not implement void operator=(const Instruction &); // Do not implement
@ -36,8 +35,7 @@ class Instruction : public User {
void setNext(Instruction *N) { Next = N; } void setNext(Instruction *N) { Next = N; }
void setPrev(Instruction *N) { Prev = N; } void setPrev(Instruction *N) { Prev = N; }
friend class SymbolTableListTraits<Instruction, BasicBlock, Function, friend class SymbolTableListTraits<Instruction, BasicBlock>;
ilist_traits<Instruction> >;
void setParent(BasicBlock *P); void setParent(BasicBlock *P);
protected: protected:
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,

View File

@ -26,18 +26,20 @@ class GlobalValueRefMap; // Used by ConstantVals.cpp
class FunctionType; class FunctionType;
template<> struct ilist_traits<Function> template<> struct ilist_traits<Function>
: public SymbolTableListTraits<Function, Module, Module> { : public SymbolTableListTraits<Function, Module> {
// createSentinel is used to create a node that marks the end of the list. // createSentinel is used to create a node that marks the end of the list.
static Function *createSentinel(); static Function *createSentinel();
static void destroySentinel(Function *F) { delete F; } static void destroySentinel(Function *F) { delete F; }
static iplist<Function> &getList(Module *M); static iplist<Function> &getList(Module *M);
static inline ValueSymbolTable *getSymTab(Module *M);
}; };
template<> struct ilist_traits<GlobalVariable> template<> struct ilist_traits<GlobalVariable>
: public SymbolTableListTraits<GlobalVariable, Module, Module> { : public SymbolTableListTraits<GlobalVariable, Module> {
// createSentinel is used to create a node that marks the end of the list. // createSentinel is used to create a node that marks the end of the list.
static GlobalVariable *createSentinel(); static GlobalVariable *createSentinel();
static void destroySentinel(GlobalVariable *GV) { delete GV; } static void destroySentinel(GlobalVariable *GV) { delete GV; }
static iplist<GlobalVariable> &getList(Module *M); static iplist<GlobalVariable> &getList(Module *M);
static inline ValueSymbolTable *getSymTab(Module *M);
}; };
/// A Module instance is used to store all the information related to an /// A Module instance is used to store all the information related to an
@ -319,6 +321,17 @@ inline std::ostream &operator<<(std::ostream &O, const Module &M) {
return O; return O;
} }
inline ValueSymbolTable *
ilist_traits<Function>::getSymTab(Module *M) {
return M ? &M->getValueSymbolTable() : 0;
}
inline ValueSymbolTable *
ilist_traits<GlobalVariable>::getSymTab(Module *M) {
return M ? &M->getValueSymbolTable() : 0;
}
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -31,24 +31,17 @@ template<typename NodeTy> class ilist_iterator;
template<typename NodeTy, typename Traits> class iplist; template<typename NodeTy, typename Traits> class iplist;
template<typename Ty> struct ilist_traits; template<typename Ty> struct ilist_traits;
// ValueSubClass - The type of objects that I hold // ValueSubClass - The type of objects that I hold, e.g. Instruction.
// ItemParentType - I call setParent() on all of my "ValueSubclass" items, and // ItemParentType - The type of object that owns the list, e.g. BasicBlock.
// this is the value that I pass in. // TraitBaseClass - The class this trait should inherit from, it should
// SymTabType - This is the class type, whose symtab I insert my // inherit from ilist_traits<ValueSubClass>
// ValueSubClass items into. Most of the time it is
// ItemParentType, but Instructions have item parents of BB's
// but symtabtype's of a Function
// //
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, template<typename ValueSubClass, typename ItemParentClass>
typename SubClass=ilist_traits<ValueSubClass> >
class SymbolTableListTraits { class SymbolTableListTraits {
SymTabClass *SymTabObject; typedef ilist_traits<ValueSubClass> TraitsClass;
ItemParentClass *ItemParent; ItemParentClass *ItemParent;
public: public:
SymbolTableListTraits() : SymTabObject(0), ItemParent(0) {} SymbolTableListTraits() : ItemParent(0) {}
SymTabClass *getParent() { return SymTabObject; }
const SymTabClass *getParent() const { return SymTabObject; }
static ValueSubClass *getPrev(ValueSubClass *V) { return V->getPrev(); } static ValueSubClass *getPrev(ValueSubClass *V) { return V->getPrev(); }
static ValueSubClass *getNext(ValueSubClass *V) { return V->getNext(); } static ValueSubClass *getNext(ValueSubClass *V) { return V->getNext(); }
@ -68,10 +61,10 @@ public:
ilist_traits<ValueSubClass> > &L2, ilist_traits<ValueSubClass> > &L2,
ilist_iterator<ValueSubClass> first, ilist_iterator<ValueSubClass> first,
ilist_iterator<ValueSubClass> last); ilist_iterator<ValueSubClass> last);
//private: //private:
void setItemParent(ItemParentClass *IP) { ItemParent = IP; }//This is private! void setItemParent(ItemParentClass *IP) { ItemParent = IP; }
void setParent(SymTabClass *Parent); // This is private! template<typename TPtr>
void setSymTabObject(TPtr *, TPtr);
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -18,10 +18,8 @@
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
namespace llvm { namespace llvm {
template<typename ValueSubClass, typename ItemParentClass, template<typename ValueSubClass, typename ItemParentClass>
typename SymTabClass, typename SubClass>
class SymbolTableListTraits; class SymbolTableListTraits;
template<typename NodeTy> struct ilist_traits;
class BasicBlock; class BasicBlock;
class Function; class Function;
class Module; class Module;
@ -32,16 +30,11 @@ namespace llvm {
/// ///
class ValueSymbolTable { class ValueSymbolTable {
friend class Value; friend class Value;
friend class SymbolTableListTraits<Argument, Function, Function, friend class SymbolTableListTraits<Argument, Function>;
ilist_traits<Argument> >; friend class SymbolTableListTraits<BasicBlock, Function>;
friend class SymbolTableListTraits<BasicBlock, Function, Function, friend class SymbolTableListTraits<Instruction, BasicBlock>;
ilist_traits<BasicBlock> >; friend class SymbolTableListTraits<Function, Module>;
friend class SymbolTableListTraits<Instruction, BasicBlock, Function, friend class SymbolTableListTraits<GlobalVariable, Module>;
ilist_traits<Instruction> >;
friend class SymbolTableListTraits<Function, Module, Module,
ilist_traits<Function> >;
friend class SymbolTableListTraits<GlobalVariable, Module, Module,
ilist_traits<GlobalVariable> >;
/// @name Types /// @name Types
/// @{ /// @{
public: public:

View File

@ -22,6 +22,15 @@
#include <algorithm> #include <algorithm>
using namespace llvm; using namespace llvm;
inline ValueSymbolTable *
ilist_traits<Instruction>::getSymTab(BasicBlock *BB) {
if (BB)
if (Function *F = BB->getParent())
return &F->getValueSymbolTable();
return 0;
}
namespace { namespace {
/// DummyInst - An instance of this class is used to mark the end of the /// DummyInst - An instance of this class is used to mark the end of the
/// instruction list. This is not a real instruction. /// instruction list. This is not a real instruction.
@ -57,24 +66,24 @@ iplist<Instruction> &ilist_traits<Instruction>::getList(BasicBlock *BB) {
// Explicit instantiation of SymbolTableListTraits since some of the methods // Explicit instantiation of SymbolTableListTraits since some of the methods
// are not in the public header file... // are not in the public header file...
template class SymbolTableListTraits<Instruction, BasicBlock, Function>; template class SymbolTableListTraits<Instruction, BasicBlock>;
BasicBlock::BasicBlock(const std::string &Name, Function *Parent, BasicBlock::BasicBlock(const std::string &Name, Function *NewParent,
BasicBlock *InsertBefore) BasicBlock *InsertBefore)
: Value(Type::LabelTy, Value::BasicBlockVal) { : Value(Type::LabelTy, Value::BasicBlockVal), Parent(0) {
// Initialize the instlist... // Initialize the instlist.
InstList.setItemParent(this); InstList.setItemParent(this);
// Make sure that we get added to a function // Make sure that we get added to a function
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
if (InsertBefore) { if (InsertBefore) {
assert(Parent && assert(NewParent &&
"Cannot insert block before another block with no function!"); "Cannot insert block before another block with no function!");
Parent->getBasicBlockList().insert(InsertBefore, this); NewParent->getBasicBlockList().insert(InsertBefore, this);
} else if (Parent) { } else if (NewParent) {
Parent->getBasicBlockList().push_back(this); NewParent->getBasicBlockList().push_back(this);
} }
setName(Name); setName(Name);
@ -91,7 +100,8 @@ void BasicBlock::setParent(Function *parent) {
if (getParent()) if (getParent())
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
InstList.setParent(parent); // Set Parent=parent, updating instruction symtab entries as appropriate.
InstList.setSymTabObject(&Parent, parent);
if (getParent()) if (getParent())
LeakDetector::removeGarbageObject(this); LeakDetector::removeGarbageObject(this);

View File

@ -44,8 +44,8 @@ iplist<Argument> &ilist_traits<Argument>::getList(Function *F) {
// Explicit instantiations of SymbolTableListTraits since some of the methods // Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file... // are not in the public header file...
template class SymbolTableListTraits<Argument, Function, Function>; template class SymbolTableListTraits<Argument, Function>;
template class SymbolTableListTraits<BasicBlock, Function, Function>; template class SymbolTableListTraits<BasicBlock, Function>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Argument Implementation // Argument Implementation
@ -144,9 +144,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
ParamAttrs = 0; ParamAttrs = 0;
CallingConvention = 0; CallingConvention = 0;
BasicBlocks.setItemParent(this); BasicBlocks.setItemParent(this);
BasicBlocks.setParent(this);
ArgumentList.setItemParent(this); ArgumentList.setItemParent(this);
ArgumentList.setParent(this);
SymTab = new ValueSymbolTable(); SymTab = new ValueSymbolTable();
assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy) assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy)
@ -171,7 +169,6 @@ Function::~Function() {
// Delete all of the method arguments and unlink from symbol table... // Delete all of the method arguments and unlink from symbol table...
ArgumentList.clear(); ArgumentList.clear();
ArgumentList.setParent(0);
delete SymTab; delete SymTab;
} }

View File

@ -55,8 +55,8 @@ iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
// Explicit instantiations of SymbolTableListTraits since some of the methods // Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file. // are not in the public header file.
template class SymbolTableListTraits<GlobalVariable, Module, Module>; template class SymbolTableListTraits<GlobalVariable, Module>;
template class SymbolTableListTraits<Function, Module, Module>; template class SymbolTableListTraits<Function, Module>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Primitive Module methods. // Primitive Module methods.
@ -65,9 +65,7 @@ template class SymbolTableListTraits<Function, Module, Module>;
Module::Module(const std::string &MID) Module::Module(const std::string &MID)
: ModuleID(MID), DataLayout("") { : ModuleID(MID), DataLayout("") {
FunctionList.setItemParent(this); FunctionList.setItemParent(this);
FunctionList.setParent(this);
GlobalList.setItemParent(this); GlobalList.setItemParent(this);
GlobalList.setParent(this);
ValSymTab = new ValueSymbolTable(); ValSymTab = new ValueSymbolTable();
TypeSymTab = new TypeSymbolTable(); TypeSymTab = new TypeSymbolTable();
} }
@ -75,9 +73,7 @@ Module::Module(const std::string &MID)
Module::~Module() { Module::~Module() {
dropAllReferences(); dropAllReferences();
GlobalList.clear(); GlobalList.clear();
GlobalList.setParent(0);
FunctionList.clear(); FunctionList.clear();
FunctionList.setParent(0);
LibraryList.clear(); LibraryList.clear();
delete ValSymTab; delete ValSymTab;
delete TypeSymTab; delete TypeSymTab;

View File

@ -21,53 +21,68 @@
namespace llvm { namespace llvm {
template<typename ValueSubClass, typename ItemParentClass,typename SymTabClass, /// setSymTabObject - This is called when (f.e.) the parent of a basic block
typename SubClass> /// changes. This requires us to remove all the instruction symtab entries from
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass> /// the current function and reinsert them into the new function.
::setParent(SymTabClass *STO) { template<typename ValueSubClass, typename ItemParentClass>
iplist<ValueSubClass> &List = SubClass::getList(ItemParent); template<typename TPtr>
void SymbolTableListTraits<ValueSubClass,ItemParentClass>
::setSymTabObject(TPtr *Dest, TPtr Src) {
// Get the old symtab and value list before doing the assignment.
ValueSymbolTable *OldST = TraitsClass::getSymTab(ItemParent);
// Remove all of the items from the old symtab.. // Do it.
if (SymTabObject && !List.empty()) { *Dest = Src;
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable();
for (typename iplist<ValueSubClass>::iterator I = List.begin(); // Get the new SymTab object.
I != List.end(); ++I) ValueSymbolTable *NewST = TraitsClass::getSymTab(ItemParent);
if (I->hasName()) SymTab.removeValueName(I->getValueName());
// If there is nothing to do, quick exit.
if (OldST == NewST) return;
// Move all the elements from the old symtab to the new one.
iplist<ValueSubClass> &ItemList = TraitsClass::getList(ItemParent);
if (ItemList.empty()) return;
if (OldST) {
// Remove all entries from the previous symtab.
for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
I != ItemList.end(); ++I)
if (I->hasName())
OldST->removeValueName(I->getValueName());
} }
SymTabObject = STO; if (NewST) {
// Add all of the items to the new symtab.
// Add all of the items to the new symtab... for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
if (SymTabObject && !List.empty()) { I != ItemList.end(); ++I)
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable(); if (I->hasName())
for (typename iplist<ValueSubClass>::iterator I = List.begin(); NewST->reinsertValue(I);
I != List.end(); ++I)
if (I->hasName()) SymTab.reinsertValue(I);
} }
} }
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, template<typename ValueSubClass, typename ItemParentClass>
typename SubClass> void SymbolTableListTraits<ValueSubClass,ItemParentClass>
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
::addNodeToList(ValueSubClass *V) { ::addNodeToList(ValueSubClass *V) {
assert(V->getParent() == 0 && "Value already in a container!!"); assert(V->getParent() == 0 && "Value already in a container!!");
V->setParent(ItemParent); V->setParent(ItemParent);
if (V->hasName() && SymTabObject) if (V->hasName())
SymTabObject->getValueSymbolTable().reinsertValue(V); if (ValueSymbolTable *ST = TraitsClass::getSymTab(ItemParent))
ST->reinsertValue(V);
} }
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, template<typename ValueSubClass, typename ItemParentClass>
typename SubClass> void SymbolTableListTraits<ValueSubClass,ItemParentClass>
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
::removeNodeFromList(ValueSubClass *V) { ::removeNodeFromList(ValueSubClass *V) {
V->setParent(0); V->setParent(0);
if (V->hasName() && SymTabObject) if (V->hasName())
SymTabObject->getValueSymbolTable().removeValueName(V->getValueName()); if (ValueSymbolTable *ST = TraitsClass::getSymTab(ItemParent))
ST->removeValueName(V->getValueName());
} }
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass, template<typename ValueSubClass, typename ItemParentClass>
typename SubClass> void SymbolTableListTraits<ValueSubClass,ItemParentClass>
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
::transferNodesFromList(iplist<ValueSubClass, ilist_traits<ValueSubClass> > &L2, ::transferNodesFromList(iplist<ValueSubClass, ilist_traits<ValueSubClass> > &L2,
ilist_iterator<ValueSubClass> first, ilist_iterator<ValueSubClass> first,
ilist_iterator<ValueSubClass> last) { ilist_iterator<ValueSubClass> last) {
@ -77,16 +92,17 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
// We only have to update symbol table entries if we are transferring the // We only have to update symbol table entries if we are transferring the
// instructions to a different symtab object... // instructions to a different symtab object...
SymTabClass *NewSTO = SymTabObject, *OldSTO = L2.SymTabObject; ValueSymbolTable *NewST = TraitsClass::getSymTab(ItemParent);
if (NewSTO != OldSTO) { ValueSymbolTable *OldST = TraitsClass::getSymTab(OldIP);
if (NewST != OldST) {
for (; first != last; ++first) { for (; first != last; ++first) {
ValueSubClass &V = *first; ValueSubClass &V = *first;
bool HasName = V.hasName(); bool HasName = V.hasName();
if (OldSTO && HasName) if (OldST && HasName)
OldSTO->getValueSymbolTable().removeValueName(V.getValueName()); OldST->removeValueName(V.getValueName());
V.setParent(NewIP); V.setParent(NewIP);
if (NewSTO && HasName) if (NewST && HasName)
NewSTO->getValueSymbolTable().reinsertValue(&V); NewST->reinsertValue(&V);
} }
} else { } else {
// Just transferring between blocks in the same function, simply update the // Just transferring between blocks in the same function, simply update the

View File

@ -433,7 +433,6 @@ FunctionType::FunctionType(const Type *Result,
// Calculate whether or not this type is abstract // Calculate whether or not this type is abstract
setAbstract(isAbstract); setAbstract(isAbstract);
} }
StructType::StructType(const std::vector<const Type*> &Types, bool isPacked) StructType::StructType(const std::vector<const Type*> &Types, bool isPacked)