[Mlir-commits] [mlir] 195728c - [mlir] Add structural conversion to async dialect lowering.
Christian Sigg
llvmlistbot at llvm.org
Mon Jan 11 11:37:03 PST 2021
Author: Christian Sigg
Date: 2021-01-11T20:36:49+01:00
New Revision: 195728c75aa41d80254175c5d7ac2f881333b139
URL: https://github.com/llvm/llvm-project/commit/195728c75aa41d80254175c5d7ac2f881333b139
DIFF: https://github.com/llvm/llvm-project/commit/195728c75aa41d80254175c5d7ac2f881333b139.diff
LOG: [mlir] Add structural conversion to async dialect lowering.
Lowering of async dialect uses a fixed type converter and therefore does not support lowering non-standard types.
This revision adds a structural conversion so that non-standard types in `!async.value`s can be lowered to LLVM before lowering the async dialect itself.
Reviewed By: ezhulenev
Differential Revision: https://reviews.llvm.org/D94404
Added:
Modified:
mlir/include/mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h
mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h b/mlir/include/mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h
index abb5d216028f..938c5cbbebce 100644
--- a/mlir/include/mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h
+++ b/mlir/include/mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h
@@ -13,13 +13,29 @@
namespace mlir {
+class ConversionTarget;
class ModuleOp;
template <typename T>
class OperationPass;
+class MLIRContext;
+class OwningRewritePatternList;
+class TypeConverter;
/// Create a pass to convert Async operations to the LLVM dialect.
std::unique_ptr<OperationPass<ModuleOp>> createConvertAsyncToLLVMPass();
+/// Populates patterns for async structural type conversions.
+///
+/// A "structural" type conversion is one where the underlying ops are
+/// completely agnostic to the actual types involved and simply need to update
+/// their types. An example of this is async.execute -- the async.execute op and
+/// the corresponding async.yield ops need to update their types accordingly to
+/// the TypeConverter, but otherwise don't care what type conversions are
+/// happening.
+void populateAsyncStructuralTypeConversionsAndLegality(
+ MLIRContext *context, TypeConverter &typeConverter,
+ OwningRewritePatternList &patterns, ConversionTarget &target);
+
} // namespace mlir
#endif // MLIR_CONVERSION_ASYNCTOLLVM_ASYNCTOLLVM_H
diff --git a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp
index 488432722959..587f49754446 100644
--- a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp
+++ b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp
@@ -1132,6 +1132,71 @@ void ConvertAsyncToLLVMPass::runOnOperation() {
}
} // namespace
+namespace {
+class ConvertExecuteOpTypes : public OpConversionPattern<ExecuteOp> {
+public:
+ using OpConversionPattern::OpConversionPattern;
+ LogicalResult
+ matchAndRewrite(ExecuteOp op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ ExecuteOp newOp =
+ cast<ExecuteOp>(rewriter.cloneWithoutRegions(*op.getOperation()));
+ rewriter.inlineRegionBefore(op.getRegion(), newOp.getRegion(),
+ newOp.getRegion().end());
+
+ // Set operands and update block argument and result types.
+ newOp->setOperands(operands);
+ if (failed(rewriter.convertRegionTypes(&newOp.getRegion(), *typeConverter)))
+ return failure();
+ for (auto result : newOp.getResults())
+ result.setType(typeConverter->convertType(result.getType()));
+
+ rewriter.replaceOp(op, newOp.getResults());
+ return success();
+ }
+};
+
+// Dummy pattern to trigger the appropriate type conversion / materialization.
+class ConvertAwaitOpTypes : public OpConversionPattern<AwaitOp> {
+public:
+ using OpConversionPattern::OpConversionPattern;
+ LogicalResult
+ matchAndRewrite(AwaitOp op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ rewriter.replaceOpWithNewOp<AwaitOp>(op, operands.front());
+ return success();
+ }
+};
+
+// Dummy pattern to trigger the appropriate type conversion / materialization.
+class ConvertYieldOpTypes : public OpConversionPattern<async::YieldOp> {
+public:
+ using OpConversionPattern::OpConversionPattern;
+ LogicalResult
+ matchAndRewrite(async::YieldOp op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ rewriter.replaceOpWithNewOp<async::YieldOp>(op, operands);
+ return success();
+ }
+};
+} // namespace
+
std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertAsyncToLLVMPass() {
return std::make_unique<ConvertAsyncToLLVMPass>();
}
+
+void mlir::populateAsyncStructuralTypeConversionsAndLegality(
+ MLIRContext *context, TypeConverter &typeConverter,
+ OwningRewritePatternList &patterns, ConversionTarget &target) {
+ typeConverter.addConversion([&](TokenType type) { return type; });
+ typeConverter.addConversion([&](ValueType type) {
+ return ValueType::get(typeConverter.convertType(type.getValueType()));
+ });
+
+ patterns
+ .insert<ConvertExecuteOpTypes, ConvertAwaitOpTypes, ConvertYieldOpTypes>(
+ typeConverter, context);
+
+ target.addDynamicallyLegalOp<AwaitOp, ExecuteOp, async::YieldOp>(
+ [&](Operation *op) { return typeConverter.isLegal(op); });
+}
More information about the Mlir-commits
mailing list