diff options
| author | Andrea Corallo | 2019-08-18 23:09:20 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:39 +0100 |
| commit | 79d4b6915c0dc3e27ca18353bf53ceb31a14ded2 (patch) | |
| tree | 2b1437d196365ec37430fd1125b932fc861c3f08 /src/comp.c | |
| parent | 20d42249ce8d7fad1e377621e717b238df3a4b05 (diff) | |
| download | emacs-79d4b6915c0dc3e27ca18353bf53ceb31a14ded2.tar.gz emacs-79d4b6915c0dc3e27ca18353bf53ceb31a14ded2.zip | |
make use of data relocations
Diffstat (limited to 'src/comp.c')
| -rw-r--r-- | src/comp.c | 216 |
1 files changed, 115 insertions, 101 deletions
diff --git a/src/comp.c b/src/comp.c index 9ccf73ef4bf..acf02e7c7cd 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -149,6 +149,7 @@ typedef struct { | |||
| 149 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ | 149 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ |
| 150 | Lisp_Object func_hash; /* f_name -> gcc_func. */ | 150 | Lisp_Object func_hash; /* f_name -> gcc_func. */ |
| 151 | Lisp_Object emitter_dispatcher; | 151 | Lisp_Object emitter_dispatcher; |
| 152 | gcc_jit_rvalue *data_relocs; | ||
| 152 | } comp_t; | 153 | } comp_t; |
| 153 | 154 | ||
| 154 | static comp_t comp; | 155 | static comp_t comp; |
| @@ -1349,13 +1350,22 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1349 | } | 1350 | } |
| 1350 | else if (EQ (op, Qsetimm)) | 1351 | else if (EQ (op, Qsetimm)) |
| 1351 | { | 1352 | { |
| 1352 | /* EX: (=imm #s(comp-mvar 9 1 t 3 nil) 3). */ | 1353 | /* EX: (=imm #s(comp-mvar 9 1 t 3 nil) 3 a). */ |
| 1353 | Lisp_Object arg1 = SECOND (args); | ||
| 1354 | EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); | 1354 | EMACS_UINT slot_n = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); |
| 1355 | gcc_jit_rvalue *reloc_n = | ||
| 1356 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1357 | comp.int_type, | ||
| 1358 | XFIXNUM (SECOND (args))); | ||
| 1359 | emit_comment (SSDATA (Fprin1_to_string (THIRD (args), Qnil))); | ||
| 1355 | gcc_jit_block_add_assignment (comp.block, | 1360 | gcc_jit_block_add_assignment (comp.block, |
| 1356 | NULL, | 1361 | NULL, |
| 1357 | comp.frame[slot_n], | 1362 | comp.frame[slot_n], |
| 1358 | emit_lisp_obj_from_ptr (arg1)); | 1363 | gcc_jit_lvalue_as_rvalue ( |
| 1364 | gcc_jit_context_new_array_access ( | ||
| 1365 | comp.ctxt, | ||
| 1366 | NULL, | ||
| 1367 | comp.data_relocs, | ||
| 1368 | reloc_n))); | ||
| 1359 | } | 1369 | } |
| 1360 | else if (EQ (op, Qcomment)) | 1370 | else if (EQ (op, Qcomment)) |
| 1361 | { | 1371 | { |
| @@ -1509,15 +1519,17 @@ emit_ctxt_code (void) | |||
| 1509 | XFIXNUM (FUNCALL1 (hash-table-count, | 1519 | XFIXNUM (FUNCALL1 (hash-table-count, |
| 1510 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); | 1520 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); |
| 1511 | 1521 | ||
| 1512 | gcc_jit_context_new_global ( | 1522 | comp.data_relocs |
| 1513 | comp.ctxt, | 1523 | = gcc_jit_lvalue_as_rvalue( |
| 1514 | NULL, | 1524 | gcc_jit_context_new_global ( |
| 1515 | GCC_JIT_GLOBAL_EXPORTED, | 1525 | comp.ctxt, |
| 1516 | gcc_jit_context_new_array_type (comp.ctxt, | 1526 | NULL, |
| 1527 | GCC_JIT_GLOBAL_EXPORTED, | ||
| 1528 | gcc_jit_context_new_array_type (comp.ctxt, | ||
| 1517 | NULL, | 1529 | NULL, |
| 1518 | comp.lisp_obj_type, | 1530 | comp.lisp_obj_type, |
| 1519 | d_reloc_len), | 1531 | d_reloc_len), |
| 1520 | "data_relocs"); | 1532 | "data_relocs")); |
| 1521 | 1533 | ||
| 1522 | emit_litteral_string_func ("text_data_relocs", d_reloc); | 1534 | emit_litteral_string_func ("text_data_relocs", d_reloc); |
| 1523 | 1535 | ||
| @@ -2372,6 +2384,93 @@ define_bool_to_lisp_obj (void) | |||
| 2372 | 2384 | ||
| 2373 | } | 2385 | } |
| 2374 | 2386 | ||
| 2387 | static void | ||
| 2388 | compile_function (Lisp_Object func) | ||
| 2389 | { | ||
| 2390 | char *c_name = (char *) SDATA (FUNCALL1 (comp-func-c-func-name, func)); | ||
| 2391 | Lisp_Object args = FUNCALL1 (comp-func-args, func); | ||
| 2392 | EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func)); | ||
| 2393 | bool ncall = (FUNCALL1 (comp-nargs-p, args)); | ||
| 2394 | |||
| 2395 | if (!ncall) | ||
| 2396 | { | ||
| 2397 | EMACS_INT max_args = XFIXNUM (FUNCALL1 (comp-args-max, args)); | ||
| 2398 | comp.func = | ||
| 2399 | emit_func_declare (c_name, comp.lisp_obj_type, max_args, | ||
| 2400 | NULL, GCC_JIT_FUNCTION_EXPORTED, false); | ||
| 2401 | } | ||
| 2402 | else | ||
| 2403 | { | ||
| 2404 | gcc_jit_param *param[] = | ||
| 2405 | { gcc_jit_context_new_param (comp.ctxt, | ||
| 2406 | NULL, | ||
| 2407 | comp.ptrdiff_type, | ||
| 2408 | "nargs"), | ||
| 2409 | gcc_jit_context_new_param (comp.ctxt, | ||
| 2410 | NULL, | ||
| 2411 | comp.lisp_obj_ptr_type, | ||
| 2412 | "args") }; | ||
| 2413 | comp.func = | ||
| 2414 | gcc_jit_context_new_function (comp.ctxt, | ||
| 2415 | NULL, | ||
| 2416 | GCC_JIT_FUNCTION_EXPORTED, | ||
| 2417 | comp.lisp_obj_type, | ||
| 2418 | c_name, 2, param, 0); | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | gcc_jit_lvalue *frame_array = | ||
| 2422 | gcc_jit_function_new_local ( | ||
| 2423 | comp.func, | ||
| 2424 | NULL, | ||
| 2425 | gcc_jit_context_new_array_type (comp.ctxt, | ||
| 2426 | NULL, | ||
| 2427 | comp.lisp_obj_type, | ||
| 2428 | frame_size), | ||
| 2429 | "local"); | ||
| 2430 | |||
| 2431 | gcc_jit_lvalue *frame[frame_size]; | ||
| 2432 | for (int i = 0; i < frame_size; ++i) | ||
| 2433 | frame[i] = | ||
| 2434 | gcc_jit_context_new_array_access ( | ||
| 2435 | comp.ctxt, | ||
| 2436 | NULL, | ||
| 2437 | gcc_jit_lvalue_as_rvalue (frame_array), | ||
| 2438 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 2439 | comp.int_type, | ||
| 2440 | i)); | ||
| 2441 | comp.frame = frame; | ||
| 2442 | |||
| 2443 | comp.func_blocks = CALLN (Fmake_hash_table); | ||
| 2444 | |||
| 2445 | /* Pre declare all basic blocks to gcc. | ||
| 2446 | The "entry" block must be declared as first. */ | ||
| 2447 | declare_block (Qentry); | ||
| 2448 | Lisp_Object blocks = FUNCALL1 (comp-func-blocks, func); | ||
| 2449 | Lisp_Object entry_block = Fgethash (Qentry, blocks, Qnil); | ||
| 2450 | struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks); | ||
| 2451 | for (ptrdiff_t i = 0; i < ht->count; i++) | ||
| 2452 | { | ||
| 2453 | Lisp_Object block = HASH_VALUE (ht, i); | ||
| 2454 | if (!EQ (block, entry_block)) | ||
| 2455 | declare_block (HASH_KEY (ht, i)); | ||
| 2456 | } | ||
| 2457 | |||
| 2458 | for (ptrdiff_t i = 0; i < ht->count; i++) | ||
| 2459 | { | ||
| 2460 | Lisp_Object block_name = HASH_KEY (ht, i); | ||
| 2461 | Lisp_Object block = HASH_VALUE (ht, i); | ||
| 2462 | Lisp_Object insns = FUNCALL1 (comp-block-insns, block); | ||
| 2463 | |||
| 2464 | comp.block = retrive_block (block_name); | ||
| 2465 | while (CONSP (insns)) | ||
| 2466 | { | ||
| 2467 | Lisp_Object insn = XCAR (insns); | ||
| 2468 | emit_limple_insn (insn); | ||
| 2469 | insns = XCDR (insns); | ||
| 2470 | } | ||
| 2471 | } | ||
| 2472 | } | ||
| 2473 | |||
| 2375 | 2474 | ||
| 2376 | /**********************************/ | 2475 | /**********************************/ |
| 2377 | /* Entry points exposed to lisp. */ | 2476 | /* Entry points exposed to lisp. */ |
| @@ -2574,97 +2673,6 @@ DEFUN ("comp--release-ctxt", Fcomp__release_ctxt, Scomp__release_ctxt, | |||
| 2574 | return Qt; | 2673 | return Qt; |
| 2575 | } | 2674 | } |
| 2576 | 2675 | ||
| 2577 | DEFUN ("comp--add-func-to-ctxt", Fcomp__add_func_to_ctxt, | ||
| 2578 | Scomp__add_func_to_ctxt, 1, 1, 0, | ||
| 2579 | doc: /* Add limple FUNC to the current compilation context. */) | ||
| 2580 | (Lisp_Object func) | ||
| 2581 | { | ||
| 2582 | char *c_name = (char *) SDATA (FUNCALL1 (comp-func-c-func-name, func)); | ||
| 2583 | Lisp_Object args = FUNCALL1 (comp-func-args, func); | ||
| 2584 | EMACS_INT frame_size = XFIXNUM (FUNCALL1 (comp-func-frame-size, func)); | ||
| 2585 | bool ncall = (FUNCALL1 (comp-nargs-p, args)); | ||
| 2586 | |||
| 2587 | if (!ncall) | ||
| 2588 | { | ||
| 2589 | EMACS_INT max_args = XFIXNUM (FUNCALL1 (comp-args-max, args)); | ||
| 2590 | comp.func = | ||
| 2591 | emit_func_declare (c_name, comp.lisp_obj_type, max_args, | ||
| 2592 | NULL, GCC_JIT_FUNCTION_EXPORTED, false); | ||
| 2593 | } | ||
| 2594 | else | ||
| 2595 | { | ||
| 2596 | gcc_jit_param *param[] = | ||
| 2597 | { gcc_jit_context_new_param (comp.ctxt, | ||
| 2598 | NULL, | ||
| 2599 | comp.ptrdiff_type, | ||
| 2600 | "nargs"), | ||
| 2601 | gcc_jit_context_new_param (comp.ctxt, | ||
| 2602 | NULL, | ||
| 2603 | comp.lisp_obj_ptr_type, | ||
| 2604 | "args") }; | ||
| 2605 | comp.func = | ||
| 2606 | gcc_jit_context_new_function (comp.ctxt, | ||
| 2607 | NULL, | ||
| 2608 | GCC_JIT_FUNCTION_EXPORTED, | ||
| 2609 | comp.lisp_obj_type, | ||
| 2610 | c_name, 2, param, 0); | ||
| 2611 | } | ||
| 2612 | |||
| 2613 | gcc_jit_lvalue *frame_array = | ||
| 2614 | gcc_jit_function_new_local ( | ||
| 2615 | comp.func, | ||
| 2616 | NULL, | ||
| 2617 | gcc_jit_context_new_array_type (comp.ctxt, | ||
| 2618 | NULL, | ||
| 2619 | comp.lisp_obj_type, | ||
| 2620 | frame_size), | ||
| 2621 | "local"); | ||
| 2622 | |||
| 2623 | gcc_jit_lvalue *frame[frame_size]; | ||
| 2624 | for (int i = 0; i < frame_size; ++i) | ||
| 2625 | frame[i] = | ||
| 2626 | gcc_jit_context_new_array_access ( | ||
| 2627 | comp.ctxt, | ||
| 2628 | NULL, | ||
| 2629 | gcc_jit_lvalue_as_rvalue (frame_array), | ||
| 2630 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 2631 | comp.int_type, | ||
| 2632 | i)); | ||
| 2633 | comp.frame = frame; | ||
| 2634 | |||
| 2635 | comp.func_blocks = CALLN (Fmake_hash_table); | ||
| 2636 | |||
| 2637 | /* Pre declare all basic blocks to gcc. | ||
| 2638 | The "entry" block must be declared as first. */ | ||
| 2639 | declare_block (Qentry); | ||
| 2640 | Lisp_Object blocks = FUNCALL1 (comp-func-blocks, func); | ||
| 2641 | Lisp_Object entry_block = Fgethash (Qentry, blocks, Qnil); | ||
| 2642 | struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks); | ||
| 2643 | for (ptrdiff_t i = 0; i < ht->count; i++) | ||
| 2644 | { | ||
| 2645 | Lisp_Object block = HASH_VALUE (ht, i); | ||
| 2646 | if (!EQ (block, entry_block)) | ||
| 2647 | declare_block (HASH_KEY (ht, i)); | ||
| 2648 | } | ||
| 2649 | |||
| 2650 | for (ptrdiff_t i = 0; i < ht->count; i++) | ||
| 2651 | { | ||
| 2652 | Lisp_Object block_name = HASH_KEY (ht, i); | ||
| 2653 | Lisp_Object block = HASH_VALUE (ht, i); | ||
| 2654 | Lisp_Object insns = FUNCALL1 (comp-block-insns, block); | ||
| 2655 | |||
| 2656 | comp.block = retrive_block (block_name); | ||
| 2657 | while (CONSP (insns)) | ||
| 2658 | { | ||
| 2659 | Lisp_Object insn = XCAR (insns); | ||
| 2660 | emit_limple_insn (insn); | ||
| 2661 | insns = XCDR (insns); | ||
| 2662 | } | ||
| 2663 | } | ||
| 2664 | |||
| 2665 | return Qt; | ||
| 2666 | } | ||
| 2667 | |||
| 2668 | DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, | 2676 | DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, |
| 2669 | Scomp__compile_ctxt_to_file, | 2677 | Scomp__compile_ctxt_to_file, |
| 2670 | 1, 1, 0, | 2678 | 1, 1, 0, |
| @@ -2687,6 +2695,13 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, | |||
| 2687 | 2695 | ||
| 2688 | emit_ctxt_code (); | 2696 | emit_ctxt_code (); |
| 2689 | 2697 | ||
| 2698 | /* Compile all functions. Can't be done before because the | ||
| 2699 | relocation vectore has to be already compiled. */ | ||
| 2700 | struct Lisp_Hash_Table *func_h | ||
| 2701 | = XHASH_TABLE (FUNCALL1 (comp-ctxt-funcs-h, Vcomp_ctxt)); | ||
| 2702 | for (ptrdiff_t i = 0; i < func_h->count; i++) | ||
| 2703 | compile_function (HASH_VALUE (func_h, i)); | ||
| 2704 | |||
| 2690 | if (COMP_DEBUG) | 2705 | if (COMP_DEBUG) |
| 2691 | { | 2706 | { |
| 2692 | AUTO_STRING (dot_c, ".c"); | 2707 | AUTO_STRING (dot_c, ".c"); |
| @@ -2967,7 +2982,6 @@ syms_of_comp (void) | |||
| 2967 | 2982 | ||
| 2968 | defsubr (&Scomp__init_ctxt); | 2983 | defsubr (&Scomp__init_ctxt); |
| 2969 | defsubr (&Scomp__release_ctxt); | 2984 | defsubr (&Scomp__release_ctxt); |
| 2970 | defsubr (&Scomp__add_func_to_ctxt); | ||
| 2971 | defsubr (&Scomp__compile_ctxt_to_file); | 2985 | defsubr (&Scomp__compile_ctxt_to_file); |
| 2972 | defsubr (&Snative_elisp_load); | 2986 | defsubr (&Snative_elisp_load); |
| 2973 | 2987 | ||