diff options
| author | Andrea Corallo | 2020-02-09 16:17:21 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-02-15 10:17:08 +0100 |
| commit | c27394da7e3e35ab35e0430ab331d6dadca2803d (patch) | |
| tree | 40b839bfafadd534271ab7a15de14c2c8b87e5a7 /src | |
| parent | 0c6f4caeb32b2bf531079feb5a9e73b79496b99d (diff) | |
| download | emacs-c27394da7e3e35ab35e0430ab331d6dadca2803d.tar.gz emacs-c27394da7e3e35ab35e0430ab331d6dadca2803d.zip | |
Rework frame layout
Every function call by reference gets use one unique array of
arguments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 117 |
1 files changed, 73 insertions, 44 deletions
diff --git a/src/comp.c b/src/comp.c index 4b1ddeda0f4..d95a87b03b1 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -150,10 +150,10 @@ typedef struct { | |||
| 150 | gcc_jit_field *cast_union_as_lisp_obj_ptr; | 150 | gcc_jit_field *cast_union_as_lisp_obj_ptr; |
| 151 | gcc_jit_function *func; /* Current function being compiled. */ | 151 | gcc_jit_function *func; /* Current function being compiled. */ |
| 152 | bool func_has_non_local; /* From comp-func has-non-local slot. */ | 152 | bool func_has_non_local; /* From comp-func has-non-local slot. */ |
| 153 | gcc_jit_block *block; /* Current basic block being compiled. */ | ||
| 154 | gcc_jit_lvalue **frame; /* Frame for the current function. */ | ||
| 155 | gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */ | 153 | gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */ |
| 154 | gcc_jit_block *block; /* Current basic block being compiled. */ | ||
| 156 | gcc_jit_lvalue *scratch; /* Used as scratch slot for some code sequence (switch). */ | 155 | gcc_jit_lvalue *scratch; /* Used as scratch slot for some code sequence (switch). */ |
| 156 | gcc_jit_lvalue ***arrays; /* Array index -> gcc_jit_lvalue **. */ | ||
| 157 | gcc_jit_rvalue *most_positive_fixnum; | 157 | gcc_jit_rvalue *most_positive_fixnum; |
| 158 | gcc_jit_rvalue *most_negative_fixnum; | 158 | gcc_jit_rvalue *most_negative_fixnum; |
| 159 | gcc_jit_rvalue *one; | 159 | gcc_jit_rvalue *one; |
| @@ -348,7 +348,7 @@ declare_block (Lisp_Object block_name) | |||
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static gcc_jit_lvalue * | 350 | static gcc_jit_lvalue * |
| 351 | get_slot (Lisp_Object mvar) | 351 | emit_mvar_access (Lisp_Object mvar) |
| 352 | { | 352 | { |
| 353 | Lisp_Object mvar_slot = CALL1I (comp-mvar-slot, mvar); | 353 | Lisp_Object mvar_slot = CALL1I (comp-mvar-slot, mvar); |
| 354 | 354 | ||
| @@ -361,15 +361,18 @@ get_slot (Lisp_Object mvar) | |||
| 361 | "scratch"); | 361 | "scratch"); |
| 362 | return comp.scratch; | 362 | return comp.scratch; |
| 363 | } | 363 | } |
| 364 | |||
| 365 | EMACS_INT arr_idx = XFIXNUM (CALL1I (comp-mvar-array-idx, mvar)); | ||
| 364 | EMACS_INT slot_n = XFIXNUM (mvar_slot); | 366 | EMACS_INT slot_n = XFIXNUM (mvar_slot); |
| 365 | gcc_jit_lvalue **frame = | 367 | if (comp.func_has_non_local || !SPEED) |
| 366 | /* Disable floating frame for functions with non local jumps. | 368 | return comp.arrays[arr_idx][slot_n]; |
| 367 | This is probably overkill cause we could do it just for blocks | 369 | else |
| 368 | dominated by push-handler. */ | 370 | { |
| 369 | comp.func_has_non_local | 371 | if (arr_idx) |
| 370 | || (CALL1I (comp-mvar-ref, mvar) || SPEED < 2) | 372 | return comp.arrays[arr_idx][slot_n]; |
| 371 | ? comp.frame : comp.f_frame; | 373 | else |
| 372 | return frame[slot_n]; | 374 | return comp.f_frame[slot_n]; |
| 375 | } | ||
| 373 | } | 376 | } |
| 374 | 377 | ||
| 375 | static void | 378 | static void |
| @@ -1140,7 +1143,7 @@ emit_mvar_val (Lisp_Object mvar) | |||
| 1140 | return emit_const_lisp_obj (constant, CALL1I (comp-mvar-impure, mvar)); | 1143 | return emit_const_lisp_obj (constant, CALL1I (comp-mvar-impure, mvar)); |
| 1141 | } | 1144 | } |
| 1142 | 1145 | ||
| 1143 | return gcc_jit_lvalue_as_rvalue (get_slot (mvar)); | 1146 | return gcc_jit_lvalue_as_rvalue (emit_mvar_access (mvar)); |
| 1144 | } | 1147 | } |
| 1145 | 1148 | ||
| 1146 | static void | 1149 | static void |
| @@ -1150,7 +1153,7 @@ emit_frame_assignment (Lisp_Object dst_mvar, gcc_jit_rvalue *val) | |||
| 1150 | gcc_jit_block_add_assignment ( | 1153 | gcc_jit_block_add_assignment ( |
| 1151 | comp.block, | 1154 | comp.block, |
| 1152 | NULL, | 1155 | NULL, |
| 1153 | get_slot (dst_mvar), | 1156 | emit_mvar_access (dst_mvar), |
| 1154 | val); | 1157 | val); |
| 1155 | } | 1158 | } |
| 1156 | 1159 | ||
| @@ -1239,10 +1242,28 @@ emit_limple_call_ref (Lisp_Object insn, bool direct) | |||
| 1239 | 1242 | ||
| 1240 | Lisp_Object callee = FIRST (insn); | 1243 | Lisp_Object callee = FIRST (insn); |
| 1241 | EMACS_INT nargs = XFIXNUM (Flength (CDR (insn))); | 1244 | EMACS_INT nargs = XFIXNUM (Flength (CDR (insn))); |
| 1242 | EMACS_INT base_ptr = 0; | 1245 | |
| 1243 | if (nargs) | 1246 | if (!nargs) |
| 1244 | base_ptr = XFIXNUM (CALL1I (comp-mvar-slot, SECOND (insn))); | 1247 | return emit_call_ref (callee, |
| 1245 | return emit_call_ref (callee, nargs, comp.frame[base_ptr], direct); | 1248 | nargs, |
| 1249 | comp.arrays[0][0], | ||
| 1250 | direct); | ||
| 1251 | |||
| 1252 | Lisp_Object first_arg = SECOND (insn); | ||
| 1253 | Lisp_Object arr_idx = CALL1I (comp-mvar-array-idx, first_arg); | ||
| 1254 | |||
| 1255 | /* Make sure all the arguments are layout-ed into the same array. */ | ||
| 1256 | Lisp_Object p = XCDR (XCDR (insn)); | ||
| 1257 | FOR_EACH_TAIL (p) | ||
| 1258 | if (!EQ (arr_idx, CALL1I (comp-mvar-array-idx, XCAR (p)))) | ||
| 1259 | xsignal2 (Qnative_ice, build_string ("incoherent array idx for insn"), | ||
| 1260 | insn); | ||
| 1261 | |||
| 1262 | EMACS_INT first_slot = XFIXNUM (CALL1I (comp-mvar-slot, first_arg)); | ||
| 1263 | return emit_call_ref (callee, | ||
| 1264 | nargs, | ||
| 1265 | comp.arrays[XFIXNUM (arr_idx)][first_slot], | ||
| 1266 | direct); | ||
| 1246 | } | 1267 | } |
| 1247 | 1268 | ||
| 1248 | /* Register an handler for a non local exit. */ | 1269 | /* Register an handler for a non local exit. */ |
| @@ -2867,34 +2888,43 @@ compile_function (Lisp_Object func) | |||
| 2867 | 2888 | ||
| 2868 | comp.func_has_non_local = !NILP (CALL1I (comp-func-has-non-local, func)); | 2889 | comp.func_has_non_local = !NILP (CALL1I (comp-func-has-non-local, func)); |
| 2869 | 2890 | ||
| 2870 | gcc_jit_lvalue *frame_array = | 2891 | struct Lisp_Hash_Table *array_h = |
| 2871 | gcc_jit_function_new_local ( | 2892 | XHASH_TABLE (CALL1I (comp-func-array-h, func)); |
| 2872 | comp.func, | 2893 | comp.arrays = SAFE_ALLOCA (array_h->count * sizeof (*comp.arrays)); |
| 2873 | NULL, | 2894 | for (ptrdiff_t i = 0; i < array_h->count; i++) |
| 2874 | gcc_jit_context_new_array_type (comp.ctxt, | 2895 | { |
| 2875 | NULL, | 2896 | EMACS_INT array_len = XFIXNUM (HASH_VALUE (array_h, i)); |
| 2876 | comp.lisp_obj_type, | 2897 | comp.arrays[i] = SAFE_ALLOCA (array_len * sizeof (**comp.arrays)); |
| 2877 | frame_size), | 2898 | |
| 2878 | "local"); | 2899 | gcc_jit_lvalue *arr = |
| 2879 | comp.frame = SAFE_ALLOCA (frame_size * sizeof (*comp.frame)); | 2900 | gcc_jit_function_new_local ( |
| 2880 | for (EMACS_INT i = 0; i < frame_size; ++i) | 2901 | comp.func, |
| 2881 | comp.frame[i] = | 2902 | NULL, |
| 2882 | gcc_jit_context_new_array_access ( | 2903 | gcc_jit_context_new_array_type (comp.ctxt, |
| 2883 | comp.ctxt, | 2904 | NULL, |
| 2884 | NULL, | 2905 | comp.lisp_obj_type, |
| 2885 | gcc_jit_lvalue_as_rvalue (frame_array), | 2906 | array_len), |
| 2886 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 2907 | format_string ("arr_%td", i)); |
| 2887 | comp.int_type, | 2908 | |
| 2888 | i)); | 2909 | for (ptrdiff_t j = 0; j < array_len; j++) |
| 2910 | comp.arrays[i][j] = | ||
| 2911 | gcc_jit_context_new_array_access ( | ||
| 2912 | comp.ctxt, | ||
| 2913 | NULL, | ||
| 2914 | gcc_jit_lvalue_as_rvalue (arr), | ||
| 2915 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 2916 | comp.int_type, | ||
| 2917 | j)); | ||
| 2918 | } | ||
| 2889 | 2919 | ||
| 2890 | /* | 2920 | /* |
| 2891 | The floating frame is a copy of the normal frame that can be used to store | 2921 | The floating frame is a copy of the normal frame that can be used to store |
| 2892 | locals if the are not going to be used in a nargs call. | 2922 | locals if the are not going to be used in a nargs call. |
| 2893 | This has two advantages: | 2923 | This has two advantages: |
| 2894 | - Enable gcc for better reordering (frame array is clobbered every time is | 2924 | - Enable gcc for better reordering (frame array is clobbered every time is |
| 2895 | passed as parameter being involved into an nargs function call). | 2925 | passed as parameter being involved into an nargs function call). |
| 2896 | - Allow gcc to trigger other optimizations that are prevented by memory | 2926 | - Allow gcc to trigger other optimizations that are prevented by memory |
| 2897 | referencing. | 2927 | referencing. |
| 2898 | */ | 2928 | */ |
| 2899 | if (SPEED >= 2) | 2929 | if (SPEED >= 2) |
| 2900 | { | 2930 | { |
| @@ -2952,7 +2982,6 @@ compile_function (Lisp_Object func) | |||
| 2952 | build_string ("failing to compile function"), | 2982 | build_string ("failing to compile function"), |
| 2953 | CALL1I (comp-func-name, func), | 2983 | CALL1I (comp-func-name, func), |
| 2954 | build_string (err)); | 2984 | build_string (err)); |
| 2955 | |||
| 2956 | SAFE_FREE (); | 2985 | SAFE_FREE (); |
| 2957 | } | 2986 | } |
| 2958 | 2987 | ||