27
27
using namespace mlir ;
28
28
29
29
static void
30
- getForwardSliceImpl (Operation *op, SetVector<Operation *> *forwardSlice,
30
+ getForwardSliceImpl (Operation *op, DenseSet<Operation *> &visited,
31
+ SetVector<Operation *> *forwardSlice,
31
32
const SliceOptions::TransitiveFilter &filter = nullptr ) {
32
33
if (!op)
33
34
return ;
@@ -42,19 +43,23 @@ getForwardSliceImpl(Operation *op, SetVector<Operation *> *forwardSlice,
42
43
for (Block &block : region)
43
44
for (Operation &blockOp : block)
44
45
if (forwardSlice->count (&blockOp) == 0 )
45
- getForwardSliceImpl (&blockOp, forwardSlice, filter);
46
- for (Value result : op->getResults ()) {
47
- for (Operation *userOp : result.getUsers ())
48
- if (forwardSlice->count (userOp) == 0 )
49
- getForwardSliceImpl (userOp, forwardSlice, filter);
50
- }
46
+ getForwardSliceImpl (&blockOp, visited, forwardSlice, filter);
47
+
48
+ for (Value result : op->getResults ())
49
+ for (Operation *userOp : result.getUsers ()) {
50
+ if (forwardSlice->count (userOp) == 0 && visited.insert (userOp).second )
51
+ getForwardSliceImpl (userOp, visited, forwardSlice, filter);
52
+
53
+ visited.erase (userOp);
54
+ }
51
55
52
56
forwardSlice->insert (op);
53
57
}
54
58
55
59
void mlir::getForwardSlice (Operation *op, SetVector<Operation *> *forwardSlice,
56
60
const ForwardSliceOptions &options) {
57
- getForwardSliceImpl (op, forwardSlice, options.filter );
61
+ DenseSet<Operation *> visited;
62
+ getForwardSliceImpl (op, visited, forwardSlice, options.filter );
58
63
if (!options.inclusive ) {
59
64
// Don't insert the top level operation, we just queried on it and don't
60
65
// want it in the results.
@@ -70,8 +75,9 @@ void mlir::getForwardSlice(Operation *op, SetVector<Operation *> *forwardSlice,
70
75
71
76
void mlir::getForwardSlice (Value root, SetVector<Operation *> *forwardSlice,
72
77
const SliceOptions &options) {
78
+ DenseSet<Operation *> visited;
73
79
for (Operation *user : root.getUsers ())
74
- getForwardSliceImpl (user, forwardSlice, options.filter );
80
+ getForwardSliceImpl (user, visited, forwardSlice, options.filter );
75
81
76
82
// Reverse to get back the actual topological order.
77
83
// std::reverse does not work out of the box on SetVector and I want an
@@ -80,7 +86,7 @@ void mlir::getForwardSlice(Value root, SetVector<Operation *> *forwardSlice,
80
86
forwardSlice->insert (v.rbegin (), v.rend ());
81
87
}
82
88
83
- static void getBackwardSliceImpl (Operation *op,
89
+ static void getBackwardSliceImpl (Operation *op, DenseSet<Operation *> &visited,
84
90
SetVector<Operation *> *backwardSlice,
85
91
const BackwardSliceOptions &options) {
86
92
if (!op || op->hasTrait <OpTrait::IsIsolatedFromAbove>())
@@ -94,8 +100,11 @@ static void getBackwardSliceImpl(Operation *op,
94
100
95
101
auto processValue = [&](Value value) {
96
102
if (auto *definingOp = value.getDefiningOp ()) {
97
- if (backwardSlice->count (definingOp) == 0 )
98
- getBackwardSliceImpl (definingOp, backwardSlice, options);
103
+ if (backwardSlice->count (definingOp) == 0 &&
104
+ visited.insert (definingOp).second )
105
+ getBackwardSliceImpl (definingOp, visited, backwardSlice, options);
106
+
107
+ visited.erase (definingOp);
99
108
} else if (auto blockArg = dyn_cast<BlockArgument>(value)) {
100
109
if (options.omitBlockArguments )
101
110
return ;
@@ -108,7 +117,7 @@ static void getBackwardSliceImpl(Operation *op,
108
117
if (parentOp && backwardSlice->count (parentOp) == 0 ) {
109
118
assert (parentOp->getNumRegions () == 1 &&
110
119
llvm::hasSingleElement (parentOp->getRegion (0 ).getBlocks ()));
111
- getBackwardSliceImpl (parentOp, backwardSlice, options);
120
+ getBackwardSliceImpl (parentOp, visited, backwardSlice, options);
112
121
}
113
122
} else {
114
123
llvm_unreachable (" No definingOp and not a block argument." );
@@ -138,7 +147,8 @@ static void getBackwardSliceImpl(Operation *op,
138
147
void mlir::getBackwardSlice (Operation *op,
139
148
SetVector<Operation *> *backwardSlice,
140
149
const BackwardSliceOptions &options) {
141
- getBackwardSliceImpl (op, backwardSlice, options);
150
+ DenseSet<Operation *> visited;
151
+ getBackwardSliceImpl (op, visited, backwardSlice, options);
142
152
143
153
if (!options.inclusive ) {
144
154
// Don't insert the top level operation, we just queried on it and don't
0 commit comments