mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 22:31:12 +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>
|
||||
|
||||
* lib/lightning.c: Do not mark all registers in unknown state
|
||||
|
|
|
@ -77,6 +77,7 @@ EXTRA_DIST = \
|
|||
carry.tst carry.ok \
|
||||
call.tst call.ok \
|
||||
float.tst float.ok \
|
||||
jmpr.tst jmpr.ok \
|
||||
qalu.inc \
|
||||
qalu_mul.tst qalu_mul.ok \
|
||||
qalu_div.tst qalu_div.ok \
|
||||
|
@ -104,7 +105,7 @@ base_TESTS = \
|
|||
fop_abs fop_sqrt \
|
||||
varargs stack \
|
||||
clobber carry call \
|
||||
float \
|
||||
float jmpr \
|
||||
qalu_mul qalu_div \
|
||||
ret
|
||||
|
||||
|
@ -131,7 +132,7 @@ x87_TESTS = \
|
|||
fop_abs.x87 fop_sqrt.x87 \
|
||||
varargs.x87 stack.x87 \
|
||||
clobber.x87 carry.x87 call.x87 \
|
||||
float.x87
|
||||
float.x87 jmpr.x87
|
||||
$(x87_TESTS): check.x87.sh
|
||||
$(LN_S) $(srcdir)/check.x87.sh $@
|
||||
TESTS += $(x87_TESTS)
|
||||
|
@ -153,7 +154,7 @@ x87_nodata_TESTS = \
|
|||
fop_abs.x87.nodata fop_sqrt.x87.nodata \
|
||||
varargs.x87.nodata stack.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
|
||||
$(LN_S) $(srcdir)/check.x87.nodata.sh $@
|
||||
TESTS += $(x87_nodata_TESTS)
|
||||
|
@ -177,7 +178,7 @@ arm_TESTS = \
|
|||
fop_abs.arm fop_sqrt.arm \
|
||||
varargs.arm stack.arm \
|
||||
clobber.arm carry.arm call.arm \
|
||||
float.arm
|
||||
float.arm jmpr.arm
|
||||
$(arm_TESTS): check.arm.sh
|
||||
$(LN_S) $(srcdir)/check.arm.sh $@
|
||||
TESTS += $(arm_TESTS)
|
||||
|
@ -201,7 +202,7 @@ swf_TESTS = \
|
|||
fop_abs.swf fop_sqrt.swf \
|
||||
varargs.swf stack.swf \
|
||||
clobber.swf carry.swf call.swf \
|
||||
float.swf
|
||||
float.swf jmpr.arm
|
||||
$(swf_TESTS): check.swf.sh
|
||||
$(LN_S) $(srcdir)/check.swf.sh $@
|
||||
TESTS += $(swf_TESTS)
|
||||
|
@ -225,7 +226,7 @@ nodata_TESTS = \
|
|||
fop_abs.nodata fop_sqrt.nodata \
|
||||
varargs.nodata stack.nodata \
|
||||
clobber.nodata carry.nodata call.nodata \
|
||||
float.nodata
|
||||
float.nodata jmpr.nodata
|
||||
$(nodata_TESTS): check.nodata.sh
|
||||
$(LN_S) $(srcdir)/check.nodata.sh $@
|
||||
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
|
||||
* also benefit from not needing to spill/reload), so, the
|
||||
* user must ensure to either spill/reload, or only leave
|
||||
* live registers on JIT_Vn if using a jump that cannot
|
||||
* be tracked around the generated jit code */
|
||||
for (spec = JIT_R_NUM - 1; spec >= 0; spec--) {
|
||||
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 */
|
||||
* live values on registers that are advertised as
|
||||
* callee save (as per jit_callee_save_p); on most targets
|
||||
* these are the JIT_Vn registers. */
|
||||
for (regno = 0; regno < _jitc->reglen; regno++) {
|
||||
spec = jit_class(_rvs[regno].spec);
|
||||
if (jit_regset_tstbit(mask, regno) &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue