aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2020-02-09 16:17:21 +0100
committerAndrea Corallo2020-02-15 10:17:08 +0100
commitc27394da7e3e35ab35e0430ab331d6dadca2803d (patch)
tree40b839bfafadd534271ab7a15de14c2c8b87e5a7 /src
parent0c6f4caeb32b2bf531079feb5a9e73b79496b99d (diff)
downloademacs-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.c117
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
350static gcc_jit_lvalue * 350static gcc_jit_lvalue *
351get_slot (Lisp_Object mvar) 351emit_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
375static void 378static 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
1146static void 1149static 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