all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Nicolas Bértolo" <nicolasbertolo@gmail.com>
To: Andrea Corallo <akrl@sdf.org>
Cc: 41615@debbugs.gnu.org
Subject: bug#41615: [feature/native-comp] Dump prettier C code.
Date: Mon, 1 Jun 2020 09:25:18 -0300	[thread overview]
Message-ID: <CAFnS-O=CHDPbfG0BmP_T_qiokzGzB3ivETRGUVtCs-mmTE700A@mail.gmail.com> (raw)
In-Reply-To: <xjflfl7jlrt.fsf@sdf.org>

[-- Attachment #1: Type: text/plain, Size: 278 bytes --]

I rewrote the "cast with functions" patch and added a few more patches.
- Implement cast to bool as !!x instead of (x & 0xFF).
- Throw an ICE when asked to perform sign extension. I didn't see any
  issues with this one. So for now it is not necessary to implement them.

Nico.

[-- Attachment #2: 0003-Implement-casts-to-bool-using-double-negation-like-i.patch --]
[-- Type: application/octet-stream, Size: 3761 bytes --]

From 39b8d7b0bbcda4f4f34759b02cc2cf30523536ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Sun, 31 May 2020 17:24:03 -0300
Subject: [PATCH 3/4] Implement casts to bool using double negation like in C.

* src/comp.c (define_cast_to_bool): New function that uses double
negation to cast to bool.
---
 src/comp.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/src/comp.c b/src/comp.c
index 6f92801b13f..ed2e5f37338 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -2909,10 +2909,76 @@ define_thread_state_struct (void)
   size_t bytes_size;
 };
 
+static gcc_jit_function *
+define_cast_to_bool (struct cast_type from, int from_index)
+{
+  char *name = format_string ("cast_from_%s_to_%s", from.name, "bool");
+  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_INTERNAL,
+                               comp.bool_type,
+                               name,
+                               1,
+                               &param,
+                               0);
+
+  DECL_BLOCK (entry_block, result);
+
+  gcc_jit_lvalue *tmp_union
+    = gcc_jit_function_new_local (result,
+                                  NULL,
+                                  comp.cast_union_type,
+                                  "union_cast");
+
+  /*  Zero the union first.  */
+  gcc_jit_block_add_assignment (entry_block, NULL,
+                                gcc_jit_lvalue_access_field (tmp_union, NULL,
+                                  comp.cast_union_fields[NUM_CAST_TYPES]),
+                                  gcc_jit_context_new_rvalue_from_int (
+				    comp.ctxt,
+				    comp.cast_types[NUM_CAST_TYPES],
+                                    0));
+
+  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_rvalue *cast_to_biggest
+    = gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (tmp_union),
+                                   NULL,
+                                   comp.cast_union_fields[NUM_CAST_TYPES]);
+
+  gcc_jit_rvalue *first_negation
+    = gcc_jit_context_new_unary_op (comp.ctxt,
+                                    NULL,
+                                    GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
+                                    comp.bool_type,
+                                    cast_to_biggest);
+
+  gcc_jit_rvalue *second_negation
+    = gcc_jit_context_new_unary_op (comp.ctxt,
+                                    NULL,
+                                    GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
+                                    comp.bool_type,
+                                    first_negation);
+
+  gcc_jit_block_end_with_return (entry_block,
+                                 NULL,
+                                 second_negation);
+
+  return result;
+}
+
 static gcc_jit_function *
 define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
                     int to_index)
 {
+  if (to.type == comp.bool_type)
+    return define_cast_to_bool (from, from_index);
+
   char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
   gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
                                                     from.type, "arg");
-- 
2.25.1.windows.1


