Skip to content

Commit

Permalink
Add early return and recursive tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
ltratt committed Dec 1, 2024
1 parent 4ce6fe0 commit bd40930
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 48 deletions.
63 changes: 63 additions & 0 deletions tests/c/early_return.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Run-time:
// env-var: YKD_LOG_IR=-:jit-post-opt
// env-var: YKD_SERIALISE_COMPILATION=1
// env-var: YK_LOG=4
// stderr:
// 3
// 2
// yk-jit-event: start-tracing
// 1
// yk-jit-event: stop-tracing-early-return
// return
// yk-jit-event: start-tracing
// 3
// yk-jit-event: stop-tracing
// --- Begin jit-pre-opt ---
// ...
// --- End jit-pre-opt ---
// exit

// Check that basic trace compilation works.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yk.h>
#include <yk_testing.h>

void loop(YkMT *, YkLocation *);

void loop(YkMT *mt, YkLocation *loc) {
int res = 9998;
int i = 3;
NOOPT_VAL(res);
NOOPT_VAL(i);
while (i > 0) {
yk_mt_control_point(mt, loc);
fprintf(stderr, "%d\n", i);
i--;
}
yk_mt_early_return(mt);
fprintf(stderr, "return\n");
NOOPT_VAL(res);
}

int main(int argc, char **argv) {
YkMT *mt = yk_mt_new(NULL);
yk_mt_hot_threshold_set(mt, 2);
YkLocation loc = yk_location_new();

int res = 9998;
int i = 4;
NOOPT_VAL(loc);
NOOPT_VAL(res);
NOOPT_VAL(i);
loop(mt, &loc);
loop(mt, &loc);
fprintf(stderr, "exit\n");
NOOPT_VAL(res);
yk_location_drop(loc);
yk_mt_shutdown(mt);
return (EXIT_SUCCESS);
}
1 change: 0 additions & 1 deletion tests/c/fcmp_double.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Run-time:
// env-var: YKD_LOG_IR=aot,jit-pre-opt,jit-asm
// env-var: YKD_SERIALISE_COMPILATION=1
// env-var: YK_LOG=4
// stderr:
Expand Down
1 change: 0 additions & 1 deletion tests/c/fcmp_float.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Run-time:
// env-var: YKD_LOG_IR=aot,jit-pre-opt,jit-asm
// env-var: YKD_SERIALISE_COMPILATION=1
// env-var: YK_LOG=4
// stderr:
Expand Down
63 changes: 63 additions & 0 deletions tests/c/recursive.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Run-time:
// env-var: YKD_LOG_IR=-:jit-pre-opt,jit-post-opt
// env-var: YKD_SERIALISE_COMPILATION=1
// env-var: YK_LOG=4
// stderr:
// 3
// 2
// yk-jit-event: start-tracing
// 1
// yk-jit-event: stop-tracing-early-return
// return
// yk-jit-event: start-tracing
// 3
// yk-jit-event: stop-tracing
// --- Begin jit-pre-opt ---
// ...
// --- End jit-pre-opt ---
// exit

// Check that basic trace compilation works.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yk.h>
#include <yk_testing.h>

int loop(YkMT *, YkLocation *, int);

int loop(YkMT *mt, YkLocation *loc, int i) {
int res = 9998;
NOOPT_VAL(res);
NOOPT_VAL(i);
while (i > 0) {
yk_mt_control_point(mt, loc);
if (i > 2) {
loop(mt, loc, i - 1);
}
fprintf(stderr, "%d\n", i);
i--;
}
yk_mt_early_return(mt);
fprintf(stderr, "return\n");
NOOPT_VAL(res);
return i;
}

int main(int argc, char **argv) {
YkMT *mt = yk_mt_new(NULL);
yk_mt_hot_threshold_set(mt, 2);
YkLocation loc = yk_location_new();

int res = 9998;
NOOPT_VAL(loc);
NOOPT_VAL(res);
loop(mt, &loc, 3);
fprintf(stderr, "exit\n");
NOOPT_VAL(res);
yk_location_drop(loc);
yk_mt_shutdown(mt);
return (EXIT_SUCCESS);
}
7 changes: 7 additions & 0 deletions ykcapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ pub extern "C" fn yk_mt_control_point(_mt: *mut MT, _loc: *mut Location) {
// Intentionally empty.
}

#[no_mangle]
pub extern "C" fn __yk_mt_early_return(mt: *mut MT, frameaddr: *mut c_void) {
let mt = unsafe { &*mt };
let arc = unsafe { Arc::from_raw(mt) };
arc.early_return(frameaddr);
}

// The new control point called after the interpreter has been patched by ykllvm.
#[cfg(target_arch = "x86_64")]
#[naked]
Expand Down
16 changes: 16 additions & 0 deletions ykcapi/yk.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ void yk_mt_shutdown(YkMT *);
// execute JITted code.
void yk_mt_control_point(YkMT *, YkLocation *);

// At each point a function containing a control point can exit "early" this
// function must be called. "Early" includes, but is not
// limited to, the following:
//
// 1. Immediately after a non-infinite loop containing a call to
// `yk_mt_control_point`.
// 2. Immediately before `return` statements in code reachable from a
// `yk_mt_control_point`.
//
// Failure to call this function will lead to undefined behaviour.
# define yk_mt_early_return(mt) __yk_mt_early_return(mt, __builtin_frame_address(0))

// This is an internal function to yk: calling it directly leads to undefined
// behaviour.
void __yk_mt_early_return(YkMT *, void *);

// Set the threshold at which `YkLocation`'s are considered hot.
void yk_mt_hot_threshold_set(YkMT *, YkHotThreshold);

Expand Down
2 changes: 1 addition & 1 deletion ykrt/src/compile/jitc_yk/codegen/x64/deopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn running_trace(gidxs: &[usize]) -> Arc<X64CompiledTrace> {
/// * glen - Length for list in `gptr`.
#[no_mangle]
pub(crate) extern "C" fn __yk_deopt(
frameaddr: *const c_void,
frameaddr: *mut c_void,
gidx: u64,
gp_regs: &[u64; 16],
fp_regs: &[u64; 16],
Expand Down
Loading

0 comments on commit bd40930

Please sign in to comment.