diff options
| author | Andrea Corallo | 2019-09-22 16:37:57 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:52 +0100 |
| commit | 6e205873992a2f8eeaecb30adf56346481a2c192 (patch) | |
| tree | 76fd29e08f48c3ac84f53a355b25451b22f34d7f /src/comp.c | |
| parent | 772357698a226cdbf123d04d58573b79fd8814a2 (diff) | |
| download | emacs-6e205873992a2f8eeaecb30adf56346481a2c192.tar.gz emacs-6e205873992a2f8eeaecb30adf56346481a2c192.zip | |
floating frame in place
Diffstat (limited to 'src/comp.c')
| -rw-r--r-- | src/comp.c | 99 |
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 | ||
| 286 | static gcc_jit_lvalue * | ||
| 287 | get_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 | |||
| 285 | static void | 296 | static void |
| 286 | register_emitter (Lisp_Object key, void *func) | 297 | register_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 | |||
| 1041 | static void | ||
| 1042 | emit_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 | ||
| 1031 | static gcc_jit_rvalue * | 1052 | static gcc_jit_rvalue * |
| @@ -1119,7 +1140,7 @@ emit_limple_call_ref (Lisp_Object insn, bool direct) | |||
| 1119 | static void | 1140 | static void |
| 1120 | emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, | 1141 | emit_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. |