1249259Sdim//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This class defines the interface that one who uses a Value must implement. 11249259Sdim// Each instance of the Value class keeps track of what User's have handles 12249259Sdim// to it. 13249259Sdim// 14249259Sdim// * Instructions are the largest class of Users. 15249259Sdim// * Constants may be users of other constants (think arrays and stuff) 16249259Sdim// 17249259Sdim//===----------------------------------------------------------------------===// 18249259Sdim 19249259Sdim#ifndef LLVM_IR_USER_H 20249259Sdim#define LLVM_IR_USER_H 21249259Sdim 22249259Sdim#include "llvm/IR/Value.h" 23249259Sdim#include "llvm/Support/ErrorHandling.h" 24249259Sdim 25249259Sdimnamespace llvm { 26249259Sdim 27249259Sdim/// OperandTraits - Compile-time customization of 28249259Sdim/// operand-related allocators and accessors 29249259Sdim/// for use of the User class 30249259Sdimtemplate <class> 31249259Sdimstruct OperandTraits; 32249259Sdim 33249259Sdimclass User : public Value { 34249259Sdim User(const User &) LLVM_DELETED_FUNCTION; 35249259Sdim void *operator new(size_t) LLVM_DELETED_FUNCTION; 36249259Sdim template <unsigned> 37249259Sdim friend struct HungoffOperandTraits; 38249259Sdim virtual void anchor(); 39249259Sdimprotected: 40249259Sdim /// OperandList - This is a pointer to the array of Uses for this User. 41249259Sdim /// For nodes of fixed arity (e.g. a binary operator) this array will live 42249259Sdim /// prefixed to some derived class instance. For nodes of resizable variable 43249259Sdim /// arity (e.g. PHINodes, SwitchInst etc.), this memory will be dynamically 44249259Sdim /// allocated and should be destroyed by the classes' virtual dtor. 45249259Sdim Use *OperandList; 46249259Sdim 47249259Sdim /// NumOperands - The number of values used by this User. 48249259Sdim /// 49249259Sdim unsigned NumOperands; 50249259Sdim 51249259Sdim void *operator new(size_t s, unsigned Us); 52249259Sdim User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps) 53249259Sdim : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {} 54249259Sdim Use *allocHungoffUses(unsigned) const; 55249259Sdim void dropHungoffUses() { 56249259Sdim Use::zap(OperandList, OperandList + NumOperands, true); 57249259Sdim OperandList = 0; 58249259Sdim // Reset NumOperands so User::operator delete() does the right thing. 59249259Sdim NumOperands = 0; 60249259Sdim } 61249259Sdimpublic: 62249259Sdim ~User() { 63249259Sdim Use::zap(OperandList, OperandList + NumOperands); 64249259Sdim } 65249259Sdim /// operator delete - free memory allocated for User and Use objects 66249259Sdim void operator delete(void *Usr); 67249259Sdim /// placement delete - required by std, but never called. 68249259Sdim void operator delete(void*, unsigned) { 69249259Sdim llvm_unreachable("Constructor throws?"); 70249259Sdim } 71249259Sdim /// placement delete - required by std, but never called. 72249259Sdim void operator delete(void*, unsigned, bool) { 73249259Sdim llvm_unreachable("Constructor throws?"); 74249259Sdim } 75249259Sdimprotected: 76249259Sdim template <int Idx, typename U> static Use &OpFrom(const U *that) { 77249259Sdim return Idx < 0 78249259Sdim ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx] 79249259Sdim : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx]; 80249259Sdim } 81249259Sdim template <int Idx> Use &Op() { 82249259Sdim return OpFrom<Idx>(this); 83249259Sdim } 84249259Sdim template <int Idx> const Use &Op() const { 85249259Sdim return OpFrom<Idx>(this); 86249259Sdim } 87249259Sdimpublic: 88249259Sdim Value *getOperand(unsigned i) const { 89249259Sdim assert(i < NumOperands && "getOperand() out of range!"); 90249259Sdim return OperandList[i]; 91249259Sdim } 92249259Sdim void setOperand(unsigned i, Value *Val) { 93249259Sdim assert(i < NumOperands && "setOperand() out of range!"); 94249259Sdim assert((!isa<Constant>((const Value*)this) || 95249259Sdim isa<GlobalValue>((const Value*)this)) && 96249259Sdim "Cannot mutate a constant with setOperand!"); 97249259Sdim OperandList[i] = Val; 98249259Sdim } 99249259Sdim const Use &getOperandUse(unsigned i) const { 100249259Sdim assert(i < NumOperands && "getOperandUse() out of range!"); 101249259Sdim return OperandList[i]; 102249259Sdim } 103249259Sdim Use &getOperandUse(unsigned i) { 104249259Sdim assert(i < NumOperands && "getOperandUse() out of range!"); 105249259Sdim return OperandList[i]; 106249259Sdim } 107249259Sdim 108249259Sdim unsigned getNumOperands() const { return NumOperands; } 109249259Sdim 110249259Sdim // --------------------------------------------------------------------------- 111249259Sdim // Operand Iterator interface... 112249259Sdim // 113249259Sdim typedef Use* op_iterator; 114249259Sdim typedef const Use* const_op_iterator; 115249259Sdim 116249259Sdim inline op_iterator op_begin() { return OperandList; } 117249259Sdim inline const_op_iterator op_begin() const { return OperandList; } 118249259Sdim inline op_iterator op_end() { return OperandList+NumOperands; } 119249259Sdim inline const_op_iterator op_end() const { return OperandList+NumOperands; } 120249259Sdim 121249259Sdim /// Convenience iterator for directly iterating over the Values in the 122249259Sdim /// OperandList 123249259Sdim class value_op_iterator : public std::iterator<std::forward_iterator_tag, 124249259Sdim Value*> { 125249259Sdim op_iterator OI; 126249259Sdim public: 127249259Sdim explicit value_op_iterator(Use *U) : OI(U) {} 128249259Sdim 129249259Sdim bool operator==(const value_op_iterator &x) const { 130249259Sdim return OI == x.OI; 131249259Sdim } 132249259Sdim bool operator!=(const value_op_iterator &x) const { 133249259Sdim return !operator==(x); 134249259Sdim } 135249259Sdim 136249259Sdim /// Iterator traversal: forward iteration only 137249259Sdim value_op_iterator &operator++() { // Preincrement 138249259Sdim ++OI; 139249259Sdim return *this; 140249259Sdim } 141249259Sdim value_op_iterator operator++(int) { // Postincrement 142249259Sdim value_op_iterator tmp = *this; ++*this; return tmp; 143249259Sdim } 144249259Sdim 145249259Sdim /// Retrieve a pointer to the current Value. 146249259Sdim Value *operator*() const { 147249259Sdim return *OI; 148249259Sdim } 149249259Sdim 150249259Sdim Value *operator->() const { return operator*(); } 151249259Sdim }; 152249259Sdim 153249259Sdim inline value_op_iterator value_op_begin() { 154249259Sdim return value_op_iterator(op_begin()); 155249259Sdim } 156249259Sdim inline value_op_iterator value_op_end() { 157249259Sdim return value_op_iterator(op_end()); 158249259Sdim } 159249259Sdim 160249259Sdim // dropAllReferences() - This function is in charge of "letting go" of all 161249259Sdim // objects that this User refers to. This allows one to 162249259Sdim // 'delete' a whole class at a time, even though there may be circular 163249259Sdim // references... First all references are dropped, and all use counts go to 164249259Sdim // zero. Then everything is deleted for real. Note that no operations are 165249259Sdim // valid on an object that has "dropped all references", except operator 166249259Sdim // delete. 167249259Sdim // 168249259Sdim void dropAllReferences() { 169249259Sdim for (op_iterator i = op_begin(), e = op_end(); i != e; ++i) 170249259Sdim i->set(0); 171249259Sdim } 172249259Sdim 173249259Sdim /// replaceUsesOfWith - Replaces all references to the "From" definition with 174249259Sdim /// references to the "To" definition. 175249259Sdim /// 176249259Sdim void replaceUsesOfWith(Value *From, Value *To); 177249259Sdim 178249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 179249259Sdim static inline bool classof(const Value *V) { 180249259Sdim return isa<Instruction>(V) || isa<Constant>(V); 181249259Sdim } 182249259Sdim}; 183249259Sdim 184249259Sdimtemplate<> struct simplify_type<User::op_iterator> { 185249259Sdim typedef Value* SimpleType; 186249259Sdim static SimpleType getSimplifiedValue(User::op_iterator &Val) { 187249259Sdim return Val->get(); 188249259Sdim } 189249259Sdim}; 190249259Sdimtemplate<> struct simplify_type<User::const_op_iterator> { 191249259Sdim typedef /*const*/ Value* SimpleType; 192249259Sdim static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { 193249259Sdim return Val->get(); 194249259Sdim } 195249259Sdim}; 196249259Sdim 197249259Sdim// value_use_iterator::getOperandNo - Requires the definition of the User class. 198249259Sdimtemplate<typename UserTy> 199249259Sdimunsigned value_use_iterator<UserTy>::getOperandNo() const { 200249259Sdim return U - U->getUser()->op_begin(); 201249259Sdim} 202249259Sdim 203249259Sdim} // End llvm namespace 204249259Sdim 205249259Sdim#endif 206