Commit Graph

57 Commits

Author SHA1 Message Date
Alex Zinenko f5b99275d2 Cleanups in ExecutionEngine.
Make sure the module is always passed to the optimization layer.
Drop unused default argument for the IR transformation and remove the function
that was only used in this default argument.  The transformation wrapper
constructor already checks for the null function, so the caller can just pass
`{}` if they don't want any transformation (no callers currently need this).

PiperOrigin-RevId: 233068817
2019-03-29 16:22:08 -07:00
Alex Zinenko 8093f17a66 ExecutionEngine: provide a hook for LLVM IR passes
The current ExecutionEngine flow generates the LLVM IR from MLIR and
JIT-compiles it as is without any transformation.  It thus misses the
opportunity to perform optimizations supported by LLVM or collect statistics
about the module.  Modify the Orc JITter to perform transformations on the LLVM
IR.  Accept an optional LLVM module transformation function when constructing
the ExecutionEngine and use it while JIT-compiling.  This prevents MLIR
ExecutionEngine from depending on LLVM passes; its clients should depend on the
passes they require.

PiperOrigin-RevId: 232877060
2019-03-29 16:19:49 -07:00
River Riddle c46b0feadb Fix use of llvm::Module::getOrInsertFunction after the upstream opaque pointer type changes.
PiperOrigin-RevId: 232002583
2019-03-29 16:05:39 -07:00
Nicolas Vasilache cacf05892e Add a C API for EDSCs in other languages + python
This CL adds support for calling EDSCs from other languages than C++.
Following the LLVM convention this CL:
1. declares simple opaque types and a C API in mlir-c/Core.h;
2. defines the implementation directly in lib/EDSC/Types.cpp and
lib/EDSC/MLIREmitter.cpp.

Unlike LLVM however the nomenclature for these types and API functions is not
well-defined, naming suggestions are most welcome.

To avoid the need for conversion functions, Types.h and MLIREmitter.h include
mlir-c/Core.h and provide constructors and conversion operators between the
mlir::edsc type and the corresponding C type.

In this first commit, mlir-c/Core.h only contains the types for the C API
to allow EDSCs to work from Python. This includes both a minimal set of core
MLIR
types (mlir_context_t, mlir_type_t, mlir_func_t) as well as the EDSC types
(edsc_mlir_emitter_t, edsc_expr_t, edsc_stmt_t, edsc_indexed_t). This can be
restructured in the future as concrete needs arise.

For now, the API only supports:
1. scalar types;
2. memrefs of scalar types with static or symbolic shapes;
3. functions with input and output of these types.

The C API is not complete wrt ownership semantics. This is in large part due
to the fact that python bindings are written with Pybind11 which allows very
idiomatic C++ bindings. An effort is made to write a large chunk of these
bindings using the C API but some C++isms are used where the design benefits
from this simplication. A fully isolated C API will make more sense once we
also integrate with another language like Swift and have enough use cases to
drive the design.

Lastly, this CL also fixes a bug in mlir::ExecutionEngine were the order of
declaration of llvmContext and the JIT result in an improper order of
destructors (which used to crash before the fix).

PiperOrigin-RevId: 231290250
2019-03-29 15:41:53 -07:00
Nicolas Vasilache 629f5b7fcb Add a simple arity-agnostic invocation of JIT-compiled functions.
This is useful to call generic function with unspecified number of arguments
e.g. when interfacing with ML frameworks.

PiperOrigin-RevId: 230974736
2019-03-29 15:38:08 -07:00
Mehdi Amini d9ce382fc9 Use a unique_ptr instead of manual deletion for PIMPL idiom (NFC)
PiperOrigin-RevId: 230930254
2019-03-29 15:37:07 -07:00
Alex Zinenko 5a4403787f 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-03-29 15:36:08 -07:00