Skip to content

Commit 552f1a8

Browse files
[mlir][Transforms] Dialect conversion: Simplify handling of dropped arguments (#96207)
This commit simplifies the handling of dropped arguments and updates some dialect conversion documentation that is outdated. When converting a block signature, a `BlockTypeConversionRewrite` object and potentially multiple `ReplaceBlockArgRewrite` are created. During the "commit" phase, uses of the old block arguments are replaced with the new block arguments, but the old implementation was written in an inconsistent way: some block arguments were replaced in `BlockTypeConversionRewrite::commit` and some were replaced in `ReplaceBlockArgRewrite::commit`. The new `BlockTypeConversionRewrite::commit` implementation is much simpler and no longer modifies any IR; that is done only in `ReplaceBlockArgRewrite` now. The `ConvertedArgInfo` data structure is no longer needed. To that end, materializations of dropped arguments are now built in `applySignatureConversion` instead of `materializeLiveConversions`; the latter function no longer has to deal with dropped arguments. Other minor improvements: - Improve variable name: `origOutputType` -> `origArgType`. Add an assertion to check that this field is only used for argument materializations. - Add more comments to `applySignatureConversion`. Note: Error messages around failed materializations for dropped basic block arguments changed slightly. That is because those materializations are now built in `legalizeUnresolvedMaterialization` instead of `legalizeConvertedArgumentTypes`. This commit is in preparation of decoupling argument/source/target materializations from the dialect conversion.
1 parent 6699807 commit 552f1a8

File tree

4 files changed

+119
-156
lines changed

4 files changed

+119
-156
lines changed

mlir/docs/DialectConversion.md

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,13 @@ depending on the situation.
246246
247247
- An argument materialization is used when converting the type of a block
248248
argument during a [signature conversion](#region-signature-conversion).
249+
The new block argument types are specified in a `SignatureConversion`
250+
object. An original block argument can be converted into multiple
251+
block arguments, which is not supported everywhere in the dialect
252+
conversion. (E.g., adaptors support only a single replacement value for
253+
each original value.) Therefore, an argument materialization is used to
254+
convert potentially multiple new block arguments back into a single SSA
255+
value.
249256
250257
* Source Materialization
251258
@@ -259,6 +266,9 @@ depending on the situation.
259266
* When a block argument has been converted to a different type, but
260267
the original argument still has users that will remain live after
261268
the conversion process has finished.
269+
* When a block argument has been dropped, but the argument still has
270+
users that will remain live after the conversion process has
271+
finished.
262272
* When the result type of an operation has been converted to a
263273
different type, but the original result still has users that will
264274
remain live after the conversion process is finished.
@@ -328,36 +338,40 @@ class TypeConverter {
328338
registerConversion(wrapCallback<T>(std::forward<FnT>(callback)));
329339
}
330340
331-
/// Register a materialization function, which must be convertible to the
332-
/// following form:
333-
/// `Optional<Value> (OpBuilder &, T, ValueRange, Location)`,
334-
/// where `T` is any subclass of `Type`.
335-
/// This function is responsible for creating an operation, using the
336-
/// OpBuilder and Location provided, that "converts" a range of values into a
337-
/// single value of the given type `T`. It must return a Value of the
338-
/// converted type on success, an `std::nullopt` if it failed but other
339-
/// materialization can be attempted, and `nullptr` on unrecoverable failure.
340-
/// It will only be called for (sub)types of `T`.
341-
///
341+
/// All of the following materializations require function objects that are
342+
/// convertible to the following form:
343+
/// `std::optional<Value>(OpBuilder &, T, ValueRange, Location)`,
344+
/// where `T` is any subclass of `Type`. This function is responsible for
345+
/// creating an operation, using the OpBuilder and Location provided, that
346+
/// "casts" a range of values into a single value of the given type `T`. It
347+
/// must return a Value of the converted type on success, an `std::nullopt` if
348+
/// it failed but other materialization can be attempted, and `nullptr` on
349+
/// unrecoverable failure. It will only be called for (sub)types of `T`.
350+
/// Materialization functions must be provided when a type conversion may
351+
/// persist after the conversion has finished.
352+
342353
/// This method registers a materialization that will be called when
343-
/// converting an illegal block argument type, to a legal type.
354+
/// converting (potentially multiple) block arguments that were the result of
355+
/// a signature conversion of a single block argument, to a single SSA value
356+
/// of a legal type.
344357
template <typename FnT,
345358
typename T = typename llvm::function_traits<FnT>::template arg_t<1>>
346359
void addArgumentMaterialization(FnT &&callback) {
347360
argumentMaterializations.emplace_back(
348361
wrapMaterialization<T>(std::forward<FnT>(callback)));
349362
}
350363
/// This method registers a materialization that will be called when
351-
/// converting a legal type to an illegal source type. This is used when
352-
/// conversions to an illegal type must persist beyond the main conversion.
364+
/// converting a legal replacement value back to an illegal source type.
365+
/// This is used when some uses of the original, illegal value must persist
366+
/// beyond the main conversion.
353367
template <typename FnT,
354368
typename T = typename llvm::function_traits<FnT>::template arg_t<1>>
355369
void addSourceMaterialization(FnT &&callback) {
356370
sourceMaterializations.emplace_back(
357371
wrapMaterialization<T>(std::forward<FnT>(callback)));
358372
}
359373
/// This method registers a materialization that will be called when
360-
/// converting type from an illegal, or source, type to a legal type.
374+
/// converting an illegal (source) value to a legal (target) type.
361375
template <typename FnT,
362376
typename T = typename llvm::function_traits<FnT>::template arg_t<1>>
363377
void addTargetMaterialization(FnT &&callback) {

mlir/include/mlir/Transforms/DialectConversion.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ class TypeConverter {
168168
registerConversion(wrapCallback<T>(std::forward<FnT>(callback)));
169169
}
170170

171-
/// Register a materialization function, which must be convertible to the
172-
/// following form:
171+
/// All of the following materializations require function objects that are
172+
/// convertible to the following form:
173173
/// `std::optional<Value>(OpBuilder &, T, ValueRange, Location)`,
174174
/// where `T` is any subclass of `Type`. This function is responsible for
175175
/// creating an operation, using the OpBuilder and Location provided, that
@@ -179,26 +179,29 @@ class TypeConverter {
179179
/// unrecoverable failure. It will only be called for (sub)types of `T`.
180180
/// Materialization functions must be provided when a type conversion may
181181
/// persist after the conversion has finished.
182-
///
182+
183183
/// This method registers a materialization that will be called when
184-
/// converting an illegal block argument type, to a legal type.
184+
/// converting (potentially multiple) block arguments that were the result of
185+
/// a signature conversion of a single block argument, to a single SSA value
186+
/// of a legal type.
185187
template <typename FnT, typename T = typename llvm::function_traits<
186188
std::decay_t<FnT>>::template arg_t<1>>
187189
void addArgumentMaterialization(FnT &&callback) {
188190
argumentMaterializations.emplace_back(
189191
wrapMaterialization<T>(std::forward<FnT>(callback)));
190192
}
191193
/// This method registers a materialization that will be called when
192-
/// converting a legal type to an illegal source type. This is used when
193-
/// conversions to an illegal type must persist beyond the main conversion.
194+
/// converting a legal replacement value back to an illegal source type.
195+
/// This is used when some uses of the original, illegal value must persist
196+
/// beyond the main conversion.
194197
template <typename FnT, typename T = typename llvm::function_traits<
195198
std::decay_t<FnT>>::template arg_t<1>>
196199
void addSourceMaterialization(FnT &&callback) {
197200
sourceMaterializations.emplace_back(
198201
wrapMaterialization<T>(std::forward<FnT>(callback)));
199202
}
200203
/// This method registers a materialization that will be called when
201-
/// converting type from an illegal, or source, type to a legal type.
204+
/// converting an illegal (source) value to a legal (target) type.
202205
template <typename FnT, typename T = typename llvm::function_traits<
203206
std::decay_t<FnT>>::template arg_t<1>>
204207
void addTargetMaterialization(FnT &&callback) {

0 commit comments

Comments
 (0)