From 92d75e5c53241ac76e8fdcb6fc66ade68354687c Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Tue, 27 Sep 2022 22:38:45 +0530 Subject: [PATCH] src/comp.c: Use libgccjit's bitcast API for type coercion, when available. * (type_to_cast_index, define_type_punning, define_cast_from_to, define_cast_functions): Define functions when gcc_jit_context_new_bitcast is not available. * (emit_coerce): Use gcc_jit_context_new_bitcast to coerce types, when available. --- src/comp.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/comp.c b/src/comp.c index 1b767ba0dd8..27e914028da 100644 --- a/src/comp.c +++ b/src/comp.c @@ -68,6 +68,7 @@ along with GNU Emacs. If not, see . */ #undef gcc_jit_context_get_type #undef gcc_jit_context_new_array_access #undef gcc_jit_context_new_array_type +#undef gcc_jit_context_new_bitcast #undef gcc_jit_context_new_binary_op #undef gcc_jit_context_new_call #undef gcc_jit_context_new_call_through_ptr @@ -180,8 +181,13 @@ DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call_through_ptr, (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *fn_ptr, int numargs, gcc_jit_rvalue **args)); DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_cast, + (gcc_jit_context * ctxt, gcc_jit_location *loc, + gcc_jit_rvalue *rvalue, gcc_jit_type *type)); +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_bitcast, (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *rvalue, gcc_jit_type *type)); +#endif DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_comparison, (gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_comparison op, gcc_jit_rvalue *a, gcc_jit_rvalue *b)); @@ -293,6 +299,9 @@ init_gccjit_functions (void) LOAD_DLL_FN (library, gcc_jit_context_get_type); LOAD_DLL_FN (library, gcc_jit_context_new_array_access); LOAD_DLL_FN (library, gcc_jit_context_new_array_type); +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + LOAD_DLL_FN (library, gcc_jit_context_new_bitcast); +#endif LOAD_DLL_FN (library, gcc_jit_context_new_binary_op); LOAD_DLL_FN (library, gcc_jit_context_new_call); LOAD_DLL_FN (library, gcc_jit_context_new_call_through_ptr); @@ -368,6 +377,9 @@ init_gccjit_functions (void) #define gcc_jit_context_get_type fn_gcc_jit_context_get_type #define gcc_jit_context_new_array_access fn_gcc_jit_context_new_array_access #define gcc_jit_context_new_array_type fn_gcc_jit_context_new_array_type +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + #define gcc_jit_context_new_bitcast fn_gcc_jit_context_new_bitcast +#endif #define gcc_jit_context_new_binary_op fn_gcc_jit_context_new_binary_op #define gcc_jit_context_new_call fn_gcc_jit_context_new_call #define gcc_jit_context_new_call_through_ptr fn_gcc_jit_context_new_call_through_ptr @@ -518,7 +530,9 @@ typedef struct { static f_reloc_t freloc; +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast #define NUM_CAST_TYPES 15 +#endif typedef struct { EMACS_INT len; @@ -593,13 +607,15 @@ typedef struct { gcc_jit_rvalue *current_thread_ref; /* Other globals. */ gcc_jit_rvalue *pure_ptr; - /* libgccjit has really limited support for casting therefore this union will - be used for the scope. */ +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + /* This version of libgccjit has really limited support for casting + therefore this union will be used for the scope. */ gcc_jit_type *cast_union_type; gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES]; gcc_jit_function *cast_ptr_to_int; gcc_jit_function *cast_int_to_ptr; gcc_jit_type *cast_types[NUM_CAST_TYPES]; +#endif gcc_jit_function *func; /* Current function being compiled. */ bool func_has_non_local; /* From comp-func has-non-local slot. */ EMACS_INT func_speed; /* From comp-func speed slot. */ @@ -1100,6 +1116,7 @@ emit_cond_jump (gcc_jit_rvalue *test, } +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast static int type_to_cast_index (gcc_jit_type * type) { @@ -1109,6 +1126,7 @@ type_to_cast_index (gcc_jit_type * type) xsignal1 (Qnative_ice, build_string ("unsupported cast")); } +#endif static gcc_jit_rvalue * emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) @@ -1145,14 +1163,41 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) } #endif +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + bool old_is_ptr = gcc_jit_type_is_pointer (old_type); + bool new_is_ptr = gcc_jit_type_is_pointer (new_type); + + gcc_jit_rvalue *tmp = obj; + + if (old_is_ptr != new_is_ptr) + { + if (old_is_ptr) + { + tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, + comp.void_ptr_type); + tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp, + comp.uintptr_type); + } + else + { + tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, + comp.uintptr_type); + tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp, + comp.void_ptr_type); + } + } + return gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, new_type); +#else /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ int old_index = type_to_cast_index (old_type); int new_index = type_to_cast_index (new_type); /* 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); + NULL, + comp.cast_functions_from_to + [old_index][new_index], + 1, &obj); +#endif } static gcc_jit_rvalue * @@ -3318,6 +3363,7 @@ define_thread_state_struct (void) gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s)); } +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast static gcc_jit_function * define_type_punning (const char *name, gcc_jit_type *from, gcc_jit_field *from_field, @@ -3336,6 +3382,7 @@ define_type_punning (const char *name, DECL_BLOCK (entry_block, result); + gcc_jit_lvalue *tmp_union = gcc_jit_function_new_local (result, NULL, @@ -3422,6 +3469,7 @@ define_cast_functions (void) { comp.unsigned_long_type, "unsigned_long", false }, { comp.unsigned_type, "unsigned", false }, { comp.void_ptr_type, "void_ptr", true } }; + gcc_jit_field *cast_union_fields[2]; /* Define the union used for type punning. */ @@ -3451,6 +3499,7 @@ define_cast_functions (void) comp.void_ptr_type, cast_union_fields[0]); + for (int i = 0; i < NUM_CAST_TYPES; ++i) comp.cast_types[i] = cast_types[i].type; @@ -3460,6 +3509,7 @@ define_cast_functions (void) comp.cast_functions_from_to[i][j] = define_cast_from_to (cast_types[i], cast_types[j]); } +#endif /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ static void define_CHECK_TYPE (void) @@ -4660,7 +4710,9 @@ Return t on success. */) define_jmp_buf (); define_handler_struct (); define_thread_state_struct (); +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast define_cast_functions (); +#endif return Qt; } -- 2.39.2