22
22
#include < optional>
23
23
24
24
namespace mlir {
25
+ class WeakOpRef ;
26
+ class WeakOpRefHolder {
27
+ private:
28
+ mlir::Operation *op;
29
+
30
+ public:
31
+ WeakOpRefHolder (mlir::Operation *op) : op(op) {}
32
+ ~WeakOpRefHolder ();
33
+ friend class WeakOpRef ;
34
+ };
35
+
36
+ class WeakOpRef {
37
+ private:
38
+ std::shared_ptr<WeakOpRefHolder> holder;
39
+
40
+ public:
41
+ WeakOpRef (std::shared_ptr<WeakOpRefHolder> const &r);
42
+
43
+ WeakOpRef (WeakOpRef const &r);
44
+ WeakOpRef (WeakOpRef &&r);
45
+ ~WeakOpRef ();
46
+
47
+ WeakOpRef &operator =(WeakOpRef const &r);
48
+ WeakOpRef &operator =(WeakOpRef &&r);
49
+
50
+ void swap (WeakOpRef &r);
51
+ bool expired () const ;
52
+ long use_count () const { return holder ? holder.use_count () : 0 ; }
53
+
54
+ mlir::Operation *operator ->() const ;
55
+ mlir::Operation &operator *() const ;
56
+ };
57
+
25
58
namespace detail {
26
59
// / This is a "tag" used for mapping the properties storage in
27
60
// / llvm::TrailingObjects.
@@ -210,7 +243,7 @@ class alignas(8) Operation final
210
243
Operation *cloneWithoutRegions ();
211
244
212
245
// / Returns the operation block that contains this operation.
213
- Block *getBlock () { return block ; }
246
+ Block *getBlock () { return blockHasWeakRefPair. getPointer () ; }
214
247
215
248
// / Return the context this operation is associated with.
216
249
MLIRContext *getContext () { return location->getContext (); }
@@ -227,11 +260,15 @@ class alignas(8) Operation final
227
260
228
261
// / Returns the region to which the instruction belongs. Returns nullptr if
229
262
// / the instruction is unlinked.
230
- Region *getParentRegion () { return block ? block->getParent () : nullptr ; }
263
+ Region *getParentRegion () {
264
+ return getBlock () ? getBlock ()->getParent () : nullptr ;
265
+ }
231
266
232
267
// / Returns the closest surrounding operation that contains this operation
233
268
// / or nullptr if this is a top-level operation.
234
- Operation *getParentOp () { return block ? block->getParentOp () : nullptr ; }
269
+ Operation *getParentOp () {
270
+ return getBlock () ? getBlock ()->getParentOp () : nullptr ;
271
+ }
235
272
236
273
// / Return the closest surrounding parent operation that is of type 'OpTy'.
237
274
template <typename OpTy>
@@ -545,6 +582,7 @@ class alignas(8) Operation final
545
582
AttrClass getAttrOfType (StringAttr name) {
546
583
return llvm::dyn_cast_or_null<AttrClass>(getAttr (name));
547
584
}
585
+
548
586
template <typename AttrClass>
549
587
AttrClass getAttrOfType (StringRef name) {
550
588
return llvm::dyn_cast_or_null<AttrClass>(getAttr (name));
@@ -559,13 +597,15 @@ class alignas(8) Operation final
559
597
}
560
598
return attrs.contains (name);
561
599
}
600
+
562
601
bool hasAttr (StringRef name) {
563
602
if (getPropertiesStorageSize ()) {
564
603
if (std::optional<Attribute> inherentAttr = getInherentAttr (name))
565
604
return (bool )*inherentAttr;
566
605
}
567
606
return attrs.contains (name);
568
607
}
608
+
569
609
template <typename AttrClass, typename NameT>
570
610
bool hasAttrOfType (NameT &&name) {
571
611
return static_cast <bool >(
@@ -585,6 +625,7 @@ class alignas(8) Operation final
585
625
if (attributes.set (name, value) != value)
586
626
attrs = attributes.getDictionary (getContext ());
587
627
}
628
+
588
629
void setAttr (StringRef name, Attribute value) {
589
630
setAttr (StringAttr::get (getContext (), name), value);
590
631
}
@@ -605,6 +646,7 @@ class alignas(8) Operation final
605
646
attrs = attributes.getDictionary (getContext ());
606
647
return removedAttr;
607
648
}
649
+
608
650
Attribute removeAttr (StringRef name) {
609
651
return removeAttr (StringAttr::get (getContext (), name));
610
652
}
@@ -626,6 +668,7 @@ class alignas(8) Operation final
626
668
// Allow access to the constructor.
627
669
friend Operation;
628
670
};
671
+
629
672
using dialect_attr_range = iterator_range<dialect_attr_iterator>;
630
673
631
674
// / Return a range corresponding to the dialect attributes for this operation.
@@ -634,10 +677,12 @@ class alignas(8) Operation final
634
677
return {dialect_attr_iterator (attrs.begin (), attrs.end ()),
635
678
dialect_attr_iterator (attrs.end (), attrs.end ())};
636
679
}
680
+
637
681
dialect_attr_iterator dialect_attr_begin () {
638
682
auto attrs = getAttrs ();
639
683
return dialect_attr_iterator (attrs.begin (), attrs.end ());
640
684
}
685
+
641
686
dialect_attr_iterator dialect_attr_end () {
642
687
auto attrs = getAttrs ();
643
688
return dialect_attr_iterator (attrs.end (), attrs.end ());
@@ -705,6 +750,7 @@ class alignas(8) Operation final
705
750
assert (index < getNumSuccessors ());
706
751
return getBlockOperands ()[index ].get ();
707
752
}
753
+
708
754
void setSuccessor (Block *block, unsigned index);
709
755
710
756
// ===--------------------------------------------------------------------===//
@@ -892,12 +938,14 @@ class alignas(8) Operation final
892
938
int getPropertiesStorageSize () const {
893
939
return ((int )propertiesStorageSize) * 8 ;
894
940
}
941
+
895
942
// / Returns the properties storage.
896
943
OpaqueProperties getPropertiesStorage () {
897
944
if (propertiesStorageSize)
898
945
return getPropertiesStorageUnsafe ();
899
946
return {nullptr };
900
947
}
948
+
901
949
OpaqueProperties getPropertiesStorage () const {
902
950
if (propertiesStorageSize)
903
951
return {reinterpret_cast <void *>(const_cast <detail::OpProperties *>(
@@ -933,6 +981,11 @@ class alignas(8) Operation final
933
981
// / Compute a hash for the op properties (if any).
934
982
llvm::hash_code hashProperties ();
935
983
984
+ bool hasWeakReference () { return blockHasWeakRefPair.getInt (); }
985
+ void setHasWeakReference (bool hasWeakRef) {
986
+ blockHasWeakRefPair.setInt (hasWeakRef);
987
+ }
988
+
936
989
private:
937
990
// ===--------------------------------------------------------------------===//
938
991
// Ordering
@@ -1016,7 +1069,7 @@ class alignas(8) Operation final
1016
1069
// / requires a 'getParent() const' method. Once ilist_node removes this
1017
1070
// / constraint, we should drop the const to fit the rest of the MLIR const
1018
1071
// / model.
1019
- Block *getParent () const { return block ; }
1072
+ Block *getParent () const { return blockHasWeakRefPair. getPointer () ; }
1020
1073
1021
1074
// / Expose a few methods explicitly for the debugger to call for
1022
1075
// / visualization.
@@ -1031,8 +1084,9 @@ class alignas(8) Operation final
1031
1084
}
1032
1085
#endif
1033
1086
1034
- // / The operation block that contains this operation.
1035
- Block *block = nullptr ;
1087
+ // / The operation block that contains this operation and a bit that signifies
1088
+ // / if the operation has a weak reference.
1089
+ llvm::PointerIntPair<Block *, /* IntBits=*/ 1 , bool > blockHasWeakRefPair;
1036
1090
1037
1091
// / This holds information about the source location the operation was defined
1038
1092
// / or derived from.
0 commit comments