@@ -230,17 +230,17 @@ The `TypeConverter` contains several hooks for detailing how to convert types,
230
230
and how to materialize conversions between types in various situations. The two
231
231
main aspects of the `TypeConverter` are conversion and materialization.
232
232
233
- A `conversion` describes how a given illegal source `Type` should be converted
234
- to N target types. If the source type is already "legal", it should convert to
235
- itself . Type conversions are specified via the `addConversion` method described
233
+ A `conversion` describes how a given source `Type` should be converted to N
234
+ target types. If the source type is converted to itself, we say it is a "legal"
235
+ type . Type conversions are specified via the `addConversion` method described
236
236
below.
237
237
238
- A `materialization` describes how a set of values should be converted to a
239
- single value of a desired type . An important distinction with a `conversion` is
240
- that a `materialization` can produce IR, whereas a `conversion` cannot. These
241
- materializations are used by the conversion framework to ensure type safety
242
- during the conversion process. There are several types of materializations
243
- depending on the situation.
238
+ A `materialization` describes how a list of values should be converted to a
239
+ list of values with specific types . An important distinction from a
240
+ `conversion` is that a `materialization` can produce IR, whereas a `conversion`
241
+ cannot. These materializations are used by the conversion framework to ensure
242
+ type safety during the conversion process. There are several types of
243
+ materializations depending on the situation.
244
244
245
245
* Argument Materialization
246
246
@@ -252,16 +252,15 @@ depending on the situation.
252
252
conversion. (E.g., adaptors support only a single replacement value for
253
253
each original value.) Therefore, an argument materialization is used to
254
254
convert potentially multiple new block arguments back into a single SSA
255
- value.
255
+ value. An argument materialization is also used when replacing an op
256
+ result with multiple values.
256
257
257
258
* Source Materialization
258
259
259
- - A source materialization converts from a value with a "legal" target
260
- type, back to a specific source type. This is used when an operation is
261
- "legal" during the conversion process, but contains a use of an illegal
262
- type. This may happen during a conversion where some operations are
263
- converted to those with different resultant types, but still retain
264
- users of the original type system.
260
+ - A source materialization is used when a value was replaced with a value
261
+ of a different type, but there are still users that expects the original
262
+ ("source") type at the end of the conversion process. A source
263
+ materialization converts the replacement value back to the source type.
265
264
- This materialization is used in the following situations:
266
265
* When a block argument has been converted to a different type, but
267
266
the original argument still has users that will remain live after
@@ -275,16 +274,12 @@ depending on the situation.
275
274
276
275
* Target Materialization
277
276
278
- - A target materialization converts from a value with an "illegal" source
279
- type, to a value of a "legal" type. This is used when a pattern expects
280
- the remapped operands to be of a certain set of types, but the original
281
- input operands have not been converted. This may happen during a
282
- conversion where some operations are converted to those with different
283
- resultant types, but still retain uses of the original type system.
284
- - This materialization is used in the following situations:
285
- * When the remapped operands of a
286
- [conversion pattern](#conversion-patterns) are not legal for the
287
- type conversion provided by the pattern.
277
+ - A target materialization converts a value to the type that is expected
278
+ by a conversion pattern according to its type converter.
279
+ - A target materialization is used when a pattern expects the remapped
280
+ operands to be of a certain set of types, but the original input
281
+ operands have either not been replaced or been replaced with values of
282
+ a different type.
288
283
289
284
If a converted value is used by an operation that isn't converted, it needs a
290
285
conversion back to the `source` type, hence source materialization; if an
@@ -297,10 +292,8 @@ will not implicitly change during the conversion process. When the type of a
297
292
value definition, either block argument or operation result, is being changed,
298
293
the users of that definition must also be updated during the conversion process.
299
294
If they aren't, a type conversion must be materialized to ensure that a value of
300
- the expected type is still present within the IR. If a target materialization is
301
- required, but cannot be performed, the pattern application fails. If a source
302
- materialization is required, but cannot be performed, the entire conversion
303
- process fails.
295
+ the expected type is still present within the IR. If a materialization is
296
+ required, but cannot be performed, the entire conversion process fails.
304
297
305
298
Several of the available hooks are detailed below:
306
299
@@ -362,9 +355,9 @@ class TypeConverter {
362
355
}
363
356
364
357
/// This method registers a materialization that will be called when
365
- /// converting a legal replacement value back to an illegal source type.
366
- /// This is used when some uses of the original, illegal value must persist
367
- /// beyond the main conversion.
358
+ /// converting a replacement value back to its original source type.
359
+ /// This is used when some uses of the original value persist beyond the main
360
+ /// conversion.
368
361
template <typename FnT,
369
362
typename T = typename llvm::function_traits<FnT>::template arg_t<1>>
370
363
void addSourceMaterialization(FnT &&callback) {
@@ -373,7 +366,22 @@ class TypeConverter {
373
366
}
374
367
375
368
/// This method registers a materialization that will be called when
376
- /// converting an illegal (source) value to a legal (target) type.
369
+ /// converting a value to a target type according to a pattern's type
370
+ /// converter.
371
+ ///
372
+ /// Note: Target materializations can optionally inspect the "original"
373
+ /// type. This type may be different from the type of the input value.
374
+ /// For example, let's assume that a conversion pattern "P1" replaced an SSA
375
+ /// value "v1" (type "t1") with "v2" (type "t2"). Then a different conversion
376
+ /// pattern "P2" matches an op that has "v1" as an operand. Let's furthermore
377
+ /// assume that "P2" determines that the converted target type of "t1" is
378
+ /// "t3", which may be different from "t2". In this example, the target
379
+ /// materialization will be invoked with: outputType = "t3", inputs = "v2",
380
+ /// originalType = "t1". Note that the original type "t1" cannot be recovered
381
+ /// from just "t3" and "v2"; that's why the originalType parameter exists.
382
+ ///
383
+ /// Note: During a 1:N conversion, the result types can be a TypeRange. In
384
+ /// that case the materialization produces a SmallVector<Value>.
377
385
template <typename FnT,
378
386
typename T = typename llvm::function_traits<FnT>::template arg_t<1>>
379
387
void addTargetMaterialization(FnT &&callback) {
0 commit comments