[Mlir-commits] [mlir] [mlir][Transforms] Dialect conversion: Simplify handling of dropped arguments (PR #96207)
Matthias Springer
llvmlistbot at llvm.org
Fri Jun 21 03:38:26 PDT 2024
================
@@ -1349,65 +1300,65 @@ Block *ConversionPatternRewriterImpl::applySignatureConversion(
// Replace all uses of the old block with the new block.
block->replaceAllUsesWith(newBlock);
- // Remap each of the original arguments as determined by the signature
- // conversion.
- SmallVector<std::optional<ConvertedArgInfo>, 1> argInfo;
- argInfo.resize(origArgCount);
-
for (unsigned i = 0; i != origArgCount; ++i) {
- auto inputMap = signatureConversion.getInputMapping(i);
- if (!inputMap)
- continue;
BlockArgument origArg = block->getArgument(i);
+ Type origArgType = origArg.getType();
- // If inputMap->replacementValue is not nullptr, then the argument is
- // dropped and a replacement value is provided to be the remappedValue.
- if (inputMap->replacementValue) {
- assert(inputMap->size == 0 &&
- "invalid to provide a replacement value when the argument isn't "
- "dropped");
- mapping.map(origArg, inputMap->replacementValue);
- appendRewrite<ReplaceBlockArgRewrite>(block, origArg);
- continue;
- }
-
- // Otherwise, this is a 1->1+ mapping.
- auto replArgs =
- newBlock->getArguments().slice(inputMap->inputNo, inputMap->size);
- Value newArg;
-
- // If this is a 1->1 mapping and the types of new and replacement arguments
- // match (i.e. it's an identity map), then the argument is mapped to its
- // original type.
+ // Helper function that tries to legalize the given type. Returns the given
+ // type if it could not be legalized.
// FIXME: We simply pass through the replacement argument if there wasn't a
// converter, which isn't great as it allows implicit type conversions to
// appear. We should properly restructure this code to handle cases where a
// converter isn't provided and also to properly handle the case where an
// argument materialization is actually a temporary source materialization
// (e.g. in the case of 1->N).
- if (replArgs.size() == 1 &&
- (!converter || replArgs[0].getType() == origArg.getType())) {
- newArg = replArgs.front();
- } else {
- Type origOutputType = origArg.getType();
+ auto tryLegalizeType = [&](Type type) {
+ if (converter)
+ if (Type t = converter->convertType(type))
+ return t;
+ return type;
+ };
- // Legalize the argument output type.
- Type outputType = origOutputType;
- if (Type legalOutputType = converter->convertType(outputType))
- outputType = legalOutputType;
+ std::optional<TypeConverter::SignatureConversion::InputMapping> inputMap =
+ signatureConversion.getInputMapping(i);
+ if (!inputMap) {
+ // This block argument was dropped and no replacement value was provided.
+ // Materialize a replacement value "out of thin air".
+ Value repl = buildUnresolvedMaterialization(
+ MaterializationKind::Source, newBlock, newBlock->begin(),
----------------
matthias-springer wrote:
I was also wondering about that. The previous implementation already used a source conversion here. In practice, either one would work in most cases. (I tried argument conversions here and only 1 test case failed; most tests use the same materialization function for source and argument conversions, but that could also be because most people probably do not know the difference.)
Given that we build a replacement value with the old bbarg type (which could be an illegal type), I think a source materialization is appropriate here. (It is somewhat unclear why we don't first legalize/convert the old bbarg type before calling the materialization function; the previous implementation already did it that way.)
https://github.com/llvm/llvm-project/pull/96207
More information about the Mlir-commits
mailing list