[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 4/4] Expose and add documentation for jit_live/jit_get_reg/ji
From: |
Paulo César Pereira de Andrade |
Subject: |
Re: [PATCH 4/4] Expose and add documentation for jit_live/jit_get_reg/jit_unget_reg. |
Date: |
Fri, 12 Aug 2022 08:27:28 -0300 |
Em sex., 12 de ago. de 2022 às 07:07, Marc Nieper-Wißkirchen
<marc.nieper+gnu@gmail.com> escreveu:
>
> Hi Paulo,
Hi Marc,
> could it be that you missed this patch set when you recently went through the
> backlog of patches?
It was added. Just that there was no official release with the patch. See
http://git.savannah.gnu.org/cgit/lightning.git/commit/?id=cf148ec18d20c5e86c9203444c7c763753965f01
> Thank you very much,
>
> Marc
>
> ---------- Forwarded message ---------
> Von: Marc Nieper-Wißkirchen <marc.nieper+gnu@gmail.com>
> Date: Sa., 3. Apr. 2021 um 18:36 Uhr
> Subject: [PATCH 4/4] Expose and add documentation for
> jit_live/jit_get_reg/jit_unget_reg.
> To: <lightning@gnu.org>
> Cc: Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
>
>
> From: Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
>
> * check/Makefile.am: Add test for the live instruction.
> * check/live.ok: New file.
> * check/live.tst: New file.
> * doc/body.texi: Add documentation for the live instruction and
> for jit_get_reg/jit_get_unreg. Fix menu entries.
> * include/lightning.h.in (jit_get_reg, jit_unget_reg): Expose the
> macros in the public header file.
> * include/lightning/jit_private.h (jit_get_reg, jit_unget_reg):
> Remove the macros from the private header file.
> ---
> ChangeLog | 17 ++++++-
> check/Makefile.am | 3 +-
> check/live.ok | 1 +
> check/live.tst | 33 ++++++++++++
> doc/body.texi | 89 ++++++++++++++++++++++++++++++---
> include/lightning.h.in | 6 +++
> include/lightning/jit_private.h | 8 ---
> 7 files changed, 138 insertions(+), 19 deletions(-)
> create mode 100644 check/live.ok
> create mode 100644 check/live.tst
>
> diff --git a/ChangeLog b/ChangeLog
> index 20bfcfe..9964207 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,6 +1,19 @@
> -021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
> +2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
> +
> + * check/Makefile.am: Add test for the live instruction.
> + * check/live.ok: New file.
> + * check/live.tst: New file.
> + * doc/body.texi: Add documentation for the live instruction and
> + for jit_get_reg/jit_get_unreg. Fix menu entries.
> + * include/lightning.h.in (jit_get_reg, jit_unget_reg): Expose the
> + macros in the public header file.
> + * include/lightning/jit_private.h (jit_get_reg, jit_unget_reg):
> + Remove the macros from the private header file.
> +
> +2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
>
> - * Makefile.am, check/Makefile.am, doc/Makefile.am, lib/Makefile.am:
> Include $(top_builddir)/include in include paths
> + * Makefile.am, check/Makefile.am, doc/Makefile.am,
> + lib/Makefile.am: Include $(top_builddir)/include in include paths
> for the autoconf-generated header file lightning.h.
>
> 2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
> diff --git a/check/Makefile.am b/check/Makefile.am
> index 80b6f9d..583bb12 100644
> --- a/check/Makefile.am
> +++ b/check/Makefile.am
> @@ -91,6 +91,7 @@ EXTRA_DIST = \
> call.tst call.ok \
> float.tst float.ok \
> jmpr.tst jmpr.ok \
> + live.tst live.ok \
> put.tst put.ok \
> qalu.inc \
> qalu_mul.tst qalu_mul.ok \
> @@ -125,7 +126,7 @@ base_TESTS = \
> fop_abs fop_sqrt \
> varargs stack \
> clobber carry call \
> - float jmpr put \
> + float jmpr live put \
> qalu_mul qalu_div \
> range ranger ret tramp \
> va_list
> diff --git a/check/live.ok b/check/live.ok
> new file mode 100644
> index 0000000..9766475
> --- /dev/null
> +++ b/check/live.ok
> @@ -0,0 +1 @@
> +ok
> diff --git a/check/live.tst b/check/live.tst
> new file mode 100644
> index 0000000..f082a66
> --- /dev/null
> +++ b/check/live.tst
> @@ -0,0 +1,33 @@
> +.data 16
> +ok:
> +.c "ok"
> +
> +.code
> + jmpi main
> +
> +check_r0:
> + prolog
> + movi %v0 exit_r0
> + movi %r0 1
> + movi %r2 10
> + // on x86 this changes %rax on other arches could use %r0 as temporary
> + divi %r1 %r2 3
> + live %r0
> + // %r0 must still be 1
> + jmpr %v0
> +exit_r0:
> + retr %r0
> + epilog
> +
> +main:
> + prolog
> + calli check_r0
> + retval %r1
> + beqi r0_ok %r1 1
> + calli @abort
> +r0_ok:
> + prepare
> + pushargi ok
> + finishi @puts
> + ret
> + epilog
> diff --git a/doc/body.texi b/doc/body.texi
> index 4aef7a3..c14f635 100644
> --- a/doc/body.texi
> +++ b/doc/body.texi
> @@ -30,6 +30,7 @@ dynamic code generation.
> * The instruction set:: The RISC instruction set used in GNU lightning
> * GNU lightning examples:: GNU lightning's examples
> * Reentrancy:: Re-entrant usage of GNU lightning
> +* Registers:: Accessing the whole register file
> * Customizations:: Advanced code generation customizations
> * Acknowledgements:: Acknowledgements for GNU lightning
> @end menu
> @@ -43,8 +44,8 @@ This document describes @value{TOPIC} the @lightning{}
> library for
> dynamic code generation.
> @end iftex
>
> -Dynamic code generation is the generation of machine code
> -at runtime. It is typically used to strip a layer of interpretation
> +Dynamic code generation is the generation of machine code
> +at runtime. It is typically used to strip a layer of interpretation
> by allowing compilation to occur at runtime. One of the most
> well-known applications of dynamic code generation is perhaps that
> of interpreters that compile source code to an intermediate bytecode
> @@ -53,7 +54,7 @@ approach effectively combines the portability of bytecode
> representations with the speed of machine code. Another common
> application of dynamic code generation is in the field of hardware
> simulators and binary emulators, which can use the same techniques
> -to translate simulated instructions to the instructions of the
> +to translate simulated instructions to the instructions of the
> underlying machine.
>
> Yet other applications come to mind: for example, windowing
> @@ -68,7 +69,7 @@ retargeted for each machine; in addition, coding a run-time
> code
> generator is a tedious and error-prone task more than a difficult one.
>
> @lightning{} provides a portable, fast and easily retargetable dynamic
> -code generation system.
> +code generation system.
>
> To be portable, @lightning{} abstracts over current architectures'
> quirks and unorthogonalities. The interface that it exposes to is that
> @@ -695,6 +696,51 @@ in = arg @rem{! Same as above}
> ret @rem{! Return to caller}
> @end example
>
> +@item Register liveness
> +
> +During code generation, @lightning{} occasionally needs scratch registers
> +or needs to use architecture-defined registers. For that, @lightning{}
> +internally maintains register liveness information.
> +
> +In the following example, @code{qdivr} will need special registers like
> +@code{R0} on some architectures. As @lightning{} understands that
> +@code{R0} is used in the subsequent instruction, it will create
> +save/restore code for @code{R0} in case.
> +
> +@example
> +...
> +qdivr V0, V1, V2, V3
> +movr V3, R0
> +...
> +@end example
> +
> +The same is not true in the example that follows. Here, @code{R0} is
> +not alive after the division operation because @code{R0} is neither an
> +argument register nor a callee-save register. Thus, no save/restore
> +code for @code{R0} will be created in case.
> +
> +@example
> +...
> +qdivr V0, V1, V2, V3
> +jmpr R1
> +...
> +@end example
> +
> +The @code{live} instruction can be used to mark a register as live after
> +it as in the following example. Here, @code{R0} will be preserved
> +across the division.
> +
> +@example
> +...
> +qdivr V0, V1, V2, V3
> +live R0
> +jmpr R1
> +...
> +@end example
> +
> +The @code{live} instruction is useful at code entry and exit points,
> +like after and before a @code{callr} instruction.
> +
> @item Trampolines, continuations and tail call optimization
>
> Frequently it is required to generate jit code that must jump to
> @@ -1005,9 +1051,9 @@ programmer would write):
> mov %i0, %g2 retl
> inc %g2 inc %o0
> mov %g2, %i0
> - restore
> - retl
> - nop
> + restore
> + retl
> + nop
> @end example
> In this case, @lightning{} introduces overhead to create a register
> window (not knowing that the procedure is a leaf procedure) and to
> @@ -1480,7 +1526,7 @@ implementation and to avoid needing the user to keep
> adding an extra
> argument to every call, as multiple jit states generating code in
> paralell should be very uncommon.
>
> -@section Registers
> +@node Registers
> @chapter Accessing the whole register file
>
> As mentioned earlier in this chapter, all @lightning{} back-ends are
> @@ -1496,6 +1542,33 @@ constant. Of course, expressions like @code{JIT_R0}
> and
> @code{JIT_R(0)} denote the same register, and likewise for
> integer callee-saved, or floating-point, registers.
>
> +@section Scratch registers
> +
> +For operations, @lightning{} does not support directly, like storing
> +a literal in memory, @code{jit_get_reg} and @code{jit_unget_reg} can be used
> to
> +acquire and release a scratch register as in the following pattern:
> +
> +@example
> + 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);
> +@end example
> +
> +As @code{jit_get_reg} and @code{jit_unget_reg} may generate spills and
> +reloads but don't follow branches, the code between both must be in
> +the same basic block and must not contain any branches as in the
> +following (bad) example.
> +
> +@example
> + jit_int32_t reg = jit_get_reg (jit_class_gpr);
> + jit_ldxi (reg, JIT_V0, offset);
> + jump = jit_bnei (reg, V0);
> + jit_movr (JIT_V1, reg);
> + jit_patch (jump);
> + jit_unget_reg (reg);
> +@end example
> +
> @node Customizations
> @chapter Customizations
>
> diff --git a/include/lightning.h.in b/include/lightning.h.in
> index 70560c9..e1d8a0a 100644
> --- a/include/lightning.h.in
> +++ b/include/lightning.h.in
> @@ -1011,6 +1011,12 @@ extern void _jit_retr_d(jit_state_t*, jit_fpr_t);
> extern void _jit_reti_d(jit_state_t*, jit_float64_t);
> extern void _jit_retval_d(jit_state_t*, jit_fpr_t);
>
> +#define jit_get_reg(s) _jit_get_reg(_jit,s)
> +extern jit_int32_t _jit_get_reg(jit_state_t*, jit_int32_t);
> +
> +#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
> +extern void _jit_unget_reg(jit_state_t*, jit_int32_t);
> +
> #define jit_new_node(c) _jit_new_node(_jit,c)
> extern jit_node_t *_jit_new_node(jit_state_t*, jit_code_t);
> #define jit_new_node_w(c,u) _jit_new_node_w(_jit,c,u)
> diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h
> index 8c05853..e00e74d 100644
> --- a/include/lightning/jit_private.h
> +++ b/include/lightning/jit_private.h
> @@ -672,14 +672,6 @@ _jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
> extern void
> _jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
>
> -#define jit_get_reg(s) _jit_get_reg(_jit,s)
> -extern jit_int32_t
> -_jit_get_reg(jit_state_t*, jit_int32_t);
> -
> -#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
> -extern void
> -_jit_unget_reg(jit_state_t*, jit_int32_t);
> -
> #define jit_save(reg) _jit_save(_jit, reg)
> extern void
> _jit_save(jit_state_t*, jit_int32_t);
> --
> 2.25.1
>