From 53dd28d682b98da1d687e7d8aafd988c89683a76 Mon Sep 17 00:00:00 2001 From: pcpa Date: Sun, 10 Aug 2014 11:39:53 -0300 Subject: [PATCH] Always mark return registers as live in epilog * lib/lightning.c: Always mark JIT_RET and JIT_FRET as live in a function epilog. This is required because on some ports a complex sequence, allocating one or more registers, may be required to jump from a ret* to the epilog, and the lightning api does not have annotations to know if a function returns a value, or the type of the return value. --- ChangeLog | 10 ++++++++++ lib/lightning.c | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1097a7265..eb9201ea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2014-08-10 Paulo Andrade + + * lib/lightning.c: Always mark JIT_RET and JIT_FRET as + live in a function epilog. This is required because + on some ports a complex sequence, allocating one or more + registers, may be required to jump from a ret* to the + epilog, and the lightning api does not have annotations + to know if a function returns a value, or the type of + the return value. + 2014-08-10 Paulo Andrade * lib/lightning.c: Change the correct live bitmask of diff --git a/lib/lightning.c b/lib/lightning.c index ecad2be0a..cb6ddac4a 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -2029,9 +2029,27 @@ _jit_update(jit_state_t *_jit, jit_node_t *node, jit_regset_and(mask, mask, &ztmp); } break; - case jit_code_prolog: case jit_code_epilog: + case jit_code_prolog: jit_regset_set_ui(mask, 0); return; + case jit_code_epilog: + jit_regset_set_ui(mask, 0); +#if defined(JIT_RET) + /* On some backends it may be required to allocate one + * or more registers to jump from a jit_ret* to the + * epilog label. + * Because currently there is no type information, + * assume JIT_RET and JIT_FRET are live in the epilog. + * Only JIT_RET really should be marked as live, to + * prevent it being allocated, usually in the jump to + * the epilog, but also mark JIT_FRET as live for the + * sake of correctness. */ + jit_regset_setbit(live, JIT_RET); +#endif +#if defined(JIT_FRET) + jit_regset_setbit(live, JIT_FRET); +#endif + return; case jit_code_callr: value = jit_regno(node->u.w); if (!(node->u.w & jit_regno_patch)) {