Em seg., 10 de fev. de 2020 às 17:43, Paul Cercueil
<address@hidden> escreveu:
Hi Paulo,
Hi Paul,
Le lun., févr. 10, 2020 at 17:33, Paulo César Pereira de Andrade
<address@hidden> a écrit :
> Em seg., 10 de fev. de 2020 às 15:09, Paulo César Pereira de
Andrade
> <address@hidden> escreveu:
>
> [...]
>> > Here is a new example program that shows incorrect behaviour
with
>> the
>> > latest master.
>> > My JIT_R1 (== r10) is set at the beginning of the program and
>> read back
>> > at the end, but it's used in between as a temporary register
by
>> > Lightning.
>>
>> With the correction of the bug in git master, the example
should
>> be
>> correct.
>> Checking only on for now Linux it did not reuse the register,
but
>> if
>> you are sure the functions called with jit_callr(JIT_R2) do not
>> modify
>> JIT_R1, it is required to add a jit_live(JIT_R1) because
otherwise
>> non
>> callee save registers are considered dead when returning from a
>> function.
>
> You can use jit_live(JIT_R1) if *really* 100% certain the
function
> calls
> do not clobber it. Otherwise, another approach would be to save
to the
> stack and reload when returning from the function. You cannot
> guarantee
> the called function will not modify JIT_R1, because even if it is
a
> jit
> function, it might be used as a temporary there.
Yes, that's what I do - the called functions are trampolines that
wrap
C calls with code to save/restore all caller-saved registers, so it
is
guaranteed that they won't be modified.
The problem is not in the called function, though. As you can see I
do
call jit_live(JIT_R1), but JIT_R1 gets used as temporary in the
generated code anyway. The reason why it happens on Windows and not
on
Linux is because of the different ABI, which means jit_get_reg() is
used much more often there.
I understand what is happening. Sorry for the confusion.
I am afraid for this condition it would be required some new code,
only jit_live() abstraction is not enough.
The reason is that jit_live() is only a hint. And it is considered
live
after that point, or, if there is no function call or jump to unknown
location it will propagate to earlier code.
In this case, it is used in a range where it thinks the value is
dead,
due to the function calls.
Basically, in your example, jit_live() is being used as a hint to
tell
that the function did return a value in JIT_R1.