diff --git a/mlir/lib/Transforms/DialectConversion.cpp b/mlir/lib/Transforms/DialectConversion.cpp --- a/mlir/lib/Transforms/DialectConversion.cpp +++ b/mlir/lib/Transforms/DialectConversion.cpp @@ -1509,9 +1509,9 @@ explicit OperationConverter(ConversionTarget &target, const OwningRewritePatternList &patterns, OpConversionMode mode, - DenseSet *legalizableOps = nullptr) + DenseSet *unlegalizableOps = nullptr) : opLegalizer(target, patterns), mode(mode), - legalizableOps(legalizableOps) {} + unlegalizableOps(unlegalizableOps) {} /// Converts the given operations to the conversion target. LogicalResult convertOperations(ArrayRef ops, @@ -1531,9 +1531,10 @@ /// The conversion mode to use when legalizing operations. OpConversionMode mode; - /// A set of pre-existing operations that were found to be legalizable to the - /// target. This field is only used when mode == OpConversionMode::Analysis. - DenseSet *legalizableOps; + /// A set of pre-existing operations that were found not to be legalizable to + /// the target. This field is only used when mode == + /// OpConversionMode::Analysis. + DenseSet *unlegalizableOps; }; } // end anonymous namespace @@ -1563,17 +1564,22 @@ << "failed to legalize operation '" << op->getName() << "'"; /// Partial conversions allow conversions to fail iff the operation was not /// explicitly marked as illegal. - if (mode == OpConversionMode::Partial && opLegalizer.isIllegal(op)) + if ((mode == OpConversionMode::Partial || + mode == OpConversionMode::Analysis) && + opLegalizer.isIllegal(op)) return op->emitError() << "failed to legalize operation '" << op->getName() << "' that was explicitly marked illegal"; + if (mode == OpConversionMode::Analysis) { + /// An analysis conversion emits any errors that would occur if a full + /// conversion were attempted, but should continue on without failure + /// (i.e. performing a partial conversion). + unlegalizableOps->insert(op); + op->emitWarning() << "failed to legalize operation '" << op->getName() + << "'"; + return success(); + } } else { - /// Analysis conversions don't fail if any operations fail to legalize, - /// they are only interested in the operations that were successfully - /// legalized. - if (mode == OpConversionMode::Analysis) - legalizableOps->insert(op); - // If legalization succeeded, convert the types any of the blocks within // this operation. if (failed(convertBlockSignatures(rewriter, op))) @@ -1605,12 +1611,10 @@ if (failed(convert(rewriter, op))) return rewriter.getImpl().discardRewrites(), failure(); - // Otherwise, the body conversion succeeded. Apply rewrites if this is not an - // analysis conversion. - if (mode == OpConversionMode::Analysis) - rewriter.getImpl().discardRewrites(); - else - rewriter.getImpl().applyRewrites(); + // Apply rewrites. + rewriter.getImpl().applyRewrites(); + + // Otherwise, the body conversion succeeded. return success(); } @@ -1936,24 +1940,25 @@ } /// Apply an analysis conversion on the given operations, and all nested -/// operations. This method analyzes which operations would be successfully -/// converted to the target if a conversion was applied. All operations that -/// were found to be legalizable to the given 'target' are placed within the -/// provided 'convertedOps' set; note that no actual rewrites are applied to the -/// operations on success and only pre-existing operations are added to the set. +/// operations. This method applies a partial conversion and analyzes on the way +/// which operations would fail to convert successfully if a full conversion +/// were attempted. +/// +/// All operations that are found not to be legalizable to the given 'target' +/// are placed within the provided 'unconvertedOps' set. LogicalResult mlir::applyAnalysisConversion( ArrayRef ops, ConversionTarget &target, const OwningRewritePatternList &patterns, - DenseSet &convertedOps, TypeConverter *converter) { + DenseSet &unconvertedOps, TypeConverter *converter) { OperationConverter opConverter(target, patterns, OpConversionMode::Analysis, - &convertedOps); + &unconvertedOps); return opConverter.convertOperations(ops, converter); } LogicalResult mlir::applyAnalysisConversion(Operation *op, ConversionTarget &target, const OwningRewritePatternList &patterns, - DenseSet &convertedOps, + DenseSet &unconvertedOps, TypeConverter *converter) { return applyAnalysisConversion(llvm::makeArrayRef(op), target, patterns, - convertedOps, converter); + unconvertedOps, converter); } diff --git a/mlir/test/Transforms/test-legalizer-analysis.mlir b/mlir/test/Transforms/test-legalizer-analysis.mlir --- a/mlir/test/Transforms/test-legalizer-analysis.mlir +++ b/mlir/test/Transforms/test-legalizer-analysis.mlir @@ -1,19 +1,17 @@ // RUN: mlir-opt -allow-unregistered-dialect -test-legalize-patterns -verify-diagnostics -test-legalize-mode=analysis %s | FileCheck %s -// expected-remark@-2 {{op 'module' is legalizable}} -// expected-remark@-3 {{op 'module_terminator' is legalizable}} - -// expected-remark@+1 {{op 'func' is legalizable}} func @test(%arg0: f32) { - // expected-remark@+1 {{op 'test.illegal_op_a' is legalizable}} %result = "test.illegal_op_a"() : () -> (i32) + // expected-warning@+2 {{failed to legalize operation 'foo.region'}} + // expected-remark@+1 {{op 'foo.region' is not legalizable}} "foo.region"() ({ - // expected-remark@+1 {{op 'test.invalid' is legalizable}} "test.invalid"() : () -> () }) : () -> () + // expected-warning@+2 {{failed to legalize operation 'std.return'}} + // expected-remark@+1 {{op 'std.return' is not legalizable}} return } -// Check that none of the legalizable operations were modified. +// Check that the legalizable operations were modified. // CHECK-LABEL: func @test -// CHECK-NEXT: "test.illegal_op_a" -// CHECK: "test.invalid" +// CHECK-NEXT: "test.legal_op_a" +// CHECK: "test.valid" diff --git a/mlir/test/lib/Dialect/Test/TestPatterns.cpp b/mlir/test/lib/Dialect/Test/TestPatterns.cpp --- a/mlir/test/lib/Dialect/Test/TestPatterns.cpp +++ b/mlir/test/lib/Dialect/Test/TestPatterns.cpp @@ -515,14 +515,14 @@ assert(mode == ConversionMode::Analysis); // Analyze the convertible operations. - DenseSet legalizedOps; + DenseSet unlegalizedOps; if (failed(applyAnalysisConversion(getOperation(), target, patterns, - legalizedOps, &converter))) + unlegalizedOps, &converter))) return signalPassFailure(); // Emit remarks for each legalizable operation. - for (auto *op : legalizedOps) - op->emitRemark() << "op '" << op->getName() << "' is legalizable"; + for (auto *op : unlegalizedOps) + op->emitRemark() << "op '" << op->getName() << "' is not legalizable"; } /// The mode of conversion to use.