Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
jit.h File Reference

The JIT engine's C interface. More...

#include <stddef.h>
#include "serene/rt/errors.h"
Include dependency graph for jit.h:

Go to the source code of this file.

Data Structures

struct  srn_jit_config_t
 Tuning for a JIT engine, passed to srn_jit_create. More...

Typedefs

typedef struct srn_mm_t srn_mm_t
typedef struct srn_jit_t srn_jit_t
 An opaque handle to a live JIT engine, owning the underlying llvm orc session.
typedef struct srn_object_cache_t srn_object_cache_t
 An opaque handle to our object cache that utilizes llvm's ObjectCache.
typedef struct srn_jit_module_t srn_jit_module_t
 An opaque handle to one unit of code added to the JIT.
typedef struct srn_jit_config_t srn_jit_config_t
 Tuning for a JIT engine, passed to srn_jit_create.

Functions

srn_jit_tsrn_jit_create (srn_mm_t *mm, const srn_jit_config_t *config)
 Create a JIT engine backed by a fresh ORC session, allocating from mm.
void srn_jit_destroy (srn_jit_t *jit)
 Destroy jit, tearing down its ORC session and releasing every module it still holds.
const char * srn_jit_data_layout (srn_jit_t *jit)
 The target data-layout string the JIT compiles against.
const char * srn_jit_triple (srn_jit_t *jit)
 The target triple the JIT compiles for.
srn_error_tsrn_jit_add_ir (srn_jit_t *jit, srn_context_t *ctx, const char *ir, size_t len, srn_jit_module_t **out)
 Parse the textual LLVM IR in ir (of length len) and add it to jit for compilation.
srn_error_tsrn_jit_add_bitcode (srn_jit_t *jit, srn_context_t *ctx, const void *buf, size_t len, srn_jit_module_t **out)
 Add the LLVM bitcode in buf (of length len) to jit for compilation.
srn_error_tsrn_jit_define (srn_jit_t *jit, srn_context_t *ctx, const char *name, void *addr)
 Define the absolute symbol name in the JIT as resolving to addr, so generated code can call a runtime function or reach a piece of runtime data by that name.
srn_error_tsrn_jit_expose_process_symbols (srn_jit_t *jit, srn_context_t *ctx)
 Make the symbols already linked into the running process resolvable from generated code, so runtime functions need not be registered one at a time.
srn_error_tsrn_jit_lookup (srn_jit_t *jit, srn_context_t *ctx, const char *name, void **out_addr)
 Look up the compiled symbol name, forcing its module to compile if it has not already, and write its address to *out_addr.
srn_error_tsrn_jit_remove (srn_jit_t *jit, srn_context_t *ctx, srn_jit_module_t *module)
 Unload module from jit, removing the symbols it defined and freeing the code it compiled.

Detailed Description

The JIT engine's C interface.

The implementation is a C++ translation unit built on LLVM's ORCv2 API. That C++ and every LLVM type it touches stay behind this header, the rest of the runtime, and any program embedding the runtime, see only the opaque handles and the free functions declared here. We intentionally didn't use the C api of ORC as it lags behind usually and the documentation of the C++ is way better.

Code enters the JIT as a buffer of LLVM IR rather than through an IR-building interface, so producers hand over bytes and never link against LLVM. A producer stamps its module with the target data layout and triple reported by srn_jit_data_layout and srn_jit_triple, a module whose layout disagrees with the JIT is rejected.

The compile and run cycle is: create a JIT, register the runtime symbols that generated code calls (srn_jit_define), add one or more IR modules (srn_jit_add_ir), then look a compiled symbol up by name (srn_jit_lookup) and call it through the address returned. Adding and looking up are safe to drive from more than one thread.

Definition in file jit.h.

Typedef Documentation

◆ srn_jit_config_t

typedef struct srn_jit_config_t srn_jit_config_t

Tuning for a JIT engine, passed to srn_jit_create.

