aboutsummaryrefslogtreecommitdiffstats
path: root/src/comp.c
diff options
context:
space:
mode:
authorNicolás Bértolo2020-05-30 18:33:58 -0300
committerAndrea Corallo2020-06-01 21:24:33 +0100
commit035a91dd963290a40766b430e4e9a108cbbc4eac (patch)
tree8e1f48d524da5135089a262d872c8e8783ea2acb /src/comp.c
parent516575369b7168f09030d297b5a2f89a26f1894d (diff)
downloademacs-035a91dd963290a40766b430e4e9a108cbbc4eac.tar.gz
emacs-035a91dd963290a40766b430e4e9a108cbbc4eac.zip
* 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().
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c309
1 files changed, 136 insertions, 173 deletions
diff --git a/src/comp.c b/src/comp.c
index b6726822b75..8ccae7cf846 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -454,6 +454,8 @@ sigset_t saved_sigset;
454 454
455static f_reloc_t freloc; 455static f_reloc_t freloc;
456 456
457#define NUM_CAST_TYPES 15
458
457/* C side of the compiler context. */ 459/* C side of the compiler context. */
458 460
459typedef struct { 461typedef struct {
@@ -513,21 +515,14 @@ typedef struct {
513 /* libgccjit has really limited support for casting therefore this union will 515 /* libgccjit has really limited support for casting therefore this union will
514 be used for the scope. */ 516 be used for the scope. */
515 gcc_jit_type *cast_union_type; 517 gcc_jit_type *cast_union_type;
516 gcc_jit_field *cast_union_as_ll; 518 gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES];
517 gcc_jit_field *cast_union_as_ull; 519 /* We add one to make space for the last member which is the "biggest_type"
518 gcc_jit_field *cast_union_as_l; 520 member. */
519 gcc_jit_field *cast_union_as_ul; 521 gcc_jit_type *cast_types[NUM_CAST_TYPES+1];
520 gcc_jit_field *cast_union_as_u; 522 size_t cast_type_sizes[NUM_CAST_TYPES+1];
521 gcc_jit_field *cast_union_as_i; 523 const char *cast_type_names[NUM_CAST_TYPES+1];
522 gcc_jit_field *cast_union_as_b; 524 gcc_jit_field *cast_union_fields[NUM_CAST_TYPES+1];
523 gcc_jit_field *cast_union_as_uintptr; 525 size_t cast_union_field_biggest_type;
524 gcc_jit_field *cast_union_as_ptrdiff;
525 gcc_jit_field *cast_union_as_c_p;
526 gcc_jit_field *cast_union_as_v_p;
527 gcc_jit_field *cast_union_as_lisp_cons_ptr;
528 gcc_jit_field *cast_union_as_lisp_word;
529 gcc_jit_field *cast_union_as_lisp_word_tag;
530 gcc_jit_field *cast_union_as_lisp_obj_ptr;
531 gcc_jit_function *func; /* Current function being compiled. */ 526 gcc_jit_function *func; /* Current function being compiled. */
532 bool func_has_non_local; /* From comp-func has-non-local slot. */ 527 bool func_has_non_local; /* From comp-func has-non-local slot. */
533 gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */ 528 gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */
@@ -684,47 +679,6 @@ bcall0 (Lisp_Object f)
684 Ffuncall (1, &f); 679 Ffuncall (1, &f);
685} 680}
686 681
687static gcc_jit_field *
688type_to_cast_field (gcc_jit_type *type)
689{
690 gcc_jit_field *field;
691
692 if (type == comp.long_long_type)
693 field = comp.cast_union_as_ll;
694 else if (type == comp.unsigned_long_long_type)
695 field = comp.cast_union_as_ull;
696 else if (type == comp.long_type)
697 field = comp.cast_union_as_l;
698 else if (type == comp.unsigned_long_type)
699 field = comp.cast_union_as_ul;
700 else if (type == comp.unsigned_type)
701 field = comp.cast_union_as_u;
702 else if (type == comp.int_type)
703 field = comp.cast_union_as_i;
704 else if (type == comp.bool_type)
705 field = comp.cast_union_as_b;
706 else if (type == comp.void_ptr_type)
707 field = comp.cast_union_as_v_p;
708 else if (type == comp.uintptr_type)
709 field = comp.cast_union_as_uintptr;
710 else if (type == comp.ptrdiff_type)
711 field = comp.cast_union_as_ptrdiff;
712 else if (type == comp.char_ptr_type)
713 field = comp.cast_union_as_c_p;
714 else if (type == comp.lisp_cons_ptr_type)
715 field = comp.cast_union_as_lisp_cons_ptr;
716 else if (type == comp.lisp_word_type)
717 field = comp.cast_union_as_lisp_word;
718 else if (type == comp.lisp_word_tag_type)
719 field = comp.cast_union_as_lisp_word_tag;
720 else if (type == comp.lisp_obj_ptr_type)
721 field = comp.cast_union_as_lisp_obj_ptr;
722 else
723 xsignal1 (Qnative_ice, build_string ("unsupported cast"));
724
725 return field;
726}
727
728static gcc_jit_block * 682static gcc_jit_block *
729retrive_block (Lisp_Object block_name) 683retrive_block (Lisp_Object block_name)
730{ 684{
@@ -985,11 +939,19 @@ emit_cond_jump (gcc_jit_rvalue *test,
985 939
986} 940}
987 941
942static int
943type_to_cast_index (gcc_jit_type * type)
944{
945 for (int i = 0; i < NUM_CAST_TYPES; ++i)
946 if (type == comp.cast_types[i])
947 return i;
948
949 xsignal1 (Qnative_ice, build_string ("unsupported cast"));
950}
951
988static gcc_jit_rvalue * 952static gcc_jit_rvalue *
989emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) 953emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
990{ 954{
991 static ptrdiff_t i;
992
993 gcc_jit_type *old_type = gcc_jit_rvalue_get_type (obj); 955 gcc_jit_type *old_type = gcc_jit_rvalue_get_type (obj);
994 956
995 if (new_type == old_type) 957 if (new_type == old_type)
@@ -1021,25 +983,14 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
1021 } 983 }
1022#endif 984#endif
1023 985
1024 gcc_jit_field *orig_field = 986 int old_index = type_to_cast_index (old_type);
1025 type_to_cast_field (old_type); 987 int new_index = type_to_cast_index (new_type);
1026 gcc_jit_field *dest_field = type_to_cast_field (new_type);
1027 988
1028 gcc_jit_lvalue *tmp_u = 989 /* Lookup the appropriate cast function in the cast matrix. */
1029 gcc_jit_function_new_local (comp.func, 990 return gcc_jit_context_new_call (comp.ctxt,
1030 NULL, 991 NULL,
1031 comp.cast_union_type, 992 comp.cast_functions_from_to[old_index][new_index],
1032 format_string ("union_cast_%td", i++)); 993 1, &obj);
1033 gcc_jit_block_add_assignment (comp.block,
1034 NULL,
1035 gcc_jit_lvalue_access_field (tmp_u,
1036 NULL,
1037 orig_field),
1038 obj);
1039
1040 return gcc_jit_rvalue_access_field ( gcc_jit_lvalue_as_rvalue (tmp_u),
1041 NULL,
1042 dest_field);
1043} 994}
1044 995
1045static gcc_jit_rvalue * 996static gcc_jit_rvalue *
@@ -2963,109 +2914,121 @@ define_thread_state_struct (void)
2963 gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s)); 2914 gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s));
2964} 2915}
2965 2916
2966static void 2917struct cast_type
2967define_cast_union (void)
2968{ 2918{
2919 gcc_jit_type *type;
2920 const char *name;
2921 size_t bytes_size;
2922};
2969 2923
2970 comp.cast_union_as_ll = 2924static gcc_jit_function *
2971 gcc_jit_context_new_field (comp.ctxt, 2925define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
2972 NULL, 2926 int to_index)
2973 comp.long_long_type, 2927{
2974 "ll"); 2928 char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
2975 comp.cast_union_as_ull = 2929 gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
2976 gcc_jit_context_new_field (comp.ctxt, 2930 from.type, "arg");
2977 NULL, 2931 gcc_jit_function *result = gcc_jit_context_new_function (comp.ctxt,
2978 comp.unsigned_long_long_type,
2979 "ull");
2980 comp.cast_union_as_l =
2981 gcc_jit_context_new_field (comp.ctxt,
2982 NULL,
2983 comp.long_type,
2984 "l");
2985 comp.cast_union_as_ul =
2986 gcc_jit_context_new_field (comp.ctxt,
2987 NULL,
2988 comp.unsigned_long_type,
2989 "ul");
2990 comp.cast_union_as_u =
2991 gcc_jit_context_new_field (comp.ctxt,
2992 NULL,
2993 comp.unsigned_type,
2994 "u");
2995 comp.cast_union_as_i =
2996 gcc_jit_context_new_field (comp.ctxt,
2997 NULL,
2998 comp.int_type,
2999 "i");
3000 comp.cast_union_as_b =
3001 gcc_jit_context_new_field (comp.ctxt,
3002 NULL,
3003 comp.bool_type,
3004 "b");
3005 comp.cast_union_as_uintptr =
3006 gcc_jit_context_new_field (comp.ctxt,
3007 NULL,
3008 comp.uintptr_type,
3009 "uintptr");
3010 comp.cast_union_as_ptrdiff =
3011 gcc_jit_context_new_field (comp.ctxt,
3012 NULL,
3013 comp.ptrdiff_type,
3014 "ptrdiff");
3015 comp.cast_union_as_c_p =
3016 gcc_jit_context_new_field (comp.ctxt,
3017 NULL,
3018 comp.char_ptr_type,
3019 "c_p");
3020 comp.cast_union_as_v_p =
3021 gcc_jit_context_new_field (comp.ctxt,
3022 NULL,
3023 comp.void_ptr_type,
3024 "v_p");
3025 comp.cast_union_as_lisp_cons_ptr =
3026 gcc_jit_context_new_field (comp.ctxt,
3027 NULL,
3028 comp.lisp_cons_ptr_type,
3029 "cons_ptr");
3030 comp.cast_union_as_lisp_word =
3031 gcc_jit_context_new_field (comp.ctxt,
3032 NULL,
3033 comp.lisp_word_type,
3034 "lisp_word");
3035 comp.cast_union_as_lisp_word_tag =
3036 gcc_jit_context_new_field (comp.ctxt,
3037 NULL, 2932 NULL,
3038 comp.lisp_word_tag_type, 2933 GCC_JIT_FUNCTION_INTERNAL,
3039 "lisp_word_tag"); 2934 to.type,
3040 comp.cast_union_as_lisp_obj_ptr = 2935 name,
3041 gcc_jit_context_new_field (comp.ctxt, 2936 1,
3042 NULL, 2937 &param,
3043 comp.lisp_obj_ptr_type, 2938 0);
3044 "lisp_obj_ptr"); 2939
3045 2940 DECL_BLOCK (entry_block, result);
3046 2941
3047 gcc_jit_field *cast_union_fields[] = 2942 gcc_jit_lvalue *tmp_union
3048 { comp.cast_union_as_ll, 2943 = gcc_jit_function_new_local (result,
3049 comp.cast_union_as_ull, 2944 NULL,
3050 comp.cast_union_as_l, 2945 comp.cast_union_type,
3051 comp.cast_union_as_ul, 2946 "union_cast");
3052 comp.cast_union_as_u, 2947
3053 comp.cast_union_as_i, 2948 /* Zero the union first. */
3054 comp.cast_union_as_b, 2949 gcc_jit_block_add_assignment (entry_block, NULL,
3055 comp.cast_union_as_uintptr, 2950 gcc_jit_lvalue_access_field (tmp_union, NULL,
3056 comp.cast_union_as_ptrdiff, 2951 comp.cast_union_fields[NUM_CAST_TYPES]),
3057 comp.cast_union_as_c_p, 2952 gcc_jit_context_new_rvalue_from_int (
3058 comp.cast_union_as_v_p, 2953 comp.ctxt,
3059 comp.cast_union_as_lisp_cons_ptr, 2954 comp.cast_types[NUM_CAST_TYPES],
3060 comp.cast_union_as_lisp_word, 2955 0));
3061 comp.cast_union_as_lisp_word_tag, 2956
3062 comp.cast_union_as_lisp_obj_ptr }; 2957 gcc_jit_block_add_assignment (entry_block, NULL,
2958 gcc_jit_lvalue_access_field (tmp_union, NULL,
2959 comp.cast_union_fields[from_index]),
2960 gcc_jit_param_as_rvalue (param));
2961
2962 gcc_jit_block_end_with_return (entry_block,
2963 NULL,
2964 gcc_jit_rvalue_access_field (
2965 gcc_jit_lvalue_as_rvalue (tmp_union),
2966 NULL,
2967 comp.cast_union_fields[to_index]));
2968
2969 return result;
2970}
2971
2972static void
2973define_cast_functions (void)
2974{
2975 struct cast_type cast_types[NUM_CAST_TYPES]
2976 = { { comp.bool_type, "bool", sizeof (bool) },
2977 { comp.char_ptr_type, "char_ptr", sizeof (char *) },
2978 { comp.int_type, "int", sizeof (int) },
2979 { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *) },
2980 { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *) },
2981 { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag) },
2982 { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word) },
2983 { comp.long_long_type, "long_long", sizeof (long long) },
2984 { comp.long_type, "long", sizeof (long) },
2985 { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t) },
2986 { comp.uintptr_type, "uintptr", sizeof (uintptr_t) },
2987 { comp.unsigned_long_long_type, "unsigned_long_long",
2988 sizeof (unsigned long long) },
2989 { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long) },
2990 { comp.unsigned_type, "unsigned", sizeof (unsigned) },
2991 { comp.void_ptr_type, "void_ptr", sizeof (void*) } };
2992
2993 /* Find the biggest size. It should be unsigned long long, but to be
2994 sure we find it programmatically. */
2995 size_t biggest_size = 0;
2996 for (int i = 0; i < NUM_CAST_TYPES; ++i)
2997 biggest_size = max (biggest_size, cast_types[i].bytes_size);
2998
2999 /* Define the union used for casting. */
3000 for (int i = 0; i < NUM_CAST_TYPES; ++i)
3001 {
3002 comp.cast_types[i] = cast_types[i].type;
3003 comp.cast_union_fields[i] = gcc_jit_context_new_field (comp.ctxt,
3004 NULL,
3005 cast_types[i].type,
3006 cast_types[i].name);
3007 comp.cast_type_names[i] = cast_types[i].name;
3008 comp.cast_type_sizes[i] = cast_types[i].bytes_size;
3009 }
3010
3011 gcc_jit_type *biggest_type = gcc_jit_context_get_int_type (comp.ctxt,
3012 biggest_size,
3013 false);
3014 comp.cast_types[NUM_CAST_TYPES] = biggest_type;
3015 comp.cast_union_fields[NUM_CAST_TYPES]
3016 = gcc_jit_context_new_field (comp.ctxt, NULL, biggest_type, "biggest_type");
3017 comp.cast_type_names[NUM_CAST_TYPES] = "biggest_type";
3018 comp.cast_type_sizes[NUM_CAST_TYPES] = biggest_size;
3019
3063 comp.cast_union_type = 3020 comp.cast_union_type =
3064 gcc_jit_context_new_union_type (comp.ctxt, 3021 gcc_jit_context_new_union_type (comp.ctxt,
3065 NULL, 3022 NULL,
3066 "cast_union", 3023 "cast_union",
3067 ARRAYELTS (cast_union_fields), 3024 NUM_CAST_TYPES + 1,
3068 cast_union_fields); 3025 comp.cast_union_fields);
3026
3027 /* Define the cast functions using a matrix. */
3028 for (int i = 0; i < NUM_CAST_TYPES; ++i)
3029 for (int j = 0; j < NUM_CAST_TYPES; ++j)
3030 comp.cast_functions_from_to[i][j] =
3031 define_cast_from_to (cast_types[i], i, cast_types[j], j);
3069} 3032}
3070 3033
3071static void 3034static void
@@ -3881,7 +3844,7 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
3881 define_jmp_buf (); 3844 define_jmp_buf ();
3882 define_handler_struct (); 3845 define_handler_struct ();
3883 define_thread_state_struct (); 3846 define_thread_state_struct ();
3884 define_cast_union (); 3847 define_cast_functions ();
3885 3848
3886 return Qt; 3849 return Qt;
3887} 3850}