From b47aa543bb7a2e1521eea79978dc83cf0c8125bc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 17 Apr 2007 03:26:42 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/Argument.h | 8 +- llvm/include/llvm/BasicBlock.h | 10 ++- llvm/include/llvm/Function.h | 18 +++- llvm/include/llvm/GlobalVariable.h | 8 +- llvm/include/llvm/Instruction.h | 8 +- llvm/include/llvm/Module.h | 17 +++- llvm/include/llvm/SymbolTableListTraits.h | 27 +++--- llvm/include/llvm/ValueSymbolTable.h | 19 ++--- llvm/lib/VMCore/BasicBlock.cpp | 28 +++++-- llvm/lib/VMCore/Function.cpp | 7 +- llvm/lib/VMCore/Module.cpp | 8 +- llvm/lib/VMCore/SymbolTableListTraitsImpl.h | 92 ++++++++++++--------- llvm/lib/VMCore/Type.cpp | 1 - 13 files changed, 138 insertions(+), 113 deletions(-) diff --git a/llvm/include/llvm/Argument.h b/llvm/include/llvm/Argument.h index ea735b546a44..580b18249bed 100644 --- a/llvm/include/llvm/Argument.h +++ b/llvm/include/llvm/Argument.h @@ -18,9 +18,8 @@ namespace llvm { -template struct ilist_traits; -template class SymbolTableListTraits; +template + class SymbolTableListTraits; /// 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 @@ -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 void setNext(Argument *N) { Next = N; } void setPrev(Argument *N) { Prev = N; } - friend class SymbolTableListTraits >; + friend class SymbolTableListTraits; void setParent(Function *parent); public: diff --git a/llvm/include/llvm/BasicBlock.h b/llvm/include/llvm/BasicBlock.h index d8cb53884540..8cc450c127d1 100644 --- a/llvm/include/llvm/BasicBlock.h +++ b/llvm/include/llvm/BasicBlock.h @@ -25,11 +25,12 @@ template class SuccIterator; // Successor Iterator template class PredIterator; template<> struct ilist_traits - : public SymbolTableListTraits { + : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list... static Instruction *createSentinel(); static void destroySentinel(Instruction *I) { delete I; } static iplist &getList(BasicBlock *BB); + static ValueSymbolTable *getSymTab(BasicBlock *ItemParent); }; /// This represents a single basic block in LLVM. A basic block is simply a @@ -52,11 +53,12 @@ public: private : InstListType InstList; BasicBlock *Prev, *Next; // Next and Prev links for our intrusive linked list + Function *Parent; void setParent(Function *parent); void setNext(BasicBlock *N) { Next = N; } void setPrev(BasicBlock *N) { Prev = N; } - friend class SymbolTableListTraits; + friend class SymbolTableListTraits; BasicBlock(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 /// - const Function *getParent() const { return InstList.getParent(); } - Function *getParent() { return InstList.getParent(); } + const Function *getParent() const { return Parent; } + Function *getParent() { return Parent; } // getNext/Prev - Return the next or previous basic block in the list. BasicBlock *getNext() { return Next; } diff --git a/llvm/include/llvm/Function.h b/llvm/include/llvm/Function.h index 90a8275bec10..d42c8d8aa2b5 100644 --- a/llvm/include/llvm/Function.h +++ b/llvm/include/llvm/Function.h @@ -30,21 +30,23 @@ class ParamAttrsList; // Traits for intrusive list of instructions... template<> struct ilist_traits - : public SymbolTableListTraits { + : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list... static BasicBlock *createSentinel(); static void destroySentinel(BasicBlock *BB) { delete BB; } static iplist &getList(Function *F); + static ValueSymbolTable *getSymTab(Function *ItemParent); }; template<> struct ilist_traits - : public SymbolTableListTraits { + : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list... static Argument *createSentinel(); static void destroySentinel(Argument *A) { delete A; } static iplist &getList(Function *F); + static ValueSymbolTable *getSymTab(Function *ItemParent); }; class Function : public GlobalValue, public Annotable { @@ -67,7 +69,7 @@ private: ParamAttrsList *ParamAttrs; ///< Parameter attributes unsigned CallingConvention; ///< Calling convention to use - friend class SymbolTableListTraits; + friend class SymbolTableListTraits; void setParent(Module *parent); Function *Prev, *Next; @@ -238,6 +240,16 @@ public: void dropAllReferences(); }; +inline ValueSymbolTable * +ilist_traits::getSymTab(Function *F) { + return F ? &F->getValueSymbolTable() : 0; +} + +inline ValueSymbolTable * +ilist_traits::getSymTab(Function *F) { + return F ? &F->getValueSymbolTable() : 0; +} + } // End llvm namespace #endif diff --git a/llvm/include/llvm/GlobalVariable.h b/llvm/include/llvm/GlobalVariable.h index ba869b817b0b..bf638fb21a46 100644 --- a/llvm/include/llvm/GlobalVariable.h +++ b/llvm/include/llvm/GlobalVariable.h @@ -27,13 +27,11 @@ namespace llvm { class Module; class Constant; class PointerType; -template struct ilist_traits; -template class SymbolTableListTraits; +template + class SymbolTableListTraits; class GlobalVariable : public GlobalValue { - friend class SymbolTableListTraits >; + friend class SymbolTableListTraits; void operator=(const GlobalVariable &); // Do not implement GlobalVariable(const GlobalVariable &); // Do not implement diff --git a/llvm/include/llvm/Instruction.h b/llvm/include/llvm/Instruction.h index ed0357f823bf..dbf41f179f65 100644 --- a/llvm/include/llvm/Instruction.h +++ b/llvm/include/llvm/Instruction.h @@ -22,9 +22,8 @@ namespace llvm { struct AssemblyAnnotationWriter; class BinaryOperator; -template struct ilist_traits; -template class SymbolTableListTraits; +template + class SymbolTableListTraits; class Instruction : public User { void operator=(const Instruction &); // Do not implement @@ -36,8 +35,7 @@ class Instruction : public User { void setNext(Instruction *N) { Next = N; } void setPrev(Instruction *N) { Prev = N; } - friend class SymbolTableListTraits >; + friend class SymbolTableListTraits; void setParent(BasicBlock *P); protected: Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, diff --git a/llvm/include/llvm/Module.h b/llvm/include/llvm/Module.h index 3d68e736bfc4..e645f51c1c3a 100644 --- a/llvm/include/llvm/Module.h +++ b/llvm/include/llvm/Module.h @@ -26,18 +26,20 @@ class GlobalValueRefMap; // Used by ConstantVals.cpp class FunctionType; template<> struct ilist_traits - : public SymbolTableListTraits { + : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list. static Function *createSentinel(); static void destroySentinel(Function *F) { delete F; } static iplist &getList(Module *M); + static inline ValueSymbolTable *getSymTab(Module *M); }; template<> struct ilist_traits - : public SymbolTableListTraits { + : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list. static GlobalVariable *createSentinel(); static void destroySentinel(GlobalVariable *GV) { delete GV; } static iplist &getList(Module *M); + static inline ValueSymbolTable *getSymTab(Module *M); }; /// 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; } +inline ValueSymbolTable * +ilist_traits::getSymTab(Module *M) { + return M ? &M->getValueSymbolTable() : 0; +} + +inline ValueSymbolTable * +ilist_traits::getSymTab(Module *M) { + return M ? &M->getValueSymbolTable() : 0; +} + + } // End llvm namespace #endif diff --git a/llvm/include/llvm/SymbolTableListTraits.h b/llvm/include/llvm/SymbolTableListTraits.h index 969c03fc5502..099cfe0ca7fe 100644 --- a/llvm/include/llvm/SymbolTableListTraits.h +++ b/llvm/include/llvm/SymbolTableListTraits.h @@ -31,24 +31,17 @@ template class ilist_iterator; template class iplist; template struct ilist_traits; -// ValueSubClass - The type of objects that I hold -// ItemParentType - I call setParent() on all of my "ValueSubclass" items, and -// this is the value that I pass in. -// SymTabType - This is the class type, whose symtab I insert my -// ValueSubClass items into. Most of the time it is -// ItemParentType, but Instructions have item parents of BB's -// but symtabtype's of a Function +// ValueSubClass - The type of objects that I hold, e.g. Instruction. +// ItemParentType - The type of object that owns the list, e.g. BasicBlock. +// TraitBaseClass - The class this trait should inherit from, it should +// inherit from ilist_traits // -template > +template class SymbolTableListTraits { - SymTabClass *SymTabObject; + typedef ilist_traits TraitsClass; ItemParentClass *ItemParent; public: - SymbolTableListTraits() : SymTabObject(0), ItemParent(0) {} - - SymTabClass *getParent() { return SymTabObject; } - const SymTabClass *getParent() const { return SymTabObject; } + SymbolTableListTraits() : ItemParent(0) {} static ValueSubClass *getPrev(ValueSubClass *V) { return V->getPrev(); } static ValueSubClass *getNext(ValueSubClass *V) { return V->getNext(); } @@ -68,10 +61,10 @@ public: ilist_traits > &L2, ilist_iterator first, ilist_iterator last); - //private: - void setItemParent(ItemParentClass *IP) { ItemParent = IP; }//This is private! - void setParent(SymTabClass *Parent); // This is private! + void setItemParent(ItemParentClass *IP) { ItemParent = IP; } + template + void setSymTabObject(TPtr *, TPtr); }; } // End llvm namespace diff --git a/llvm/include/llvm/ValueSymbolTable.h b/llvm/include/llvm/ValueSymbolTable.h index 2436cbf42e86..679fd8680e41 100644 --- a/llvm/include/llvm/ValueSymbolTable.h +++ b/llvm/include/llvm/ValueSymbolTable.h @@ -18,10 +18,8 @@ #include "llvm/ADT/StringMap.h" namespace llvm { - template + template class SymbolTableListTraits; - template struct ilist_traits; class BasicBlock; class Function; class Module; @@ -32,16 +30,11 @@ namespace llvm { /// class ValueSymbolTable { friend class Value; - friend class SymbolTableListTraits >; - friend class SymbolTableListTraits >; - friend class SymbolTableListTraits >; - friend class SymbolTableListTraits >; - friend class SymbolTableListTraits >; + friend class SymbolTableListTraits; + friend class SymbolTableListTraits; + friend class SymbolTableListTraits; + friend class SymbolTableListTraits; + friend class SymbolTableListTraits; /// @name Types /// @{ public: diff --git a/llvm/lib/VMCore/BasicBlock.cpp b/llvm/lib/VMCore/BasicBlock.cpp index 2e3b426e2b2e..e10948e2ad31 100644 --- a/llvm/lib/VMCore/BasicBlock.cpp +++ b/llvm/lib/VMCore/BasicBlock.cpp @@ -22,6 +22,15 @@ #include using namespace llvm; +inline ValueSymbolTable * +ilist_traits::getSymTab(BasicBlock *BB) { + if (BB) + if (Function *F = BB->getParent()) + return &F->getValueSymbolTable(); + return 0; +} + + namespace { /// DummyInst - An instance of this class is used to mark the end of the /// instruction list. This is not a real instruction. @@ -57,24 +66,24 @@ iplist &ilist_traits::getList(BasicBlock *BB) { // Explicit instantiation of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits; +template class SymbolTableListTraits; -BasicBlock::BasicBlock(const std::string &Name, Function *Parent, +BasicBlock::BasicBlock(const std::string &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::LabelTy, Value::BasicBlockVal) { - // Initialize the instlist... + : Value(Type::LabelTy, Value::BasicBlockVal), Parent(0) { + // Initialize the instlist. InstList.setItemParent(this); // Make sure that we get added to a function LeakDetector::addGarbageObject(this); if (InsertBefore) { - assert(Parent && + assert(NewParent && "Cannot insert block before another block with no function!"); - Parent->getBasicBlockList().insert(InsertBefore, this); - } else if (Parent) { - Parent->getBasicBlockList().push_back(this); + NewParent->getBasicBlockList().insert(InsertBefore, this); + } else if (NewParent) { + NewParent->getBasicBlockList().push_back(this); } setName(Name); @@ -91,7 +100,8 @@ void BasicBlock::setParent(Function *parent) { if (getParent()) LeakDetector::addGarbageObject(this); - InstList.setParent(parent); + // Set Parent=parent, updating instruction symtab entries as appropriate. + InstList.setSymTabObject(&Parent, parent); if (getParent()) LeakDetector::removeGarbageObject(this); diff --git a/llvm/lib/VMCore/Function.cpp b/llvm/lib/VMCore/Function.cpp index edce58d6aaa1..7949e39f84d0 100644 --- a/llvm/lib/VMCore/Function.cpp +++ b/llvm/lib/VMCore/Function.cpp @@ -44,8 +44,8 @@ iplist &ilist_traits::getList(Function *F) { // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits; -template class SymbolTableListTraits; +template class SymbolTableListTraits; +template class SymbolTableListTraits; //===----------------------------------------------------------------------===// // Argument Implementation @@ -144,9 +144,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, ParamAttrs = 0; CallingConvention = 0; BasicBlocks.setItemParent(this); - BasicBlocks.setParent(this); ArgumentList.setItemParent(this); - ArgumentList.setParent(this); SymTab = new ValueSymbolTable(); assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy) @@ -171,7 +169,6 @@ Function::~Function() { // Delete all of the method arguments and unlink from symbol table... ArgumentList.clear(); - ArgumentList.setParent(0); delete SymTab; } diff --git a/llvm/lib/VMCore/Module.cpp b/llvm/lib/VMCore/Module.cpp index 016ab16ff521..465cb6944586 100644 --- a/llvm/lib/VMCore/Module.cpp +++ b/llvm/lib/VMCore/Module.cpp @@ -55,8 +55,8 @@ iplist &ilist_traits::getList(Module *M) { // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file. -template class SymbolTableListTraits; -template class SymbolTableListTraits; +template class SymbolTableListTraits; +template class SymbolTableListTraits; //===----------------------------------------------------------------------===// // Primitive Module methods. @@ -65,9 +65,7 @@ template class SymbolTableListTraits; Module::Module(const std::string &MID) : ModuleID(MID), DataLayout("") { FunctionList.setItemParent(this); - FunctionList.setParent(this); GlobalList.setItemParent(this); - GlobalList.setParent(this); ValSymTab = new ValueSymbolTable(); TypeSymTab = new TypeSymbolTable(); } @@ -75,9 +73,7 @@ Module::Module(const std::string &MID) Module::~Module() { dropAllReferences(); GlobalList.clear(); - GlobalList.setParent(0); FunctionList.clear(); - FunctionList.setParent(0); LibraryList.clear(); delete ValSymTab; delete TypeSymTab; diff --git a/llvm/lib/VMCore/SymbolTableListTraitsImpl.h b/llvm/lib/VMCore/SymbolTableListTraitsImpl.h index 9c3d2525cf33..ce2c0c0cc79e 100644 --- a/llvm/lib/VMCore/SymbolTableListTraitsImpl.h +++ b/llvm/lib/VMCore/SymbolTableListTraitsImpl.h @@ -21,53 +21,68 @@ namespace llvm { -template -void SymbolTableListTraits -::setParent(SymTabClass *STO) { - iplist &List = SubClass::getList(ItemParent); +/// setSymTabObject - This is called when (f.e.) the parent of a basic block +/// changes. This requires us to remove all the instruction symtab entries from +/// the current function and reinsert them into the new function. +template +template +void SymbolTableListTraits +::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.. - if (SymTabObject && !List.empty()) { - ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable(); - for (typename iplist::iterator I = List.begin(); - I != List.end(); ++I) - if (I->hasName()) SymTab.removeValueName(I->getValueName()); + // Do it. + *Dest = Src; + + // Get the new SymTab object. + ValueSymbolTable *NewST = TraitsClass::getSymTab(ItemParent); + + // 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 &ItemList = TraitsClass::getList(ItemParent); + if (ItemList.empty()) return; + + if (OldST) { + // Remove all entries from the previous symtab. + for (typename iplist::iterator I = ItemList.begin(); + I != ItemList.end(); ++I) + if (I->hasName()) + OldST->removeValueName(I->getValueName()); } - SymTabObject = STO; - - // Add all of the items to the new symtab... - if (SymTabObject && !List.empty()) { - ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable(); - for (typename iplist::iterator I = List.begin(); - I != List.end(); ++I) - if (I->hasName()) SymTab.reinsertValue(I); + if (NewST) { + // Add all of the items to the new symtab. + for (typename iplist::iterator I = ItemList.begin(); + I != ItemList.end(); ++I) + if (I->hasName()) + NewST->reinsertValue(I); } + } -template -void SymbolTableListTraits +template +void SymbolTableListTraits ::addNodeToList(ValueSubClass *V) { assert(V->getParent() == 0 && "Value already in a container!!"); V->setParent(ItemParent); - if (V->hasName() && SymTabObject) - SymTabObject->getValueSymbolTable().reinsertValue(V); + if (V->hasName()) + if (ValueSymbolTable *ST = TraitsClass::getSymTab(ItemParent)) + ST->reinsertValue(V); } -template -void SymbolTableListTraits +template +void SymbolTableListTraits ::removeNodeFromList(ValueSubClass *V) { V->setParent(0); - if (V->hasName() && SymTabObject) - SymTabObject->getValueSymbolTable().removeValueName(V->getValueName()); + if (V->hasName()) + if (ValueSymbolTable *ST = TraitsClass::getSymTab(ItemParent)) + ST->removeValueName(V->getValueName()); } -template -void SymbolTableListTraits +template +void SymbolTableListTraits ::transferNodesFromList(iplist > &L2, ilist_iterator first, ilist_iterator last) { @@ -77,16 +92,17 @@ void SymbolTableListTraits // We only have to update symbol table entries if we are transferring the // instructions to a different symtab object... - SymTabClass *NewSTO = SymTabObject, *OldSTO = L2.SymTabObject; - if (NewSTO != OldSTO) { + ValueSymbolTable *NewST = TraitsClass::getSymTab(ItemParent); + ValueSymbolTable *OldST = TraitsClass::getSymTab(OldIP); + if (NewST != OldST) { for (; first != last; ++first) { ValueSubClass &V = *first; bool HasName = V.hasName(); - if (OldSTO && HasName) - OldSTO->getValueSymbolTable().removeValueName(V.getValueName()); + if (OldST && HasName) + OldST->removeValueName(V.getValueName()); V.setParent(NewIP); - if (NewSTO && HasName) - NewSTO->getValueSymbolTable().reinsertValue(&V); + if (NewST && HasName) + NewST->reinsertValue(&V); } } else { // Just transferring between blocks in the same function, simply update the diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index 10063126e54d..e4c89f182a17 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -433,7 +433,6 @@ FunctionType::FunctionType(const Type *Result, // Calculate whether or not this type is abstract setAbstract(isAbstract); - } StructType::StructType(const std::vector &Types, bool isPacked)