A null config selects the defaults (optimisation level 2, default pipeline installed).

◆ srn_jit_module_t

An opaque handle to one unit of code added to the JIT.

Returned by the add functions and passed back to srn_jit_remove to unload that unit. A module handle stays valid until it is removed or the owning JIT is destroyed.

Definition at line 68 of file jit.h.

◆ srn_jit_t

typedef struct srn_jit_t srn_jit_t

An opaque handle to a live JIT engine, owning the underlying llvm orc session.

Definition at line 56 of file jit.h.

◆ srn_mm_t

typedef struct srn_mm_t srn_mm_t

Definition at line 51 of file jit.h.

◆ srn_object_cache_t

An opaque handle to our object cache that utilizes llvm's ObjectCache.

Definition at line 61 of file jit.h.

Function Documentation

◆ srn_jit_add_bitcode()

srn_error_t * srn_jit_add_bitcode ( srn_jit_t * jit,
srn_context_t * ctx,
const void * buf,
size_t len,
srn_jit_module_t ** out )

Add the LLVM bitcode in buf (of length len) to jit for compilation.

Behaves like srn_jit_add_ir but reads the binary bitcode encoding rather than text.

◆ srn_jit_add_ir()

srn_error_t * srn_jit_add_ir ( srn_jit_t * jit,
srn_context_t * ctx,
const char * ir,
size_t len,
srn_jit_module_t ** out )

Parse the textual LLVM IR in ir (of length len) and add it to jit for compilation.

On success returns null; when out is non-null it receives a handle to the added module. On failure returns an error allocated in ctx and leaves out untouched.

◆ srn_jit_create()

srn_jit_t * srn_jit_create ( srn_mm_t * mm,
const srn_jit_config_t * config )

Create a JIT engine backed by a fresh ORC session, allocating from mm.

config may be null to take the defaults. Returns null when the native target cannot be initialised or the engine cannot be built.

◆ srn_jit_data_layout()

const char * srn_jit_data_layout ( srn_jit_t * jit)

The target data-layout string the JIT compiles against.

A producer must stamp every module it adds with this layout. The string is owned by jit and stays valid until the engine is destroyed.

◆ srn_jit_define()

srn_error_t * srn_jit_define ( srn_jit_t * jit,
srn_context_t * ctx,
const char * name,
void * addr )

Define the absolute symbol name in the JIT as resolving to addr, so generated code can call a runtime function or reach a piece of runtime data by that name.

Returns null on success, or an error allocated in ctx when the symbol already exists.

◆ srn_jit_destroy()

void srn_jit_destroy ( srn_jit_t * jit)

Destroy jit, tearing down its ORC session and releasing every module it still holds.

A null jit is a no-op.

◆ srn_jit_expose_process_symbols()

srn_error_t * srn_jit_expose_process_symbols ( srn_jit_t * jit,
srn_context_t * ctx )

Make the symbols already linked into the running process resolvable from generated code, so runtime functions need not be registered one at a time.

Returns null on success or an error allocated in ctx.

◆ srn_jit_lookup()

srn_error_t * srn_jit_lookup ( srn_jit_t * jit,
srn_context_t * ctx,
const char * name,
void ** out_addr )

Look up the compiled symbol name, forcing its module to compile if it has not already, and write its address to *out_addr.

The caller casts that address to the matching function or data pointer. Returns null on success, or an error allocated in ctx when the symbol is absent.

◆ srn_jit_remove()

srn_error_t * srn_jit_remove ( srn_jit_t * jit,
srn_context_t * ctx,
srn_jit_module_t * module )

Unload module from jit, removing the symbols it defined and freeing the code it compiled.

Returns null on success or an error allocated in ctx.

◆ srn_jit_triple()

const char * srn_jit_triple ( srn_jit_t * jit)

The target triple the JIT compiles for.

Owned by jit and valid until the engine is destroyed.