2019-09-28 00:44:54 +08:00
|
|
|
// RUN: mlir-cpu-runner %s | FileCheck %s
|
|
|
|
// RUN: mlir-cpu-runner %s -e foo | FileCheck -check-prefix=NOMAIN %s
|
2019-11-23 08:04:44 +08:00
|
|
|
// RUN: mlir-cpu-runner %s --entry-point-result=i32 -e int32_main | FileCheck -check-prefix=INT32MAIN %s
|
|
|
|
// RUN: mlir-cpu-runner %s --entry-point-result=i64 -e int64_main | FileCheck -check-prefix=INT64MAIN %s
|
2019-09-28 00:44:54 +08:00
|
|
|
// RUN: mlir-cpu-runner %s -O3 | FileCheck %s
|
Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT. The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly. Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.
For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation. In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes. This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.
Provide a binary for the runner and a test that exercises it.
PiperOrigin-RevId: 230876363
2019-01-25 19:16:06 +08:00
|
|
|
|
2019-09-28 00:44:54 +08:00
|
|
|
// RUN: cp %s %t
|
|
|
|
// RUN: mlir-cpu-runner %t -dump-object-file | FileCheck %t
|
|
|
|
// RUN: ls %t.o
|
|
|
|
// RUN: rm %t.o
|
2019-08-31 04:01:34 +08:00
|
|
|
|
2019-09-28 00:44:54 +08:00
|
|
|
// RUN: mlir-cpu-runner %s -dump-object-file -object-filename=%T/test.o | FileCheck %s
|
|
|
|
// RUN: ls %T/test.o
|
|
|
|
// RUN: rm %T/test.o
|
2019-08-31 04:01:34 +08:00
|
|
|
|
2019-09-26 20:41:26 +08:00
|
|
|
// Declarations of C library functions.
|
2019-10-10 16:33:33 +08:00
|
|
|
llvm.func @fabsf(!llvm.float) -> !llvm.float
|
2020-08-04 17:37:50 +08:00
|
|
|
llvm.func @malloc(!llvm.i64) -> !llvm.ptr<i8>
|
|
|
|
llvm.func @free(!llvm.ptr<i8>)
|
Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT. The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly. Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.
For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation. In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes. This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.
Provide a binary for the runner and a test that exercises it.
PiperOrigin-RevId: 230876363
2019-01-25 19:16:06 +08:00
|
|
|
|
2019-09-26 20:41:26 +08:00
|
|
|
// Check that a simple function with a nested call works.
|
2019-10-10 16:33:33 +08:00
|
|
|
llvm.func @main() -> !llvm.float {
|
2019-09-26 20:41:26 +08:00
|
|
|
%0 = llvm.mlir.constant(-4.200000e+02 : f32) : !llvm.float
|
|
|
|
%1 = llvm.call @fabsf(%0) : (!llvm.float) -> !llvm.float
|
|
|
|
llvm.return %1 : !llvm.float
|
Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT. The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly. Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.
For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation. In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes. This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.
Provide a binary for the runner and a test that exercises it.
PiperOrigin-RevId: 230876363
2019-01-25 19:16:06 +08:00
|
|
|
}
|
2019-09-26 20:41:26 +08:00
|
|
|
// CHECK: 4.200000e+02
|
Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT. The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly. Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.
For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation. In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes. This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.
Provide a binary for the runner and a test that exercises it.
PiperOrigin-RevId: 230876363
2019-01-25 19:16:06 +08:00
|
|
|
|
2019-09-26 20:41:26 +08:00
|
|
|
// Helper typed functions wrapping calls to "malloc" and "free".
|
2020-08-04 17:37:50 +08:00
|
|
|
llvm.func @allocation() -> !llvm.ptr<float> {
|
2019-09-26 20:41:26 +08:00
|
|
|
%0 = llvm.mlir.constant(4 : index) : !llvm.i64
|
2020-08-04 17:37:50 +08:00
|
|
|
%1 = llvm.call @malloc(%0) : (!llvm.i64) -> !llvm.ptr<i8>
|
|
|
|
%2 = llvm.bitcast %1 : !llvm.ptr<i8> to !llvm.ptr<float>
|
|
|
|
llvm.return %2 : !llvm.ptr<float>
|
2019-09-26 20:41:26 +08:00
|
|
|
}
|
2020-08-04 17:37:50 +08:00
|
|
|
llvm.func @deallocation(%arg0: !llvm.ptr<float>) {
|
|
|
|
%0 = llvm.bitcast %arg0 : !llvm.ptr<float> to !llvm.ptr<i8>
|
|
|
|
llvm.call @free(%0) : (!llvm.ptr<i8>) -> ()
|
2019-09-26 20:41:26 +08:00
|
|
|
llvm.return
|
Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT. The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly. Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.
For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation. In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes. This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.
Provide a binary for the runner and a test that exercises it.
PiperOrigin-RevId: 230876363
2019-01-25 19:16:06 +08:00
|
|
|
}
|
2019-09-02 02:32:52 +08:00
|
|
|
|
2019-09-26 20:41:26 +08:00
|
|
|
// Check that allocation and deallocation works, and that a custom entry point
|
|
|
|
// works.
|
2019-10-10 16:33:33 +08:00
|
|
|
llvm.func @foo() -> !llvm.float {
|
2020-08-04 17:37:50 +08:00
|
|
|
%0 = llvm.call @allocation() : () -> !llvm.ptr<float>
|
2019-09-26 20:41:26 +08:00
|
|
|
%1 = llvm.mlir.constant(0 : index) : !llvm.i64
|
|
|
|
%2 = llvm.mlir.constant(1.234000e+03 : f32) : !llvm.float
|
2020-08-04 17:37:50 +08:00
|
|
|
%3 = llvm.getelementptr %0[%1] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
|
|
|
llvm.store %2, %3 : !llvm.ptr<float>
|
|
|
|
%4 = llvm.getelementptr %0[%1] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
|
|
|
%5 = llvm.load %4 : !llvm.ptr<float>
|
|
|
|
llvm.call @deallocation(%0) : (!llvm.ptr<float>) -> ()
|
2019-09-26 20:41:26 +08:00
|
|
|
llvm.return %5 : !llvm.float
|
2019-09-02 02:32:52 +08:00
|
|
|
}
|
2019-09-26 20:41:26 +08:00
|
|
|
// NOMAIN: 1.234000e+03
|
2019-11-23 08:04:44 +08:00
|
|
|
|
|
|
|
// Check that i32 return type works
|
|
|
|
llvm.func @int32_main() -> !llvm.i32 {
|
|
|
|
%0 = llvm.mlir.constant(42 : i32) : !llvm.i32
|
|
|
|
llvm.return %0 : !llvm.i32
|
|
|
|
}
|
|
|
|
// INT32MAIN: 42
|
|
|
|
|
|
|
|
// Check that i64 return type works
|
|
|
|
llvm.func @int64_main() -> !llvm.i64 {
|
|
|
|
%0 = llvm.mlir.constant(42 : i64) : !llvm.i64
|
|
|
|
llvm.return %0 : !llvm.i64
|
|
|
|
}
|
|
|
|
// INT64MAIN: 42
|