X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FUser.h;h=570f381d1a8c4eb168e16f21305cfc3d0b0be78f;hb=fb2bbbe78674a34e5ec2ec6f8c566ac5cbb26154;hp=2175ad0ae06bcb71717aa3418832b6f8b68cff4d;hpb=b0a994b4c03ee1a27aef551b43f70c2ce2e003ad;p=oota-llvm.git diff --git a/include/llvm/User.h b/include/llvm/User.h index 2175ad0ae06..570f381d1a8 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -1,5 +1,12 @@ //===-- llvm/User.h - User class definition ---------------------*- C++ -*-===// // +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// // This class defines the interface that one who 'use's a Value must implement. // Each instance of the Value class keeps track of what User's have handles // to it. @@ -14,53 +21,106 @@ #include "llvm/Value.h" +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: - std::vector Operands; -public: - User(const Type *Ty, ValueTy vty, const std::string &name = ""); + /// 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 + /// 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; + + /// NumOperands - The number of values used by this User. + /// + unsigned NumOperands; - inline Value *getOperand(unsigned i) { - assert(i < Operands.size() && "getOperand() out of range!"); - return Operands[i]; + 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() { + 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?"); } - inline const Value *getOperand(unsigned i) const { - assert(i < Operands.size() && "getOperand() const out of range!"); - return Operands[i]; + template Use &Op() { + return OperandTraits::op_begin(this)[Idx]; } - inline void setOperand(unsigned i, Value *Val) { - assert(i < Operands.size() && "setOperand() out of range!"); - Operands[i] = Val; + template const Use &Op() const { + return OperandTraits::op_begin(const_cast(this))[Idx]; } - inline unsigned getNumOperands() const { return Operands.size(); } + Value *getOperand(unsigned i) const { + assert(i < NumOperands && "getOperand() out of range!"); + return OperandList[i]; + } + void setOperand(unsigned i, Value *Val) { + assert(i < NumOperands && "setOperand() out of range!"); + OperandList[i] = Val; + } + unsigned getNumOperands() const { return NumOperands; } // --------------------------------------------------------------------------- // Operand Iterator interface... // - typedef std::vector::iterator op_iterator; - typedef std::vector::const_iterator const_op_iterator; + typedef Use* op_iterator; + typedef const Use* const_op_iterator; - inline op_iterator op_begin() { return Operands.begin(); } - inline const_op_iterator op_begin() const { return Operands.begin(); } - inline op_iterator op_end() { return Operands.end(); } - inline const_op_iterator op_end() const { return Operands.end(); } - - /// op_erase - This method is used to remove one of the arguments from the - /// operands list. Only use this if you know what you are doing. - /// - op_iterator op_erase(op_iterator I) { return Operands.erase(I); } + inline op_iterator op_begin() { return OperandList; } + inline const_op_iterator op_begin() const { return OperandList; } + inline op_iterator op_end() { return OperandList+NumOperands; } + inline const_op_iterator op_end() const { return OperandList+NumOperands; } // 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 - // valid on an object that has "dropped all references", except operator + // 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. // - inline void dropAllReferences() { - Operands.clear(); + void dropAllReferences() { + for (op_iterator i = op_begin(), e = op_end(); i != e; ++i) + i->set(0); } /// replaceUsesOfWith - Replaces all references to the "From" definition with @@ -71,30 +131,51 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const User *) { return true; } static inline bool classof(const Value *V) { - return V->getValueType() == Value::GlobalVariableVal || - V->getValueType() == Value::ConstantVal || - V->getValueType() == Value::InstructionVal; + return isa(V) || isa(V); } }; +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; - + static SimpleType getSimplifiedValue(const User::op_iterator &Val) { - return (SimpleType)Val->get(); + return static_cast(Val->get()); } }; + template<> struct simplify_type : public simplify_type {}; template<> struct simplify_type { typedef Value* SimpleType; - + static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) { - return (SimpleType)Val->get(); + return static_cast(Val->get()); } }; + template<> struct simplify_type : public simplify_type {}; + +// value_use_iterator::getOperandNo - Requires the definition of the User class. +template +unsigned value_use_iterator::getOperandNo() const { + return U - U->getUser()->op_begin(); +} + +} // End llvm namespace + #endif