X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FUser.h;h=62bc9f034618492629fe718763e0992aad9cac8f;hb=8c74f7f2991a10977fd5a003b2901b56eb2e19a8;hp=0e98da50e9360620b8354bcc79af2298f927f95e;hpb=f718e70c7ee45daee8a46d1601d054ed9fd8f31d;p=oota-llvm.git diff --git a/include/llvm/User.h b/include/llvm/User.h index 0e98da50e93..62bc9f03461 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -1,10 +1,10 @@ //===-- llvm/User.h - User class definition ---------------------*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// 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. @@ -20,37 +20,89 @@ #define LLVM_USER_H #include "llvm/Value.h" -#include namespace llvm { +/// OperandTraits - Compile-time customization of +/// operand-related allocators and accessors +/// for use of the User class +template +struct OperandTraits; + 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. + /// OperandList - This is a pointer to the array of Uses for this User. /// 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, etc), this memory will be - /// dynamically allocated and should be destroyed by the classes virtual dtor. + /// prefixed to some derived class instance. 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; + void *operator new(size_t s, unsigned Us); + User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps) + : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {} + Use *allocHungoffUses(unsigned) const; + void dropHungoffUses() { + Use::zap(OperandList, OperandList + NumOperands, true); + OperandList = 0; + // Reset NumOperands so User::operator delete() does the right thing. + NumOperands = 0; + } public: - User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps, - const std::string &name = "") - : Value(Ty, vty, name), OperandList(OpList), NumOperands(NumOps) {} - - Value *getOperand(unsigned i) const { + ~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?"); + } + /// placement delete - required by std, but never called. + void operator delete(void*, unsigned, bool) { + assert(0 && "Constructor throws?"); + } +protected: + template static Use &OpFrom(const U *that) { + return Idx < 0 + ? OperandTraits::op_end(const_cast(that))[Idx] + : OperandTraits::op_begin(const_cast(that))[Idx]; + } + template Use &Op() { + return OpFrom(this); + } + template const Use &Op() const { + return OpFrom(this); + } +public: + 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!"); + assert((!isa((const Value*)this) || + isa((const Value*)this)) && + "Cannot mutate a constant with setOperand!"); OperandList[i] = Val; } + const Use &getOperandUse(unsigned i) const { + assert(i < NumOperands && "getOperandUse() out of range!"); + return OperandList[i]; + } + Use &getOperandUse(unsigned i) { + assert(i < NumOperands && "getOperandUse() out of range!"); + return OperandList[i]; + } + unsigned getNumOperands() const { return NumOperands; } // --------------------------------------------------------------------------- @@ -67,15 +119,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 - // 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. // 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 @@ -92,24 +143,33 @@ public: template<> struct simplify_type { typedef Value* SimpleType; - + static SimpleType getSimplifiedValue(const User::op_iterator &Val) { 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 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