[mlir][CAPI] Include anchor op in mlirParsePassPipeline

The pipeline string must now include the pass manager's anchor op. This
makes the parse API properly roundtrip the printed form of a pass
manager. Since this is already an API break, I also added an extra
callback argument which is used for reporting errors.

The old functionality of appending to an existing pass manager is
available through `mlirOpPassManagerAddPipeline`.

Reviewed By: mehdi_amini, ftynse

Differential Revision: https://reviews.llvm.org/D136403
This commit is contained in:
rkayaith 2022-10-19 22:37:12 -04:00
parent d511a5d471
commit 215eba4e1e
3 changed files with 30 additions and 13 deletions

View File

@ -123,10 +123,12 @@ MLIR_CAPI_EXPORTED void mlirPrintPassPipeline(MlirOpPassManager passManager,
MlirStringCallback callback,
void *userData);
/// Parse a textual MLIR pass pipeline and add it to the provided OpPassManager.
/// Parse a textual MLIR pass pipeline and assign it to the provided
/// OpPassManager. If parsing fails an error message is reported using the
/// provided callback.
MLIR_CAPI_EXPORTED MlirLogicalResult
mlirParsePassPipeline(MlirOpPassManager passManager, MlirStringRef pipeline);
mlirParsePassPipeline(MlirOpPassManager passManager, MlirStringRef pipeline,
MlirStringCallback callback, void *userData);
//===----------------------------------------------------------------------===//
// External Pass API.

View File

@ -86,10 +86,14 @@ void mlirPrintPassPipeline(MlirOpPassManager passManager,
}
MlirLogicalResult mlirParsePassPipeline(MlirOpPassManager passManager,
MlirStringRef pipeline) {
// TODO: errors are sent to std::errs() at the moment, we should pass in a
// stream and redirect to a diagnostic.
return wrap(mlir::parsePassPipeline(unwrap(pipeline), *unwrap(passManager)));
MlirStringRef pipeline,
MlirStringCallback callback,
void *userData) {
detail::CallbackOstream stream(callback, userData);
FailureOr<OpPassManager> pm = parsePassPipeline(unwrap(pipeline), stream);
if (succeeded(pm))
*unwrap(passManager) = std::move(*pm);
return wrap(pm);
}
//===----------------------------------------------------------------------===//

View File

@ -182,7 +182,8 @@ void testParsePassPipeline() {
MlirLogicalResult status = mlirParsePassPipeline(
mlirPassManagerGetAsOpPassManager(pm),
mlirStringRefCreateFromCString(
"builtin.module(func.func(print-op-stats{json=false}))"));
"builtin.module(func.func(print-op-stats{json=false}))"),
printToStderr, NULL);
// Expect a failure, we haven't registered the print-op-stats pass yet.
if (mlirLogicalResultIsSuccess(status)) {
fprintf(
@ -195,7 +196,8 @@ void testParsePassPipeline() {
status = mlirParsePassPipeline(
mlirPassManagerGetAsOpPassManager(pm),
mlirStringRefCreateFromCString(
"builtin.module(func.func(print-op-stats{json=false}))"));
"builtin.module(func.func(print-op-stats{json=false}))"),
printToStderr, NULL);
// Expect a failure, we haven't registered the print-op-stats pass yet.
if (mlirLogicalResultIsFailure(status)) {
fprintf(stderr,
@ -203,9 +205,7 @@ void testParsePassPipeline() {
exit(EXIT_FAILURE);
}
// CHECK: Round-trip: builtin.module(
// CHECK-SAME: builtin.module(func.func(print-op-stats{json=false}))
// CHECK-SAME: )
// CHECK: Round-trip: builtin.module(func.func(print-op-stats{json=false}))
fprintf(stderr, "Round-trip: ");
mlirPrintPassPipeline(mlirPassManagerGetAsOpPassManager(pm), printToStderr,
NULL);
@ -221,7 +221,7 @@ void testParsePassPipeline() {
exit(EXIT_FAILURE);
}
// CHECK: Appended: builtin.module(
// CHECK-SAME: builtin.module(func.func(print-op-stats{json=false})),
// CHECK-SAME: func.func(print-op-stats{json=false}),
// CHECK-SAME: func.func(print-op-stats{json=false})
// CHECK-SAME: )
fprintf(stderr, "Appended: ");
@ -242,6 +242,14 @@ void testParseErrorCapture() {
MlirOpPassManager opm = mlirPassManagerGetAsOpPassManager(pm);
MlirStringRef invalidPipeline = mlirStringRefCreateFromCString("invalid");
// CHECK: mlirParsePassPipeline:
// CHECK: expected pass pipeline to be wrapped with the anchor operation type
fprintf(stderr, "mlirParsePassPipeline:\n");
if (mlirLogicalResultIsSuccess(
mlirParsePassPipeline(opm, invalidPipeline, printToStderr, NULL)))
exit(EXIT_FAILURE);
fprintf(stderr, "\n");
// CHECK: mlirOpPassManagerAddPipeline:
// CHECK: 'invalid' does not refer to a registered pass or pass pipeline
fprintf(stderr, "mlirOpPassManagerAddPipeline:\n");
@ -253,6 +261,9 @@ void testParseErrorCapture() {
// Make sure all output is going through the callback.
// CHECK: dontPrint: <>
fprintf(stderr, "dontPrint: <");
if (mlirLogicalResultIsSuccess(
mlirParsePassPipeline(opm, invalidPipeline, dontPrint, NULL)))
exit(EXIT_FAILURE);
if (mlirLogicalResultIsSuccess(
mlirOpPassManagerAddPipeline(opm, invalidPipeline, dontPrint, NULL)))
exit(EXIT_FAILURE);