[-- Attachment #3: 0004-Throw-an-ICE-when-asked-to-emit-a-cast-with-sign-ext.patch --]
[-- Type: application/octet-stream, Size: 6248 bytes --]

From 435ed84c6df4911b238f67c79492533e0c71ca46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Sun, 31 May 2020 18:09:12 -0300
Subject: [PATCH 4/4] Throw an ICE when asked to emit a cast with sign
 extension.

* src/comp.c (cast_kind_of_type): Enum that specifies the kind of type
in the cast enum (unsigned, signed, pointer).
(emit_coerce): Throw an ICE when asked to emit a cast with sign
extension.
(define_cast_from_to): Return NULL for casts involving sign extension.
(define_cast_functions): Specify the kind of each type in the cast
union.
---
 src/comp.c | 58 ++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/src/comp.c b/src/comp.c
index ed2e5f37338..8dc936f451a 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -450,6 +450,13 @@ #define F_RELOC_MAX_SIZE 1500
 
 #define NUM_CAST_TYPES 15
 
+enum cast_kind_of_type
+  {
+    kind_unsigned,
+    kind_signed,
+    kind_pointer
+  };
+
 /* C side of the compiler context.  */
 
 typedef struct {
@@ -514,6 +521,7 @@ #define NUM_CAST_TYPES 15
       member.  */
   gcc_jit_type *cast_types[NUM_CAST_TYPES+1];
   size_t cast_type_sizes[NUM_CAST_TYPES+1];
+  enum cast_kind_of_type cast_type_kind[NUM_CAST_TYPES+1];
   const char *cast_type_names[NUM_CAST_TYPES+1];
   gcc_jit_field *cast_union_fields[NUM_CAST_TYPES+1];
   size_t cast_union_field_biggest_type;
@@ -980,6 +988,13 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
   int old_index = type_to_cast_index (old_type);
   int new_index = type_to_cast_index (new_type);
 
+  if (comp.cast_type_sizes[old_index] < comp.cast_type_sizes[new_index]
+      && comp.cast_type_kind[new_index] == kind_signed)
+    xsignal3 (Qnative_ice,
+              build_string ("FIXME: sign extension not implemented"),
+              build_string (comp.cast_type_names[old_index]),
+              build_string (comp.cast_type_names[new_index]));
+
   /* Lookup the appropriate cast function in the cast matrix.  */
   return gcc_jit_context_new_call (comp.ctxt,
            NULL,
@@ -2907,6 +2922,7 @@ define_thread_state_struct (void)
   gcc_jit_type *type;
   const char *name;
   size_t bytes_size;
+  enum cast_kind_of_type kind;
 };
 
 static gcc_jit_function *
@@ -2979,6 +2995,11 @@ define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
   if (to.type == comp.bool_type)
     return define_cast_to_bool (from, from_index);
 
+  /*  FIXME: sign extension not implemented.  */
+  if (comp.cast_type_sizes[from_index] < comp.cast_type_sizes[to_index]
+      && comp.cast_type_kind[to_index] == kind_signed)
+    return NULL;
+
   char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
   gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
                                                     from.type, "arg");
@@ -3027,22 +3048,27 @@ define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
 define_cast_functions (void)
 {
   struct cast_type cast_types[NUM_CAST_TYPES]
-    = { { comp.bool_type, "bool", sizeof (bool) },
-        { comp.char_ptr_type, "char_ptr", sizeof (char *) },
-        { comp.int_type, "int", sizeof (int) },
-        { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *) },
-        { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *) },
-        { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag) },
-        { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word) },
-        { comp.long_long_type, "long_long", sizeof (long long) },
-        { comp.long_type, "long", sizeof (long) },
-        { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t) },
-        { comp.uintptr_type, "uintptr", sizeof (uintptr_t) },
+    = { { comp.bool_type, "bool", sizeof (bool), kind_unsigned },
+        { comp.char_ptr_type, "char_ptr", sizeof (char *), kind_pointer },
+        { comp.int_type, "int", sizeof (int), kind_signed },
+        { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *),
+          kind_pointer },
+        { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *),
+          kind_pointer },
+        { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag),
+          kind_unsigned },
+        { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word),
+          LISP_WORDS_ARE_POINTERS ? kind_pointer : kind_signed },
+        { comp.long_long_type, "long_long", sizeof (long long), kind_signed },
+        { comp.long_type, "long", sizeof (long), kind_signed },
+        { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t), kind_signed },
+        { comp.uintptr_type, "uintptr", sizeof (uintptr_t), kind_unsigned },
         { comp.unsigned_long_long_type, "unsigned_long_long",
-          sizeof (unsigned long long) },
-        { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long) },
-        { comp.unsigned_type, "unsigned", sizeof (unsigned) },
-        { comp.void_ptr_type, "void_ptr", sizeof (void*) } };
+          sizeof (unsigned long long), kind_unsigned },
+        { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long),
+          kind_unsigned },
+        { comp.unsigned_type, "unsigned", sizeof (unsigned), kind_unsigned },
+        { comp.void_ptr_type, "void_ptr", sizeof (void*), kind_pointer } };
 
   /* Find the biggest size.  It should be unsigned long long, but to be
      sure we find it programmatically.  */
