diff options
| author | Nicolás Bértolo | 2020-05-30 18:33:58 -0300 |
|---|---|---|
| committer | Andrea Corallo | 2020-06-01 21:24:33 +0100 |
| commit | 035a91dd963290a40766b430e4e9a108cbbc4eac (patch) | |
| tree | 8e1f48d524da5135089a262d872c8e8783ea2acb /src | |
| parent | 516575369b7168f09030d297b5a2f89a26f1894d (diff) | |
| download | emacs-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')
| -rw-r--r-- | src/comp.c | 309 |
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 | ||
| 455 | static f_reloc_t freloc; | 455 | static 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 | ||
| 459 | typedef struct { | 461 | typedef 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 | ||
| 687 | static gcc_jit_field * | ||
| 688 | type_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 | |||
| 728 | static gcc_jit_block * | 682 | static gcc_jit_block * |
| 729 | retrive_block (Lisp_Object block_name) | 683 | retrive_block (Lisp_Object block_name) |
| 730 | { | 684 | { |
| @@ -985,11 +939,19 @@ emit_cond_jump (gcc_jit_rvalue *test, | |||
| 985 | 939 | ||
| 986 | } | 940 | } |
| 987 | 941 | ||
| 942 | static int | ||
| 943 | type_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 | |||
| 988 | static gcc_jit_rvalue * | 952 | static gcc_jit_rvalue * |
| 989 | emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) | 953 | emit_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 | ||
| 1045 | static gcc_jit_rvalue * | 996 | static 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 | ||
| 2966 | static void | 2917 | struct cast_type |
| 2967 | define_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 = | 2924 | static gcc_jit_function * |
| 2971 | gcc_jit_context_new_field (comp.ctxt, | 2925 | define_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 | ¶m, |
| 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 | |||
| 2972 | static void | ||
| 2973 | define_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 | ||
| 3071 | static void | 3034 | static 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 | } |