aboutsummaryrefslogtreecommitdiffstats
path: root/src/comp.c
diff options
context:
space:
mode:
authorAndrea Corallo2019-09-09 12:01:03 +0200
committerAndrea Corallo2020-01-01 11:37:46 +0100
commitb9f37a2a09ac6bcef1a03cc49489f15ff01a74b7 (patch)
tree7090c8ca8f03093d419f67973af012b37934a855 /src/comp.c
parentc702e25a7a9e1ba2b75942dcc00402947757786d (diff)
downloademacs-b9f37a2a09ac6bcef1a03cc49489f15ff01a74b7.tar.gz
emacs-b9f37a2a09ac6bcef1a03cc49489f15ff01a74b7.zip
pacify gcc and improve sanaity checks
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/src/comp.c b/src/comp.c
index 8422c7d3431..f966a2427b7 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -44,8 +44,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
44 generated code C-like code more bloated. 44 generated code C-like code more bloated.
45*/ 45*/
46 46
47#define CONST_PROP_MAX 0
48
49/* C symbols emited for the load relocation mechanism. */ 47/* C symbols emited for the load relocation mechanism. */
50#define DATA_RELOC_SYM "d_reloc" 48#define DATA_RELOC_SYM "d_reloc"
51#define IMPORTED_FUNC_RELOC_SYM "f_reloc" 49#define IMPORTED_FUNC_RELOC_SYM "f_reloc"
@@ -79,6 +77,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
79#endif 77#endif
80#define SETJMP_NAME STR (SETJMP) 78#define SETJMP_NAME STR (SETJMP)
81 79
80#define ICE_IF(test, msg) \
81 do { \
82 if (test) \
83 ice (msg); \
84 } while (0)
85
82/* C side of the compiler context. */ 86/* C side of the compiler context. */
83 87
84typedef struct { 88typedef struct {
@@ -186,8 +190,7 @@ Lisp_Object helper_save_window_excursion (Lisp_Object v1);
186void helper_unwind_protect (Lisp_Object handler); 190void helper_unwind_protect (Lisp_Object handler);
187Lisp_Object helper_temp_output_buffer_setup (Lisp_Object x); 191Lisp_Object helper_temp_output_buffer_setup (Lisp_Object x);
188Lisp_Object helper_unbind_n (Lisp_Object n); 192Lisp_Object helper_unbind_n (Lisp_Object n);
189bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (const union vectorlike_header *a, 193bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code);
190 enum pvec_type code);
191 194
192 195
193static char * ATTRIBUTE_FORMAT_PRINTF (1, 2) 196static char * ATTRIBUTE_FORMAT_PRINTF (1, 2)
@@ -204,6 +207,16 @@ format_string (const char *format, ...)
204} 207}
205 208
206static void 209static void
210ice (const char* msg)
211{
212 if (msg)
213 msg = format_string ("Internal native compiler error: %s", msg);
214 else
215 msg = "Internal native compiler error";
216 error ("%s", msg);
217}
218
219static void
207bcall0 (Lisp_Object f) 220bcall0 (Lisp_Object f)
208{ 221{
209 Ffuncall (1, &f); 222 Ffuncall (1, &f);
@@ -243,7 +256,7 @@ type_to_cast_field (gcc_jit_type *type)
243 else if (type == comp.lisp_obj_ptr_type) 256 else if (type == comp.lisp_obj_ptr_type)
244 field = comp.cast_union_as_lisp_obj_ptr; 257 field = comp.cast_union_as_lisp_obj_ptr;
245 else 258 else
246 error ("Unsupported cast"); 259 ice ("unsupported cast");
247 260
248 return field; 261 return field;
249} 262}
@@ -252,8 +265,7 @@ static gcc_jit_block *
252retrive_block (Lisp_Object block_name) 265retrive_block (Lisp_Object block_name)
253{ 266{
254 Lisp_Object value = Fgethash (block_name, comp.func_blocks, Qnil); 267 Lisp_Object value = Fgethash (block_name, comp.func_blocks, Qnil);
255 if (NILP (value)) 268 ICE_IF (NILP (value), "missing basic block");
256 error ("LIMPLE basic block inconsistency");
257 269
258 return (gcc_jit_block *) xmint_pointer (value); 270 return (gcc_jit_block *) xmint_pointer (value);
259} 271}
@@ -264,8 +276,8 @@ declare_block (Lisp_Object block_name)
264 char *name_str = (char *) SDATA (SYMBOL_NAME (block_name)); 276 char *name_str = (char *) SDATA (SYMBOL_NAME (block_name));
265 gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); 277 gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str);
266 Lisp_Object value = make_mint_ptr (block); 278 Lisp_Object value = make_mint_ptr (block);
267 if (!NILP (Fgethash (block_name, comp.func_blocks, Qnil))) 279 ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks, Qnil)),
268 error ("LIMPLE basic block inconsistency"); 280 "double basic block declaration");
269 Fputhash (block_name, value, comp.func_blocks); 281 Fputhash (block_name, value, comp.func_blocks);
270} 282}
271 283
@@ -295,7 +307,8 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type,
295 int nargs, gcc_jit_type **types) 307 int nargs, gcc_jit_type **types)
296{ 308{
297 /* Don't want to declare the same function two times. */ 309 /* Don't want to declare the same function two times. */
298 eassert (NILP (Fgethash (subr_sym, comp.func_hash, Qnil))); 310 ICE_IF (!NILP (Fgethash (subr_sym, comp.func_hash, Qnil)),
311 "unexpected double function declaration");
299 312
300 if (nargs == MANY) 313 if (nargs == MANY)
301 { 314 {
@@ -317,8 +330,6 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type,
317 types[i] = comp.lisp_obj_type; 330 types[i] = comp.lisp_obj_type;
318 } 331 }
319 332
320 eassert (types);
321
322 /* String containing the function ptr name. */ 333 /* String containing the function ptr name. */
323 Lisp_Object f_ptr_name = 334 Lisp_Object f_ptr_name =
324 CALLN (Ffuncall, intern_c_string (STR (comp-c-func-name)), 335 CALLN (Ffuncall, intern_c_string (STR (comp-c-func-name)),
@@ -359,16 +370,17 @@ static gcc_jit_function *
359declare_exported_func (const char *f_name, gcc_jit_type *ret_type, 370declare_exported_func (const char *f_name, gcc_jit_type *ret_type,
360 unsigned nargs, gcc_jit_rvalue **args) 371 unsigned nargs, gcc_jit_rvalue **args)
361{ 372{
362 gcc_jit_type *type[nargs]; 373 USE_SAFE_ALLOCA;
363 374 gcc_jit_type **type = SAFE_ALLOCA (nargs * sizeof (*type));
364 fill_declaration_types (type, args, nargs); 375 fill_declaration_types (type, args, nargs);
365 376
366 gcc_jit_param *param[nargs]; 377 gcc_jit_param **param = SAFE_ALLOCA (nargs *sizeof (*param));
367 for (int i = nargs - 1; i >= 0; i--) 378 for (int i = nargs - 1; i >= 0; i--)
368 param[i] = gcc_jit_context_new_param(comp.ctxt, 379 param[i] = gcc_jit_context_new_param(comp.ctxt,
369 NULL, 380 NULL,
370 type[i], 381 type[i],
371 format_string ("par_%d", i)); 382 format_string ("par_%d", i));
383 SAFE_FREE ();
372 return gcc_jit_context_new_function(comp.ctxt, NULL, 384 return gcc_jit_context_new_function(comp.ctxt, NULL,
373 GCC_JIT_GLOBAL_EXPORTED, 385 GCC_JIT_GLOBAL_EXPORTED,
374 ret_type, 386 ret_type,
@@ -383,14 +395,14 @@ emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, unsigned nargs,
383 gcc_jit_rvalue **args) 395 gcc_jit_rvalue **args)
384{ 396{
385 Lisp_Object value = Fgethash (subr_sym, comp.func_hash, Qnil); 397 Lisp_Object value = Fgethash (subr_sym, comp.func_hash, Qnil);
386 eassert (!NILP (value)); 398 ICE_IF (NILP (value), "missing function declaration");
387 399
388 gcc_jit_lvalue *f_ptr = 400 gcc_jit_lvalue *f_ptr =
389 gcc_jit_lvalue_access_field (comp.func_relocs, 401 gcc_jit_lvalue_access_field (comp.func_relocs,
390 NULL, 402 NULL,
391 (gcc_jit_field *) xmint_pointer (value)); 403 (gcc_jit_field *) xmint_pointer (value));
392 if (!f_ptr) 404
393 error ("Undeclared function relocation."); 405 ICE_IF (!f_ptr, "undeclared function relocation");
394 406
395 emit_comment (format_string ("calling subr: %s", 407 emit_comment (format_string ("calling subr: %s",
396 SSDATA (SYMBOL_NAME (subr_sym)))); 408 SSDATA (SYMBOL_NAME (subr_sym))));
@@ -1050,7 +1062,7 @@ emit_set_internal (Lisp_Object args)
1050 #s(comp-mvar 6 1 t 3 nil)) 1062 #s(comp-mvar 6 1 t 3 nil))
1051 */ 1063 */
1052 /* TODO: Inline the most common case. */ 1064 /* TODO: Inline the most common case. */
1053 eassert (list_length (args) == 3); 1065 ICE_IF (list_length (args) != 3, "unexpected arg length for insns");
1054 args = XCDR (args); 1066 args = XCDR (args);
1055 int i = 0; 1067 int i = 0;
1056 gcc_jit_rvalue *gcc_args[4]; 1068 gcc_jit_rvalue *gcc_args[4];
@@ -1069,14 +1081,16 @@ emit_set_internal (Lisp_Object args)
1069static gcc_jit_rvalue * 1081static gcc_jit_rvalue *
1070emit_simple_limple_call (Lisp_Object args, gcc_jit_type *ret_type) 1082emit_simple_limple_call (Lisp_Object args, gcc_jit_type *ret_type)
1071{ 1083{
1084 USE_SAFE_ALLOCA;
1072 int i = 0; 1085 int i = 0;
1073 Lisp_Object callee = FIRST (args); 1086 Lisp_Object callee = FIRST (args);
1074 args = XCDR (args); 1087 args = XCDR (args);
1075 ptrdiff_t nargs = list_length (args); 1088 ptrdiff_t nargs = list_length (args);
1076 gcc_jit_rvalue *gcc_args[nargs]; 1089 gcc_jit_rvalue **gcc_args = SAFE_ALLOCA (nargs * sizeof (*gcc_args));
1077 FOR_EACH_TAIL (args) 1090 FOR_EACH_TAIL (args)
1078 gcc_args[i++] = emit_mvar_val (XCAR (args)); 1091 gcc_args[i++] = emit_mvar_val (XCAR (args));
1079 1092
1093 SAFE_FREE ();
1080 return emit_call (callee, ret_type, nargs, gcc_args); 1094 return emit_call (callee, ret_type, nargs, gcc_args);
1081} 1095}
1082 1096
@@ -1195,7 +1209,7 @@ emit_limple_insn (Lisp_Object insn)
1195{ 1209{
1196 Lisp_Object op = XCAR (insn); 1210 Lisp_Object op = XCAR (insn);
1197 Lisp_Object args = XCDR (insn); 1211 Lisp_Object args = XCDR (insn);
1198 Lisp_Object arg0; 1212 Lisp_Object arg0 UNINIT;
1199 gcc_jit_rvalue *res; 1213 gcc_jit_rvalue *res;
1200 1214
1201 if (CONSP (args)) 1215 if (CONSP (args))
@@ -1243,13 +1257,13 @@ emit_limple_insn (Lisp_Object insn)
1243 { 1257 {
1244 EMACS_UINT clobber_slot = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); 1258 EMACS_UINT clobber_slot = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0));
1245 gcc_jit_rvalue *handler = emit_mvar_val (arg0); 1259 gcc_jit_rvalue *handler = emit_mvar_val (arg0);
1246 int h_num; 1260 int h_num UNINIT;
1247 if (EQ (SECOND (args), Qcatcher)) 1261 if (EQ (SECOND (args), Qcatcher))
1248 h_num = CATCHER; 1262 h_num = CATCHER;
1249 else if (EQ (SECOND (args), Qcondition_case)) 1263 else if (EQ (SECOND (args), Qcondition_case))
1250 h_num = CONDITION_CASE; 1264 h_num = CONDITION_CASE;
1251 else 1265 else
1252 eassert (false); 1266 ice ("incoherent insn");
1253 gcc_jit_rvalue *handler_type = 1267 gcc_jit_rvalue *handler_type =
1254 gcc_jit_context_new_rvalue_from_int (comp.ctxt, 1268 gcc_jit_context_new_rvalue_from_int (comp.ctxt,
1255 comp.int_type, 1269 comp.int_type,
@@ -1299,8 +1313,10 @@ emit_limple_insn (Lisp_Object insn)
1299 else if (EQ (FIRST (arg1), Qcallref)) 1313 else if (EQ (FIRST (arg1), Qcallref))
1300 res = emit_limple_call_ref (XCDR (arg1)); 1314 res = emit_limple_call_ref (XCDR (arg1));
1301 else 1315 else
1302 error ("LIMPLE inconsistent arg1 for op ="); 1316 ice ("LIMPLE inconsistent arg1 for op =");
1303 eassert (res); 1317
1318 ICE_IF (!res, "incoherent insn");
1319
1304 gcc_jit_block_add_assignment (comp.block, 1320 gcc_jit_block_add_assignment (comp.block,
1305 NULL, 1321 NULL,
1306 comp.frame[slot_n], 1322 comp.frame[slot_n],
@@ -1420,7 +1436,7 @@ emit_limple_insn (Lisp_Object insn)
1420 } 1436 }
1421 else 1437 else
1422 { 1438 {
1423 error ("LIMPLE op inconsistent"); 1439 ice ("LIMPLE op inconsistent");
1424 } 1440 }
1425} 1441}
1426 1442
@@ -1690,6 +1706,8 @@ This emit the code needed by every compilation unit to be loaded.
1690static void 1706static void
1691emit_ctxt_code (void) 1707emit_ctxt_code (void)
1692{ 1708{
1709 USE_SAFE_ALLOCA;
1710
1693 declare_runtime_imported_data (); 1711 declare_runtime_imported_data ();
1694 /* Imported objects. */ 1712 /* Imported objects. */
1695 EMACS_UINT d_reloc_len = 1713 EMACS_UINT d_reloc_len =
@@ -1720,7 +1738,7 @@ emit_ctxt_code (void)
1720 Lisp_Object f_subr = FUNCALL1 (comp-ctxt-func-relocs-l, Vcomp_ctxt); 1738 Lisp_Object f_subr = FUNCALL1 (comp-ctxt-func-relocs-l, Vcomp_ctxt);
1721 f_reloc_len += XFIXNUM (Flength (f_subr)); 1739 f_reloc_len += XFIXNUM (Flength (f_subr));
1722 1740
1723 gcc_jit_field *fields[f_reloc_len]; 1741 gcc_jit_field **fields = SAFE_ALLOCA (f_reloc_len * sizeof (*fields));
1724 Lisp_Object f_reloc_list = Qnil; 1742 Lisp_Object f_reloc_list = Qnil;
1725 int n_frelocs = 0; 1743 int n_frelocs = 0;
1726 1744
@@ -1774,6 +1792,7 @@ emit_ctxt_code (void)
1774 /* Exported functions info. */ 1792 /* Exported functions info. */
1775 Lisp_Object func_list = FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt); 1793 Lisp_Object func_list = FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt);
1776 emit_static_object (TEXT_EXPORTED_FUNC_RELOC_SYM, func_list); 1794 emit_static_object (TEXT_EXPORTED_FUNC_RELOC_SYM, func_list);
1795 SAFE_FREE ();
1777} 1796}
1778 1797
1779 1798
@@ -2626,6 +2645,7 @@ define_bool_to_lisp_obj (void)
2626static void 2645static void
2627compile_function (Lisp_Object func) 2646compile_function (Lisp_Object func)
2628{ 2647{
2648 USE_SAFE_ALLOCA;
2629 char *c_name = SSDATA (FUNCALL1 (comp-func-c-func-name, func)); 2649 char *c_name = SSDATA (FUNCALL1 (comp-func-c-func-name, func));
2630 Lisp_Object args = FUNCALL1 (comp-func-args, func); 2650 Lisp_Object args = FUNCALL1 (comp-func-args, func);
2631 EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func)); 2651 EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func));
@@ -2666,7 +2686,7 @@ compile_function (Lisp_Object func)
2666 frame_size), 2686 frame_size),
2667 "local"); 2687 "local");
2668 2688
2669 gcc_jit_lvalue *frame[frame_size]; 2689 gcc_jit_lvalue **frame = SAFE_ALLOCA (frame_size * sizeof (*frame));
2670 for (int i = 0; i < frame_size; ++i) 2690 for (int i = 0; i < frame_size; ++i)
2671 frame[i] = 2691 frame[i] =
2672 gcc_jit_context_new_array_access ( 2692 gcc_jit_context_new_array_access (
@@ -2698,7 +2718,7 @@ compile_function (Lisp_Object func)
2698 Lisp_Object block_name = HASH_KEY (ht, i); 2718 Lisp_Object block_name = HASH_KEY (ht, i);
2699 Lisp_Object block = HASH_VALUE (ht, i); 2719 Lisp_Object block = HASH_VALUE (ht, i);
2700 Lisp_Object insns = FUNCALL1 (comp-block-insns, block); 2720 Lisp_Object insns = FUNCALL1 (comp-block-insns, block);
2701 eassert (!NILP (block) && !NILP (insns)); 2721 ICE_IF (NILP (block) || NILP (insns), "basic block is missing or empty");
2702 2722
2703 comp.block = retrive_block (block_name); 2723 comp.block = retrive_block (block_name);
2704 while (CONSP (insns)) 2724 while (CONSP (insns))
@@ -2709,10 +2729,11 @@ compile_function (Lisp_Object func)
2709 } 2729 }
2710 } 2730 }
2711 const char *err = gcc_jit_context_get_first_error (comp.ctxt); 2731 const char *err = gcc_jit_context_get_first_error (comp.ctxt);
2712 if (err) 2732 ICE_IF (err,
2713 error ("Failing to compile function %s with error:%s", 2733 format_string ("failing to compile function %s with error: %s",
2714 SSDATA (SYMBOL_NAME (FUNCALL1 (comp-func-symbol-name, func))), 2734 SSDATA (SYMBOL_NAME (FUNCALL1 (comp-func-symbol-name, func))),
2715 err); 2735 err));
2736 SAFE_FREE ();
2716} 2737}
2717 2738
2718 2739
@@ -2727,7 +2748,7 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
2727{ 2748{
2728 if (comp.ctxt) 2749 if (comp.ctxt)
2729 { 2750 {
2730 error ("Compiler context already taken"); 2751 ice ("compiler context already taken");
2731 return Qnil; 2752 return Qnil;
2732 } 2753 }
2733 2754
@@ -3065,8 +3086,7 @@ helper_unbind_n (Lisp_Object n)
3065} 3086}
3066 3087
3067bool 3088bool
3068helper_PSEUDOVECTOR_TYPEP_XUNTAG (const union vectorlike_header *a, 3089helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code)
3069 enum pvec_type code)
3070{ 3090{
3071 return PSEUDOVECTOR_TYPEP (XUNTAG (a, Lisp_Vectorlike, 3091 return PSEUDOVECTOR_TYPEP (XUNTAG (a, Lisp_Vectorlike,
3072 union vectorlike_header), 3092 union vectorlike_header),
@@ -3163,7 +3183,7 @@ load_comp_unit (dynlib_handle_ptr handle)
3163 f_relocs[i] = (void *) specbind; 3183 f_relocs[i] = (void *) specbind;
3164 } else 3184 } else
3165 { 3185 {
3166 error ("Unexpected function relocation %s", f_str); 3186 ice (format_string ("unexpected function relocation %s", f_str));
3167 } 3187 }
3168 } 3188 }
3169 3189