@@ -3060,6 +3086,7 @@ define_cast_functions (void)
                                     cast_types[i].name);
       comp.cast_type_names[i] = cast_types[i].name;
       comp.cast_type_sizes[i] = cast_types[i].bytes_size;
+      comp.cast_type_kind[i] = cast_types[i].kind;
     }
 
   gcc_jit_type *biggest_type = gcc_jit_context_get_int_type (comp.ctxt,
@@ -3070,6 +3097,7 @@ define_cast_functions (void)
     = gcc_jit_context_new_field (comp.ctxt, NULL, biggest_type, "biggest_type");
   comp.cast_type_names[NUM_CAST_TYPES] = "biggest_type";
   comp.cast_type_sizes[NUM_CAST_TYPES] = biggest_size;
+  comp.cast_type_kind[NUM_CAST_TYPES] = kind_unsigned;
 
   comp.cast_union_type =
     gcc_jit_context_new_union_type (comp.ctxt,
-- 
2.25.1.windows.1


[-- Attachment #4: 0001-Remove-unnecessary-DLL-load-of-gcc_jit_block_add_ass.patch --]
[-- Type: application/octet-stream, Size: 2111 bytes --]

From ec7af221c7dbf9b9fc551ef38d6e70a1bf09d4e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Sun, 31 May 2020 15:55:18 -0300
Subject: [PATCH 1/4] Remove unnecessary DLL load of
 gcc_jit_block_add_assignment_op.

---
 src/comp.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/src/comp.c b/src/comp.c
index 81c4d2fe32a..8d8094e9869 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -46,7 +46,6 @@
 # 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
@@ -201,10 +200,6 @@ 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));
@@ -247,7 +242,6 @@ 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);
@@ -306,7 +300,6 @@ 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
-- 
2.25.1.windows.1


[-- Attachment #5: 0002-Define-casts-using-functions.patch --]
[-- Type: application/octet-stream, Size: 14051 bytes --]

From 91189343ccd6943eafc2f3dc8b3b19b8ea879903 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Sat, 30 May 2020 18:33:58 -0300
Subject: [PATCH 2/4] 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 | 313 +++++++++++++++++++++++------------------------------
 1 file changed, 138 insertions(+), 175 deletions(-)

diff --git a/src/comp.c b/src/comp.c
index 8d8094e9869..6f92801b13f 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -448,6 +448,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 {
@@ -507,21 +509,14 @@ #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];
+  /*  We add one to make space for the last member which is the "biggest_type"
+      member.  */
+  gcc_jit_type *cast_types[NUM_CAST_TYPES+1];
+  size_t cast_type_sizes[NUM_CAST_TYPES+1];
+  const char *cast_type_names[NUM_CAST_TYPES+1];
+  gcc_jit_field *cast_union_fields[NUM_CAST_TYPES+1];
+  size_t cast_union_field_biggest_type;
   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.  */
@@ -678,47 +673,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)
 {
@@ -979,11 +933,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)
@@ -1015,25 +977,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 *
@@ -1090,7 +1041,7 @@ emit_rvalue_from_long_long (gcc_jit_type *type, long long n)
 	  gcc_jit_context_new_rvalue_from_int (comp.ctxt,
 					       comp.unsigned_long_long_type,
 					       32)),
