1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-12 23:00:22 +02:00

Consider all callee_save_p regs as live on non trackable jumps

This commit is contained in:
pcpa 2014-09-07 15:32:32 -03:00
parent 120dfc956d
commit c8bb0dad56
5 changed files with 94 additions and 19 deletions

View file

@ -1,3 +1,20 @@
2014-09-07 Paulo Andrade <pcpa@gnu.org>
* lib/lightning.c: Mark all registers advertised as live, as
per jit_callee_save_p as live whenever reaching a jump that
cannot be tracked. This is a rethink of the previous commit,
and is a better approach, otherwise there would not be much
sense on relying on jit_callee_save_p if it could not be
trusted.
* check/jmpr.tst, check/jmpr.ok: New files implementing a very
simple test case, that would actually cause an assertion on
code before the change to only mark as live when reaching a
jump that could not tracked, the actually advertised as callee
save registers.
check/Makefile.am: Update for new jmpr test case.
2014-09-01 Paulo Andrade <pcpa@gnu.org> 2014-09-01 Paulo Andrade <pcpa@gnu.org>
* lib/lightning.c: Do not mark all registers in unknown state * lib/lightning.c: Do not mark all registers in unknown state

View file

@ -77,6 +77,7 @@ EXTRA_DIST = \
carry.tst carry.ok \ carry.tst carry.ok \
call.tst call.ok \ call.tst call.ok \
float.tst float.ok \ float.tst float.ok \
jmpr.tst jmpr.ok \
qalu.inc \ qalu.inc \
qalu_mul.tst qalu_mul.ok \ qalu_mul.tst qalu_mul.ok \
qalu_div.tst qalu_div.ok \ qalu_div.tst qalu_div.ok \
@ -104,7 +105,7 @@ base_TESTS = \
fop_abs fop_sqrt \ fop_abs fop_sqrt \
varargs stack \ varargs stack \
clobber carry call \ clobber carry call \
float \ float jmpr \
qalu_mul qalu_div \ qalu_mul qalu_div \
ret ret
@ -131,7 +132,7 @@ x87_TESTS = \
fop_abs.x87 fop_sqrt.x87 \ fop_abs.x87 fop_sqrt.x87 \
varargs.x87 stack.x87 \ varargs.x87 stack.x87 \
clobber.x87 carry.x87 call.x87 \ clobber.x87 carry.x87 call.x87 \
float.x87 float.x87 jmpr.x87
$(x87_TESTS): check.x87.sh $(x87_TESTS): check.x87.sh
$(LN_S) $(srcdir)/check.x87.sh $@ $(LN_S) $(srcdir)/check.x87.sh $@
TESTS += $(x87_TESTS) TESTS += $(x87_TESTS)
@ -153,7 +154,7 @@ x87_nodata_TESTS = \
fop_abs.x87.nodata fop_sqrt.x87.nodata \ fop_abs.x87.nodata fop_sqrt.x87.nodata \
varargs.x87.nodata stack.x87.nodata \ varargs.x87.nodata stack.x87.nodata \
clobber.x87.nodata carry.x87.nodata call.x87.nodata \ clobber.x87.nodata carry.x87.nodata call.x87.nodata \
float.x87.nodata float.x87.nodata jmpr.x87.nodata
$(x87_nodata_TESTS): check.x87.nodata.sh $(x87_nodata_TESTS): check.x87.nodata.sh
$(LN_S) $(srcdir)/check.x87.nodata.sh $@ $(LN_S) $(srcdir)/check.x87.nodata.sh $@
TESTS += $(x87_nodata_TESTS) TESTS += $(x87_nodata_TESTS)
@ -177,7 +178,7 @@ arm_TESTS = \
fop_abs.arm fop_sqrt.arm \ fop_abs.arm fop_sqrt.arm \
varargs.arm stack.arm \ varargs.arm stack.arm \
clobber.arm carry.arm call.arm \ clobber.arm carry.arm call.arm \
float.arm float.arm jmpr.arm
$(arm_TESTS): check.arm.sh $(arm_TESTS): check.arm.sh
$(LN_S) $(srcdir)/check.arm.sh $@ $(LN_S) $(srcdir)/check.arm.sh $@
TESTS += $(arm_TESTS) TESTS += $(arm_TESTS)
@ -201,7 +202,7 @@ swf_TESTS = \
fop_abs.swf fop_sqrt.swf \ fop_abs.swf fop_sqrt.swf \
varargs.swf stack.swf \ varargs.swf stack.swf \
clobber.swf carry.swf call.swf \ clobber.swf carry.swf call.swf \
float.swf float.swf jmpr.arm
$(swf_TESTS): check.swf.sh $(swf_TESTS): check.swf.sh
$(LN_S) $(srcdir)/check.swf.sh $@ $(LN_S) $(srcdir)/check.swf.sh $@
TESTS += $(swf_TESTS) TESTS += $(swf_TESTS)
@ -225,7 +226,7 @@ nodata_TESTS = \
fop_abs.nodata fop_sqrt.nodata \ fop_abs.nodata fop_sqrt.nodata \
varargs.nodata stack.nodata \ varargs.nodata stack.nodata \
clobber.nodata carry.nodata call.nodata \ clobber.nodata carry.nodata call.nodata \
float.nodata float.nodata jmpr.nodata
$(nodata_TESTS): check.nodata.sh $(nodata_TESTS): check.nodata.sh
$(LN_S) $(srcdir)/check.nodata.sh $@ $(LN_S) $(srcdir)/check.nodata.sh $@
TESTS += $(nodata_TESTS) TESTS += $(nodata_TESTS)

