[mlir][emitc] Add a pointer type

Adds a pointer type to EmitC. The emission of pointers is so far only
possible by using the `emitc.opaque` type

Co-authored-by: Simon Camphausen <simon.camphausen@iml.fraunhofer.de>

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D119337
This commit is contained in:
Marius Brehler 2022-02-09 14:31:39 +00:00
parent 779bbbf27f
commit 88b9d1a49a
5 changed files with 80 additions and 3 deletions

View File

@ -35,7 +35,7 @@ def EmitC_OpaqueType : EmitC_Type<"Opaque", "opaque"> {
```mlir
!emitc.opaque<"int">
!emitc.opaque<"float *">
!emitc.opaque<"mytype">
!emitc.opaque<"std::vector<std::string>">
```
}];
@ -43,4 +43,31 @@ def EmitC_OpaqueType : EmitC_Type<"Opaque", "opaque"> {
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<i32>
// Pointer emitted as `float*`
!emitc.ptr<f32>
// Pointer emitted as `int*`
!emitc.ptr<!emitc.opaque<"int">>
```
}];
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

View File

@ -193,6 +193,10 @@ void emitc::OpaqueAttr::print(AsmPrinter &printer) const {
#define GET_TYPEDEF_CLASSES
#include "mlir/Dialect/EmitC/IR/EmitCTypes.cpp.inc"
//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//
Type emitc::OpaqueType::parse(AsmParser &parser) {
if (parser.parseLess())
return Type();

View File

@ -976,6 +976,12 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
os << oType.getValue();
return success();
}
if (auto pType = type.dyn_cast<emitc::PointerType>()) {
if (failed(emitType(loc, pType.getPointee())))
return failure();
os << "*";
return success();
}
return emitError(loc, "cannot emit type ") << type;
}

View File

@ -17,3 +17,23 @@ func @opaque_types() {
return
}
// CHECK-LABEL: func @pointer_types() {
func @pointer_types() {
// CHECK-NEXT: !emitc.ptr<i32>
emitc.call "f"() {template_args = [!emitc<"ptr<i32>">]} : () -> ()
// CHECK-NEXT: !emitc.ptr<i64>
emitc.call "f"() {template_args = [!emitc.ptr<i64>]} : () -> ()
// CHECK-NEXT: !emitc.ptr<f32>
emitc.call "f"() {template_args = [!emitc<"ptr<f32>">]} : () -> ()
// CHECK-NEXT: !emitc.ptr<f64>
emitc.call "f"() {template_args = [!emitc.ptr<f64>]} : () -> ()
// CHECK-NEXT: !emitc.ptr<i32>
%0 = emitc.call "f"() : () -> (!emitc.ptr<i32>)
// CHECK-NEXT: (!emitc.ptr<i32>) -> !emitc.ptr<!emitc.ptr<i32>>
%1 = emitc.call "f"(%0) : (!emitc.ptr<i32>) -> (!emitc.ptr<!emitc.ptr<i32>>)
// CHECK-NEXT: !emitc.ptr<!emitc.opaque<"int">>
emitc.call "f"() {template_args = [!emitc.ptr<!emitc.opaque<"int">>]} : () -> ()
return
}

View File

@ -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<int>();
emitc.call "f"() {template_args = [!emitc<"opaque<\"int\">">]} : () -> ()
// CHECK-NEXT: f<byte>();
@ -15,3 +15,23 @@ func @opaque_template_args() {
return
}
// CHECK-LABEL: void ptr_types() {
func @ptr_types() {
// CHECK-NEXT: f<int32_t*>();
emitc.call "f"() {template_args = [!emitc<"ptr<i32>">]} : () -> ()
// CHECK-NEXT: f<int64_t*>();
emitc.call "f"() {template_args = [!emitc.ptr<i64>]} : () -> ()
// CHECK-NEXT: f<float*>();
emitc.call "f"() {template_args = [!emitc<"ptr<f32>">]} : () -> ()
// CHECK-NEXT: f<double*>();
emitc.call "f"() {template_args = [!emitc.ptr<f64>]} : () -> ()
// CHECK-NEXT: int32_t* [[V0:[^ ]*]] = f();
%0 = emitc.call "f"() : () -> (!emitc.ptr<i32>)
// CHECK-NEXT: int32_t** [[V1:[^ ]*]] = f([[V0:[^ ]*]]);
%1 = emitc.call "f"(%0) : (!emitc.ptr<i32>) -> (!emitc.ptr<!emitc.ptr<i32>>)
// CHECK-NEXT: f<int*>();
emitc.call "f"() {template_args = [!emitc.ptr<!emitc.opaque<"int">>]} : () -> ()
return
}