diff --git a/include/llvm/Use.h b/include/llvm/Use.h index b116e8c3b50..891eaf85657 100644 --- a/include/llvm/Use.h +++ b/include/llvm/Use.h @@ -66,22 +66,11 @@ inline T *transferTag(const T *From, const T *To) { // Use is here to make keeping the "use" list of a Value up-to-date really easy. // class Use { - class UseWaymark; - friend class UseWaymark; - Value *getValue() const; - /// nilUse - returns a 'token' that marks the end of the def/use chain - static Use *nilUse(const Value *V) { - return addTag((Use*)V, fullStopTagN); - } - static bool isNil(Use *U) { return extractTag(U) == fullStopTagN; } - void showWaymarks() const; - static bool isStop(Use *U) { - return isStopTag(extractTag(U)); - } -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); @@ -92,7 +81,7 @@ private: /// Destructor - Only for zap() inline ~Use() { - if (Val1) removeFromList(); + if (Val) removeFromList(); } /// Default ctor - This leaves the Use completely uninitialized. The only thing @@ -102,22 +91,11 @@ private: enum PrevPtrTag { zeroDigitTag = noTag , oneDigitTag = tagOne , stopTag = tagTwo - , fullStopTag = tagThree - , tagMask = tagThree }; + , fullStopTag = tagThree }; - enum NextPtrTag { zeroDigitTagN = tagTwo - , oneDigitTagN = tagOne - , stopTagN = noTag - , fullStopTagN = tagThree - , tagMaskN = tagThree }; - - static bool isStopTag(NextPtrTag T) { - bool P[] = { true, false, false, true }; - return P[T]; - } public: - operator Value*() const { return get(); } - inline Value *get() const; + operator Value*() const { return Val; } + Value *get() const { return Val; } User *getUser() const; const Use* getImpliedUser() const; static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0); @@ -130,38 +108,31 @@ public: return RHS; } const Use &operator=(const Use &RHS) { - set(RHS.Val1); + set(RHS.Val); return *this; } - Value *operator->() { return get(); } - const Value *operator->() const { return get(); } + Value *operator->() { return Val; } + const Value *operator->() const { return Val; } - Use *getNext() const { return extractTag(Next) == fullStopTagN - ? 0 - : stripTag(Next); } + Use *getNext() const { return Next; } private: - Value *Val1; + Value *Val; Use *Next, **Prev; void setPrev(Use **NewPrev) { - Prev = transferTag(Prev, NewPrev); + Prev = transferTag(Prev, NewPrev); } void addToList(Use **List) { Next = *List; - Use *StrippedNext(getNext()); - if (StrippedNext) StrippedNext->setPrev(&Next); + if (Next) Next->setPrev(&Next); setPrev(List); *List = this; } void removeFromList() { - // __builtin_prefetch(Next); - Use **StrippedPrev = stripTag(Prev); - Use *StrippedNext(getNext()); - if (isStop(Next)) - assert((isStop(*StrippedPrev) || (StrippedNext ? isStop(StrippedNext->Next) : true)) && "joining digits?"); + Use **StrippedPrev = stripTag(Prev); *StrippedPrev = Next; - if (StrippedNext) StrippedNext->setPrev(StrippedPrev); + if (Next) Next->setPrev(StrippedPrev); } friend class Value; @@ -190,10 +161,7 @@ class value_use_iterator : public forward_iterator { typedef value_use_iterator _Self; Use *U; - explicit value_use_iterator(Use *u) : U(extractTag(u) - == Use::fullStopTagN - ? 0 - : stripTag(u)) {} + explicit value_use_iterator(Use *u) : U(u) {} friend class Value; public: typedef typename super::reference reference; @@ -210,11 +178,11 @@ public: } /// atEnd - return true if this iterator is equal to use_end() on the value. - bool atEnd() const { return !U; } + bool atEnd() const { return U == 0; } // Iterator traversal: forward iteration only _Self &operator++() { // Preincrement - assert(!atEnd() && "Cannot increment end iterator!"); + assert(U && "Cannot increment end iterator!"); U = U->getNext(); return *this; } @@ -222,9 +190,9 @@ public: _Self tmp = *this; ++*this; return tmp; } - // Retrieve a reference to the current User + // Retrieve a pointer to the current User. UserTy *operator*() const { - assert(!atEnd() && "Cannot dereference end iterator!"); + assert(U && "Cannot dereference end iterator!"); return U->getUser(); } @@ -238,11 +206,6 @@ public: unsigned getOperandNo() const; }; -Value *Use::get() const { - return fullStopTagN == extractTag(Next) - ? reinterpret_cast(stripTag(Next)) - : (Val1 == getValue() ? Val1 : 0); // should crash if not equal! -} template<> struct simplify_type > { typedef User* SimpleType; diff --git a/include/llvm/Value.h b/include/llvm/Value.h index b25f599d0f2..1d2c61ea199 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -138,7 +138,7 @@ public: typedef value_use_iterator use_iterator; typedef value_use_iterator use_const_iterator; - bool use_empty() const { return Use::isNil(UseList); } + bool use_empty() const { return UseList == 0; } use_iterator use_begin() { return use_iterator(UseList); } use_const_iterator use_begin() const { return use_const_iterator(UseList); } use_iterator use_end() { return use_iterator(0); } @@ -245,16 +245,14 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) { } void Use::init(Value *V, User *) { - Val1 = V; + Val = V; if (V) V->addUse(*this); - else Next = nilUse(0); } void Use::set(Value *V) { - if (Val1) removeFromList(); - Val1 = V; + if (Val) removeFromList(); + Val = V; if (V) V->addUse(*this); - else Next = nilUse(0); } diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp index 3cdf3474270..d96a0e57fd4 100644 --- a/lib/VMCore/Use.cpp +++ b/lib/VMCore/Use.cpp @@ -20,31 +20,8 @@ namespace llvm { //===----------------------------------------------------------------------===// void Use::swap(Use &RHS) { - ptrdiff_t dist((char*)&RHS - (char*)this); - - if (dist) { - Use *valid1(stripTag(Next)); - Use *valid2(stripTag(RHS.Next)); - if (valid1 && valid2) { - bool real1(fullStopTagN != extractTag(Next)); - bool real2(fullStopTagN != extractTag(RHS.Next)); - (char*&)*stripTag(Prev) += dist; - (char*&)*stripTag(RHS.Prev) -= dist; - if (real1) - (char*&)valid1->Next += dist; - if (real2) - (char*&)valid2->Next -= dist; - - } - - // swap the members - std::swap(Next, RHS.Next); - Use** Prev1 = transferTag(Prev, stripTag(RHS.Prev)); - RHS.Prev = transferTag(RHS.Prev, stripTag(Prev)); - Prev = Prev1; - } - /* Value *V1(Val1); - Value *V2(RHS.Val1); + Value *V1(Val); + Value *V2(RHS.Val); if (V1 != V2) { if (V1) { removeFromList(); @@ -52,20 +29,19 @@ void Use::swap(Use &RHS) { if (V2) { RHS.removeFromList(); - Val1 = V2; + Val = V2; V2->addUse(*this); } else { - Val1 = 0; + Val = 0; } if (V1) { - RHS.Val1 = V1; + RHS.Val = V1; V1->addUse(RHS); } else { - RHS.Val1 = 0; + RHS.Val = 0; } } - */ } //===----------------------------------------------------------------------===// @@ -76,7 +52,7 @@ const Use *Use::getImpliedUser() const { const Use *Current = this; while (true) { - unsigned Tag = extractTag((Current++)->Prev); + unsigned Tag = extractTag((Current++)->Prev); switch (Tag) { case zeroDigitTag: case oneDigitTag: @@ -86,7 +62,7 @@ const Use *Use::getImpliedUser() const { ++Current; ptrdiff_t Offset = 1; while (true) { - unsigned Tag = extractTag(Current->Prev); + unsigned Tag = extractTag(Current->Prev); switch (Tag) { case zeroDigitTag: case oneDigitTag: @@ -113,8 +89,7 @@ Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) { ptrdiff_t Count = Done; while (Start != Stop) { --Stop; - Stop->Val1 = 0; - Stop->Next = nilUse(0); + Stop->Val = 0; if (!Count) { Stop->Prev = reinterpret_cast(Done == 0 ? fullStopTag : stopTag); ++Done; diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index a5e0ff397e5..bc5b7a9f81c 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -34,7 +34,7 @@ static inline const Type *checkType(const Type *Ty) { Value::Value(const Type *ty, unsigned scid) : SubclassID(scid), SubclassData(0), VTy(checkType(ty)), - UseList(Use::nilUse(this)), Name(0) { + UseList(0), Name(0) { if (isa(this) || isa(this)) assert((VTy->isFirstClassType() || VTy == Type::VoidTy || isa(ty) || VTy->getTypeID() == Type::StructTyID) && @@ -298,7 +298,7 @@ void Value::takeName(Value *V) { // void Value::uncheckedReplaceAllUsesWith(Value *New) { while (!use_empty()) { - Use &U = *use_begin().U; + Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a // constant because they are uniqued. if (Constant *C = dyn_cast(U.getUser())) { diff --git a/lib/VMCore/getValue.cpp b/lib/VMCore/getValue.cpp deleted file mode 100644 index 2eae584402a..00000000000 --- a/lib/VMCore/getValue.cpp +++ /dev/null @@ -1,474 +0,0 @@ -//===-- Use.cpp - Implement the Use class ---------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the algorithm for finding the User of a Use. -// -//===----------------------------------------------------------------------===// - -#include "llvm/User.h" -// this can later be removed: -#include - -namespace llvm { - -class Use::UseWaymark { - - friend class Use; - -enum { spareBits = 2, requiredSteps = sizeof(Value*) * 8 - spareBits }; - -/// repaintByCopying -- given a pattern and a -/// junk tagspace, copy the former's tags into -/// the latter -/// -static inline void repaintByCopying(Use *Tagspace, Use *Junk) { - for (int I = requiredSteps; I; --I) { - Use *Next = stripTag(Junk->Next); - Junk->Next = transferTag(Tagspace->Next, Next); - Tagspace = stripTag(Tagspace->Next); - Junk = Next; - } - - assert((extractTag(Junk->Next) == Use::stopTagN) - && "Why repaint by copying if the next is not Stop?"); -} - - -/// repaintByCalculating -- given a pattern and a -/// junk tagspace, compute tags into the latter -/// -static inline void repaintByCalculating(unsigned long Tags, Use *Junk) { - Tags >>= spareBits; - - for (int I = requiredSteps - 1; I >= 0; --I) { - Use::NextPtrTag Tag(Tags & (1 << I) ? Use::oneDigitTagN : Use::zeroDigitTagN); - Use *Next = stripTag(Junk->Next); - Junk->Next = transferTag(reinterpret_cast(Tag), Next); - Junk = Next; - } - - assert((extractTag(Junk->Next) == Use::fullStopTagN) - && "Why repaint by calculating if the next is not FullStop?"); -} - -/// punchAwayDigits -- ensure that repainted area -/// begins with a stop -/// -static inline void punchAwayDigits(Use **Uprev) { - Uprev = stripTag(Uprev); - // if (PrevU) - // assert(&PrevU->Next == Uprev && "U->Prev differs from PrevU?"); - *Uprev = stripTag(*Uprev); -} - - -/// gatherAndPotentiallyRepaint is invoked for either -/// - sweeping over (a small amount of) initial junk -/// - or sweeping over a great amount of junk which -/// provides enough space to reproduce the bit pattern -/// of the Value* at its end, in which case it gets -/// overpainted. -/// In any case this routine is invoked with U being -/// pointed at from a Use with a stop tag. -/// -static inline Value *gatherAndPotentiallyRepaint(Use *U) { - int Cushion = requiredSteps; - - Use *Next(U->Next); - // __builtin_prefetch(Next); - Use::NextPtrTag Tag(extractTag(Next)); - Next = stripTag(Next); - - // try to pick up exactly requiredSteps digits - // from immediately behind the (precondition) stop - unsigned long Acc(0); - while (1) { - if (Cushion <= 0) { - assert((Tag == Use::fullStopTagN || Tag == Use::stopTagN) - && "More digits?"); - return reinterpret_cast(Acc << spareBits); - } - - switch (Tag) { - case Use::fullStopTagN: - return reinterpret_cast(Next); - case Use::stopTagN: { - goto efficiency; - } - default: - Acc = (Acc << 1) | (Tag & 1); - Next = Next->Next; - // __builtin_prefetch(Next); - --Cushion; - Tag = extractTag(Next); - Next = stripTag(Next); - continue; - } - break; - } - - while (Cushion > 0) { - switch (Tag) { - case Use::fullStopTagN: - return reinterpret_cast(Next); - case Use::stopTagN: { - efficiency: - // try to pick up exactly requiredSteps digits - int digits = requiredSteps; - Acc = 0; - - while (1) { - if (!digits) - return reinterpret_cast(Acc << spareBits); - - Next = Next->Next; - // __builtin_prefetch(Next); - --Cushion; - Tag = extractTag(Next); - Next = stripTag(Next); - switch (Tag) { - case Use::fullStopTagN: - if (Cushion <= 0) { - punchAwayDigits(U->Prev); - repaintByCalculating(reinterpret_cast(Next), U); - } - return reinterpret_cast(Next); - case Use::stopTagN: { - if (Cushion <= 0) { - U = stripTag(U->Next); - } - goto efficiency; - } - default: - --digits; - Acc = (Acc << 1) | (Tag & 1); - if (Cushion <= 0) { - U = stripTag(U->Next); - } - continue; - } - break; - } - } - // fall through - default: - Next = Next->Next; - // __builtin_prefetch(Next); - --Cushion; - Tag = extractTag(Next); - Next = stripTag(Next); - } // switch - } // while - - // Now we know that we have a nice cushion between U and Next. Do the same - // thing as above, but don't decrement Cushion any more, instead push U - // forward. After the value is found, repaint beginning at U. - - while (1) { - switch (Tag) { - case Use::fullStopTagN: { - punchAwayDigits(U->Prev); - repaintByCalculating(reinterpret_cast(Next), U); - return reinterpret_cast(Next); - } - case Use::stopTagN: { - // try to pick up exactly requiredSteps digits - int digits = requiredSteps; - Acc = 0; - Use *Tagspace(Next); - - while (1) { - if (!digits) { - punchAwayDigits(U->Prev); - repaintByCopying(Tagspace, U); - return reinterpret_cast(Acc << spareBits); - } - - Next = Next->Next; - // __builtin_prefetch(Next); - U = stripTag(U->Next); - Tag = extractTag(Next); - Next = stripTag(Next); - switch (Tag) { - case Use::fullStopTagN: { - punchAwayDigits(U->Prev); - repaintByCalculating(reinterpret_cast(Next), U); - return reinterpret_cast(Next); - } - case Use::stopTagN: { - break; - } - default: - --digits; - Acc = (Acc << 1) | (Tag & 1); - continue; - } - break; - } - } - // fall through - default: - Next = Next->Next; - // __builtin_prefetch(Next); - U = stripTag(U->Next); - Tag = extractTag(Next); - Next = stripTag(Next); - } // switch - } // while -} - - -/// skipPotentiallyGathering is invoked for either -/// - picking up exactly ToGo digits -/// - or finding a stop which marks the beginning -/// of a repaintable area -/// -static inline Value *skipPotentiallyGathering(Use *U, - unsigned long Acc, - int ToGo) { - while (1) { - if (!ToGo) - return reinterpret_cast(Acc << spareBits); - - Use *Next(U->Next); - // __builtin_prefetch(Next); - Use::NextPtrTag Tag(extractTag(Next)); - Next = stripTag(Next); - switch (Tag) { - case Use::fullStopTagN: - return reinterpret_cast(Next); - case Use::stopTagN: - return gatherAndPotentiallyRepaint(Next); - default: - Acc = (Acc << 1) | (Tag & 1); - --ToGo; - U = Next; - } - } -} - -}; // class UseWaymark - -Value *Use::getValue() const { - // __builtin_prefetch(Next); - NextPtrTag Tag(extractTag(Next)); - switch (Tag) { - case fullStopTagN: - return reinterpret_cast(stripTag(Next)); - case stopTagN: - return UseWaymark::gatherAndPotentiallyRepaint(Next); - default: - return UseWaymark::skipPotentiallyGathering(stripTag(Next), - Tag & 1, - Use::UseWaymark::requiredSteps - 1); - } -} - -static char TagChar(int Tag) { - return "s10S"[Tag]; -} - -void Use::showWaymarks() const { - const Use *me(this); - if (NextPtrTag Tag = extractTag(me)) { - me = stripTag(me); - std::cerr << '(' << TagChar(Tag) << ')'; - } - - me = me->Next; - NextPtrTag TagHere = extractTag(me); - std::cerr << TagChar(TagHere); - - me = stripTag(me); - if (TagHere == fullStopTagN) { - std::cerr << " ---> " << me << std::endl; - std::cerr << "1234567890123456789012345678901234567890123456789012345678901234567890" << std::endl; - std::cerr << " 1 2 3 4 5 6 7" << std::endl; - } - else - me->showWaymarks(); -} - -} // namespace llvm - -#if 0 - -// ################################################################ -// ############################# TESTS ############################ -// ################################################################ - -using namespace llvm; - -namespace T1 -{ - Use u00; -} - -namespace T2 -{ - Use u00((Value*)0xCAFEBABCUL); - Use u01(u00); -} - -namespace T3 -{ - template - struct UseChain; - - template <> - struct UseChain<0> { - Use first; - UseChain(Value *V) : first(V) {} - UseChain(Use &U) : first(U) {} - }; - - template - struct UseChain { - Use first; - UseChain rest; - UseChain(Value *V) - : first(rest.first) - , rest(V) {} - UseChain(Use &U) - : first(rest.first) - , rest(U) {} - }; - - UseChain<30> uc31((Value*)0xCAFEBABCUL); - Use& u31(uc31.first); - UseChain<31> uc32((Value*)0xCAFEBABCUL); - Use& u32(uc32.first); -} - -namespace T4 -{ - template - struct UseChain; - - template - struct UseChain<0, PAT> { - Use first; - static const unsigned long Pat = PAT >> 2; - UseChain(Value *V) : first(V) {} - UseChain(Use &U) : first(U) {} - }; - - template - struct UseChain { - Use first; - UseChain rest; - static const unsigned long Digit = UseChain::Pat & 1; - static const Use::NextPtrTag Tag = Digit ? Use::oneDigitTagN : Use::zeroDigitTagN; - static const unsigned long Pat = UseChain::Pat >> 1; - UseChain(Value *V = reinterpret_cast(PAT)) - : first(*addTag(&rest.first, Tag)) - , rest(V) {} - UseChain(Use &U) - : first(*addTag(&rest.first, Tag)) - , rest(U) {} - }; - - UseChain<30, 0xCAFEBABCUL> uc31; - Use& u31(uc31.first); - Use us32(u31); - - UseChain<29, 0xCAFEBABCUL> uc30; - Use& u30(uc30.first); - Use us31(u30); - - T3::UseChain<3> s3a((Value*)0xCAFEBABCUL); - UseChain<30, 0xCAFEBABCUL> uc31s3S(s3a.first); - Use& m35(uc31s3S.first); - - T3::UseChain<3> s3b((Value*)0xCAFEBABCUL); - UseChain<29, 0xCAFEBABCUL> uc30s3S(s3b.first); - Use& m34(uc30s3S.first); - - T3::UseChain<3> s3c((Value*)0xCAFEBABCUL); - UseChain<25, 0xCAFEBABCUL> uc25s3S(s3c.first); - Use& m30(uc25s3S.first); - - Use ms36(m35); - Use ms35(m34); - Use ms31(m30); - Use ms32(ms31); - - UseChain<24, 0xCAFEBABCUL> uc25; - Use& u25(uc25.first); - T3::UseChain<10> m11s24dS(u25); - Use& m36(m11s24dS.first); - - - T3::UseChain<10> s10S((Value*)0xCAFEBABCUL); - UseChain<20, 0xCAFEBABCUL> d20ss10S(s10S.first); - T3::UseChain<20> s20sd20ss10S(d20ss10S.first); - Use& m53(s20sd20ss10S.first); -} - - -int main(){ - if (NULL != T1::u00.getValue()) - return 1; - if ((Value*)0xCAFEBABCUL != T2::u00.getValue()) - return 2; - if ((Value*)0xCAFEBABCUL != T2::u01.getValue()) - return 2; - if ((Value*)0xCAFEBABCUL != T3::u31.getValue()) - return 3; - if ((Value*)0xCAFEBABCUL != T3::u32.getValue()) - return 3; - if ((Value*)0xCAFEBABCUL != T3::u32.getValue()) // check the mutated value - return 3; - if ((Value*)0xCAFEBABCUL != T4::u31.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::u30.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::us32.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::us31.getValue()) - return 4; - - // mixed tests - if ((Value*)0xCAFEBABCUL != T4::m35.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::m34.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::m30.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms36.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms35.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms35.getValue()) // check the mutated value - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms32.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms32.getValue()) - return 4; - if ((Value*)0xCAFEBABCUL != T4::ms32.getValue()) // check the mutated value - return 4; - - T4::m36.showWaymarks(); - if ((Value*)0xCAFEBABCUL != T4::m36.getValue()) - return 4; - T4::m36.showWaymarks(); - if ((Value*)0xCAFEBABCUL != T4::m36.getValue()) // check the mutated value - return 4; - T4::m36.showWaymarks(); - - T4::m53.showWaymarks(); - if ((Value*)0xCAFEBABCUL != T4::m53.getValue()) - return 4; - T4::m53.showWaymarks(); - if ((Value*)0xCAFEBABCUL != T4::m53.getValue()) // check the mutated value - return 4; - T4::m53.showWaymarks(); -} - -#endif