lightning
[Top][All Lists]
Advanced

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

[PATCH 4/4] Expose and add documentation for jit_live/jit_get_reg/jit_un


From: Marc Nieper-Wißkirchen
Subject: [PATCH 4/4] Expose and add documentation for jit_live/jit_get_reg/jit_unget_reg.
Date: Sat, 3 Apr 2021 18:36:26 +0200

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




reply via email to

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