-	low));
+             low));
 }
 
 static gcc_jit_rvalue *
@@ -1132,7 +1083,7 @@ emit_rvalue_from_unsigned_long_long (gcc_jit_type *type, unsigned long long n)
                gcc_jit_context_new_rvalue_from_int (comp.ctxt,
                                                     comp.unsigned_long_long_type,
                                                     32)),
-             low));
+	low));
 }
 
 static gcc_jit_rvalue *
@@ -2951,109 +2902,121 @@ 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;
+  size_t bytes_size;
+};
 
-  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,
+static gcc_jit_function *
+define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
+                    int to_index)
+{
+  char *name = format_string ("cast_from_%s_to_%s", from.name, 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,
-                               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 };
+                               GCC_JIT_FUNCTION_INTERNAL,
+                               to.type,
+                               name,
+                               1,
+                               &param,
+                               0);
+
+  DECL_BLOCK (entry_block, result);
+
+  gcc_jit_lvalue *tmp_union
+    = gcc_jit_function_new_local (result,
+                                  NULL,
+                                  comp.cast_union_type,
+                                  "union_cast");
+
+  /*  Zero the union first.  */
+  gcc_jit_block_add_assignment (entry_block, NULL,
+                                gcc_jit_lvalue_access_field (tmp_union, NULL,
+                                  comp.cast_union_fields[NUM_CAST_TYPES]),
+                                  gcc_jit_context_new_rvalue_from_int (
+				    comp.ctxt,
+				    comp.cast_types[NUM_CAST_TYPES],
+                                    0));
+
+  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", sizeof (bool) },
+        { comp.char_ptr_type, "char_ptr", sizeof (char *) },
+        { comp.int_type, "int", sizeof (int) },
+        { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *) },
+        { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *) },
+        { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag) },
+        { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word) },
+        { comp.long_long_type, "long_long", sizeof (long long) },
+        { comp.long_type, "long", sizeof (long) },
+        { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t) },
+        { comp.uintptr_type, "uintptr", sizeof (uintptr_t) },
+        { comp.unsigned_long_long_type, "unsigned_long_long",
+          sizeof (unsigned long long) },
+        { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long) },
+        { comp.unsigned_type, "unsigned", sizeof (unsigned) },
+        { comp.void_ptr_type, "void_ptr", sizeof (void*) } };
+
+  /* Find the biggest size.  It should be unsigned long long, but to be
+     sure we find it programmatically.  */
+  size_t biggest_size = 0;
+  for (int i = 0; i < NUM_CAST_TYPES; ++i)
+    biggest_size = max (biggest_size, cast_types[i].bytes_size);
+
+  /* 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_type_names[i] = cast_types[i].name;
+      comp.cast_type_sizes[i] = cast_types[i].bytes_size;
+    }
+
+  gcc_jit_type *biggest_type = gcc_jit_context_get_int_type (comp.ctxt,
+                                                             biggest_size,
+                                                             false);
+  comp.cast_types[NUM_CAST_TYPES] = biggest_type;
+  comp.cast_union_fields[NUM_CAST_TYPES]
+    = gcc_jit_context_new_field (comp.ctxt, NULL, biggest_type, "biggest_type");
+  comp.cast_type_names[NUM_CAST_TYPES] = "biggest_type";
+  comp.cast_type_sizes[NUM_CAST_TYPES] = biggest_size;
+
   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+1,
+				    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
@@ -3869,7 +3832,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 ();
 
   return Qt;
 }
-- 
2.25.1.windows.1


  reply	other threads:[~2020-06-01 12:25 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-30 15:08 bug#41615: [feature/native-comp] Dump prettier C code Nicolas Bértolo
2020-05-30 22:20 ` 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 [this message]
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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFnS-O=CHDPbfG0BmP_T_qiokzGzB3ivETRGUVtCs-mmTE700A@mail.gmail.com' \
    --to=nicolasbertolo@gmail.com \
    --cc=41615@debbugs.gnu.org \
    --cc=akrl@sdf.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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.