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:
parent
120dfc956d
commit
c8bb0dad56
5 changed files with 94 additions and 19 deletions
17
ChangeLog
17
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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
1
check/jmpr.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ok
|
66
check/jmpr.tst
Normal file
66
check/jmpr.tst
Normal 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
|
|
@ -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) &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue