From: "Nicolas Bértolo" <nicolasbertolo@gmail.com>
To: 41615@debbugs.gnu.org
Subject: bug#41615: [feature/native-comp] Dump prettier C code.
Date: Sat, 30 May 2020 12:08:07 -0300 [thread overview]
Message-ID: <CAFnS-OmcxkPdLiWEDjQtitZ=deZKsVN-VWtK4nbeozO3O5MVpA@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 307 bytes --]
I found two ways to improve the looks of the dumped code.
- Define static data using string literals of at most 200 bytes. This
reduces
the line count and lets us understand what the static object consists of.
- Define casts using functions. These functions should get always get
inlined.
Thanks, Nico
[-- Attachment #1.2: Type: text/html, Size: 402 bytes --]
[-- Attachment #2: 0002-Define-casts-using-functions.patch --]
[-- Type: application/octet-stream, Size: 11727 bytes --]
From 8ed42509e55e78e67d9989e4c119c1b8f6bea463 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Wed, 20 May 2020 00:46:30 -0300
Subject: [PATCH 2/2] Define casts using functions.
This is to dump prettier C files.
This does not affect compilation times in my tests.
* src/comp.c: Define a 15x15 cast matrix. Use it in emit_coerce().
---
src/comp.c | 278 ++++++++++++++++++++---------------------------------
1 file changed, 104 insertions(+), 174 deletions(-)
diff --git a/src/comp.c b/src/comp.c
index 3f4b3e03b7..f5f6b1baca 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -454,6 +454,8 @@ #define F_RELOC_MAX_SIZE 1500
static f_reloc_t freloc;
+#define NUM_CAST_TYPES 15
+
/* C side of the compiler context. */
typedef struct {
@@ -512,21 +514,9 @@ #define F_RELOC_MAX_SIZE 1500
/* libgccjit has really limited support for casting therefore this union will
be used for the scope. */
gcc_jit_type *cast_union_type;
- gcc_jit_field *cast_union_as_ll;
- gcc_jit_field *cast_union_as_ull;
- gcc_jit_field *cast_union_as_l;
- gcc_jit_field *cast_union_as_ul;
- gcc_jit_field *cast_union_as_u;
- gcc_jit_field *cast_union_as_i;
- gcc_jit_field *cast_union_as_b;
- gcc_jit_field *cast_union_as_uintptr;
- gcc_jit_field *cast_union_as_ptrdiff;
- gcc_jit_field *cast_union_as_c_p;
- gcc_jit_field *cast_union_as_v_p;
- gcc_jit_field *cast_union_as_lisp_cons_ptr;
- gcc_jit_field *cast_union_as_lisp_word;
- gcc_jit_field *cast_union_as_lisp_word_tag;
- gcc_jit_field *cast_union_as_lisp_obj_ptr;
+ gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES];
+ gcc_jit_type *cast_types[NUM_CAST_TYPES];
+ gcc_jit_field *cast_union_fields[NUM_CAST_TYPES];
gcc_jit_function *func; /* Current function being compiled. */
bool func_has_non_local; /* From comp-func has-non-local slot. */
gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */
@@ -684,47 +674,6 @@ bcall0 (Lisp_Object f)
Ffuncall (1, &f);
}
-static gcc_jit_field *
-type_to_cast_field (gcc_jit_type *type)
-{
- gcc_jit_field *field;
-
- if (type == comp.long_long_type)
- field = comp.cast_union_as_ll;
- else if (type == comp.unsigned_long_long_type)
- field = comp.cast_union_as_ull;
- else if (type == comp.long_type)
- field = comp.cast_union_as_l;
- else if (type == comp.unsigned_long_type)
- field = comp.cast_union_as_ul;
- else if (type == comp.unsigned_type)
- field = comp.cast_union_as_u;
- else if (type == comp.int_type)
- field = comp.cast_union_as_i;
- else if (type == comp.bool_type)
- field = comp.cast_union_as_b;
- else if (type == comp.void_ptr_type)
- field = comp.cast_union_as_v_p;
- else if (type == comp.uintptr_type)
- field = comp.cast_union_as_uintptr;
- else if (type == comp.ptrdiff_type)
- field = comp.cast_union_as_ptrdiff;
- else if (type == comp.char_ptr_type)
- field = comp.cast_union_as_c_p;
- else if (type == comp.lisp_cons_ptr_type)
- field = comp.cast_union_as_lisp_cons_ptr;
- else if (type == comp.lisp_word_type)
- field = comp.cast_union_as_lisp_word;
- else if (type == comp.lisp_word_tag_type)
- field = comp.cast_union_as_lisp_word_tag;
- else if (type == comp.lisp_obj_ptr_type)
- field = comp.cast_union_as_lisp_obj_ptr;
- else
- xsignal1 (Qnative_ice, build_string ("unsupported cast"));
-
- return field;
-}
-
static gcc_jit_block *
retrive_block (Lisp_Object block_name)
{
@@ -985,11 +934,19 @@ emit_cond_jump (gcc_jit_rvalue *test,
}
+static int
+type_to_cast_index(gcc_jit_type * type)
+{
+ for (int i = 0; i < NUM_CAST_TYPES; ++i)
+ if (type == comp.cast_types[i])
+ return i;
+
+ xsignal1 (Qnative_ice, build_string ("unsupported cast"));
+}
+
static gcc_jit_rvalue *
emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
{
- static ptrdiff_t i;
-
gcc_jit_type *old_type = gcc_jit_rvalue_get_type (obj);
if (new_type == old_type)
@@ -1021,25 +978,14 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
}
#endif
- gcc_jit_field *orig_field =
- type_to_cast_field (old_type);
- gcc_jit_field *dest_field = type_to_cast_field (new_type);
-
- gcc_jit_lvalue *tmp_u =
- gcc_jit_function_new_local (comp.func,
- NULL,
- comp.cast_union_type,
- format_string ("union_cast_%td", i++));
- gcc_jit_block_add_assignment (comp.block,
- NULL,
- gcc_jit_lvalue_access_field (tmp_u,
- NULL,
- orig_field),
- obj);
+ int old_index = type_to_cast_index (old_type);
+ int new_index = type_to_cast_index (new_type);
- return gcc_jit_rvalue_access_field ( gcc_jit_lvalue_as_rvalue (tmp_u),
- NULL,
- dest_field);
+ /* Lookup the appropriate cast function in the cast matrix. */
+ return gcc_jit_context_new_call (comp.ctxt,
+ NULL,
+ comp.cast_functions_from_to[old_index][new_index],
+ 1, &obj);
}
static gcc_jit_rvalue *
@@ -3128,109 +3074,93 @@ define_thread_state_struct (void)
gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s));
}
-static void
-define_cast_union (void)
+struct cast_type
{
+ gcc_jit_type * type;
+ const char *name;
+};
+
+static gcc_jit_function *
+define_cast_from_to(struct cast_type from, int from_index, struct cast_type to, int to_index)
+{
+ Lisp_Object name = CALLN(Fformat,
+ build_string("cast_from_%s_to_%s"),
+ build_string(from.name),
+ build_string(to.name));
+ gcc_jit_param * param = gcc_jit_context_new_param(comp.ctxt, NULL,
+ from.type, "arg");
+ gcc_jit_function * result =
+ gcc_jit_context_new_function (comp.ctxt,
+ NULL,
+ GCC_JIT_FUNCTION_ALWAYS_INLINE,
+ to.type,
+ SSDATA(name),
+ 1,
+ ¶m,
+ 0);
+
+ DECL_BLOCK (entry_block, result);
+
+ gcc_jit_lvalue *tmp_union
+ = gcc_jit_function_new_local (result, NULL, comp.cast_union_type, "union_cast");
+
+ gcc_jit_block_add_assignment (entry_block, NULL,
+ gcc_jit_lvalue_access_field (tmp_union, NULL,
+ comp.cast_union_fields[from_index]),
+ gcc_jit_param_as_rvalue(param));
+
+ gcc_jit_block_end_with_return(entry_block,
+ NULL,
+ gcc_jit_rvalue_access_field (
+ gcc_jit_lvalue_as_rvalue (tmp_union),
+ NULL,
+ comp.cast_union_fields[to_index]));
+
+ return result;
+}
+
+static void
+define_cast_functions (void)
+{
+ struct cast_type cast_types[NUM_CAST_TYPES] =
+ {{comp.bool_type, "bool"},
+ {comp.char_ptr_type, "char_ptr"},
+ {comp.int_type, "int"},
+ {comp.lisp_cons_ptr_type, "cons_ptr"},
+ {comp.lisp_obj_ptr_type, "lisp_obj_ptr"},
+ {comp.lisp_word_tag_type, "lisp_word_tag"},
+ {comp.lisp_word_type, "lisp_word"},
+ {comp.long_long_type, "long_long"},
+ {comp.long_type, "long"},
+ {comp.ptrdiff_type, "ptrdiff"},
+ {comp.uintptr_type, "uintptr"},
+ {comp.unsigned_long_long_type, "unsigned_long_long"},
+ {comp.unsigned_long_type, "unsigned_long"},
+ {comp.unsigned_type, "unsigned"},
+ {comp.void_ptr_type, "void_ptr"}};
+
+ /* Define the union used for casting. */
+ for (int i = 0; i < NUM_CAST_TYPES; ++i)
+ {
+ comp.cast_types[i] = cast_types[i].type;
+ comp.cast_union_fields[i] = gcc_jit_context_new_field (comp.ctxt,
+ NULL,
+ cast_types[i].type,
+ cast_types[i].name);
+ }
- comp.cast_union_as_ll =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.long_long_type,
- "ll");
- comp.cast_union_as_ull =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.unsigned_long_long_type,
- "ull");
- comp.cast_union_as_l =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.long_type,
- "l");
- comp.cast_union_as_ul =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.unsigned_long_type,
- "ul");
- comp.cast_union_as_u =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.unsigned_type,
- "u");
- comp.cast_union_as_i =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.int_type,
- "i");
- comp.cast_union_as_b =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.bool_type,
- "b");
- comp.cast_union_as_uintptr =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.uintptr_type,
- "uintptr");
- comp.cast_union_as_ptrdiff =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.ptrdiff_type,
- "ptrdiff");
- comp.cast_union_as_c_p =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.char_ptr_type,
- "c_p");
- comp.cast_union_as_v_p =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.void_ptr_type,
- "v_p");
- comp.cast_union_as_lisp_cons_ptr =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.lisp_cons_ptr_type,
- "cons_ptr");
- comp.cast_union_as_lisp_word =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.lisp_word_type,
- "lisp_word");
- comp.cast_union_as_lisp_word_tag =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.lisp_word_tag_type,
- "lisp_word_tag");
- comp.cast_union_as_lisp_obj_ptr =
- gcc_jit_context_new_field (comp.ctxt,
- NULL,
- comp.lisp_obj_ptr_type,
- "lisp_obj_ptr");
-
-
- gcc_jit_field *cast_union_fields[] =
- { comp.cast_union_as_ll,
- comp.cast_union_as_ull,
- comp.cast_union_as_l,
- comp.cast_union_as_ul,
- comp.cast_union_as_u,
- comp.cast_union_as_i,
- comp.cast_union_as_b,
- comp.cast_union_as_uintptr,
- comp.cast_union_as_ptrdiff,
- comp.cast_union_as_c_p,
- comp.cast_union_as_v_p,
- comp.cast_union_as_lisp_cons_ptr,
- comp.cast_union_as_lisp_word,
- comp.cast_union_as_lisp_word_tag,
- comp.cast_union_as_lisp_obj_ptr };
comp.cast_union_type =
gcc_jit_context_new_union_type (comp.ctxt,
NULL,
"cast_union",
- ARRAYELTS (cast_union_fields),
- cast_union_fields);
+ NUM_CAST_TYPES,
+ comp.cast_union_fields);
+
+ /* Define the cast functions using a matrix. */
+ for (int i = 0; i < NUM_CAST_TYPES; ++i)
+ for (int j = 0; j < NUM_CAST_TYPES; ++j)
+ comp.cast_functions_from_to[i][j] =
+ define_cast_from_to (cast_types[i], i, cast_types[j], j);
}
static void
@@ -4041,7 +3971,7 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
define_jmp_buf ();
define_handler_struct ();
define_thread_state_struct ();
- define_cast_union ();
+ define_cast_functions ();
define_naive_bzero ();
define_naive_memcpy ();
--
2.25.1.windows.1
[-- Attachment #3: 0001-Define-static-data-using-string-literals.patch --]
[-- Type: application/octet-stream, Size: 16303 bytes --]
From 9a090c02aedd5ee23951bacb5f0c5275a373875d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Wed, 20 May 2020 00:34:32 -0300
Subject: [PATCH 1/2] Define static data using string literals.
The purpose of this change is to dump prettier C files.
This does not affect compilation times in my tests.
* src/comp.c (emit_static_object): Define static objects using string
literals, memcpy and bzero.
---
src/comp.c | 300 +++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 282 insertions(+), 18 deletions(-)
diff --git a/src/comp.c b/src/comp.c
index 996168bbb5..3f4b3e03b7 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -46,6 +46,7 @@
# include "w32common.h"
#undef gcc_jit_block_add_assignment
+#undef gcc_jit_block_add_assignment_op
#undef gcc_jit_block_add_comment
#undef gcc_jit_block_add_eval
#undef gcc_jit_block_end_with_conditional
@@ -75,6 +76,7 @@
#undef gcc_jit_context_new_rvalue_from_int
#undef gcc_jit_context_new_rvalue_from_long
#undef gcc_jit_context_new_rvalue_from_ptr
+#undef gcc_jit_context_new_string_literal
#undef gcc_jit_context_new_struct_type
#undef gcc_jit_context_new_unary_op
#undef gcc_jit_context_new_union_type
@@ -164,6 +166,8 @@ DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_rvalue_from_long,
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type, long value));
DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_rvalue_from_ptr,
(gcc_jit_context *ctxt, gcc_jit_type *pointer_type, void *value));
+DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_string_literal,
+ (gcc_jit_context *ctxt, const char *value));
DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_unary_op,
(gcc_jit_context *ctxt, gcc_jit_location *loc,
enum gcc_jit_unary_op op, gcc_jit_type *result_type,
@@ -197,6 +201,9 @@ DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_pointer, (gcc_jit_type *type));
DEF_DLL_FN (void, gcc_jit_block_add_assignment,
(gcc_jit_block *block, gcc_jit_location *loc, gcc_jit_lvalue *lvalue,
gcc_jit_rvalue *rvalue));
+DEF_DLL_FN (void, gcc_jit_block_add_assignment_op,
+ (gcc_jit_block *block, gcc_jit_location *loc, gcc_jit_lvalue *lvalue,
+ enum gcc_jit_binary_op op, gcc_jit_rvalue *rvalue));
DEF_DLL_FN (void, gcc_jit_block_add_eval,
(gcc_jit_block *block, gcc_jit_location *loc,
gcc_jit_rvalue *rvalue));
@@ -239,6 +246,7 @@ init_gccjit_functions (void)
/* In alphabetical order */
LOAD_DLL_FN (library, gcc_jit_block_add_assignment);
+ LOAD_DLL_FN (library, gcc_jit_block_add_assignment_op);
LOAD_DLL_FN (library, gcc_jit_block_add_comment);
LOAD_DLL_FN (library, gcc_jit_block_add_eval);
LOAD_DLL_FN (library, gcc_jit_block_end_with_conditional);
@@ -268,6 +276,7 @@ init_gccjit_functions (void)
LOAD_DLL_FN (library, gcc_jit_context_new_rvalue_from_int);
LOAD_DLL_FN (library, gcc_jit_context_new_rvalue_from_long);
LOAD_DLL_FN (library, gcc_jit_context_new_rvalue_from_ptr);
+ LOAD_DLL_FN (library, gcc_jit_context_new_string_literal);
LOAD_DLL_FN (library, gcc_jit_context_new_struct_type);
LOAD_DLL_FN (library, gcc_jit_context_new_unary_op);
LOAD_DLL_FN (library, gcc_jit_context_new_union_type);
@@ -296,6 +305,7 @@ init_gccjit_functions (void)
/* In alphabetical order */
#define gcc_jit_block_add_assignment fn_gcc_jit_block_add_assignment
+#define gcc_jit_block_add_assignment_op fn_gcc_jit_block_add_assignment_op
#define gcc_jit_block_add_comment fn_gcc_jit_block_add_comment
#define gcc_jit_block_add_eval fn_gcc_jit_block_add_eval
#define gcc_jit_block_end_with_conditional fn_gcc_jit_block_end_with_conditional
@@ -325,6 +335,7 @@ #define gcc_jit_context_new_param fn_gcc_jit_context_new_param
#define gcc_jit_context_new_rvalue_from_int fn_gcc_jit_context_new_rvalue_from_int
#define gcc_jit_context_new_rvalue_from_long fn_gcc_jit_context_new_rvalue_from_long
#define gcc_jit_context_new_rvalue_from_ptr fn_gcc_jit_context_new_rvalue_from_ptr
+#define gcc_jit_context_new_string_literal fn_gcc_jit_context_new_string_literal
#define gcc_jit_context_new_struct_type fn_gcc_jit_context_new_struct_type
#define gcc_jit_context_new_unary_op fn_gcc_jit_context_new_unary_op
#define gcc_jit_context_new_union_type fn_gcc_jit_context_new_union_type
@@ -548,6 +559,8 @@ #define F_RELOC_MAX_SIZE 1500
gcc_jit_rvalue *data_relocs_ephemeral;
/* Synthesized struct holding func relocs. */
gcc_jit_lvalue *func_relocs;
+ gcc_jit_function *naive_bzero;
+ gcc_jit_function *naive_memcpy;
Lisp_Object d_default_idx;
Lisp_Object d_impure_idx;
Lisp_Object d_ephemeral_idx;
@@ -2346,10 +2359,7 @@ emit_static_object (const char *name, Lisp_Object obj)
{
/* libgccjit has no support for initialized static data.
The mechanism below is certainly not aesthetic but I assume the bottle neck
- in terms of performance at load time will still be the reader.
- NOTE: we can not relay on libgccjit even for valid NULL terminated C
- strings cause of this funny bug that will affect all pre gcc10 era gccs:
- https://gcc.gnu.org/ml/jit/2019-q3/msg00013.html */
+ in terms of performance at load time will still be the reader. */
Lisp_Object str = Fprin1_to_string (obj, Qnil);
ptrdiff_t len = SBYTES (str);
@@ -2398,22 +2408,91 @@ emit_static_object (const char *name, Lisp_Object obj)
gcc_jit_lvalue *arr =
gcc_jit_lvalue_access_field (data_struct, NULL, fields[1]);
- for (ptrdiff_t i = 0; i < len; i++, p++)
+ gcc_jit_lvalue *ptrvar = gcc_jit_function_new_local (f, NULL,
+ comp.char_ptr_type,
+ "ptr");
+
+ gcc_jit_block_add_assignment (
+ block,
+ NULL,
+ ptrvar,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access (
+ comp.ctxt,
+ NULL,
+ gcc_jit_lvalue_as_rvalue (arr),
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt, comp.int_type, 0)),
+ NULL));
+
+ /* Emit a call to naive_bzero() to clear all the static object. It
+ is not strictly necessary since the dynamic linker will take care
+ of zeroing the memory too. */
+ gcc_jit_rvalue *bzero_args[2]
+ = {gcc_jit_lvalue_as_rvalue (ptrvar),
+ gcc_jit_context_new_rvalue_from_long (comp.ctxt,
+ comp.unsigned_long_long_type,
+ len + 1)};
+
+ gcc_jit_block_add_eval (block, NULL,
+ gcc_jit_context_new_call (comp.ctxt, NULL,
+ comp.naive_bzero, 2,
+ bzero_args));
+
+ for (ptrdiff_t i = 0; i < len;)
{
- gcc_jit_block_add_assignment (
- block,
- NULL,
- gcc_jit_context_new_array_access (
- comp.ctxt,
- NULL,
- gcc_jit_lvalue_as_rvalue (arr),
- gcc_jit_context_new_rvalue_from_int (comp.ctxt,
- comp.ptrdiff_type,
- i)),
- gcc_jit_context_new_rvalue_from_int (comp.ctxt,
- comp.char_type,
- *p));
+ /* We can't use string literals longer that 200 bytes because
+ they cause a crash in older versions of gccjit.
+ https://gcc.gnu.org/ml/jit/2019-q3/msg00013.html */
+ char str[200];
+ strncpy (str, p, 200);
+ str[199] = 0;
+ uintptr_t l = strlen (str);
+
+ if (l != 0)
+ {
+ p += l;
+ i += l;
+
+ gcc_jit_rvalue *args[3]
+ = {gcc_jit_lvalue_as_rvalue (ptrvar),
+ gcc_jit_context_new_string_literal (comp.ctxt, str),
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt,
+ comp.unsigned_long_long_type,
+ l)};
+
+ gcc_jit_block_add_eval (block, NULL,
+ gcc_jit_context_new_call (comp.ctxt, NULL,
+ comp.naive_memcpy,
+ 3, args));
+ gcc_jit_block_add_assignment (block, NULL, ptrvar,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access (comp.ctxt, NULL,
+ gcc_jit_lvalue_as_rvalue (ptrvar),
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt,
+ comp.uintptr_type,
+ l)),
+ NULL));
+ }
+ else
+ {
+ /* If strlen returned 0 that means that the static object
+ contains a NULL byte. In that case just move over to the
+ next block. We can rely on the byte being zero because of
+ the previous call to bzero and because the dynamic linker
+ cleared it. */
+ p++;
+ i++;
+ gcc_jit_block_add_assignment (
+ block, NULL, ptrvar,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access (
+ comp.ctxt, NULL, gcc_jit_lvalue_as_rvalue (ptrvar),
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt,
+ comp.uintptr_type, 1)),
+ NULL));
+ }
}
+
gcc_jit_block_add_assignment (
block,
NULL,
@@ -2759,6 +2838,189 @@ define_jmp_buf (void)
1, &field);
}
+/*
+ * naive implementation of bzero. Hopefully it will be turned into a
+ * smarter implementation by the optimizer.
+ */
+
+static void
+define_naive_bzero (void)
+{
+ /*
+static void
+naive_bzero (char * ptr, unsigned long long len)
+{
+ unsigned long long i;
+
+entry_block:
+ i = (unsigned long long)0;
+ goto test_block;
+
+test_block:
+ if (len > i) goto loop_block; else goto return_block;
+
+loop_block:
+ ptr[i] = (char)0;
+ i += (unsigned long long)1;
+ goto test_block;
+
+return_block:
+ return;
+}
+ */
+ gcc_jit_param *params[2] = {
+ gcc_jit_context_new_param (comp.ctxt, NULL, comp.char_ptr_type, "ptr"),
+ gcc_jit_context_new_param (comp.ctxt, NULL, comp.unsigned_long_long_type,
+ "len"),
+ };
+
+ comp.naive_bzero
+ = gcc_jit_context_new_function (comp.ctxt, NULL, GCC_JIT_FUNCTION_INTERNAL,
+ comp.void_type, "naive_bzero", 2,
+ params, false);
+
+ DECL_BLOCK (entry_block, comp.naive_bzero);
+ DECL_BLOCK (test_block, comp.naive_bzero);
+ DECL_BLOCK (loop_block, comp.naive_bzero);
+ DECL_BLOCK (return_block, comp.naive_bzero);
+
+ gcc_jit_lvalue *ptr = gcc_jit_param_as_lvalue (params[0]);
+ gcc_jit_lvalue *i = gcc_jit_function_new_local (comp.naive_bzero, NULL,
+ comp.uintptr_type, "i");
+
+ gcc_jit_block_add_assignment (entry_block, NULL, i,
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt,
+ comp.uintptr_type,
+ 0));
+ gcc_jit_block_end_with_jump (entry_block, NULL, test_block);
+
+ /* if (len > i) */
+
+ gcc_jit_rvalue *comparison_result
+ = gcc_jit_context_new_comparison (comp.ctxt, NULL, GCC_JIT_COMPARISON_GT,
+ gcc_jit_param_as_rvalue (params[1]),
+ gcc_jit_lvalue_as_rvalue (i));
+
+ gcc_jit_block_end_with_conditional (test_block, NULL, comparison_result,
+ loop_block, return_block);
+
+ /* ptr[i] = 0; */
+ /* i += 1; */
+
+ gcc_jit_block_add_assignment (loop_block, NULL,
+ gcc_jit_context_new_array_access (comp.ctxt, NULL,
+ gcc_jit_lvalue_as_rvalue (ptr),
+ gcc_jit_lvalue_as_rvalue (i)),
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt, comp.char_type, 0));
+
+ gcc_jit_block_add_assignment_op (
+ loop_block, NULL, i, GCC_JIT_BINARY_OP_PLUS,
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt, comp.uintptr_type, 1));
+
+ gcc_jit_block_end_with_jump (loop_block, NULL, test_block);
+
+ /* return; */
+
+ gcc_jit_block_end_with_void_return (return_block, NULL);
+}
+
+/*
+ * naive implementation of memcpy. Hopefully it will be turned into a
+ * smarter implementation by the optimizer.
+ */
+
+static void
+define_naive_memcpy (void)
+{
+ /*
+static void *
+naive_memcpy (char * dest, char * src, unsigned long long len)
+{
+ unsigned long long i;
+
+entry_block:
+ i = (unsigned long long)0;
+ goto test_block;
+
+test_block:
+ if (len > i) goto loop_block; else goto return_block;
+
+loop_block:
+ dest[i] = src[i];
+ i += (unsigned long long)1;
+ goto test_block;
+
+return_block:
+ return dest;
+}
+ */
+ gcc_jit_param *params[3] = {
+ gcc_jit_context_new_param (comp.ctxt, NULL, comp.char_ptr_type, "dest"),
+ gcc_jit_context_new_param (comp.ctxt, NULL, comp.char_ptr_type, "src"),
+ gcc_jit_context_new_param (comp.ctxt, NULL, comp.unsigned_long_long_type,
+ "len"),
+ };
+
+ comp.naive_memcpy
+ = gcc_jit_context_new_function (comp.ctxt, NULL, GCC_JIT_FUNCTION_INTERNAL,
+ comp.void_ptr_type, "naive_memcpy", 3,
+ params, false);
+
+ DECL_BLOCK (entry_block, comp.naive_memcpy);
+ DECL_BLOCK (test_block, comp.naive_memcpy);
+ DECL_BLOCK (loop_block, comp.naive_memcpy);
+ DECL_BLOCK (return_block, comp.naive_memcpy);
+
+ gcc_jit_lvalue *dest = gcc_jit_param_as_lvalue (params[0]);
+ gcc_jit_lvalue *src = gcc_jit_param_as_lvalue (params[1]);
+ gcc_jit_lvalue *i = gcc_jit_function_new_local (comp.naive_memcpy, NULL,
+ comp.uintptr_type, "i");
+
+ gcc_jit_block_add_assignment (entry_block, NULL, i,
+ gcc_jit_context_new_rvalue_from_int (comp.ctxt,
+ comp.uintptr_type,
+ 0));
+ gcc_jit_block_end_with_jump (entry_block, NULL, test_block);
+
+ /* if (len > i) */
+
+ gcc_jit_rvalue *comparison_result
+ = gcc_jit_context_new_comparison (comp.ctxt, NULL, GCC_JIT_COMPARISON_GT,
+ gcc_jit_param_as_rvalue (params[2]),
+ gcc_jit_lvalue_as_rvalue (i));
+
+ gcc_jit_block_end_with_conditional (test_block, NULL, comparison_result,
+ loop_block, return_block);
+
+ /* dest[i] = src[i]; */
+ /* i += 1; */
+
+ gcc_jit_block_add_assignment (loop_block, NULL,
+ gcc_jit_context_new_array_access (comp.ctxt, NULL,
+ gcc_jit_lvalue_as_rvalue (dest),
+ gcc_jit_lvalue_as_rvalue (i)),
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_context_new_array_access (comp.ctxt, NULL,
+ gcc_jit_lvalue_as_rvalue (src),
+ gcc_jit_lvalue_as_rvalue (i))));
+
+ gcc_jit_block_add_assignment_op (loop_block,
+ NULL,
+ i,
+ GCC_JIT_BINARY_OP_PLUS,
+ gcc_jit_context_new_rvalue_from_int (
+ comp.ctxt,
+ comp.uintptr_type,
+ 1));
+
+ gcc_jit_block_end_with_jump (loop_block, NULL, test_block);
+
+ /* return dest; */
+
+ gcc_jit_block_end_with_return (return_block, NULL,
+ gcc_jit_param_as_rvalue (params[0]));
+}
+
/* struct handler definition */
static void
@@ -3780,6 +4042,8 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
define_handler_struct ();
define_thread_state_struct ();
define_cast_union ();
+ define_naive_bzero ();
+ define_naive_memcpy ();
return Qt;
}
--
2.25.1.windows.1
next reply other threads:[~2020-05-30 15:08 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-30 15:08 Nicolas Bértolo [this message]
2020-05-30 22:20 ` bug#41615: [feature/native-comp] Dump prettier C code Nicolas Bértolo
2020-05-31 10:45 ` Andrea Corallo
2020-05-31 15:42 ` Nicolas Bértolo
2020-05-31 11:37 ` Andrea Corallo
2020-05-31 15:48 ` Andrea Corallo
2020-05-31 15:54 ` Nicolas Bértolo
2020-05-31 16:57 ` Andrea Corallo
2020-05-31 17:26 ` Nicolas Bértolo
2020-05-31 18:11 ` Andrea Corallo
2020-05-31 19:38 ` Nicolas Bértolo
2020-05-31 20:00 ` Andrea Corallo
2020-05-31 20:18 ` Andrea Corallo
2020-06-01 7:19 ` Andrea Corallo
2020-06-01 12:25 ` Nicolas Bértolo
2020-06-01 20:28 ` Andrea Corallo
2020-06-01 23:11 ` Nicolas Bértolo
2020-06-04 9:52 ` Andrea Corallo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAFnS-OmcxkPdLiWEDjQtitZ=deZKsVN-VWtK4nbeozO3O5MVpA@mail.gmail.com' \
--to=nicolasbertolo@gmail.com \
--cc=41615@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).