@@ -60,33 +60,35 @@ static bool canBeHoisted(Operation *op,
60
60
op, [&](OpOperand &operand) { return definedOutside (operand.get ()); });
61
61
}
62
62
63
- // / Merges srcEffect's Memory Effect on its resource into the
63
+ // / Merges srcEffect's Memory Effect on its resource into the
64
64
// / resourceConflicts map, flagging the resource if the srcEffect
65
65
// / results in a conflict.
66
66
// /
67
67
// / \param resourceConflicts The map to store resources' conflicts status.
68
68
// / \param srcEffect The effect to merge into the resourceConflicts map.
69
- // / \param srcHasConflict Whether the srcEffect results in a conflict based
69
+ // / \param srcHasConflict Whether the srcEffect results in a conflict based
70
70
// / on higher level analysis.
71
71
// /
72
72
// / resourceConflicts is modified by the function and will be non-empty
73
- static void mergeResource (
74
- DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>> &resourceConflicts,
75
- const MemoryEffects::EffectInstance &srcEffect,
76
- bool srcHasConflict) {
73
+ static void
74
+ mergeResource (DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>>
75
+ &resourceConflicts,
76
+ const MemoryEffects::EffectInstance &srcEffect,
77
+ bool srcHasConflict) {
77
78
78
79
TypeID srcResourceID = srcEffect.getResource ()->getResourceID ();
79
80
80
- bool srcIsAllocOrFree = isa<MemoryEffects::Allocate>(srcEffect.getEffect ())
81
- || isa<MemoryEffects::Free>(srcEffect.getEffect ());
81
+ bool srcIsAllocOrFree = isa<MemoryEffects::Allocate>(srcEffect.getEffect ()) ||
82
+ isa<MemoryEffects::Free>(srcEffect.getEffect ());
82
83
83
84
bool conflict = srcHasConflict || srcIsAllocOrFree;
84
85
85
86
auto dstIt = resourceConflicts.find (srcResourceID);
86
87
87
88
// if it doesn't already exist, create entry for resource in map
88
89
if (dstIt == resourceConflicts.end ()) {
89
- resourceConflicts.insert (std::make_pair (srcResourceID, std::make_pair (conflict, srcEffect)));
90
+ resourceConflicts.insert (
91
+ std::make_pair (srcResourceID, std::make_pair (conflict, srcEffect)));
90
92
return ;
91
93
}
92
94
@@ -100,10 +102,10 @@ static void mergeResource(
100
102
bool srcWrite = isa<MemoryEffects::Write>(srcEffect.getEffect ());
101
103
bool dstRead = isa<MemoryEffects::Read>(dstEffect.getEffect ());
102
104
bool readBeforeWrite = dstRead && srcWrite;
103
-
105
+
104
106
conflict = conflict || readBeforeWrite;
105
107
106
- dstIt->second =std::make_pair (conflict, srcEffect);
108
+ dstIt->second = std::make_pair (conflict, srcEffect);
107
109
}
108
110
109
111
// / Returns true if any of op's OpOperands are defined outside of loopLike
@@ -120,22 +122,24 @@ static bool hasLoopVariantInput(LoopLikeOpInterface loopLike, Operation *op) {
120
122
// / flagged as having a conflict within the resourceConflicts map OR
121
123
// / (b) op doesn't have a MemoryEffectOpInterface or has one but
122
124
// / without any specific effects.
123
- static bool mayHaveMemoryEffectConflict (Operation *op,
124
- DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>> &resourceConflicts) {
125
+ static bool mayHaveMemoryEffectConflict (
126
+ Operation *op,
127
+ DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>>
128
+ &resourceConflicts) {
125
129
126
130
auto memInterface = dyn_cast<MemoryEffectOpInterface>(op);
127
-
131
+
128
132
// op does not implement the memory effect op interface
129
133
// shouldn't be flagged as movable to be conservative
130
- if (!memInterface)
134
+ if (!memInterface)
131
135
return true ;
132
136
133
137
// gather all effects on op
134
138
llvm::SmallVector<MemoryEffects::EffectInstance> effects;
135
139
memInterface.getEffects (effects);
136
140
137
141
// op has interface but no effects, be conservative
138
- if (effects.empty ())
142
+ if (effects.empty ())
139
143
return true ;
140
144
141
145
// RFC moving ops with HasRecursiveMemoryEffects that have nested ops
@@ -145,10 +149,10 @@ static bool mayHaveMemoryEffectConflict(Operation *op,
145
149
for (const MemoryEffects::EffectInstance &effect : effects) {
146
150
auto resourceID = effect.getResource ()->getResourceID ();
147
151
148
- auto resConIt = resourceConflicts.find (resourceID);
152
+ auto resConIt = resourceConflicts.find (resourceID);
149
153
if (resConIt == resourceConflicts.end ())
150
154
return true ; // RFC realistically shouldn't reach here but just in case?
151
-
155
+
152
156
bool hasConflict = resConIt->second .first ;
153
157
if (hasConflict)
154
158
return true ;
@@ -157,13 +161,15 @@ static bool mayHaveMemoryEffectConflict(Operation *op,
157
161
return false ;
158
162
}
159
163
160
- void mlir::gatherResourceConflicts (LoopLikeOpInterface loopLike, Operation *op,
161
- DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>> &resourceConflicts) {
164
+ void mlir::gatherResourceConflicts (
165
+ LoopLikeOpInterface loopLike, Operation *op,
166
+ DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>>
167
+ &resourceConflicts) {
162
168
163
169
if (auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
164
170
// gather all effects on op
165
171
SmallVector<MemoryEffects::EffectInstance> effects =
166
- MemoryEffects::getMemoryEffectsSorted (op);
172
+ MemoryEffects::getMemoryEffectsSorted (op);
167
173
168
174
if (!effects.empty ()) {
169
175
// any variant input to the op could be the data source
@@ -173,24 +179,24 @@ void mlir::gatherResourceConflicts(LoopLikeOpInterface loopLike, Operation *op,
173
179
for (const MemoryEffects::EffectInstance &effect : effects) {
174
180
bool conflict = false ;
175
181
bool isWrite = isa<MemoryEffects::Write>(effect.getEffect ());
176
-
182
+
177
183
// all writes to a resource that follow a read on any other resource
178
184
// have to be considered a conflict as guaranteeing that the read
179
185
// is invariant and won't affect the write requires more robust logic
180
186
if (isa<MemoryEffects::Read>(effect.getEffect ()))
181
187
writesConflict = true ;
182
188
183
189
if (isWrite && writesConflict)
184
- conflict = true ;
190
+ conflict = true ;
185
191
186
192
mergeResource (resourceConflicts, effect, conflict);
187
193
}
188
194
}
189
195
}
190
196
191
197
for (Region ®ion : op->getRegions ())
192
- for (Operation &opInner : region.getOps ())
193
- gatherResourceConflicts (loopLike, &opInner, resourceConflicts);
198
+ for (Operation &opInner : region.getOps ())
199
+ gatherResourceConflicts (loopLike, &opInner, resourceConflicts);
194
200
}
195
201
196
202
size_t mlir::moveLoopInvariantCode (
@@ -213,7 +219,8 @@ size_t mlir::moveLoopInvariantCode(
213
219
// continuous region --> need to add fork checking.
214
220
//
215
221
// loop "do" and "then" regions also merged.
216
- DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>> resourceConflicts;
222
+ DenseMap<TypeID, std::pair<bool , MemoryEffects::EffectInstance>>
223
+ resourceConflicts;
217
224
gatherResourceConflicts (loopLike, loopLike.getOperation (), resourceConflicts);
218
225
219
226
auto regions = loopLike.getLoopRegions ();
@@ -239,12 +246,12 @@ size_t mlir::moveLoopInvariantCode(
239
246
LDBG () << " Checking op: "
240
247
<< OpWithFlags (op, OpPrintingFlags ().skipRegions ());
241
248
242
- bool noMemoryConflicts = isMemoryEffectFree (op)
243
- || ! mayHaveMemoryEffectConflict (op, resourceConflicts);
244
-
245
- if (!noMemoryConflicts
246
- || !shouldMoveOutOfRegion (op, region)
247
- || !canBeHoisted (op, definedOutside))
249
+ bool noMemoryConflicts =
250
+ isMemoryEffectFree (op) ||
251
+ ! mayHaveMemoryEffectConflict (op, resourceConflicts);
252
+
253
+ if (!noMemoryConflicts || !shouldMoveOutOfRegion (op, region) ||
254
+ !canBeHoisted (op, definedOutside))
248
255
continue ;
249
256
250
257
LDBG () << " Moving loop-invariant op: " << *op;
@@ -268,9 +275,7 @@ size_t mlir::moveLoopInvariantCode(LoopLikeOpInterface loopLike) {
268
275
[&](Value value, Region *) {
269
276
return loopLike.isDefinedOutsideOfLoop (value);
270
277
},
271
- [&](Operation *op, Region *) {
272
- return isSpeculatable (op);
273
- },
278
+ [&](Operation *op, Region *) { return isSpeculatable (op); },
274
279
[&](Operation *op, Region *) { loopLike.moveOutOfLoop (op); });
275
280
}
276
281
0 commit comments