X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FUse.h;h=0a971d18ce3a31b1478a1bf41e09382a316b82b2;hb=99ec779a93cf7a09ac336b63d2d67818960343a1;hp=eeff52fcb6a4e1797fe3a846340db95b7440dcfc;hpb=5dc8050ca3797d7001d05ade44bae199bbe324cf;p=oota-llvm.git diff --git a/include/llvm/Use.h b/include/llvm/Use.h index eeff52fcb6a..0a971d18ce3 100644 --- a/include/llvm/Use.h +++ b/include/llvm/Use.h @@ -2,8 +2,8 @@ // // 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. // //===----------------------------------------------------------------------===// // @@ -17,7 +17,7 @@ #define LLVM_USE_H #include "llvm/Support/Casting.h" -#include "llvm/ADT/iterator" +#include "llvm/ADT/iterator.h" namespace llvm { @@ -25,6 +25,40 @@ class Value; class User; +//===----------------------------------------------------------------------===// +// Generic Tagging Functions +//===----------------------------------------------------------------------===// + +/// Tag - generic tag type for (at least 32 bit) pointers +enum Tag { noTag, tagOne, tagTwo, tagThree }; + +/// addTag - insert tag bits into an (untagged) pointer +template +inline T *addTag(const T *P, TAG Tag) { + return reinterpret_cast(ptrdiff_t(P) | Tag); +} + +/// stripTag - remove tag bits from a pointer, +/// making it dereferencable +template +inline T *stripTag(const T *P) { + return reinterpret_cast(ptrdiff_t(P) & ~MASK); +} + +/// extractTag - extract tag bits from a pointer +template +inline TAG extractTag(const T *P) { + return TAG(ptrdiff_t(P) & MASK); +} + +/// transferTag - transfer tag bits from a pointer, +/// to an untagged pointer +template +inline T *transferTag(const T *From, const T *To) { + return reinterpret_cast((ptrdiff_t(From) & MASK) | ptrdiff_t(To)); +} + + //===----------------------------------------------------------------------===// // Use Class //===----------------------------------------------------------------------===// @@ -32,21 +66,40 @@ class User; // Use is here to make keeping the "use" list of a Value up-to-date really easy. // class Use { -public: +private: + /// init - specify Value and User + /// @deprecated in 2.4, will be removed soon inline void init(Value *V, User *U); +public: + /// swap - provide a fast substitute to std::swap + /// that also works with less standard-compliant compilers + void swap(Use &RHS); + +private: + /// Copy ctor - do not implement + Use(const Use &U); - Use(Value *V, User *U) { init(V, U); } - Use(const Use &U) { init(U.Val, U.U); } - inline ~Use(); + /// Destructor - Only for zap() + inline ~Use() { + if (Val) removeFromList(); + } - /// Default ctor - This leaves the Use completely unitialized. The only thing + /// Default ctor - This leaves the Use completely uninitialized. The only thing /// that is valid to do with this use is to call the "init" method. - inline Use() : Val(0) {} + inline Use() {} + enum PrevPtrTag { zeroDigitTag = noTag + , oneDigitTag = tagOne + , stopTag = tagTwo + , fullStopTag = tagThree }; +public: operator Value*() const { return Val; } Value *get() const { return Val; } - User *getUser() const { return U; } + User *getUser() const; + const Use* getImpliedUser() const; + static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0); + static void zap(Use *Start, const Use *Stop, bool del = false); inline void set(Value *Val); @@ -64,19 +117,22 @@ public: Use *getNext() const { return Next; } private: - Use *Next, **Prev; Value *Val; - User *U; + Use *Next, **Prev; + void setPrev(Use **NewPrev) { + Prev = transferTag(Prev, NewPrev); + } void addToList(Use **List) { Next = *List; - if (Next) Next->Prev = &Next; - Prev = List; + if (Next) Next->setPrev(&Next); + setPrev(List); *List = this; } void removeFromList() { - *Prev = Next; - if (Next) Next->Prev = Prev; + Use **StrippedPrev = stripTag(Prev); + *StrippedPrev = Next; + if (Next) Next->setPrev(StrippedPrev); } friend class Value; @@ -105,7 +161,7 @@ class value_use_iterator : public forward_iterator { typedef value_use_iterator _Self; Use *U; - value_use_iterator(Use *u) : U(u) {} + explicit value_use_iterator(Use *u) : U(u) {} friend class Value; public: typedef typename super::reference reference; @@ -121,6 +177,9 @@ public: return !operator==(x); } + /// atEnd - return true if this iterator is equal to use_end() on the value. + bool atEnd() const { return U == 0; } + // Iterator traversal: forward iteration only _Self &operator++() { // Preincrement assert(U && "Cannot increment end iterator!"); @@ -131,15 +190,20 @@ public: _Self tmp = *this; ++*this; return tmp; } - // Retrieve a reference to the current SCC + // Retrieve a reference to the current User UserTy *operator*() const { - assert(U && "Cannot increment end iterator!"); + assert(U && "Cannot dereference end iterator!"); return U->getUser(); } UserTy *operator->() const { return operator*(); } Use &getUse() const { return *U; } + + /// getOperandNo - Return the operand # of this use in its User. Defined in + /// User.h + /// + unsigned getOperandNo() const; };