| // RUN: mlir-opt %s -wrap-emitc-func-in-class -split-input-file | FileCheck %s |
| // RUN: mlir-opt %s -wrap-emitc-func-in-class=func-name=execute -split-input-file | FileCheck %s --check-prefixes=EXECUTE |
| // RUN: mlir-opt %s -wrap-emitc-func-in-class=class-name-format=Custom_{} -split-input-file | FileCheck %s --check-prefixes=CLASS-NAME-FORMAT |
| |
| emitc.func @foo(%arg0 : !emitc.array<1xf32>) { |
| emitc.call_opaque "bar" (%arg0) : (!emitc.array<1xf32>) -> () |
| emitc.return |
| } |
| |
| // CHECK: emitc.class @fooClass { |
| // CHECK: emitc.field @fieldName0 : !emitc.array<1xf32> |
| // CHECK: emitc.func @"operator()"() { |
| // CHECK: %0 = get_field @fieldName0 : !emitc.array<1xf32> |
| // CHECK: call_opaque "bar"(%0) : (!emitc.array<1xf32>) -> () |
| // CHECK: return |
| // CHECK: } |
| // CHECK: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |
| |
| // ----- |
| |
| module attributes { } { |
| emitc.func @model(%arg0: !emitc.array<1xf32> {emitc.name_hint = "another_feature"}, |
| %arg1: !emitc.array<1xf32> {emitc.name_hint = "some_feature"}, |
| %arg2: !emitc.array<1xf32> {emitc.name_hint = "output_0"}) attributes { } { |
| %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t |
| %1 = subscript %arg1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| %2 = load %1 : <f32> |
| %3 = subscript %arg0[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| %4 = load %3 : <f32> |
| %5 = add %2, %4 : (f32, f32) -> f32 |
| %6 = subscript %arg2[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| assign %5 : f32 to %6 : <f32> |
| return |
| } |
| } |
| |
| // CHECK: emitc.class @modelClass { |
| // CHECK: emitc.field @fieldName0 : !emitc.array<1xf32> {emitc.name_hint = "another_feature"} |
| // CHECK: emitc.field @fieldName1 : !emitc.array<1xf32> {emitc.name_hint = "some_feature"} |
| // CHECK: emitc.field @fieldName2 : !emitc.array<1xf32> {emitc.name_hint = "output_0"} |
| // CHECK: emitc.func @"operator()"() { |
| // CHECK: get_field @fieldName0 : !emitc.array<1xf32> |
| // CHECK: get_field @fieldName1 : !emitc.array<1xf32> |
| // CHECK: get_field @fieldName2 : !emitc.array<1xf32> |
| // CHECK: "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t |
| // CHECK: subscript {{.*}}[{{.*}}] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| // CHECK: load {{.*}} : <f32> |
| // CHECK: subscript {{.*}}[{{.*}}] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| // CHECK: load {{.*}} : <f32> |
| // CHECK: add {{.*}}, {{.*}} : (f32, f32) -> f32 |
| // CHECK: subscript {{.*}}[{{.*}}] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32> |
| // CHECK: assign {{.*}} : f32 to {{.*}} : <f32> |
| // CHECK: return |
| // CHECK: } |
| // CHECK: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_model { |
| |
| // ----- |
| // Tests that GlobalOps are moved into the ClassOp wrapper correctly as fields |
| |
| module attributes { } { |
| emitc.global static const @global_arr : !emitc.array<1xi8> = dense<0> |
| emitc.func @foo() { |
| %0 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| emitc.return |
| } |
| } |
| |
| // CHECK: emitc.class @fooClass { |
| // CHECK: emitc.field @global_arr : !emitc.array<1xi8> = dense<0> |
| // CHECK: emitc.func @"operator()"() { |
| // CHECK: %0 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK: return |
| // CHECK: } |
| // CHECK: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |
| |
| // ----- |
| // Tests that only GlobalOps that are used within a function are moved into the |
| // ClassOp wrapper as fields |
| |
| module attributes { } { |
| emitc.global static const @global_arr : !emitc.array<1xi8> = dense<0> |
| emitc.global static const @global_arr2 : !emitc.array<1xi8> = dense<0> |
| emitc.func @foo() { |
| %0 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| emitc.return |
| } |
| } |
| |
| // CHECK: module { |
| // CHECK-NEXT: emitc.global static const @global_arr2 : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.class @fooClass { |
| // CHECK-NEXT: emitc.field @global_arr : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |
| |
| // ----- |
| // Tests that when multiple functions use different globals, only the used globals |
| // are moved into their respective ClassOp wrappers as fields. |
| |
| module attributes { } { |
| emitc.global static const @global_arr1 : !emitc.array<1xi8> = dense<0> |
| emitc.global static const @global_arr2 : !emitc.array<1xi8> = dense<0> |
| emitc.global static const @global_arr3 : !emitc.array<1xi8> = dense<0> |
| emitc.func @foo() { |
| %0 = emitc.get_global @global_arr1 : !emitc.array<1xi8> |
| emitc.return |
| } |
| emitc.func @bar() { |
| %0 = emitc.get_global @global_arr2 : !emitc.array<1xi8> |
| emitc.return |
| } |
| } |
| |
| // CHECK: module { |
| // CHECK-NEXT: emitc.global static const @global_arr3 : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.class @fooClass { |
| // CHECK-NEXT: emitc.field @global_arr1 : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr1 : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: emitc.class @barClass { |
| // CHECK-NEXT: emitc.field @global_arr2 : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr2 : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |
| // CLASS-NAME-FORMAT: emitc.class @Custom_bar { |
| |
| // ----- |
| // Tests that when multiple functions use the same global, the global is moved |
| // into each ClassOp wrapper as a field and erased from the module. |
| |
| module attributes { } { |
| emitc.global static const @global_arr : !emitc.array<1xi8> = dense<0> |
| emitc.func @foo() { |
| %0 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| emitc.return |
| } |
| emitc.func @bar() { |
| %0 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| emitc.return |
| } |
| } |
| |
| // CHECK: module { |
| // CHECK-NEXT: emitc.class @fooClass { |
| // CHECK-NEXT: emitc.field @global_arr : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: emitc.class @barClass { |
| // CHECK-NEXT: emitc.field @global_arr : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |
| // CLASS-NAME-FORMAT: emitc.class @Custom_bar { |
| |
| // ----- |
| // Tests that multiple uses of the same global in a function result in a single field. |
| |
| module attributes { } { |
| emitc.global static const @global_arr : !emitc.array<1xi8> = dense<0> |
| emitc.func @foo() { |
| %0 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| %1 = emitc.get_global @global_arr : !emitc.array<1xi8> |
| emitc.return |
| } |
| } |
| |
| // CHECK: module { |
| // CHECK-NEXT: emitc.class @fooClass { |
| // CHECK-NEXT: emitc.field @global_arr : !emitc.array<1xi8> = dense<0> |
| // CHECK-NEXT: emitc.func @"operator()"() { |
| // CHECK-NEXT: %0 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK-NEXT: %1 = get_field @global_arr : !emitc.array<1xi8> |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| // CHECK-NEXT: } |
| |
| // EXECUTE-NOT: operator |
| // EXECUTE: execute() |
| |
| // CLASS-NAME-FORMAT: emitc.class @Custom_foo { |