X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FUser.h;h=570f381d1a8c4eb168e16f21305cfc3d0b0be78f;hb=e089160d1065d83986fd97fae7f0af08c03e7d47;hp=0f1dcfe7a0947f0869a5b46ae6ac02855b0299fc;hpb=57ef4f46c182cdbe014d469892090ff50c739cf9;p=oota-llvm.git diff --git a/include/llvm/User.h b/include/llvm/User.h index 0f1dcfe7a09..570f381d1a8 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -23,14 +23,38 @@ namespace llvm { +/// OperandTraits - Compile-time customization of +/// operand-related allocators and accessors +/// for use of the User class +template +struct OperandTraits; + +class User; + +/// OperandTraits - specialization to User +template <> +struct OperandTraits { + static inline Use *op_begin(User*); + static inline Use *op_end(User*); + static inline unsigned operands(const User*); + template + struct Layout { + typedef U overlay; + }; + static inline void *allocate(unsigned); +}; + class User : public Value { User(const User &); // Do not implement + void *operator new(size_t); // Do not implement + template + friend struct HungoffOperandTraits; protected: /// OperandList - This is a pointer to the array of Users for this operand. /// For nodes of fixed arity (e.g. a binary operator) this array will live - /// embedded into the derived class. For nodes of variable arity - /// (e.g. ConstantArrays, CallInst, PHINodes, ReturnInst etc), this memory - /// will be dynamically allocated and should be destroyed by the classes + /// prefixed to the derived class. For nodes of resizable variable arity + /// (e.g. PHINodes, SwitchInst etc.), this memory will be dynamically + /// allocated and should be destroyed by the classes' /// virtual dtor. Use *OperandList; @@ -38,10 +62,33 @@ protected: /// unsigned NumOperands; + void *operator new(size_t s, unsigned Us); + User(const Type *ty, unsigned vty, Use *OpList, unsigned NumOps) + : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {} + Use *allocHungoffUses(unsigned) const; + void dropHungoffUses(Use *U) { + if (OperandList == U) { + OperandList = 0; + NumOperands = 0; + } + Use::zap(U, U->getImpliedUser(), true); + } public: - User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps) - : Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {} - + ~User() { + Use::zap(OperandList, OperandList + NumOperands); + } + /// operator delete - free memory allocated for User and Use objects + void operator delete(void *Usr); + /// placement delete - required by std, but never called. + void operator delete(void*, unsigned) { + assert(0 && "Constructor throws?"); + } + template Use &Op() { + return OperandTraits::op_begin(this)[Idx]; + } + template const Use &Op() const { + return OperandTraits::op_begin(const_cast(this))[Idx]; + } Value *getOperand(unsigned i) const { assert(i < NumOperands && "getOperand() out of range!"); return OperandList[i]; @@ -66,15 +113,14 @@ public: // dropAllReferences() - This function is in charge of "letting go" of all // objects that this User refers to. This allows one to // 'delete' a whole class at a time, even though there may be circular - // references... first all references are dropped, and all use counts go to - // zero. Then everything is delete'd for real. Note that no operations are + // references... First all references are dropped, and all use counts go to + // zero. Then everything is deleted for real. Note that no operations are // valid on an object that has "dropped all references", except operator // delete. // void dropAllReferences() { - Use *OL = OperandList; - for (unsigned i = 0, e = NumOperands; i != e; ++i) - OL[i].set(0); + for (op_iterator i = op_begin(), e = op_end(); i != e; ++i) + i->set(0); } /// replaceUsesOfWith - Replaces all references to the "From" definition with @@ -89,6 +135,18 @@ public: } }; +inline Use *OperandTraits::op_begin(User *U) { + return U->op_begin(); +} + +inline Use *OperandTraits::op_end(User *U) { + return U->op_end(); +} + +inline unsigned OperandTraits::operands(const User *U) { + return U->getNumOperands(); +} + template<> struct simplify_type { typedef Value* SimpleType;