aboutsummaryrefslogtreecommitdiffstats
path: root/src/comp.c
diff options
context:
space:
mode:
authorAndrea Corallo2019-09-22 16:37:57 +0200
committerAndrea Corallo2020-01-01 11:37:52 +0100
commit6e205873992a2f8eeaecb30adf56346481a2c192 (patch)
tree76fd29e08f48c3ac84f53a355b25451b22f34d7f /src/comp.c
parent772357698a226cdbf123d04d58573b79fd8814a2 (diff)
downloademacs-6e205873992a2f8eeaecb30adf56346481a2c192.tar.gz
emacs-6e205873992a2f8eeaecb30adf56346481a2c192.zip
floating frame in place
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c99
1 files changed, 59 insertions, 40 deletions
diff --git a/src/comp.c b/src/comp.c
index 2abf4d2a2bd..00fda6e7051 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -149,6 +149,7 @@ typedef struct {
149 gcc_jit_function *func; /* Current function being compiled. */ 149 gcc_jit_function *func; /* Current function being compiled. */
150 gcc_jit_block *block; /* Current basic block being compiled. */ 150 gcc_jit_block *block; /* Current basic block being compiled. */
151 gcc_jit_lvalue **frame; /* Frame for the current function. */ 151 gcc_jit_lvalue **frame; /* Frame for the current function. */
152 gcc_jit_lvalue **f_frame; /* "Floating" frame for the current function. */
152 gcc_jit_rvalue *most_positive_fixnum; 153 gcc_jit_rvalue *most_positive_fixnum;
153 gcc_jit_rvalue *most_negative_fixnum; 154 gcc_jit_rvalue *most_negative_fixnum;
154 gcc_jit_rvalue *one; 155 gcc_jit_rvalue *one;
@@ -282,6 +283,16 @@ declare_block (Lisp_Object block_name)
282 Fputhash (block_name, value, comp.func_blocks_h); 283 Fputhash (block_name, value, comp.func_blocks_h);
283} 284}
284 285
286static gcc_jit_lvalue *
287get_slot (Lisp_Object mvar)
288{
289 EMACS_INT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, mvar));
290 gcc_jit_lvalue **frame =
291 (FUNCALL1 (comp-mvar-ref, mvar) || comp_speed < 2)
292 ? comp.frame : comp.f_frame;
293 return frame[slot_n];
294}
295
285static void 296static void
286register_emitter (Lisp_Object key, void *func) 297register_emitter (Lisp_Object key, void *func)
287{ 298{
@@ -1024,8 +1035,18 @@ emit_mvar_val (Lisp_Object mvar)
1024 return emit_const_lisp_obj (constant); 1035 return emit_const_lisp_obj (constant);
1025 } 1036 }
1026 1037
1027 return 1038 return gcc_jit_lvalue_as_rvalue (get_slot (mvar));
1028 gcc_jit_lvalue_as_rvalue(comp.frame[XFIXNUM (FUNCALL1 (comp-mvar-slot, mvar))]); 1039}
1040
1041static void
1042emit_frame_assignment (Lisp_Object dst_mvar, gcc_jit_rvalue *val)
1043{
1044
1045 gcc_jit_block_add_assignment (
1046 comp.block,
1047 NULL,
1048 get_slot (dst_mvar),
1049 val);
1029} 1050}
1030 1051
1031static gcc_jit_rvalue * 1052static gcc_jit_rvalue *
@@ -1119,7 +1140,7 @@ emit_limple_call_ref (Lisp_Object insn, bool direct)
1119static void 1140static void
1120emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, 1141emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type,
1121 gcc_jit_block *handler_bb, gcc_jit_block *guarded_bb, 1142 gcc_jit_block *handler_bb, gcc_jit_block *guarded_bb,
1122 EMACS_UINT clobber_slot) 1143 Lisp_Object clobbered_mvar)
1123{ 1144{
1124 /* Ex: (push-handler #s(comp-mvar 6 0 t (arith-error) nil) 1 bb_3 bb_2). */ 1145 /* Ex: (push-handler #s(comp-mvar 6 0 t (arith-error) nil) 1 bb_3 bb_2). */
1125 1146
@@ -1169,10 +1190,8 @@ emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type,
1169 gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), 1190 gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c),
1170 NULL, 1191 NULL,
1171 comp.handler_next_field))); 1192 comp.handler_next_field)));
1172 gcc_jit_block_add_assignment ( 1193 emit_frame_assignment (
1173 comp.block, 1194 clobbered_mvar,
1174 NULL,
1175 comp.frame[clobber_slot],
1176 gcc_jit_lvalue_as_rvalue( 1195 gcc_jit_lvalue_as_rvalue(
1177 gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), 1196 gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c),
1178 NULL, 1197 NULL,
@@ -1235,7 +1254,6 @@ emit_limple_insn (Lisp_Object insn)
1235 } 1254 }
1236 else if (EQ (op, Qpush_handler)) 1255 else if (EQ (op, Qpush_handler))
1237 { 1256 {
1238 EMACS_UINT clobber_slot = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0));
1239 gcc_jit_rvalue *handler = emit_mvar_val (arg0); 1257 gcc_jit_rvalue *handler = emit_mvar_val (arg0);
1240 int h_num UNINIT; 1258 int h_num UNINIT;
1241 if (EQ (SECOND (args), Qcatcher)) 1259 if (EQ (SECOND (args), Qcatcher))
@@ -1251,7 +1269,7 @@ emit_limple_insn (Lisp_Object insn)
1251 gcc_jit_block *handler_bb = retrive_block (THIRD (args)); 1269 gcc_jit_block *handler_bb = retrive_block (THIRD (args));
1252 gcc_jit_block *guarded_bb = retrive_block (FORTH (args)); 1270 gcc_jit_block *guarded_bb = retrive_block (FORTH (args));
1253 emit_limple_push_handler (handler, handler_type, handler_bb, guarded_bb, 1271 emit_limple_push_handler (handler, handler_type, handler_bb, guarded_bb,
1254 clobber_slot); 1272 arg0);
1255 } 1273 }
1256 else if (EQ (op, Qpop_handler)) 1274 else if (EQ (op, Qpop_handler))
1257 { 1275 {
@@ -1283,7 +1301,6 @@ emit_limple_insn (Lisp_Object insn)
1283 } 1301 }
1284 else if (EQ (op, Qset)) 1302 else if (EQ (op, Qset))
1285 { 1303 {
1286 EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0));
1287 Lisp_Object arg1 = SECOND (args); 1304 Lisp_Object arg1 = SECOND (args);
1288 1305
1289 if (EQ (Ftype_of (arg1), Qcomp_mvar)) 1306 if (EQ (Ftype_of (arg1), Qcomp_mvar))
@@ -1301,23 +1318,16 @@ emit_limple_insn (Lisp_Object insn)
1301 1318
1302 ICE_IF (!res, gcc_jit_context_get_first_error (comp.ctxt)); 1319 ICE_IF (!res, gcc_jit_context_get_first_error (comp.ctxt));
1303 1320
1304 gcc_jit_block_add_assignment (comp.block, 1321 emit_frame_assignment (arg0, res);
1305 NULL,
1306 comp.frame[slot_n],
1307 res);
1308 } 1322 }
1309 else if (EQ (op, Qset_par_to_local)) 1323 else if (EQ (op, Qset_par_to_local))
1310 { 1324 {
1311 /* Ex: (setpar #s(comp-mvar 2 0 nil nil nil) 0). */ 1325 /* Ex: (setpar #s(comp-mvar 2 0 nil nil nil) 0). */
1312 EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0));
1313 EMACS_UINT param_n = XFIXNUM (SECOND (args)); 1326 EMACS_UINT param_n = XFIXNUM (SECOND (args));
1314 gcc_jit_rvalue *param = 1327 gcc_jit_rvalue *param =
1315 gcc_jit_param_as_rvalue (gcc_jit_function_get_param (comp.func, 1328 gcc_jit_param_as_rvalue (gcc_jit_function_get_param (comp.func,
1316 param_n)); 1329 param_n));
1317 gcc_jit_block_add_assignment (comp.block, 1330 emit_frame_assignment (arg0, param);
1318 NULL,
1319 comp.frame[slot_n],
1320 param);
1321 } 1331 }
1322 else if (EQ (op, Qset_args_to_local)) 1332 else if (EQ (op, Qset_args_to_local))
1323 { 1333 {
@@ -1332,11 +1342,7 @@ emit_limple_insn (Lisp_Object insn)
1332 gcc_jit_rvalue *res = 1342 gcc_jit_rvalue *res =
1333 gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference (gcc_args, NULL)); 1343 gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference (gcc_args, NULL));
1334 1344
1335 EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); 1345 emit_frame_assignment (arg0, res);
1336 gcc_jit_block_add_assignment (comp.block,
1337 NULL,
1338 comp.frame[slot_n],
1339 res);
1340 } 1346 }
1341 else if (EQ (op, Qset_rest_args_to_local)) 1347 else if (EQ (op, Qset_rest_args_to_local))
1342 { 1348 {
@@ -1367,10 +1373,7 @@ emit_limple_insn (Lisp_Object insn)
1367 res = emit_call (Qlist, comp.lisp_obj_type, 2, 1373 res = emit_call (Qlist, comp.lisp_obj_type, 2,
1368 list_args, false); 1374 list_args, false);
1369 1375
1370 gcc_jit_block_add_assignment (comp.block, 1376 emit_frame_assignment (arg0, res);
1371 NULL,
1372 comp.frame[slot_n],
1373 res);
1374 } 1377 }
1375 else if (EQ (op, Qinc_args)) 1378 else if (EQ (op, Qinc_args))
1376 { 1379 {
@@ -1393,21 +1396,18 @@ emit_limple_insn (Lisp_Object insn)
1393 else if (EQ (op, Qsetimm)) 1396 else if (EQ (op, Qsetimm))
1394 { 1397 {
1395 /* EX: (=imm #s(comp-mvar 9 1 t 3 nil) 3 a). */ 1398 /* EX: (=imm #s(comp-mvar 9 1 t 3 nil) 3 a). */
1396 EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0));
1397 gcc_jit_rvalue *reloc_n = 1399 gcc_jit_rvalue *reloc_n =
1398 gcc_jit_context_new_rvalue_from_int (comp.ctxt, 1400 gcc_jit_context_new_rvalue_from_int (comp.ctxt,
1399 comp.int_type, 1401 comp.int_type,
1400 XFIXNUM (SECOND (args))); 1402 XFIXNUM (SECOND (args)));
1401 emit_comment (SSDATA (Fprin1_to_string (THIRD (args), Qnil))); 1403 emit_comment (SSDATA (Fprin1_to_string (THIRD (args), Qnil)));
1402 gcc_jit_block_add_assignment (comp.block, 1404 emit_frame_assignment (
1403 NULL, 1405 arg0,
1404 comp.frame[slot_n], 1406 gcc_jit_lvalue_as_rvalue (
1405 gcc_jit_lvalue_as_rvalue ( 1407 gcc_jit_context_new_array_access (comp.ctxt,
1406 gcc_jit_context_new_array_access ( 1408 NULL,
1407 comp.ctxt, 1409 comp.data_relocs,
1408 NULL, 1410 reloc_n)));
1409 comp.data_relocs,
1410 reloc_n)));
1411 } 1411 }
1412 else if (EQ (op, Qcomment)) 1412 else if (EQ (op, Qcomment))
1413 { 1413 {
@@ -2703,9 +2703,8 @@ compile_function (Lisp_Object func)
2703 comp.lisp_obj_type, 2703 comp.lisp_obj_type,
2704 frame_size), 2704 frame_size),
2705 "local"); 2705 "local");
2706
2707 comp.frame = SAFE_ALLOCA (frame_size * sizeof (*comp.frame)); 2706 comp.frame = SAFE_ALLOCA (frame_size * sizeof (*comp.frame));
2708 for (int i = 0; i < frame_size; ++i) 2707 for (unsigned i = 0; i < frame_size; ++i)
2709 comp.frame[i] = 2708 comp.frame[i] =
2710 gcc_jit_context_new_array_access ( 2709 gcc_jit_context_new_array_access (
2711 comp.ctxt, 2710 comp.ctxt,
@@ -2715,6 +2714,26 @@ compile_function (Lisp_Object func)
2715 comp.int_type, 2714 comp.int_type,
2716 i)); 2715 i));
2717 2716
2717 /*
2718 The floating frame is a copy of the normal frame that can be used to store
2719 locals if the are not going to be used in a nargs call.
2720 This has two advantages:
2721 - Enable gcc for better reordering (frame array is clobbered every time is
2722 passed as parameter being invoved into an nargs function call).
2723 - Allow gcc to trigger other optimizations that are prevented by memory
2724 referencing (ex TCO).
2725 */
2726 if (comp_speed >= 2)
2727 {
2728 comp.f_frame = SAFE_ALLOCA (frame_size * sizeof (*comp.f_frame));
2729 for (unsigned i = 0; i < frame_size; ++i)
2730 comp.f_frame[i] =
2731 gcc_jit_function_new_local (comp.func,
2732 NULL,
2733 comp.lisp_obj_type,
2734 format_string ("local%u", i));
2735 }
2736
2718 comp.func_blocks_h = CALLN (Fmake_hash_table); 2737 comp.func_blocks_h = CALLN (Fmake_hash_table);
2719 2738
2720 /* Pre declare all basic blocks to gcc. 2739 /* Pre declare all basic blocks to gcc.