lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] Lightning Digest, Vol 91, Issue 9


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] Lightning Digest, Vol 91, Issue 9
Date: Thu, 17 Oct 2019 14:47:41 -0300

Em ter, 15 de out de 2019 às 02:50, Marc Nieper-Wißkirchen
<address@hidden> escreveu:
>
> Hi Paul, hi Paulo,
>
> >   This feature already existed on earlier versions of lightning 2,
> > and was droped due to being close to unmaintenable. Maybe you want
> > to revive it :)
> >
> >   Can you describe use cases of it?
> >
> >   Either way, I imagine it is to have extra long lived registers. If
> > not, I suggest using jit_get_reg and jit_unget_reg while generating the
> > IR. A register value returned by jit_get_reg before calling jit_emit
> > should be used for an as small as possible code range, and avoid using
> > it in branches (for example, use only to jump over an instruction).
> > Basically, jit_get_reg as exported will generate a spill/reload in the
> > range it is used. And then, when calling jit_emit, it will check these
> > registers, and if safe, will remove the spill/reload.
> >
> >   Using JIT_Ax (and JIT_FAx) might break badly when there are variadic
> > functions involved, and argument registers are already in the pool of
> > temporaries returned by jit_get_reg. Just that jit_get_reg should
> > prevent bugs by checking possible clobbers.
>
> That's great news about jit_get_reg and jit_unget_reg. May I ask to
> add documentation about them to the manual, including examples of
> their use? In particular, what exactly has to be avoided with respect
> to branches.

  The most common case where jit_get_reg/jit_unget_reg should be useful
is to store a literal. For example:
void store_immediate(jit_word_t immediate) {
    jit_int32_t reg = jit_get_reg(jit_class_gpr);
    jit_movi(reg, immediate);
    jit_stxi(offsetof(some_struct, some_field), JIT_V0, reg);
    jit_unget_reg(reg);
}
  It should not be live after branches, otherwise most likely it may
generate bad code, by reloading it when jit_unget_reg is called.
  Basically, when jit_get_reg is called, it generates an internal
jit_code_save, to spill it. When jit_unget_reg is called, it generates
a jit_code_load, to reload it. When calling jit_emit, it checks these
code_save/code_load ranges, and remove it if the spill/reload is not
required.
  One example involving branches could be:
    reg = jit_get_reg(jit_class_gpr);
    jit_ldxi(reg, JIT_V0, offset);
    jump = jit_bnei(reg, 0);
    jit_movr(JIT_V1, reg);
    jit_patch(jump);
    jit_unget_reg(reg);
but, due to the branch, that is not followed, it will spill/reload and
not check the code range.

> Speaking of the official manual, could you also include the
> documentation of `jit_live' with examples and what will work and what
> won't? That would be great!

  Ok. I will work on updating the documentation for these.

> Thanks,
>
> Marc

Thanks,
Paulo



reply via email to

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