diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td @@ -35,7 +35,7 @@ ```mlir !emitc.opaque<"int"> - !emitc.opaque<"float *"> + !emitc.opaque<"mytype"> !emitc.opaque<"std::vector"> ``` }]; @@ -43,4 +43,31 @@ let parameters = (ins StringRefParameter<"the opaque value">:$value); } +def EmitC_PointerType : EmitC_Type<"Pointer", "ptr"> { + let summary = "EmitC pointer type"; + + let description = [{ + A pointer data type. + + Example: + + ```mlir + // Pointer emitted as `int32_t*` + !emitc.ptr + // Pointer emitted as `float*` + !emitc.ptr + // Pointer emitted as `int*` + !emitc.ptr> + ``` + }]; + + let parameters = (ins "Type":$pointee); + let builders = [ + TypeBuilderWithInferredContext<(ins "Type":$pointee), [{ + return $_get(pointee.getContext(), pointee); + }]> + ]; + let assemblyFormat = "`<` qualified($pointee) `>`"; +} + #endif // MLIR_DIALECT_EMITC_IR_EMITCTYPES diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp --- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp +++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp @@ -193,6 +193,10 @@ #define GET_TYPEDEF_CLASSES #include "mlir/Dialect/EmitC/IR/EmitCTypes.cpp.inc" +//===----------------------------------------------------------------------===// +// OpaqueType +//===----------------------------------------------------------------------===// + Type emitc::OpaqueType::parse(AsmParser &parser) { if (parser.parseLess()) return Type(); diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp --- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp +++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp @@ -976,6 +976,12 @@ os << oType.getValue(); return success(); } + if (auto pType = type.dyn_cast()) { + if (failed(emitType(loc, pType.getPointee()))) + return failure(); + os << "*"; + return success(); + } return emitError(loc, "cannot emit type ") << type; } diff --git a/mlir/test/Dialect/EmitC/types.mlir b/mlir/test/Dialect/EmitC/types.mlir --- a/mlir/test/Dialect/EmitC/types.mlir +++ b/mlir/test/Dialect/EmitC/types.mlir @@ -17,3 +17,23 @@ return } + +// CHECK-LABEL: func @pointer_types() { +func @pointer_types() { + // CHECK-NEXT: !emitc.ptr + emitc.call "f"() {template_args = [!emitc<"ptr">]} : () -> () + // CHECK-NEXT: !emitc.ptr + emitc.call "f"() {template_args = [!emitc.ptr]} : () -> () + // CHECK-NEXT: !emitc.ptr + emitc.call "f"() {template_args = [!emitc<"ptr">]} : () -> () + // CHECK-NEXT: !emitc.ptr + emitc.call "f"() {template_args = [!emitc.ptr]} : () -> () + // CHECK-NEXT: !emitc.ptr + %0 = emitc.call "f"() : () -> (!emitc.ptr) + // CHECK-NEXT: (!emitc.ptr) -> !emitc.ptr> + %1 = emitc.call "f"(%0) : (!emitc.ptr) -> (!emitc.ptr>) + // CHECK-NEXT: !emitc.ptr> + emitc.call "f"() {template_args = [!emitc.ptr>]} : () -> () + + return +} diff --git a/mlir/test/Target/Cpp/types.mlir b/mlir/test/Target/Cpp/types.mlir --- a/mlir/test/Target/Cpp/types.mlir +++ b/mlir/test/Target/Cpp/types.mlir @@ -1,7 +1,7 @@ // RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s -// CHECK-LABEL: void opaque_template_args() { -func @opaque_template_args() { +// CHECK-LABEL: void opaque_types() { +func @opaque_types() { // CHECK-NEXT: f(); emitc.call "f"() {template_args = [!emitc<"opaque<\"int\">">]} : () -> () // CHECK-NEXT: f(); @@ -15,3 +15,23 @@ return } + +// CHECK-LABEL: void ptr_types() { +func @ptr_types() { + // CHECK-NEXT: f(); + emitc.call "f"() {template_args = [!emitc<"ptr">]} : () -> () + // CHECK-NEXT: f(); + emitc.call "f"() {template_args = [!emitc.ptr]} : () -> () + // CHECK-NEXT: f(); + emitc.call "f"() {template_args = [!emitc<"ptr">]} : () -> () + // CHECK-NEXT: f(); + emitc.call "f"() {template_args = [!emitc.ptr]} : () -> () + // CHECK-NEXT: int32_t* [[V0:[^ ]*]] = f(); + %0 = emitc.call "f"() : () -> (!emitc.ptr) + // CHECK-NEXT: int32_t** [[V1:[^ ]*]] = f([[V0:[^ ]*]]); + %1 = emitc.call "f"(%0) : (!emitc.ptr) -> (!emitc.ptr>) + // CHECK-NEXT: f(); + emitc.call "f"() {template_args = [!emitc.ptr>]} : () -> () + + return +}