lightning
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64
Date: Wed, 4 Sep 2019 10:04:44 -0300

Em qua, 4 de set de 2019 às 03:37, Marc Nieper-Wißkirchen
<address@hidden> escreveu:

  Hi Marc,

> >   I believe the function your code calls is to avoid inlining identical 
> > code,
> > if that is the case, you could use a simple block of code, to avoid the
> > prolog/epilog cost. If it is a C function, the compiler should generate
> > an optimized version, or you could write it in assembly.
> >
> >   For example, using the new 'live' wrapper (btw, in this specific
> > example, using 'live' is not required, because it understands %r0 is
> > live due to using it as a printf argument):
> > """
> > #define USE_JMPR    1
> > .data    16
> > fmt:
> > .c    "%d %d %d\n"
> > .code
> >     jmpi main
> > helper:
> >     movi %v1 5
> >     movi %v2 7
> > #if USE_JMPR
> >     jmpr %v0
> > #else
> >     jmpi label
> > #endif
> > main:
> >     prolog
> >     movi %v1 2
> >     movi %v2 3
> >     addr %r0 %v1 %v2
> > #if USE_JMPR
> >     movi %v0 label
> > #endif
> >     jmpi helper
> > label:
> > #if USE_JMPR
> >     live %r0
> > #endif
> >     qdivr %v1 %v2 %v2 %v1
> >     prepare
> >         pushargi fmt
> >         ellipsis
> >         pushargr %r0
> >         pushargr %v1
> >         pushargr %v2
> >     finishi @printf
> >     ret
> >     epilog
> > """
> >
> >   Suppose 'helper' above is a common code, then, your code can
> > just jump to the common code, and from the common code, jump
> > back; you might also make it inside a jit function, because if the
> > common code needs to spill/reload a temporary, it must have
> > a stack frame, in that case, just create an block only reachable
> > from a jump to the common code.
> >   If the address to jump back is known, the helper code can jump
> > back to it, allowing lightning to follow the jump and understand the
> > live registers, otherwise, can use jmpr, passing the 'jump back'
> > address in a register.
> >   jmpr allows flexibility in that kind of construct, as well as different
> > approaches for dispatch tables.
> >   Another alternative is to use jit_tramp and jit_frame. See check/tramp.tst
> > or check/ctramp.c for an example, implementing a Fibonacci number
> > calculator and tail call optimized code.
>
> To which extent is code like your example code guaranteed to work,
> Paulo? For example, could we mark *all* registers live after "jmpi
> helper"?

  Lightning might run out of registers, cause an assertion and return
JIT_NOREG. If lightning it compiled with -DNDEBUG the assertion
will become a noop and it will generate invalid code, after several
assertions of an invalid register.

> On some ports, like x86_64, a jmpi instruction needs a scratch
> register, and when all registers are marked live after jmpi, the only
> way to get a scratch register is to spill one live register before the
> jmpi and reload it afterward.

  When it cannot spill/reload, it calls jit_get_reg with the
jit_class_nospill flag, and if there are no free registers it fails as
described above.

> Does GNU lightning work this way?
>
> I have another question about your code: In the above example, the
> callee-saved registers JIT_Vx are used to hold parameters for the
> handler subroutine. Is it also possible to declare a caller-saved
> register to use as an argument (in-going and/or out-going) for the
> handler?

    Not any kind of formal declaration, but it can use it in any way. It
is just inventing its own ABI. Using JIT_Vx for in/out arguments makes
things simpler because they are not scratch registers, so, they are not
clobbered in function calls. Note that the example is not a function
call, but a jump to a common thunk only accessible with a jump. And
as previously described, this thunk would be better inside a prolog/epilog
pair, because if it needs to spill/reload a temporary, it will again
cause an assertion, due to not having a stack frame.

> Cheers,
>
> Marc

Thanks,
Paulo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]