diff options
| author | Andrea Corallo | 2019-09-21 09:48:15 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:50 +0100 |
| commit | 89172ac4376403b987bad897cdcfd22f9e5d97c8 (patch) | |
| tree | 8049844434e53a71af5be374f2e5a6cee3f82d53 /src | |
| parent | c31b471cadcb9b8171de04b09a044bb775682a3a (diff) | |
| download | emacs-89172ac4376403b987bad897cdcfd22f9e5d97c8.tar.gz emacs-89172ac4376403b987bad897cdcfd22f9e5d97c8.zip | |
split declaration and compilation
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 130 |
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) | |||
| 265 | static gcc_jit_block * | 265 | static gcc_jit_block * |
| 266 | retrive_block (Lisp_Object block_name) | 266 | retrive_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 | ||
| 285 | static void | 285 | static 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 | ||
| 356 | static void | ||
| 357 | fill_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 | |||
| 370 | static gcc_jit_function * | ||
| 371 | declare_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 | |||
| 394 | static gcc_jit_rvalue * | 356 | static gcc_jit_rvalue * |
| 395 | emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, unsigned nargs, | 357 | emit_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. */ | ||
| 2663 | static void | 2616 | static void |
| 2664 | compile_function (Lisp_Object func) | 2617 | declare_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 | |||
| 2672 | static void | ||
| 2673 | compile_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 | ||