@@ -40,7 +40,8 @@ class SILInstruction;
40
40
class SILLocation ;
41
41
class DeadEndBlocks ;
42
42
class ValueBaseUseIterator ;
43
- class ValueUseIterator ;
43
+ class ConsumingUseIterator ;
44
+ class NonConsumingUseIterator ;
44
45
class SILValue ;
45
46
46
47
// / An enumeration which contains values for all the concrete ValueBase
@@ -263,10 +264,20 @@ class ValueBase : public SILNode, public SILAllocated<ValueBase> {
263
264
264
265
using use_iterator = ValueBaseUseIterator;
265
266
using use_range = iterator_range<use_iterator>;
267
+ using consuming_use_iterator = ConsumingUseIterator;
268
+ using consuming_use_range = iterator_range<consuming_use_iterator>;
269
+ using non_consuming_use_iterator = NonConsumingUseIterator;
270
+ using non_consuming_use_range = iterator_range<non_consuming_use_iterator>;
266
271
267
272
inline use_iterator use_begin () const ;
268
273
inline use_iterator use_end () const ;
269
274
275
+ inline consuming_use_iterator consuming_use_begin () const ;
276
+ inline consuming_use_iterator consuming_use_end () const ;
277
+
278
+ inline non_consuming_use_iterator non_consuming_use_begin () const ;
279
+ inline non_consuming_use_iterator non_consuming_use_end () const ;
280
+
270
281
// / Returns a range of all uses, which is useful for iterating over all uses.
271
282
// / To ignore debug-info instructions use swift::getNonDebugUses instead
272
283
// / (see comment in DebugUtils.h).
@@ -285,6 +296,12 @@ class ValueBase : public SILNode, public SILAllocated<ValueBase> {
285
296
// / and it has a single consuming user. Returns .none otherwise.
286
297
inline Operand *getSingleConsumingUse () const ;
287
298
299
+ // / Returns a range of all consuming uses
300
+ inline consuming_use_range getConsumingUses () const ;
301
+
302
+ // / Returns a range of all non consuming uses
303
+ inline non_consuming_use_range getNonConsumingUses () const ;
304
+
288
305
template <class T >
289
306
inline T *getSingleUserOfType () const ;
290
307
@@ -711,8 +728,10 @@ class Operand {
711
728
TheValue->FirstUse = this ;
712
729
}
713
730
731
+ friend class ValueBase ;
714
732
friend class ValueBaseUseIterator ;
715
- friend class ValueUseIterator ;
733
+ friend class ConsumingUseIterator ;
734
+ friend class NonConsumingUseIterator ;
716
735
template <unsigned N> friend class FixedOperandList ;
717
736
friend class TrailingOperandsList ;
718
737
};
@@ -729,6 +748,7 @@ using OperandValueArrayRef = ArrayRefView<Operand, SILValue, getSILValueType>;
729
748
// / An iterator over all uses of a ValueBase.
730
749
class ValueBaseUseIterator : public std ::iterator<std::forward_iterator_tag,
731
750
Operand*, ptrdiff_t > {
751
+ protected:
732
752
Operand *Cur;
733
753
public:
734
754
ValueBaseUseIterator () = default ;
@@ -770,6 +790,74 @@ inline ValueBase::use_iterator ValueBase::use_end() const {
770
790
inline iterator_range<ValueBase::use_iterator> ValueBase::getUses () const {
771
791
return { use_begin (), use_end () };
772
792
}
793
+
794
+ class ConsumingUseIterator : public ValueBaseUseIterator {
795
+ public:
796
+ explicit ConsumingUseIterator (Operand *cur) : ValueBaseUseIterator(cur) {}
797
+ ConsumingUseIterator &operator ++() {
798
+ assert (Cur && " incrementing past end()!" );
799
+ assert (Cur->isConsumingUse ());
800
+ while ((Cur = Cur->NextUse )) {
801
+ if (Cur->isConsumingUse ())
802
+ break ;
803
+ }
804
+ return *this ;
805
+ }
806
+
807
+ ConsumingUseIterator operator ++(int unused) {
808
+ ConsumingUseIterator copy = *this ;
809
+ ++*this ;
810
+ return copy;
811
+ }
812
+ };
813
+
814
+ inline ValueBase::consuming_use_iterator
815
+ ValueBase::consuming_use_begin () const {
816
+ auto cur = FirstUse;
817
+ while (cur && !cur->isConsumingUse ()) {
818
+ cur = cur->NextUse ;
819
+ }
820
+ return ValueBase::consuming_use_iterator (cur);
821
+ }
822
+
823
+ inline ValueBase::consuming_use_iterator ValueBase::consuming_use_end () const {
824
+ return ValueBase::consuming_use_iterator (nullptr );
825
+ }
826
+
827
+ class NonConsumingUseIterator : public ValueBaseUseIterator {
828
+ public:
829
+ explicit NonConsumingUseIterator (Operand *cur) : ValueBaseUseIterator(cur) {}
830
+ NonConsumingUseIterator &operator ++() {
831
+ assert (Cur && " incrementing past end()!" );
832
+ assert (!Cur->isConsumingUse ());
833
+ while ((Cur = Cur->NextUse )) {
834
+ if (!Cur->isConsumingUse ())
835
+ break ;
836
+ }
837
+ return *this ;
838
+ }
839
+
840
+ NonConsumingUseIterator operator ++(int unused) {
841
+ NonConsumingUseIterator copy = *this ;
842
+ ++*this ;
843
+ return copy;
844
+ }
845
+ };
846
+
847
+ inline ValueBase::non_consuming_use_iterator
848
+ ValueBase::non_consuming_use_begin () const {
849
+ auto cur = FirstUse;
850
+ while (cur && cur->isConsumingUse ()) {
851
+ cur = cur->NextUse ;
852
+ }
853
+ return ValueBase::non_consuming_use_iterator (cur);
854
+ }
855
+
856
+ inline ValueBase::non_consuming_use_iterator
857
+ ValueBase::non_consuming_use_end () const {
858
+ return ValueBase::non_consuming_use_iterator (nullptr );
859
+ }
860
+
773
861
inline bool ValueBase::hasOneUse () const {
774
862
auto I = use_begin (), E = use_end ();
775
863
if (I == E) return false ;
@@ -806,6 +894,15 @@ inline Operand *ValueBase::getSingleConsumingUse() const {
806
894
return result;
807
895
}
808
896
897
+ inline ValueBase::consuming_use_range ValueBase::getConsumingUses () const {
898
+ return {consuming_use_begin (), consuming_use_end ()};
899
+ }
900
+
901
+ inline ValueBase::non_consuming_use_range
902
+ ValueBase::getNonConsumingUses () const {
903
+ return {non_consuming_use_begin (), non_consuming_use_end ()};
904
+ }
905
+
809
906
inline bool ValueBase::hasTwoUses () const {
810
907
auto iter = use_begin (), end = use_end ();
811
908
for (unsigned i = 0 ; i < 2 ; ++i) {
0 commit comments