From: Gordon Henriksen Date: Sun, 9 Dec 2007 22:46:10 +0000 (+0000) Subject: Devirtualizing Value destructor (PR889). Patch by Pawel Kunio! X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=ed455c8fa25dd37a13b33f0afa66be03ac49b5bb Devirtualizing Value destructor (PR889). Patch by Pawel Kunio! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44747 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index c995043616c..bb71e115fd0 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -35,6 +35,11 @@ class Argument : public Value { // Defined in the Function.cpp file friend class SymbolTableListTraits; void setParent(Function *parent); +protected: + static void destroyThis(Argument*v) { + Value::destroyThis(v); + } + friend class Value; public: /// Argument ctor - If Function argument is specified, this argument is /// inserted at the end of the argument list for the function. diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index cd38b4280c8..d5a1fe1c33c 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -65,6 +65,9 @@ private : BasicBlock(const BasicBlock &); // Do not implement void operator=(const BasicBlock &); // Do not implement +protected: + static void destroyThis(BasicBlock*); + friend class Value; public: /// Instruction iterators... typedef InstListType::iterator iterator; @@ -76,7 +79,6 @@ public: /// explicit BasicBlock(const std::string &Name = "", Function *Parent = 0, BasicBlock *InsertBefore = 0); - ~BasicBlock(); /// getParent - Return the enclosing method, or null if none /// @@ -206,6 +208,33 @@ private: const BasicBlock *getPrev() const { return Prev; } }; +/// DummyInst - An instance of this class is used to mark the end of the +/// instruction list. This is not a real instruction. +class DummyInst : public Instruction { +protected: + static void destroyThis(DummyInst* v) { + Instruction::destroyThis(v); + } + friend class Value; +public: + DummyInst(); + + Instruction *clone() const { + assert(0 && "Cannot clone EOL");abort(); + return 0; + } + const char *getOpcodeName() const { return "*end-of-list-inst*"; } + + // Methods for support type inquiry through isa, cast, and dyn_cast... + static inline bool classof(const DummyInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == OtherOpsEnd; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + inline int ilist_traits::getListOffset() { return BasicBlock::getInstListOffset(); diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index d925fdb618e..e48a9c5d740 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -43,6 +43,10 @@ protected: : User(Ty, vty, Ops, NumOps) {} void destroyConstantImpl(); + static void destroyThis(Constant*v) { + User::destroyThis(v); + } + friend class Value; public: /// Static constructor to get a '0' constant of arbitrary type... /// diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index a2595904672..2c7f577e349 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -46,6 +46,11 @@ class ConstantInt : public Constant { ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT ConstantInt(const IntegerType *Ty, const APInt& V); APInt Val; +protected: + static void destroyThis(ConstantInt*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// Return the constant as an APInt value reference. This allows clients to /// obtain a copy of the value, with all its precision in tact. @@ -218,6 +223,10 @@ class ConstantFP : public Constant { ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT protected: ConstantFP(const Type *Ty, const APFloat& V); + static void destroyThis(ConstantFP*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static ConstantFP *get(const Type *Ty, const APFloat& V); @@ -266,6 +275,11 @@ class ConstantAggregateZero : public Constant { protected: explicit ConstantAggregateZero(const Type *Ty) : Constant(Ty, ConstantAggregateZeroVal, 0, 0) {} + + static void destroyThis(ConstantAggregateZero*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - static factory method for creating a null aggregate. It is /// illegal to call this method with a non-aggregate type. @@ -295,7 +309,8 @@ class ConstantArray : public Constant { ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT protected: ConstantArray(const ArrayType *T, const std::vector &Val); - ~ConstantArray(); + static void destroyThis(ConstantArray*); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const ArrayType *T, const std::vector &); @@ -361,7 +376,8 @@ class ConstantStruct : public Constant { ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT protected: ConstantStruct(const StructType *T, const std::vector &Val); - ~ConstantStruct(); + static void destroyThis(ConstantStruct*); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value /// @@ -405,7 +421,8 @@ class ConstantVector : public Constant { ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT protected: ConstantVector(const VectorType *T, const std::vector &Val); - ~ConstantVector(); + static void destroyThis(ConstantVector*v); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const VectorType *T, const std::vector &); @@ -462,7 +479,10 @@ protected: explicit ConstantPointerNull(const PointerType *T) : Constant(reinterpret_cast(T), Value::ConstantPointerNullVal, 0, 0) {} - + static void destroyThis(ConstantPointerNull*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value @@ -524,6 +544,10 @@ protected: static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1, Constant *V2, Constant *Mask); + static void destroyThis(ConstantExpr* v) { + Constant::destroyThis(v); + } + friend class Value; public: // Static methods to construct a ConstantExpr of different kinds. Note that // these methods may return a object that is not an instance of the @@ -709,6 +733,10 @@ class UndefValue : public Constant { UndefValue(const UndefValue &); // DO NOT IMPLEMENT protected: explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {} + static void destroyThis(UndefValue*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return an 'undef' object of the specified /// type. @@ -728,6 +756,120 @@ public: } }; +/// GetElementPtrConstantExpr - Helper class for Constants.cpp, +/// used behind the scenes to implement getelementpr constant exprs. +class GetElementPtrConstantExpr : public ConstantExpr { +protected: + static void destroyThis(GetElementPtrConstantExpr*v) { + delete [] v->OperandList; + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, + const Type *DestTy); +}; + +/// UnaryConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement unary constant exprs. +class UnaryConstantExpr : public ConstantExpr { + Use Op; +protected: + static void destroyThis(UnaryConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty); +}; + +/// BinaryConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement binary constant exprs. +class BinaryConstantExpr : public ConstantExpr { + Use Ops[2]; +protected: + static void destroyThis(BinaryConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + : ConstantExpr(C1->getType(), Opcode, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + +/// SelectConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement select constant exprs. +class SelectConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(SelectConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + +/// ExtractElementConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + Use Ops[2]; +protected: + static void destroyThis(ExtractElementConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + ExtractElementConstantExpr(Constant *C1, Constant *C2); +}; + +/// InsertElementConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(InsertElementConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + +/// ShuffleVectorConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(ShuffleVectorConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + + + +// CompareConstantExpr - Helper class for Constants.cpp, used +// behind the scenes to implement ICmp and FCmp constant expressions. This is +// needed in order to store the predicate value for these instructions. +class CompareConstantExpr : public ConstantExpr { +protected: + static void destroyThis(CompareConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + unsigned short predicate; + Use Ops[2]; + CompareConstantExpr(unsigned opc, unsigned short pred, + Constant* LHS, Constant* RHS); +}; + } // End llvm namespace #endif diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 20a43e285cf..ba91372ec62 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -53,6 +53,9 @@ template<> struct ilist_traits }; class Function : public GlobalValue, public Annotable { +protected: + static void destroyThis(Function*v); + friend class Value; public: typedef iplist ArgumentListType; typedef iplist BasicBlockListType; @@ -109,7 +112,6 @@ public: /// Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &N = "", Module *M = 0); - ~Function(); const Type *getReturnType() const; // Return the type of the ret val const FunctionType *getFunctionType() const; // Return the FunctionType for me diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index bbd19ba8816..8b0dcf53158 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -43,6 +43,11 @@ class GlobalAlias : public GlobalValue { const GlobalAlias *getPrev() const { return Prev; } Use Aliasee; +protected: + static void destroyThis(GlobalAlias*v) { + GlobalValue::destroyThis(v); + } + friend class Value; public: /// GlobalAlias ctor - If a parent module is specified, the alias is /// automatically inserted into the end of the specified module's alias list. diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index fe43ed4f69f..40e3a5ace58 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -63,11 +63,12 @@ protected: unsigned Visibility : 2; // The visibility style of this global unsigned Alignment : 16; // Alignment of this symbol, must be power of two std::string Section; // Section to emit this into, empty mean default -public: - ~GlobalValue() { - removeDeadConstantUsers(); // remove any dead constants using this. - } + static void destroyThis(GlobalValue*v) { + v->removeDeadConstantUsers(); // remove any dead constants using this. + Constant::destroyThis(v); + } +public: unsigned getAlignment() const { return Alignment; } void setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 00d4acb66da..882dec68854 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -45,6 +45,11 @@ class GlobalVariable : public GlobalValue { bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"? Use Initializer; +protected: + static void destroyThis(GlobalVariable*v) { + GlobalValue::destroyThis(v); + } + friend class Value; public: /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index 20c184ac2e7..bf7b4194758 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -36,9 +36,12 @@ class InlineAsm : public Value { InlineAsm(const FunctionType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects); - virtual ~InlineAsm(); +protected: + static void destroyThis(InlineAsm*v) { + Value::destroyThis(v); + } + friend class Value; public: - /// InlineAsm::get - Return the the specified uniqued inline asm string. /// static InlineAsm *get(const FunctionType *Ty, const std::string &AsmString, diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index a6a8fff40ce..c14b3bbc26f 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -38,14 +38,16 @@ protected: Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} - // Out of line virtual method, so the vtable, etc has a home. - ~TerminatorInst(); - /// Virtual methods - Terminators should overload these and provide inline /// overrides of non-V methods. virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; + + static void destroyThis(TerminatorInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: virtual Instruction *clone() const = 0; @@ -94,10 +96,12 @@ protected: UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) { } -public: - // Out of line virtual method, so the vtable, etc has a home. - ~UnaryInstruction(); + static void destroyThis(UnaryInstruction* v) { + Instruction::destroyThis(v); + } + friend class Value; +public: // Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { assert(i == 0 && "getOperand() out of range!"); @@ -136,6 +140,11 @@ protected: const std::string &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd); + + static void destroyThis(BinaryOperator* v) { + Instruction::destroyThis(v); + } + friend class Value; public: /// Transparently provide more efficient getOperand methods. @@ -272,6 +281,12 @@ protected: : UnaryInstruction(Ty, iType, S, InsertAtEnd) { setName(Name); } + +protected: + static void destroyThis(CastInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: /// Provides a way to construct any of the CastInst subclasses using an /// opcode instead of the subclass's constructor. The opcode must be in the @@ -493,6 +508,10 @@ protected: Use Ops[2]; // CmpInst instructions always have 2 operands, optimize + static void destroyThis(CmpInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: /// Construct a compare instruction, given the opcode, the predicate and /// the two operands. Optionally (if InstBefore is specified) insert the diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 8da89e2f389..3875cbe3b1e 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -42,10 +42,10 @@ protected: Instruction *InsertBefore = 0); Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); + + static void destroyThis(Instruction*v); + friend class Value; public: - // Out of line virtual method, so the vtable, etc has a home. - ~Instruction(); - /// mayWriteToMemory - Return true if this instruction may modify memory. /// bool mayWriteToMemory() const; diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 2d721bb4147..e5a6c980677 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -47,9 +47,6 @@ protected: AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd); public: - // Out of line virtual method, so the vtable, etc has a home. - virtual ~AllocationInst(); - /// isArrayAllocation - Return true if there is an allocation size parameter /// to the allocation instruction that is not 1. /// @@ -190,6 +187,11 @@ public: /// class FreeInst : public UnaryInstruction { void AssertOK(); +protected: + static void destroyThis(FreeInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); FreeInst(Value *Ptr, BasicBlock *InsertAfter); @@ -230,6 +232,11 @@ class LoadInst : public UnaryInstruction { #endif } void AssertOK(); +protected: + static void destroyThis(LoadInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); @@ -305,6 +312,11 @@ class StoreInst : public Instruction { #endif } void AssertOK(); +protected: + static void destroyThis(StoreInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); @@ -443,6 +455,9 @@ class GetElementPtrInst : public Instruction { } } +protected: + static void destroyThis(GetElementPtrInst*v); + friend class Value; public: /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing @@ -477,7 +492,6 @@ public: const std::string &Name = "", Instruction *InsertBefore =0); GetElementPtrInst(Value *Ptr, Value *Idx, const std::string &Name, BasicBlock *InsertAtEnd); - ~GetElementPtrInst(); virtual GetElementPtrInst *clone() const; @@ -556,6 +570,11 @@ public: /// vectors of integrals. The two operands must be the same type. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { +protected: + static void destroyThis(ICmpInst* v) { + CmpInst::destroyThis(v); + } + friend class Value; public: /// This enumeration lists the possible predicates for the ICmpInst. The /// values in the range 0-31 are reserved for FCmpInst while values in the @@ -712,6 +731,11 @@ public: /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { +protected: + static void destroyThis(FCmpInst* v) { + CmpInst::destroyThis(v); + } + friend class Value; public: /// This enumeration lists the possible predicates for the FCmpInst. Values /// in the range 0-31 are reserved for FCmpInst. @@ -857,6 +881,9 @@ class CallInst : public Instruction { setName(Name); } +protected: + static void destroyThis(CallInst*v); + friend class Value; public: /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage @@ -897,7 +924,6 @@ public: explicit CallInst(Value *F, const std::string &Name = "", Instruction *InsertBefore = 0); CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); - ~CallInst(); virtual CallInst *clone() const; @@ -989,6 +1015,11 @@ class SelectInst : public Instruction { : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) { init(SI.Ops[0], SI.Ops[1], SI.Ops[2]); } +protected: + static void destroyThis(SelectInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1044,6 +1075,11 @@ public: class VAArgInst : public UnaryInstruction { VAArgInst(const VAArgInst &VAA) : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {} +protected: + static void destroyThis(VAArgInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1083,6 +1119,11 @@ class ExtractElementInst : public Instruction { Ops[1].init(EE.Ops[1], this); } +protected: + static void destroyThis(ExtractElementInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "", Instruction *InsertBefore = 0); @@ -1130,6 +1171,11 @@ public: class InsertElementInst : public Instruction { Use Ops[3]; InsertElementInst(const InsertElementInst &IE); +protected: + static void destroyThis(InsertElementInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const std::string &Name = "",Instruction *InsertBefore = 0); @@ -1184,6 +1230,11 @@ public: class ShuffleVectorInst : public Instruction { Use Ops[3]; ShuffleVectorInst(const ShuffleVectorInst &IE); +protected: + static void destroyThis(ShuffleVectorInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const std::string &Name = "", Instruction *InsertBefor = 0); @@ -1238,6 +1289,9 @@ class PHINode : public Instruction { /// the number actually in use. unsigned ReservedSpace; PHINode(const PHINode &PN); +protected: + static void destroyThis(PHINode*); + friend class Value; public: explicit PHINode(const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1252,8 +1306,6 @@ public: setName(Name); } - ~PHINode(); - /// reserveOperandSpace - This method can be used to avoid repeated /// reallocation of PHI operand lists by reserving space for the correct /// number of operands before adding them. Unlike normal vector reserves, @@ -1522,6 +1574,9 @@ class SwitchInst : public TerminatorInst { SwitchInst(const SwitchInst &RI); void init(Value *Value, BasicBlock *Default, unsigned NumCases); void resizeOperands(unsigned No); +protected: + static void destroyThis(SwitchInst*v); + friend class Value; public: /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can @@ -1536,7 +1591,6 @@ public: /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); - ~SwitchInst(); // Accessor Methods for Switch stmt @@ -1664,6 +1718,9 @@ class InvokeInst : public TerminatorInst { setName(Name); } +protected: + static void destroyThis(InvokeInst*v); + friend class Value; public: /// Construct an InvokeInst given a range of arguments. /// InputIterator must be a random-access iterator pointing to @@ -1701,8 +1758,6 @@ public: typename std::iterator_traits::iterator_category()); } - ~InvokeInst(); - virtual InvokeInst *clone() const; /// getCallingConv/setCallingConv - Get or set the calling convention of this @@ -1872,6 +1927,11 @@ class TruncInst : public CastInst { TruncInst(const TruncInst &CI) : CastInst(CI.getType(), Trunc, CI.getOperand(0)) { } +protected: + static void destroyThis(TruncInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics TruncInst( @@ -1912,6 +1972,11 @@ class ZExtInst : public CastInst { ZExtInst(const ZExtInst &CI) : CastInst(CI.getType(), ZExt, CI.getOperand(0)) { } +protected: + static void destroyThis(ZExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics ZExtInst( @@ -1952,6 +2017,11 @@ class SExtInst : public CastInst { SExtInst(const SExtInst &CI) : CastInst(CI.getType(), SExt, CI.getOperand(0)) { } +protected: + static void destroyThis(SExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SExtInst( @@ -1991,6 +2061,11 @@ class FPTruncInst : public CastInst { FPTruncInst(const FPTruncInst &CI) : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) { } +protected: + static void destroyThis(FPTruncInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPTruncInst( @@ -2030,6 +2105,11 @@ class FPExtInst : public CastInst { FPExtInst(const FPExtInst &CI) : CastInst(CI.getType(), FPExt, CI.getOperand(0)) { } +protected: + static void destroyThis(FPExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPExtInst( @@ -2069,6 +2149,11 @@ class UIToFPInst : public CastInst { UIToFPInst(const UIToFPInst &CI) : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) { } +protected: + static void destroyThis(UIToFPInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics UIToFPInst( @@ -2108,6 +2193,11 @@ class SIToFPInst : public CastInst { SIToFPInst(const SIToFPInst &CI) : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) { } +protected: + static void destroyThis(SIToFPInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SIToFPInst( @@ -2147,6 +2237,11 @@ class FPToUIInst : public CastInst { FPToUIInst(const FPToUIInst &CI) : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) { } +protected: + static void destroyThis(FPToUIInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToUIInst( @@ -2186,6 +2281,11 @@ class FPToSIInst : public CastInst { FPToSIInst(const FPToSIInst &CI) : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) { } +protected: + static void destroyThis(FPToSIInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToSIInst( @@ -2225,6 +2325,11 @@ class IntToPtrInst : public CastInst { IntToPtrInst(const IntToPtrInst &CI) : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) { } +protected: + static void destroyThis(IntToPtrInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics IntToPtrInst( @@ -2264,6 +2369,11 @@ class PtrToIntInst : public CastInst { PtrToIntInst(const PtrToIntInst &CI) : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) { } +protected: + static void destroyThis(PtrToIntInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( @@ -2303,6 +2413,11 @@ class BitCastInst : public CastInst { BitCastInst(const BitCastInst &CI) : CastInst(CI.getType(), BitCast, CI.getOperand(0)) { } +protected: + static void destroyThis(BitCastInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics BitCastInst( diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 4e4d47513dd..97c07d810d2 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -38,6 +38,11 @@ namespace llvm { IntrinsicInst(); // DO NOT IMPLEMENT IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT + protected: + static void destroyThis(IntrinsicInst* v) { + CallInst::destroyThis(v); + } + friend class Value; public: /// StripPointerCasts - This static method strips off any unneeded pointer @@ -85,6 +90,11 @@ namespace llvm { } static Value *StripCast(Value *C); + protected: + static void destroyThis(DbgInfoIntrinsic* v) { + IntrinsicInst::destroyThis(v); + } + friend class Value; }; /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. @@ -114,6 +124,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgStopPointInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction. @@ -129,6 +144,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgFuncStartInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgRegionStartInst - This represents the llvm.dbg.region.start @@ -144,6 +164,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgRegionStartInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction. @@ -175,6 +200,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgDeclareInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. @@ -228,6 +258,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemIntrinsic* v) { + IntrinsicInst::destroyThis(v); + } + friend class Value; }; @@ -259,6 +294,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemCpyInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemMoveInst - This class wraps the llvm.memmove intrinsic. @@ -288,6 +328,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemMoveInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemSetInst - This class wraps the llvm.memset intrinsic. @@ -312,6 +357,11 @@ namespace llvm { static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemSetInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; } diff --git a/include/llvm/User.h b/include/llvm/User.h index 1ea5e189ba8..0392e20bda3 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -37,6 +37,10 @@ protected: /// unsigned NumOperands; + static void destroyThis(User*v) { + Value::destroyThis(v); + } + friend class Value; public: User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps) : Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {} diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 67af6edb8f9..58a4c8cbac6 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -66,8 +66,11 @@ private: friend class SymbolTable; // Allow SymbolTable to directly poke Name. ValueName *Name; +private: void operator=(const Value &); // Do not implement Value(const Value &); // Do not implement +protected: + static void destroyThis(Value*); public: Value(const Type *Ty, unsigned scid); diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index d45a1c41aa7..ad9ad4204c9 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -30,31 +30,9 @@ ilist_traits::getSymTab(BasicBlock *BB) { 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. - struct VISIBILITY_HIDDEN DummyInst : public Instruction { - DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(this); - } - - Instruction *clone() const { - assert(0 && "Cannot clone EOL");abort(); - return 0; - } - const char *getOpcodeName() const { return "*end-of-list-inst*"; } - - // Methods for support type inquiry through isa, cast, and dyn_cast... - static inline bool classof(const DummyInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == OtherOpsEnd; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } - }; +DummyInst::DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { + // This should not be garbage monitored. + LeakDetector::removeGarbageObject(this); } Instruction *ilist_traits::createSentinel() { @@ -88,10 +66,12 @@ BasicBlock::BasicBlock(const std::string &Name, Function *NewParent, } -BasicBlock::~BasicBlock() { - assert(getParent() == 0 && "BasicBlock still linked into the program!"); - dropAllReferences(); - InstList.clear(); +void BasicBlock::destroyThis(BasicBlock*v) +{ + assert(v->getParent() == 0 && "BasicBlock still linked into the program!"); + v->dropAllReferences(); + v->InstList.clear(); + Value::destroyThis(v); } void BasicBlock::setParent(Function *parent) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 49c27b82ccd..fb51c3f8954 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -356,8 +356,9 @@ ConstantArray::ConstantArray(const ArrayType *T, } } -ConstantArray::~ConstantArray() { - delete [] OperandList; +void ConstantArray::destroyThis(ConstantArray*v) { + delete [] v->OperandList; + Constant::destroyThis(v); } ConstantStruct::ConstantStruct(const StructType *T, @@ -379,8 +380,9 @@ ConstantStruct::ConstantStruct(const StructType *T, } } -ConstantStruct::~ConstantStruct() { - delete [] OperandList; +void ConstantStruct::destroyThis(ConstantStruct*v) { + delete [] v->OperandList; + Constant::destroyThis(v); } @@ -399,124 +401,67 @@ ConstantVector::ConstantVector(const VectorType *T, } } -ConstantVector::~ConstantVector() { - delete [] OperandList; +void ConstantVector::destroyThis(ConstantVector*v) { + delete [] v->OperandList; + Constant::destroyThis(v); } -// We declare several classes private to this file, so use an anonymous -// namespace -namespace { - -/// UnaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement unary constant exprs. -class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr { - Use Op; -public: - UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) - : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {} -}; - -/// BinaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement binary constant exprs. -class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr { - Use Ops[2]; -public: - BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) - : ConstantExpr(C1->getType(), Opcode, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - } -}; - -/// SelectConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement select constant exprs. -class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; - -/// ExtractElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// extractelement constant exprs. -class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr { - Use Ops[2]; -public: - ExtractElementConstantExpr(Constant *C1, Constant *C2) - : ConstantExpr(cast(C1->getType())->getElementType(), - Instruction::ExtractElement, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - } -}; +UnaryConstantExpr::UnaryConstantExpr(unsigned Opcode, + Constant *C, const Type *Ty) + : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) { +} -/// InsertElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// insertelement constant exprs. -class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C1->getType(), Instruction::InsertElement, - Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; +SelectConstantExpr::SelectConstantExpr(Constant *C1, + Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} -/// ShuffleVectorConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// shufflevector constant exprs. -class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C1->getType(), Instruction::ShuffleVector, - Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; +ExtractElementConstantExpr::ExtractElementConstantExpr(Constant *C1, + Constant *C2) + : ConstantExpr(cast(C1->getType())->getElementType(), + Instruction::ExtractElement, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); +} -/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is -/// used behind the scenes to implement getelementpr constant exprs. -struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr { - GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - new Use[IdxList.size()+1], IdxList.size()+1) { - OperandList[0].init(C, this); - for (unsigned i = 0, E = IdxList.size(); i != E; ++i) - OperandList[i+1].init(IdxList[i], this); - } - ~GetElementPtrConstantExpr() { - delete [] OperandList; - } -}; +InsertElementConstantExpr::InsertElementConstantExpr(Constant *C1, + Constant *C2, + Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} -// CompareConstantExpr - This class is private to Constants.cpp, and is used -// behind the scenes to implement ICmp and FCmp constant expressions. This is -// needed in order to store the predicate value for these instructions. -struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr { - unsigned short predicate; - Use Ops[2]; - CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, - Constant* LHS, Constant* RHS) - : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { - OperandList[0].init(LHS, this); - OperandList[1].init(RHS, this); - } -}; +ShuffleVectorConstantExpr::ShuffleVectorConstantExpr(Constant *C1, + Constant *C2, + Constant *C3) + : ConstantExpr(C1->getType(), Instruction::ShuffleVector, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} -} // end anonymous namespace +CompareConstantExpr::CompareConstantExpr(unsigned opc, unsigned short pred, + Constant* LHS, Constant* RHS) + : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { + OperandList[0].init(LHS, this); + OperandList[1].init(RHS, this); +} +GetElementPtrConstantExpr::GetElementPtrConstantExpr(Constant *C, + const std::vector + &IdxList, const Type *DestTy) +: ConstantExpr(DestTy, Instruction::GetElementPtr, + new Use[IdxList.size()+1], IdxList.size()+1) +{ + OperandList[0].init(C, this); + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + OperandList[i+1].init(IdxList[i], this); +} // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 04db3aa06c3..b1405e59262 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -287,16 +287,17 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, ParentModule->getFunctionList().push_back(this); } -Function::~Function() { - dropAllReferences(); // After this it is safe to delete instructions. +void Function::destroyThis(Function*v) { + v->dropAllReferences(); // After this it is safe to delete instructions. // Delete all of the method arguments and unlink from symbol table... - ArgumentList.clear(); - delete SymTab; + v->ArgumentList.clear(); + delete v->SymTab; // Drop our reference to the parameter attributes, if any. - if (ParamAttrs) - ParamAttrs->dropRef(); + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + GlobalValue::destroyThis(v); } void Function::BuildLazyArguments() const { diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index ca4ecad058c..4b4223775f2 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -17,12 +17,6 @@ #include using namespace llvm; -// Implement the first virtual method in this class in this file so the -// InlineAsm vtable is emitted here. -InlineAsm::~InlineAsm() { -} - - // NOTE: when memoizing the function type, we have to be careful to handle the // case when the type gets refined. diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 7fc6245f6da..fdee5e8b460 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -46,8 +46,8 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, // Out of line virtual method, so the vtable, etc has a home. -Instruction::~Instruction() { - assert(Parent == 0 && "Instruction still linked in the program!"); +void Instruction::destroyThis(Instruction*v) { + assert(v->Parent == 0 && "Instruction still linked in the program!"); } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 0df0466112b..84adc50994a 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -67,20 +67,6 @@ bool CallSite::onlyReadsMemory() const { } - -//===----------------------------------------------------------------------===// -// TerminatorInst Class -//===----------------------------------------------------------------------===// - -// Out of line virtual method, so the vtable, etc has a home. -TerminatorInst::~TerminatorInst() { -} - -// Out of line virtual method, so the vtable, etc has a home. -UnaryInstruction::~UnaryInstruction() { -} - - //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -96,8 +82,9 @@ PHINode::PHINode(const PHINode &PN) } } -PHINode::~PHINode() { - delete [] OperandList; +void PHINode::destroyThis(PHINode*v) { + delete [] v->OperandList; + Instruction::destroyThis(v); } // removeIncomingValue - Remove an incoming value. This is useful if a @@ -214,10 +201,11 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { // CallInst Implementation //===----------------------------------------------------------------------===// -CallInst::~CallInst() { - delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); +void CallInst::destroyThis(CallInst*v) { + delete [] v->OperandList; + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + Instruction::destroyThis(v); } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { @@ -406,10 +394,11 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { // InvokeInst Implementation //===----------------------------------------------------------------------===// -InvokeInst::~InvokeInst() { - delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); +void InvokeInst::destroyThis(InvokeInst*v) { + delete [] v->OperandList; + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + TerminatorInst::destroyThis(v); } void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, @@ -683,10 +672,6 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, setName(Name); } -// Out of line virtual method, so the vtable, etc has a home. -AllocationInst::~AllocationInst() { -} - bool AllocationInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast(getOperand(0))) return CI->getZExtValue() != 1; @@ -951,8 +936,8 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, setName(Name); } -GetElementPtrInst::~GetElementPtrInst() { - delete[] OperandList; +void GetElementPtrInst::destroyThis(GetElementPtrInst*v) { + delete[] v->OperandList; } // getIndexedType - Returns the type of the element that would be loaded with @@ -2469,8 +2454,9 @@ SwitchInst::SwitchInst(const SwitchInst &SI) } } -SwitchInst::~SwitchInst() { - delete [] OperandList; +void SwitchInst::destroyThis(SwitchInst*v) { + delete [] v->OperandList; + TerminatorInst::destroyThis(v); } diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index de6c16b5214..9b5100c8f9a 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -18,6 +18,11 @@ #include "llvm/ValueSymbolTable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/LeakDetector.h" +#include "llvm/Constants.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/InstrTypes.h" #include using namespace llvm; @@ -39,7 +44,233 @@ Value::Value(const Type *ty, unsigned scid) "Cannot create non-first-class values except for constants!"); } -Value::~Value() { +Value::~Value() +{ + switch(SubclassID) + { + case ArgumentVal: + Argument::destroyThis(cast(this)); + break; + case BasicBlockVal: + BasicBlock::destroyThis(cast(this)); + break; + case FunctionVal: + Function::destroyThis(cast(this)); + break; + case GlobalAliasVal: + GlobalAlias::destroyThis(cast(this)); + break; + case GlobalVariableVal: + GlobalVariable::destroyThis(cast(this)); + break; + case UndefValueVal: + UndefValue::destroyThis(cast(this)); + break; + case ConstantExprVal: + { + ConstantExpr* CE = dyn_cast(this); + if(CE->getOpcode() == Instruction::GetElementPtr) + { + GetElementPtrConstantExpr* GECE = + dyn_cast(CE); + GetElementPtrConstantExpr::destroyThis(GECE); + } + else if(CE->getOpcode() == Instruction::ExtractElement) + { + ExtractElementConstantExpr* EECE = + dyn_cast(CE); + ExtractElementConstantExpr::destroyThis(EECE); + } + else if(CE->getOpcode() == Instruction::InsertElement) + { + InsertElementConstantExpr* IECE = + dyn_cast(CE); + InsertElementConstantExpr::destroyThis(IECE); + } + else if(CE->getOpcode() == Instruction::Select) + { + SelectConstantExpr* SCE = dyn_cast(CE); + SelectConstantExpr::destroyThis(SCE); + } + else if(CE->getOpcode() == Instruction::ShuffleVector) + { + ShuffleVectorConstantExpr* SVCE = + dyn_cast(CE); + ShuffleVectorConstantExpr::destroyThis(SVCE); + } + else if(BinaryConstantExpr* BCE = dyn_cast(this)) + BinaryConstantExpr::destroyThis(BCE); + else if(UnaryConstantExpr* UCE = dyn_cast(this)) + UnaryConstantExpr::destroyThis(UCE); + else if(CompareConstantExpr* CCE = dyn_cast(this)) + CompareConstantExpr::destroyThis(CCE); + else + assert(0 && "Unknown ConstantExpr-inherited class in ~Value."); + } + break; + case ConstantAggregateZeroVal: + ConstantAggregateZero::destroyThis(cast(this)); + break; + case ConstantIntVal: + ConstantInt::destroyThis(cast(this)); + break; + case ConstantFPVal: + ConstantFP::destroyThis(cast(this)); + break; + case ConstantArrayVal: + ConstantArray::destroyThis(cast(this)); + break; + case ConstantStructVal: + ConstantStruct::destroyThis(cast(this)); + break; + case ConstantVectorVal: + ConstantVector::destroyThis(cast(this)); + break; + case ConstantPointerNullVal: + ConstantPointerNull::destroyThis(cast(this)); + break; + case InlineAsmVal: + InlineAsm::destroyThis(cast(this)); + break; + + default: + if (BinaryOperator *BO = dyn_cast(this)) + BinaryOperator::destroyThis(BO); + else if (CallInst *CI = dyn_cast(this)) + { + if(IntrinsicInst* II = dyn_cast(this)) + { + if(DbgInfoIntrinsic* DII = dyn_cast(this)) + { + if(DbgDeclareInst* DDI = dyn_cast(this)) + DbgDeclareInst::destroyThis(DDI); + else if(DbgFuncStartInst* DFSI = dyn_cast(this)) + DbgFuncStartInst::destroyThis(DFSI); + else if(DbgRegionEndInst* DREI = dyn_cast(this)) + DbgRegionEndInst::destroyThis(DREI); + else if(DbgRegionStartInst* DRSI = dyn_cast(this)) + DbgRegionStartInst::destroyThis(DRSI); + else if(DbgStopPointInst* DSPI = dyn_cast(this)) + DbgStopPointInst::destroyThis(DSPI); + else + assert(0 && "Unknown DbgInfo-inherited class in ~Value."); + } + else if(MemIntrinsic* MI = dyn_cast(this)) + { + if(MemCpyInst* MCI = dyn_cast(this)) + MemCpyInst::destroyThis(MCI); + else if(MemMoveInst* MMI = dyn_cast(this)) + MemMoveInst::destroyThis(MMI); + else if(MemSetInst* MSI = dyn_cast(this)) + MemSetInst::destroyThis(MSI); + else + assert(0 && "Unknown MemIntrinsic-inherited class in ~Value."); + } + else + assert(0 && "Unknown IntrinsicInst-inherited class in ~Value."); + } + else + assert(0 && "Unknown CallInst-inherited class in ~Value."); + } + else if (CmpInst *CI = dyn_cast(this)) + { + if (FCmpInst *FCI = dyn_cast(this)) + FCmpInst::destroyThis(FCI); + else if (ICmpInst *ICI = dyn_cast(this)) + ICmpInst::destroyThis(ICI); + else + assert(0 && "Unknown CmpInst-inherited class in ~Value."); + } + else if (ExtractElementInst *EEI = dyn_cast(this)) + ExtractElementInst::destroyThis(EEI); + else if (GetElementPtrInst *GEP = dyn_cast(this)) + GetElementPtrInst::destroyThis(GEP); + else if (InsertElementInst* IE = dyn_cast(this)) + InsertElementInst::destroyThis(IE); + else if (PHINode *PN = dyn_cast(this)) + PHINode::destroyThis(PN); + else if (SelectInst *SI = dyn_cast(this)) + SelectInst::destroyThis(SI); + else if (ShuffleVectorInst *SVI = dyn_cast(this)) + ShuffleVectorInst::destroyThis(SVI); + else if (StoreInst *SI = dyn_cast(this)) + StoreInst::destroyThis(SI); + else if (TerminatorInst *TI = dyn_cast(this)) + { + if (BranchInst* BI = dyn_cast(this)) + BranchInst::destroyThis(BI); + else if (InvokeInst* II = dyn_cast(this)) + InvokeInst::destroyThis(II); + else if (ReturnInst* RI = dyn_cast(this)) + ReturnInst::destroyThis(RI); + else if (SwitchInst *SI = dyn_cast(this)) + SwitchInst::destroyThis(SI); + else if (UnreachableInst *UI = dyn_cast(this)) + UnreachableInst::destroyThis(UI); + else if (UnwindInst *UI = dyn_cast(this)) + UnwindInst::destroyThis(UI); + else + assert(0 && "Unknown TerminatorInst-inherited class in ~Value."); + } + else if(UnaryInstruction* UI = dyn_cast(this)) + { + if(AllocationInst* AI = dyn_cast(this)) + { + if(AllocaInst* AI = dyn_cast(this)) + AllocaInst::destroyThis(AI); + else if(MallocInst* MI = dyn_cast(this)) + MallocInst::destroyThis(MI); + else + assert(0 && "Unknown AllocationInst-inherited class in ~Value."); + } + else if(CastInst* CI = dyn_cast(this)) + { + if(BitCastInst* BCI = dyn_cast(this)) + BitCastInst::destroyThis(BCI); + else if(FPExtInst* FPEI = dyn_cast(this)) + FPExtInst::destroyThis(FPEI); + else if(FPToSIInst* FPSII = dyn_cast(this)) + FPToSIInst::destroyThis(FPSII); + else if(FPToUIInst* FPUII = dyn_cast(this)) + FPToUIInst::destroyThis(FPUII); + else if(FPTruncInst* FPTI = dyn_cast(this)) + FPTruncInst::destroyThis(FPTI); + else if(IntToPtrInst* I2PI = dyn_cast(this)) + IntToPtrInst::destroyThis(I2PI); + else if(PtrToIntInst* P2II = dyn_cast(this)) + PtrToIntInst::destroyThis(P2II); + else if(SExtInst* SEI = dyn_cast(this)) + SExtInst::destroyThis(SEI); + else if(SIToFPInst* SIFPI = dyn_cast(this)) + SIToFPInst::destroyThis(SIFPI); + else if(TruncInst* TI = dyn_cast(this)) + TruncInst::destroyThis(TI); + else if(UIToFPInst* UIFPI = dyn_cast(this)) + UIToFPInst::destroyThis(UIFPI); + else if(ZExtInst* ZEI = dyn_cast(this)) + ZExtInst::destroyThis(ZEI); + else + assert(0 && "Unknown CastInst-inherited class in ~Value."); + } + else if(FreeInst* FI = dyn_cast(this)) + FreeInst::destroyThis(FI); + else if(LoadInst* LI = dyn_cast(this)) + LoadInst::destroyThis(LI); + else if(VAArgInst* VAI = dyn_cast(this)) + VAArgInst::destroyThis(VAI); + else + assert(0 && "Unknown UnaryInstruction-inherited class in ~Value."); + } + else if (DummyInst *DI = dyn_cast(this)) + DummyInst::destroyThis(DI); + else + assert(0 && "Unknown Instruction-inherited class in ~Value."); + break; + } +} + +void Value::destroyThis(Value*v) +{ #ifndef NDEBUG // Only in -g mode... // Check to make sure that there are no uses of this value that are still // around when the value is destroyed. If there are, then we have a dangling @@ -47,22 +278,22 @@ Value::~Value() { // still being referenced. The value in question should be printed as // a // - if (!use_empty()) { - DOUT << "While deleting: " << *Ty << " %" << Name << "\n"; - for (use_iterator I = use_begin(), E = use_end(); I != E; ++I) + if (!v->use_empty()) { + DOUT << "While deleting: " << *v->Ty << " %" << v->Name << "\n"; + for (use_iterator I = v->use_begin(), E = v->use_end(); I != E; ++I) DOUT << "Use still stuck around after Def is destroyed:" << **I << "\n"; } #endif - assert(use_empty() && "Uses remain when a value is destroyed!"); + assert(v->use_empty() && "Uses remain when a value is destroyed!"); // If this value is named, destroy the name. This should not be in a symtab // at this point. - if (Name) - Name->Destroy(); + if (v->Name) + v->Name->Destroy(); // There should be no uses of this object anymore, remove it. - LeakDetector::removeGarbageObject(this); + LeakDetector::removeGarbageObject(v); } /// hasNUses - Return true if this Value has exactly N users.