mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 06:41:13 +02:00
Add ability to tier up from within loops
* libguile/jit.c (struct scm_jit_state): Add entry and entry_label members. (analyze): Assert entry is jump target. (compile): Record indirect entry label. (compute_mcode): Record entry IP, and return entry mcode. (scm_sys_jit_compile, scm_jit_compute_mcode): Adapt to compute_mcode change. Support hot-loop transfer.
This commit is contained in:
parent
076c3ad8d7
commit
54b23adc13
1 changed files with 46 additions and 23 deletions
|
@ -148,8 +148,6 @@ static void *exit_mcode;
|
||||||
instruction, compiled as a stub on the side to reduce code size. */
|
instruction, compiled as a stub on the side to reduce code size. */
|
||||||
static void *handle_interrupts_trampoline;
|
static void *handle_interrupts_trampoline;
|
||||||
|
|
||||||
static void compute_mcode (scm_thread *, struct scm_jit_function_data *);
|
|
||||||
|
|
||||||
/* State of the JIT compiler for the current thread. */
|
/* State of the JIT compiler for the current thread. */
|
||||||
struct scm_jit_state {
|
struct scm_jit_state {
|
||||||
jit_state_t *jit;
|
jit_state_t *jit;
|
||||||
|
@ -158,6 +156,8 @@ struct scm_jit_state {
|
||||||
uint32_t *ip;
|
uint32_t *ip;
|
||||||
uint32_t *next_ip;
|
uint32_t *next_ip;
|
||||||
const uint32_t *end;
|
const uint32_t *end;
|
||||||
|
uint32_t *entry;
|
||||||
|
jit_node_t *entry_label;
|
||||||
uint8_t *op_attrs;
|
uint8_t *op_attrs;
|
||||||
jit_node_t **labels;
|
jit_node_t **labels;
|
||||||
int32_t frame_size;
|
int32_t frame_size;
|
||||||
|
@ -4377,6 +4377,9 @@ analyze (scm_jit_state *j)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Even in loops, the entry should be a jump target. */
|
||||||
|
ASSERT (j->op_attrs[j->entry - j->start] & OP_ATTR_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4408,6 +4411,8 @@ compile (scm_jit_state *j)
|
||||||
j->register_state = state;
|
j->register_state = state;
|
||||||
jit_link (j->labels[offset]);
|
jit_link (j->labels[offset]);
|
||||||
}
|
}
|
||||||
|
if (j->ip == j->entry)
|
||||||
|
j->entry_label = jit_indirect ();
|
||||||
compile1 (j);
|
compile1 (j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4437,10 +4442,12 @@ initialize_jit (void)
|
||||||
j->jit = NULL;
|
j->jit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static uint8_t *
|
||||||
compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
|
compute_mcode (scm_thread *thread, uint32_t *entry_ip,
|
||||||
|
struct scm_jit_function_data *data)
|
||||||
{
|
{
|
||||||
scm_jit_state *j = thread->jit_state;
|
scm_jit_state *j = thread->jit_state;
|
||||||
|
uint8_t *entry_mcode;
|
||||||
|
|
||||||
if (!j)
|
if (!j)
|
||||||
{
|
{
|
||||||
|
@ -4458,27 +4465,34 @@ compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
|
||||||
j->thread = thread;
|
j->thread = thread;
|
||||||
j->start = (const uint32_t *) (((char *)data) + data->start);
|
j->start = (const uint32_t *) (((char *)data) + data->start);
|
||||||
j->end = (const uint32_t *) (((char *)data) + data->end);
|
j->end = (const uint32_t *) (((char *)data) + data->end);
|
||||||
|
j->entry = entry_ip;
|
||||||
j->op_attrs = malloc ((j->end - j->start) * sizeof (*j->op_attrs));
|
j->op_attrs = malloc ((j->end - j->start) * sizeof (*j->op_attrs));
|
||||||
ASSERT (j->op_attrs);
|
ASSERT (j->op_attrs);
|
||||||
j->labels = malloc ((j->end - j->start) * sizeof (*j->labels));
|
j->labels = malloc ((j->end - j->start) * sizeof (*j->labels));
|
||||||
ASSERT (j->labels);
|
ASSERT (j->labels);
|
||||||
|
|
||||||
ASSERT (j->start < j->end);
|
ASSERT (j->start < j->end);
|
||||||
|
ASSERT (j->start <= j->entry);
|
||||||
|
ASSERT (j->entry < j->end);
|
||||||
|
|
||||||
j->frame_size = -1;
|
j->frame_size = -1;
|
||||||
j->hooks_enabled = 0; /* ? */
|
j->hooks_enabled = 0; /* ? */
|
||||||
|
|
||||||
j->jit = jit_new_state ();
|
j->jit = jit_new_state ();
|
||||||
|
|
||||||
INFO ("vcode: start=%p,+%zu\n", j->start, j->end - j->start);
|
INFO ("vcode: start=%p,+%zu entry=+%zu\n", j->start, j->end - j->start,
|
||||||
|
j->entry - j->start);
|
||||||
|
|
||||||
compile (j);
|
compile (j);
|
||||||
|
|
||||||
data->mcode = jit_emit ();
|
data->mcode = jit_emit ();
|
||||||
|
entry_mcode = jit_address (j->entry_label);
|
||||||
|
|
||||||
{
|
{
|
||||||
jit_word_t size = 0;
|
jit_word_t size = 0;
|
||||||
jit_get_code (&size);
|
jit_get_code (&size);
|
||||||
DEBUG ("mcode: %p,+%zu\n", data->mcode, size);
|
DEBUG ("mcode: %p,+%zu entry=+%zu\n", data->mcode, size,
|
||||||
|
entry_mcode - data->mcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (j->labels);
|
free (j->labels);
|
||||||
|
@ -4488,6 +4502,8 @@ compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
|
||||||
|
|
||||||
j->start = j->end = j->ip = NULL;
|
j->start = j->end = j->ip = NULL;
|
||||||
j->frame_size = -1;
|
j->frame_size = -1;
|
||||||
|
|
||||||
|
return entry_mcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a temporary function; just here while we're still kicking the
|
/* This is a temporary function; just here while we're still kicking the
|
||||||
|
@ -4507,7 +4523,7 @@ scm_sys_jit_compile (SCM fn)
|
||||||
|
|
||||||
data = (struct scm_jit_function_data *) (code + (int32_t)code[1]);
|
data = (struct scm_jit_function_data *) (code + (int32_t)code[1]);
|
||||||
|
|
||||||
compute_mcode (SCM_I_CURRENT_THREAD, data);
|
compute_mcode (SCM_I_CURRENT_THREAD, code, data);
|
||||||
|
|
||||||
return SCM_UNSPECIFIED;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
@ -4517,29 +4533,36 @@ scm_jit_compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
|
||||||
{
|
{
|
||||||
const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start);
|
const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start);
|
||||||
|
|
||||||
if (vcode_start == thread->vm.ip)
|
if (data->mcode)
|
||||||
{
|
{
|
||||||
if (!data->mcode)
|
if (vcode_start == thread->vm.ip)
|
||||||
{
|
return data->mcode;
|
||||||
compute_mcode (thread, data);
|
|
||||||
|
|
||||||
if (--jit_stop_after == 0)
|
/* FIXME: The function has mcode, compiled via some other
|
||||||
|
activation (possibly in another thread), but right now we're
|
||||||
|
currently in an interpreted loop (not at the beginning of the
|
||||||
|
function). We should re-compute the offset into the mcode.
|
||||||
|
For now though, just punt. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t *mcode = compute_mcode (thread, thread->vm.ip, data);
|
||||||
|
|
||||||
|
if (--jit_stop_after == 0)
|
||||||
|
{
|
||||||
|
scm_jit_counter_threshold = -1;
|
||||||
|
fprintf (stderr, "stopping automatic JIT compilation, as requested\n");
|
||||||
|
if (jit_pause_when_stopping)
|
||||||
{
|
{
|
||||||
scm_jit_counter_threshold = -1;
|
fprintf (stderr, "sleeping for 30s; to debug:\n");
|
||||||
fprintf (stderr, "stopping automatic JIT compilation, as requested\n");
|
fprintf (stderr, " gdb -p %d\n\n", getpid ());
|
||||||
if (jit_pause_when_stopping)
|
sleep (30);
|
||||||
{
|
|
||||||
fprintf (stderr, "sleeping for 30s; to debug:\n");
|
|
||||||
fprintf (stderr, " gdb -p %d\n\n", getpid ());
|
|
||||||
sleep (30);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data->mcode;
|
return mcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue