@@ -116,7 +116,10 @@ class Value {
116116
117117private:
118118 Type *VTy;
119- Use *UseList;
119+ union {
120+ Use *List = nullptr ;
121+ unsigned Count;
122+ } Uses;
120123
121124 friend class ValueAsMetadata ; // Allow access to IsUsedByMD.
122125 friend class ValueHandleBase ; // Allow access to HasValueHandle.
@@ -339,21 +342,28 @@ class Value {
339342#endif
340343 }
341344
345+ // / Check if this Value has a use-list.
346+ bool hasUseList () const { return !isa<ConstantData>(this ); }
347+
342348 bool use_empty () const {
343349 assertModuleIsMaterialized ();
344- return UseList == nullptr ;
350+ return hasUseList () ? Uses. List == nullptr : Uses. Count == 0 ;
345351 }
346352
347353 bool materialized_use_empty () const {
348- return UseList == nullptr ;
354+ return hasUseList () ? Uses. List == nullptr : !Uses. Count ;
349355 }
350356
351357 using use_iterator = use_iterator_impl<Use>;
352358 using const_use_iterator = use_iterator_impl<const Use>;
353359
354- use_iterator materialized_use_begin () { return use_iterator (UseList); }
360+ use_iterator materialized_use_begin () {
361+ assert (hasUseList ());
362+ return use_iterator (Uses.List );
363+ }
355364 const_use_iterator materialized_use_begin () const {
356- return const_use_iterator (UseList);
365+ assert (hasUseList ());
366+ return const_use_iterator (Uses.List );
357367 }
358368 use_iterator use_begin () {
359369 assertModuleIsMaterialized ();
@@ -380,17 +390,18 @@ class Value {
380390 return materialized_uses ();
381391 }
382392
383- bool user_empty () const {
384- assertModuleIsMaterialized ();
385- return UseList == nullptr ;
386- }
393+ bool user_empty () const { return use_empty (); }
387394
388395 using user_iterator = user_iterator_impl<User>;
389396 using const_user_iterator = user_iterator_impl<const User>;
390397
391- user_iterator materialized_user_begin () { return user_iterator (UseList); }
398+ user_iterator materialized_user_begin () {
399+ assert (hasUseList ());
400+ return user_iterator (Uses.List );
401+ }
392402 const_user_iterator materialized_user_begin () const {
393- return const_user_iterator (UseList);
403+ assert (hasUseList ());
404+ return const_user_iterator (Uses.List );
394405 }
395406 user_iterator user_begin () {
396407 assertModuleIsMaterialized ();
@@ -429,7 +440,11 @@ class Value {
429440 // /
430441 // / This is specialized because it is a common request and does not require
431442 // / traversing the whole use list.
432- bool hasOneUse () const { return hasSingleElement (uses ()); }
443+ bool hasOneUse () const {
444+ if (!hasUseList ())
445+ return Uses.Count == 1 ;
446+ return hasSingleElement (uses ());
447+ }
433448
434449 // / Return true if this Value has exactly N uses.
435450 bool hasNUses (unsigned N) const ;
@@ -491,6 +506,8 @@ class Value {
491506 static void dropDroppableUse (Use &U);
492507
493508 // / Check if this value is used in the specified basic block.
509+ // /
510+ // / Not supported for ConstantData.
494511 bool isUsedInBasicBlock (const BasicBlock *BB) const ;
495512
496513 // / This method computes the number of uses of this Value.
@@ -500,7 +517,19 @@ class Value {
500517 unsigned getNumUses () const ;
501518
502519 // / This method should only be used by the Use class.
503- void addUse (Use &U) { U.addToList (&UseList); }
520+ void addUse (Use &U) {
521+ if (hasUseList ())
522+ U.addToList (Uses.List );
523+ else
524+ U.addToList (Uses.Count );
525+ }
526+
527+ void removeUse (Use &U) {
528+ if (hasUseList ())
529+ U.removeFromList (Uses.List );
530+ else
531+ U.removeFromList (Uses.Count );
532+ }
504533
505534 // / Concrete subclass of this.
506535 // /
@@ -841,7 +870,8 @@ class Value {
841870 // /
842871 // / \return the first element in the list.
843872 // /
844- // / \note Completely ignores \a Use::Prev (doesn't read, doesn't update).
873+ // / \note Completely ignores \a Use::PrevOrCount (doesn't read, doesn't
874+ // / update).
845875 template <class Compare >
846876 static Use *mergeUseLists (Use *L, Use *R, Compare Cmp) {
847877 Use *Merged;
@@ -887,10 +917,50 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
887917 return OS;
888918}
889919
920+ inline Use::~Use () {
921+ if (Val)
922+ Val->removeUse (*this );
923+ }
924+
925+ void Use::addToList (unsigned &Count) {
926+ assert (isa<ConstantData>(Val) && " Only ConstantData is ref-counted" );
927+ ++Count;
928+
929+ // We don't have a uselist - clear the remnant if we are replacing a
930+ // non-constant value.
931+ Prev = nullptr ;
932+ Next = nullptr ;
933+ }
934+
935+ void Use::addToList (Use *&List) {
936+ assert (!isa<ConstantData>(Val) && " ConstantData has no use-list" );
937+
938+ Next = List;
939+ if (Next)
940+ Next->Prev = &Next;
941+ Prev = &List;
942+ List = this ;
943+ }
944+
945+ void Use::removeFromList (unsigned &Count) {
946+ assert (isa<ConstantData>(Val));
947+ assert (Count > 0 && " reference count underflow" );
948+ assert (!Prev && !Next && " should not have uselist remnant" );
949+ --Count;
950+ }
951+
952+ void Use::removeFromList (Use *&List) {
953+ *Prev = Next;
954+ if (Next)
955+ Next->Prev = Prev;
956+ }
957+
890958void Use::set (Value *V) {
891- if (Val) removeFromList ();
959+ if (Val)
960+ Val->removeUse (*this );
892961 Val = V;
893- if (V) V->addUse (*this );
962+ if (V)
963+ V->addUse (*this );
894964}
895965
896966Value *Use::operator =(Value *RHS) {
@@ -904,7 +974,7 @@ const Use &Use::operator=(const Use &RHS) {
904974}
905975
906976template <class Compare > void Value::sortUseList (Compare Cmp) {
907- if (!UseList || !UseList ->Next )
977+ if (!hasUseList () || !Uses. List || !Uses. List ->Next )
908978 // No need to sort 0 or 1 uses.
909979 return ;
910980
@@ -917,10 +987,10 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
917987 Use *Slots[MaxSlots];
918988
919989 // Collect the first use, turning it into a single-item list.
920- Use *Next = UseList ->Next ;
921- UseList ->Next = nullptr ;
990+ Use *Next = Uses. List ->Next ;
991+ Uses. List ->Next = nullptr ;
922992 unsigned NumSlots = 1 ;
923- Slots[0 ] = UseList ;
993+ Slots[0 ] = Uses. List ;
924994
925995 // Collect all but the last use.
926996 while (Next->Next ) {
@@ -956,15 +1026,15 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
9561026 // Merge all the lists together.
9571027 assert (Next && " Expected one more Use" );
9581028 assert (!Next->Next && " Expected only one Use" );
959- UseList = Next;
1029+ Uses. List = Next;
9601030 for (unsigned I = 0 ; I < NumSlots; ++I)
9611031 if (Slots[I])
962- // Since the uses in Slots[I] originally preceded those in UseList , send
1032+ // Since the uses in Slots[I] originally preceded those in Uses.List , send
9631033 // Slots[I] in as the left parameter to maintain a stable sort.
964- UseList = mergeUseLists (Slots[I], UseList , Cmp);
1034+ Uses. List = mergeUseLists (Slots[I], Uses. List , Cmp);
9651035
9661036 // Fix the Prev pointers.
967- for (Use *I = UseList , **Prev = &UseList ; I; I = I->Next ) {
1037+ for (Use *I = Uses. List , **Prev = &Uses. List ; I; I = I->Next ) {
9681038 I->Prev = Prev;
9691039 Prev = &I->Next ;
9701040 }
0 commit comments