1
check/jmpr.ok Normal file
View file

@ -0,0 +1 @@
ok

66
check/jmpr.tst Normal file
View file

@ -0,0 +1,66 @@
/*
This is a very simple check to a condition that on lightning 2.0.5
could cause an assertion on some backends, due to correcting a problem
with temporaries that could not be saved/reloaded due to being used only
in the hardware instruction, or being considered live for too long on the
lightning instruction, and that could not be reloaded after the jump target
(or after false/true target on conditional branches).
If this code in lib/lightning.c:_jit_update():
for (regno = 0; regno < _jitc->reglen; regno++) {
spec = jit_class(_rvs[regno].spec);
if (jit_regset_tstbit(mask, regno) &&
(spec & (jit_class_gpr|jit_class_fpr)) &&
!(spec & jit_class_sav))
jit_regset_clrbit(mask, regno);
}
were removed, this test case, on x86_64 would fail like this:
lt-lightning: lightning.c:305: _jit_get_reg: Assertion `regspec & 0x02000000' failed.
Aborted (core dumped)
*/
.data 32
ret:
#if __WORDSIZE == 32
.i 0
#else
.l 0
#endif
ok:
.c "ok"
.code
prolog
jmpi start
add_v1_v2:
addr %v1 %v1 %v2
ldi %r0 ret
jmpr %r0
start:
movi %v1 1
movi %v2 2
movi %r0 ret_add_v1_v2
sti ret %r0
movi %v0 add_v1_v2
jmpr %v0
movi_d %f0 3
beqi_d pass_movi_f0 %f0 3
calli @abort
pass_movi_f0:
beqi pass_check_v2 %v2 2
calli @abort
pass_check_v2:
ret_add_v1_v2:
beqi pass_add_v1_v2 %v1 3
calli @abort
pass_add_v1_v2:
prepare
pushargi ok
finishi @puts
ret
epilog

View file

@ -2172,19 +2172,9 @@ _jit_update(jit_state_t *_jit, jit_node_t *node,
* no options for "nospill" temporaries (other temporaries * no options for "nospill" temporaries (other temporaries
* also benefit from not needing to spill/reload), so, the * also benefit from not needing to spill/reload), so, the
* user must ensure to either spill/reload, or only leave * user must ensure to either spill/reload, or only leave
* live registers on JIT_Vn if using a jump that cannot * live values on registers that are advertised as
* be tracked around the generated jit code */ * callee save (as per jit_callee_save_p); on most targets
for (spec = JIT_R_NUM - 1; spec >= 0; spec--) { * these are the JIT_Vn registers. */
regno = jit_r(spec);
if (jit_regset_tstbit(mask, regno))
jit_regset_clrbit(mask, regno);
}
for (spec = JIT_F_NUM - 1; spec >= 0; spec--) {
regno = jit_f(spec);
if (jit_regset_tstbit(mask, regno))
jit_regset_clrbit(mask, regno);
}
/* In some backends JIT_Rn and JIT_Fn are callee save */
for (regno = 0; regno < _jitc->reglen; regno++) { for (regno = 0; regno < _jitc->reglen; regno++) {
spec = jit_class(_rvs[regno].spec); spec = jit_class(_rvs[regno].spec);
if (jit_regset_tstbit(mask, regno) && if (jit_regset_tstbit(mask, regno) &&