Lime Parser Generator 0.1.0
Runtime-extensible LALR(1) parser with SIMD tokenization and LLVM JIT
Loading...
Searching...
No Matches
jit_context.h
1/*
2** LLVM OrcJIT compilation context for the extensible SQL parser.
3**
4** Provides runtime compilation of parser hot paths (action table lookups)
5** using LLVM's OrcJIT (LLJIT) infrastructure. The JIT compiles a
6** monolithic parse function that processes entire token sequences with
7** fully-inlined state dispatch, eliminating per-token function call
8** overhead.
9**
10** OrcJIT replaces the deprecated MCJIT engine and provides:
11** - Thread-safe contexts for concurrent compilation
12** - Lazy compilation support (for future tiered compilation)
13** - Better resource management and error handling via LLVMErrorRef
14**
15** When LLVM is not available at compile time (LIME_NO_JIT is defined),
16** all JIT functions degrade to no-ops and the parser falls back to the
17** standard interpreted table-driven approach.
18*/
19#ifndef JIT_CONTEXT_H
20#define JIT_CONTEXT_H
21
22#include <stdint.h>
23#include <stdbool.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/* Forward declaration */
30typedef struct ParserSnapshot ParserSnapshot;
31
32/* ------------------------------------------------------------------ */
33/* JIT compilation status codes */
34/* ------------------------------------------------------------------ */
35
36typedef enum JITStatus {
37 JIT_OK = 0, /* Operation succeeded */
38 JIT_ERR_NO_LLVM, /* LLVM not available (compiled without) */
39 JIT_ERR_INIT_FAILED, /* LLVM initialization failed */
40 JIT_ERR_CODEGEN_FAILED, /* Code generation failed */
41 JIT_ERR_COMPILE_FAILED, /* JIT compilation failed */
42 JIT_ERR_LOOKUP_FAILED, /* Symbol lookup in JIT module failed */
43 JIT_ERR_INVALID_ARG, /* NULL or invalid argument */
44 JIT_ERR_ALREADY_COMPILED /* Snapshot already has JIT code */
45} JITStatus;
46
47/* ------------------------------------------------------------------ */
48/* JIT statistics */
49/* ------------------------------------------------------------------ */
50
54typedef struct JITStats {
55 uint32_t states_compiled;
56 uint32_t states_total;
57 uint64_t compile_time_ns;
58 uint64_t code_size_bytes;
59 bool available;
60} JITStats;
61
62/* ------------------------------------------------------------------ */
63/* Opaque JIT context handle */
64/* ------------------------------------------------------------------ */
65
66/*
67** The JITContext is an opaque handle that holds LLVM state (module,
68** execution engine, compiled function pointers). It is stored in
69** ParserSnapshot.jit_ctx and freed when the snapshot is destroyed.
70*/
71typedef struct JITContext JITContext;
72
73/*
74** Function pointer type for JIT-compiled shift action lookup.
75**
76** Given a lookahead token code, returns the action code (shift, reduce,
77** or error). Each compiled state has its own function with the action
78** table logic baked into the instruction stream.
79*/
80typedef uint16_t (*JITShiftActionFn)(uint16_t iLookAhead);
81
82/* ------------------------------------------------------------------ */
83/* Public API */
84/* ------------------------------------------------------------------ */
85
86/*
87** Create a new JIT context. Returns JIT_OK on success or an error
88** code if LLVM is unavailable or initialization fails.
89**
90** The context is heap-allocated and must be freed with jit_destroy().
91** On success *ctx_out is set to the new context; on failure it is NULL.
92*/
93JITStatus jit_create(JITContext **ctx_out);
94
95/*
96** Destroy a JIT context and free all associated LLVM resources.
97** Passing NULL is safe and does nothing.
98*/
99void jit_destroy(JITContext *ctx);
100
101/*
102** Compile JIT code for a parser snapshot's action tables.
103**
104** Generates optimized machine code for find_shift_action across all
105** parser states. On success the compiled function pointers are stored
106** inside the JITContext and can be queried with jit_get_shift_action().
107**
108** The snapshot must have valid action tables (yy_action, yy_lookahead,
109** yy_shift_ofst, yy_default arrays and nstate/action_count set).
110**
111** Returns JIT_OK on success, or an error code on failure. On failure
112** the context remains valid but contains no compiled code.
113*/
114JITStatus jit_compile_snapshot(JITContext *ctx, const ParserSnapshot *snap);
115
116/*
117** Look up the JIT-compiled shift action function for a given state.
118**
119** Returns the function pointer if state_id has been compiled, or NULL
120** if the state has no JIT code (caller should fall back to the
121** table-driven path).
122*/
123JITShiftActionFn jit_get_shift_action(const JITContext *ctx, uint32_t state_id);
124
125/*
126** Pre-warm the JIT for a set of hot parser states.
127**
128** Records which states are frequently visited so that future tiered
129** compilation can apply extra optimization to those states. Currently
130** the monolithic JIT function covers all states equally, so this is
131** a no-op beyond bookkeeping, but the API is provided for forward
132** compatibility.
133**
134** Parameters:
135** ctx - JIT context (must have compiled a snapshot)
136** hot_states - Array of state IDs to mark as hot
137** n - Number of entries in hot_states
138**
139** Returns JIT_OK on success, JIT_ERR_INVALID_ARG if ctx is NULL,
140** or JIT_ERR_NO_LLVM if compiled without LLVM.
141*/
142JITStatus jit_warmup(JITContext *ctx, const uint32_t *hot_states, uint32_t n);
143
144/*
145** Get JIT compilation statistics.
146*/
147JITStats jit_get_stats(const JITContext *ctx);
148
149/*
150** Return a human-readable string for a JIT status code.
151** The returned pointer is to static storage and must not be freed.
152*/
153const char *jit_status_string(JITStatus status);
154
155/*
156** Check whether JIT compilation is available at runtime.
157** Returns true if LLVM support was compiled in and initialization
158** succeeds, false otherwise.
159*/
160bool jit_is_available(void);
161
162/* ------------------------------------------------------------------ */
163/* Snapshot integration helpers */
164/* ------------------------------------------------------------------ */
165
166/*
167** Compile and attach JIT code to a snapshot.
168**
169** Convenience function that creates a JIT context, compiles code for
170** the snapshot's action tables, and stores the context in snap->jit_ctx.
171** If the snapshot already has a JIT context this is a no-op returning
172** JIT_ERR_ALREADY_COMPILED.
173**
174** Returns JIT_OK on success. On failure snap->jit_ctx is left unchanged.
175*/
176JITStatus jit_attach_to_snapshot(ParserSnapshot *snap);
177
178/*
179** Detach and destroy the JIT context from a snapshot.
180** This is called automatically by snapshot_release() when the refcount
181** reaches zero, but can also be called manually to free JIT resources
182** earlier.
183*/
184void jit_detach_from_snapshot(ParserSnapshot *snap);
185
186/*
187** Runtime dispatch: look up the shift action for a state+lookahead pair.
188**
189** If the snapshot has JIT code for the given state, uses the compiled
190** path. Otherwise falls back to the table-driven lookup using the
191** snapshot's action table arrays.
192**
193** This is the primary entry point for the parser runtime to query
194** shift actions when JIT is enabled.
195*/
196uint16_t jit_find_shift_action(const ParserSnapshot *snap,
197 uint16_t stateno,
198 uint16_t iLookAhead);
199
200/*
201** Batch parse a sequence of tokens using the JIT-compiled monolithic function.
202**
203** Processes all tokens in one call to avoid per-token function call overhead.
204** If JIT is available, calls the compiled jit_parse_sequence function.
205** Otherwise, falls back to calling jit_find_shift_action in a loop.
206**
207** Parameters:
208** snap - Parser snapshot (may or may not have JIT compiled)
209** tokens - Array of lookahead tokens to process
210** count - Number of tokens in the array
211** state_inout - Pointer to current parser state (updated after processing)
212*/
213void jit_parse_batch(const ParserSnapshot *snap,
214 uint16_t *tokens,
215 uint32_t count,
216 uint16_t *state_inout);
217
218#ifdef __cplusplus
219}
220#endif
221
222#endif /* JIT_CONTEXT_H */
JIT compilation statistics for a snapshot.
Definition jit_context.h:54
uint64_t code_size_bytes
Approximate generated code size in bytes.
Definition jit_context.h:58
bool available
True if JIT support is available at runtime.
Definition jit_context.h:59
uint64_t compile_time_ns
Wall-clock nanoseconds spent compiling.
Definition jit_context.h:57
uint32_t states_total
Total number of states in the snapshot.
Definition jit_context.h:56
uint32_t states_compiled
Number of states with JIT code attached.
Definition jit_context.h:55
Opaque snapshot handle.
Definition snapshot.h:117