aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2019-09-21 09:48:15 +0200
committerAndrea Corallo2020-01-01 11:37:50 +0100
commit89172ac4376403b987bad897cdcfd22f9e5d97c8 (patch)
tree8049844434e53a71af5be374f2e5a6cee3f82d53 /src
parentc31b471cadcb9b8171de04b09a044bb775682a3a (diff)
downloademacs-89172ac4376403b987bad897cdcfd22f9e5d97c8.tar.gz
emacs-89172ac4376403b987bad897cdcfd22f9e5d97c8.zip
split declaration and compilation
Diffstat (limited to 'src')
-rw-r--r--src/comp.c130
1 files changed, 59 insertions, 71 deletions
diff --git a/src/comp.c b/src/comp.c
index ed658ee5b3e..a29e56203d9 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -147,7 +147,6 @@ typedef struct {
147 gcc_jit_field *cast_union_as_lisp_obj; 147 gcc_jit_field *cast_union_as_lisp_obj;
148 gcc_jit_field *cast_union_as_lisp_obj_ptr; 148 gcc_jit_field *cast_union_as_lisp_obj_ptr;
149 gcc_jit_function *func; /* Current function being compiled. */ 149 gcc_jit_function *func; /* Current function being compiled. */
150 Lisp_Object lfunc;
151 gcc_jit_block *block; /* Current basic block being compiled. */ 150 gcc_jit_block *block; /* Current basic block being compiled. */
152 gcc_jit_lvalue **frame; /* Frame for the current function. */ 151 gcc_jit_lvalue **frame; /* Frame for the current function. */
153 gcc_jit_rvalue *most_positive_fixnum; 152 gcc_jit_rvalue *most_positive_fixnum;
@@ -166,8 +165,9 @@ typedef struct {
166 gcc_jit_function *setcdr; 165 gcc_jit_function *setcdr;
167 gcc_jit_function *check_type; 166 gcc_jit_function *check_type;
168 gcc_jit_function *check_impure; 167 gcc_jit_function *check_impure;
169 Lisp_Object func_blocks; /* blk_name -> gcc_block. */ 168 Lisp_Object func_blocks_h; /* blk_name -> gcc_block. */
170 Lisp_Object imported_func_h; /* subr_name -> reloc_field. */ 169 Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */
170 Lisp_Object imported_funcs_h; /* subr_name -> reloc_field. */
171 Lisp_Object emitter_dispatcher; 171 Lisp_Object emitter_dispatcher;
172 gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ 172 gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */
173 gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ 173 gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */
@@ -265,7 +265,7 @@ type_to_cast_field (gcc_jit_type *type)
265static gcc_jit_block * 265static gcc_jit_block *
266retrive_block (Lisp_Object block_name) 266retrive_block (Lisp_Object block_name)
267{ 267{
268 Lisp_Object value = Fgethash (block_name, comp.func_blocks, Qnil); 268 Lisp_Object value = Fgethash (block_name, comp.func_blocks_h, Qnil);
269 ICE_IF (NILP (value), "missing basic block"); 269 ICE_IF (NILP (value), "missing basic block");
270 270
271 return (gcc_jit_block *) xmint_pointer (value); 271 return (gcc_jit_block *) xmint_pointer (value);
@@ -277,9 +277,9 @@ declare_block (Lisp_Object block_name)
277 char *name_str = (char *) SDATA (SYMBOL_NAME (block_name)); 277 char *name_str = (char *) SDATA (SYMBOL_NAME (block_name));
278 gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); 278 gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str);
279 Lisp_Object value = make_mint_ptr (block); 279 Lisp_Object value = make_mint_ptr (block);
280 ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks, Qnil)), 280 ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks_h, Qnil)),
281 "double basic block declaration"); 281 "double basic block declaration");
282 Fputhash (block_name, value, comp.func_blocks); 282 Fputhash (block_name, value, comp.func_blocks_h);
283} 283}
284 284
285static void 285static void
@@ -308,7 +308,7 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type,
308 int nargs, gcc_jit_type **types) 308 int nargs, gcc_jit_type **types)
309{ 309{
310 /* Don't want to declare the same function two times. */ 310 /* Don't want to declare the same function two times. */
311 ICE_IF (!NILP (Fgethash (subr_sym, comp.imported_func_h, Qnil)), 311 ICE_IF (!NILP (Fgethash (subr_sym, comp.imported_funcs_h, Qnil)),
312 "unexpected double function declaration"); 312 "unexpected double function declaration");
313 313
314 if (nargs == MANY) 314 if (nargs == MANY)
@@ -349,63 +349,15 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type,
349 f_ptr_type, 349 f_ptr_type,
350 SSDATA (f_ptr_name)); 350 SSDATA (f_ptr_name));
351 351
352 Fputhash (subr_sym, make_mint_ptr (field), comp.imported_func_h); 352 Fputhash (subr_sym, make_mint_ptr (field), comp.imported_funcs_h);
353 return field; 353 return field;
354} 354}
355 355
356static void
357fill_declaration_types (gcc_jit_type **type, gcc_jit_rvalue **args,
358 unsigned nargs)
359{
360 /* If args are passed types are extracted from that otherwise assume params */
361 /* are all lisp objs. */
362 if (args)
363 for (unsigned i = 0; i < nargs; i++)
364 type[i] = gcc_jit_rvalue_get_type (args[i]);
365 else
366 for (unsigned i = 0; i < nargs; i++)
367 type[i] = comp.lisp_obj_type;
368}
369
370static gcc_jit_function *
371declare_exported_func (const char *f_name, gcc_jit_type *ret_type,
372 unsigned nargs, gcc_jit_rvalue **args)
373{
374 USE_SAFE_ALLOCA;
375 gcc_jit_type **type = SAFE_ALLOCA (nargs * sizeof (*type));
376 fill_declaration_types (type, args, nargs);
377
378 gcc_jit_param **param = SAFE_ALLOCA (nargs *sizeof (*param));
379 for (int i = nargs - 1; i >= 0; i--)
380 param[i] = gcc_jit_context_new_param(comp.ctxt,
381 NULL,
382 type[i],
383 format_string ("par_%d", i));
384 SAFE_FREE ();
385 return gcc_jit_context_new_function(comp.ctxt, NULL,
386 GCC_JIT_GLOBAL_EXPORTED,
387 ret_type,
388 f_name,
389 nargs,
390 param,
391 0);
392}
393
394static gcc_jit_rvalue * 356static gcc_jit_rvalue *
395emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, unsigned nargs, 357emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, unsigned nargs,
396 gcc_jit_rvalue **args) 358 gcc_jit_rvalue **args)
397{ 359{
398 /* Self call optimization. */ 360 Lisp_Object value = Fgethash (subr_sym, comp.imported_funcs_h, Qnil);
399 if (!NILP (comp.lfunc) &&
400 comp_speed >= 2 &&
401 EQ (subr_sym, FUNCALL1 (comp-func-symbol-name, comp.lfunc)))
402 return gcc_jit_context_new_call (comp.ctxt,
403 NULL,
404 comp.func,
405 nargs,
406 args);
407
408 Lisp_Object value = Fgethash (subr_sym, comp.imported_func_h, Qnil);
409 ICE_IF (NILP (value), "missing function declaration"); 361 ICE_IF (NILP (value), "missing function declaration");
410 362
411 gcc_jit_lvalue *f_ptr = 363 gcc_jit_lvalue *f_ptr =
@@ -2660,22 +2612,36 @@ define_bool_to_lisp_obj (void)
2660 2612
2661} 2613}
2662 2614
2615/* Declare a function being compiled and add it to comp.exported_funcs_h. */
2663static void 2616static void
2664compile_function (Lisp_Object func) 2617declare_function (Lisp_Object func)
2665{ 2618{
2666 USE_SAFE_ALLOCA; 2619 gcc_jit_function *gcc_func;
2667 char *c_name = SSDATA (FUNCALL1 (comp-func-c-func-name, func)); 2620 char *c_name = SSDATA (FUNCALL1 (comp-func-c-func-name, func));
2668 Lisp_Object args = FUNCALL1 (comp-func-args, func); 2621 Lisp_Object args = FUNCALL1 (comp-func-args, func);
2669 EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func));
2670 bool ncall = (FUNCALL1 (comp-nargs-p, args)); 2622 bool ncall = (FUNCALL1 (comp-nargs-p, args));
2671 2623 USE_SAFE_ALLOCA;
2672 comp.lfunc = func;
2673 2624
2674 if (!ncall) 2625 if (!ncall)
2675 { 2626 {
2676 EMACS_INT max_args = XFIXNUM (FUNCALL1 (comp-args-max, args)); 2627 EMACS_INT max_args = XFIXNUM (FUNCALL1 (comp-args-max, args));
2677 comp.func 2628 gcc_jit_type **type = SAFE_ALLOCA (max_args * sizeof (*type));
2678 = declare_exported_func (c_name, comp.lisp_obj_type, max_args, NULL); 2629 for (unsigned i = 0; i < max_args; i++)
2630 type[i] = comp.lisp_obj_type;
2631
2632 gcc_jit_param **param = SAFE_ALLOCA (max_args *sizeof (*param));
2633 for (int i = max_args - 1; i >= 0; i--)
2634 param[i] = gcc_jit_context_new_param (comp.ctxt,
2635 NULL,
2636 type[i],
2637 format_string ("par_%d", i));
2638 gcc_func = gcc_jit_context_new_function (comp.ctxt, NULL,
2639 GCC_JIT_GLOBAL_EXPORTED,
2640 comp.lisp_obj_type,
2641 c_name,
2642 max_args,
2643 param,
2644 0);
2679 } 2645 }
2680 else 2646 else
2681 { 2647 {
@@ -2688,7 +2654,7 @@ compile_function (Lisp_Object func)
2688 NULL, 2654 NULL,
2689 comp.lisp_obj_ptr_type, 2655 comp.lisp_obj_ptr_type,
2690 "args") }; 2656 "args") };
2691 comp.func = 2657 gcc_func =
2692 gcc_jit_context_new_function (comp.ctxt, 2658 gcc_jit_context_new_function (comp.ctxt,
2693 NULL, 2659 NULL,
2694 GCC_JIT_FUNCTION_EXPORTED, 2660 GCC_JIT_FUNCTION_EXPORTED,
@@ -2696,6 +2662,22 @@ compile_function (Lisp_Object func)
2696 c_name, 2, param, 0); 2662 c_name, 2, param, 0);
2697 } 2663 }
2698 2664
2665 Fputhash (FUNCALL1 (comp-func-symbol-name, func),
2666 make_mint_ptr (gcc_func),
2667 comp.exported_funcs_h);
2668
2669 SAFE_FREE ();
2670}
2671
2672static void
2673compile_function (Lisp_Object func)
2674{
2675 USE_SAFE_ALLOCA;
2676 EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func));
2677
2678 comp.func = xmint_pointer (Fgethash (FUNCALL1 (comp-func-symbol-name, func),
2679 comp.exported_funcs_h, Qnil));
2680
2699 gcc_jit_lvalue *frame_array = 2681 gcc_jit_lvalue *frame_array =
2700 gcc_jit_function_new_local ( 2682 gcc_jit_function_new_local (
2701 comp.func, 2683 comp.func,
@@ -2717,7 +2699,7 @@ compile_function (Lisp_Object func)
2717 comp.int_type, 2699 comp.int_type,
2718 i)); 2700 i));
2719 2701
2720 comp.func_blocks = CALLN (Fmake_hash_table); 2702 comp.func_blocks_h = CALLN (Fmake_hash_table);
2721 2703
2722 /* Pre declare all basic blocks to gcc. 2704 /* Pre declare all basic blocks to gcc.
2723 The "entry" block must be declared as first. */ 2705 The "entry" block must be declared as first. */
@@ -2752,7 +2734,6 @@ compile_function (Lisp_Object func)
2752 format_string ("failing to compile function %s with error: %s", 2734 format_string ("failing to compile function %s with error: %s",
2753 SSDATA (SYMBOL_NAME (FUNCALL1 (comp-func-symbol-name, func))), 2735 SSDATA (SYMBOL_NAME (FUNCALL1 (comp-func-symbol-name, func))),
2754 err)); 2736 err));
2755 comp.lfunc = Qnil;
2756 SAFE_FREE (); 2737 SAFE_FREE ();
2757} 2738}
2758 2739
@@ -2906,11 +2887,12 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
2906 sizeof (void *), 2887 sizeof (void *),
2907 false); 2888 false);
2908 2889
2890 comp.exported_funcs_h = CALLN (Fmake_hash_table);
2909 /* 2891 /*
2910 Always reinitialize this cause old function definitions are garbage collected 2892 Always reinitialize this cause old function definitions are garbage collected
2911 by libgccjit when the ctxt is released. 2893 by libgccjit when the ctxt is released.
2912 */ 2894 */
2913 comp.imported_func_h = CALLN (Fmake_hash_table); 2895 comp.imported_funcs_h = CALLN (Fmake_hash_table);
2914 2896
2915 /* Define data structures. */ 2897 /* Define data structures. */
2916 2898
@@ -2984,6 +2966,8 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
2984 struct Lisp_Hash_Table *func_h 2966 struct Lisp_Hash_Table *func_h
2985 = XHASH_TABLE (FUNCALL1 (comp-ctxt-funcs-h, Vcomp_ctxt)); 2967 = XHASH_TABLE (FUNCALL1 (comp-ctxt-funcs-h, Vcomp_ctxt));
2986 for (ptrdiff_t i = 0; i < func_h->count; i++) 2968 for (ptrdiff_t i = 0; i < func_h->count; i++)
2969 declare_function (HASH_VALUE (func_h, i));
2970 for (ptrdiff_t i = 0; i < func_h->count; i++)
2987 compile_function (HASH_VALUE (func_h, i)); 2971 compile_function (HASH_VALUE (func_h, i));
2988 2972
2989 /* FIXME use format_string here */ 2973 /* FIXME use format_string here */
@@ -3220,6 +3204,8 @@ syms_of_comp (void)
3220 DEFSYM (Qjump, "jump"); 3204 DEFSYM (Qjump, "jump");
3221 DEFSYM (Qcall, "call"); 3205 DEFSYM (Qcall, "call");
3222 DEFSYM (Qcallref, "callref"); 3206 DEFSYM (Qcallref, "callref");
3207 DEFSYM (Qdirect_call, "direct-call");
3208 DEFSYM (Qdirect_callref, "direct-callref");
3223 DEFSYM (Qncall, "ncall"); 3209 DEFSYM (Qncall, "ncall");
3224 DEFSYM (Qsetimm, "setimm"); 3210 DEFSYM (Qsetimm, "setimm");
3225 DEFSYM (Qreturn, "return"); 3211 DEFSYM (Qreturn, "return");
@@ -3265,9 +3251,11 @@ syms_of_comp (void)
3265 defsubr (&Scomp__compile_ctxt_to_file); 3251 defsubr (&Scomp__compile_ctxt_to_file);
3266 defsubr (&Snative_elisp_load); 3252 defsubr (&Snative_elisp_load);
3267 3253
3268 staticpro (&comp.imported_func_h); 3254 staticpro (&comp.exported_funcs_h);
3269 comp.imported_func_h = Qnil; 3255 comp.exported_funcs_h = Qnil;
3270 staticpro (&comp.func_blocks); 3256 staticpro (&comp.imported_funcs_h);
3257 comp.imported_funcs_h = Qnil;
3258 staticpro (&comp.func_blocks_h);
3271 staticpro (&comp.emitter_dispatcher); 3259 staticpro (&comp.emitter_dispatcher);
3272 comp.emitter_dispatcher = Qnil; 3260 comp.emitter_dispatcher = Qnil;
3273 3261