@@ -116,7 +116,10 @@ class Value {
116
116
117
117
private:
118
118
Type *VTy;
119
- Use *UseList;
119
+ union {
120
+ Use *List = nullptr ;
121
+ unsigned Count;
122
+ } Uses;
120
123
121
124
friend class ValueAsMetadata ; // Allow access to IsUsedByMD.
122
125
friend class ValueHandleBase ; // Allow access to HasValueHandle.
@@ -339,21 +342,28 @@ class Value {
339
342
#endif
340
343
}
341
344
345
+ // / Check if this Value has a use-list.
346
+ bool hasUseList () const { return !isa<ConstantData>(this ); }
347
+
342
348
bool use_empty () const {
343
349
assertModuleIsMaterialized ();
344
- return UseList == nullptr ;
350
+ return hasUseList () ? Uses. List == nullptr : Uses. Count == 0 ;
345
351
}
346
352
347
353
bool materialized_use_empty () const {
348
- return UseList == nullptr ;
354
+ return hasUseList () ? Uses. List == nullptr : !Uses. Count ;
349
355
}
350
356
351
357
using use_iterator = use_iterator_impl<Use>;
352
358
using const_use_iterator = use_iterator_impl<const Use>;
353
359
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
+ }
355
364
const_use_iterator materialized_use_begin () const {
356
- return const_use_iterator (UseList);
365
+ assert (hasUseList ());
366
+ return const_use_iterator (Uses.List );
357
367
}
358
368
use_iterator use_begin () {
359
369
assertModuleIsMaterialized ();
@@ -380,17 +390,18 @@ class Value {
380
390
return materialized_uses ();
381
391
}
382
392
383
- bool user_empty () const {
384
- assertModuleIsMaterialized ();
385
- return UseList == nullptr ;
386
- }
393
+ bool user_empty () const { return use_empty (); }
387
394
388
395
using user_iterator = user_iterator_impl<User>;
389
396
using const_user_iterator = user_iterator_impl<const User>;
390
397
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
+ }
392
402
const_user_iterator materialized_user_begin () const {
393
- return const_user_iterator (UseList);
403
+ assert (hasUseList ());
404
+ return const_user_iterator (Uses.List );
394
405
}
395
406
user_iterator user_begin () {
396
407
assertModuleIsMaterialized ();
@@ -429,7 +440,11 @@ class Value {
429
440
// /
430
441
// / This is specialized because it is a common request and does not require
431
442
// / 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
+ }
433
448
434
449
// / Return true if this Value has exactly N uses.
435
450
bool hasNUses (unsigned N) const ;
@@ -491,6 +506,8 @@ class Value {
491
506
static void dropDroppableUse (Use &U);
492
507
493
508
// / Check if this value is used in the specified basic block.
509
+ // /
510
+ // / Not supported for ConstantData.
494
511
bool isUsedInBasicBlock (const BasicBlock *BB) const ;
495
512
496
513
// / This method computes the number of uses of this Value.
@@ -500,7 +517,19 @@ class Value {
500
517
unsigned getNumUses () const ;
501
518
502
519
// / 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
+ }
504
533
505
534
// / Concrete subclass of this.
506
535
// /
@@ -841,7 +870,8 @@ class Value {
841
870
// /
842
871
// / \return the first element in the list.
843
872
// /
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).
845
875
template <class Compare >
846
876
static Use *mergeUseLists (Use *L, Use *R, Compare Cmp) {
847
877
Use *Merged;
@@ -887,10 +917,50 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
887
917
return OS;
888
918
}
889
919
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
+
890
958
void Use::set (Value *V) {
891
- if (Val) removeFromList ();
959
+ if (Val)
960
+ Val->removeUse (*this );
892
961
Val = V;
893
- if (V) V->addUse (*this );
962
+ if (V)
963
+ V->addUse (*this );
894
964
}
895
965
896
966
Value *Use::operator =(Value *RHS) {
@@ -904,7 +974,7 @@ const Use &Use::operator=(const Use &RHS) {
904
974
}
905
975
906
976
template <class Compare > void Value::sortUseList (Compare Cmp) {
907
- if (!UseList || !UseList ->Next )
977
+ if (!hasUseList () || !Uses. List || !Uses. List ->Next )
908
978
// No need to sort 0 or 1 uses.
909
979
return ;
910
980
@@ -917,10 +987,10 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
917
987
Use *Slots[MaxSlots];
918
988
919
989
// 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 ;
922
992
unsigned NumSlots = 1 ;
923
- Slots[0 ] = UseList ;
993
+ Slots[0 ] = Uses. List ;
924
994
925
995
// Collect all but the last use.
926
996
while (Next->Next ) {
@@ -956,15 +1026,15 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
956
1026
// Merge all the lists together.
957
1027
assert (Next && " Expected one more Use" );
958
1028
assert (!Next->Next && " Expected only one Use" );
959
- UseList = Next;
1029
+ Uses. List = Next;
960
1030
for (unsigned I = 0 ; I < NumSlots; ++I)
961
1031
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
963
1033
// 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);
965
1035
966
1036
// 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 ) {
968
1038
I->Prev = Prev;
969
1039
Prev = &I->Next ;
970
1040
}
0 commit comments