diff options
| author | Andrea Corallo | 2019-08-10 18:17:05 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:33:58 +0100 |
| commit | 26da67d10b93e2997679e27b56a072e4767102c2 (patch) | |
| tree | 4b637969b991a702905ac4f9b354c8b30e7f5f7b /src/comp.c | |
| parent | e1757517c33d9c6428ecab8bc277aea14ec0c96f (diff) | |
| download | emacs-26da67d10b93e2997679e27b56a072e4767102c2.tar.gz emacs-26da67d10b93e2997679e27b56a072e4767102c2.zip | |
add routine dispatcher
Diffstat (limited to 'src/comp.c')
| -rw-r--r-- | src/comp.c | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/src/comp.c b/src/comp.c index 96e9c55f443..6552ea91c14 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -145,6 +145,7 @@ typedef struct { | |||
| 145 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ | 145 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ |
| 146 | Lisp_Object func_hash; /* f_name -> gcc_func. */ | 146 | Lisp_Object func_hash; /* f_name -> gcc_func. */ |
| 147 | Lisp_Object funcs; /* List of functions defined. */ | 147 | Lisp_Object funcs; /* List of functions defined. */ |
| 148 | Lisp_Object routine_dispatcher; | ||
| 148 | } comp_t; | 149 | } comp_t; |
| 149 | 150 | ||
| 150 | static comp_t comp; | 151 | static comp_t comp; |
| @@ -232,6 +233,15 @@ declare_block (const char * block_name) | |||
| 232 | Fputhash (key, value, comp.func_blocks); | 233 | Fputhash (key, value, comp.func_blocks); |
| 233 | } | 234 | } |
| 234 | 235 | ||
| 236 | static void | ||
| 237 | register_dispatch (const char *name, void *func) | ||
| 238 | { | ||
| 239 | Lisp_Object key = make_string (name, strlen (name)); | ||
| 240 | Lisp_Object value = make_pointer_integer (XPL (func)); | ||
| 241 | Fputhash (key, value, comp.routine_dispatcher); | ||
| 242 | } | ||
| 243 | |||
| 244 | |||
| 235 | INLINE static void | 245 | INLINE static void |
| 236 | emit_comment (const char *str) | 246 | emit_comment (const char *str) |
| 237 | { | 247 | { |
| @@ -241,22 +251,6 @@ emit_comment (const char *str) | |||
| 241 | str); | 251 | str); |
| 242 | } | 252 | } |
| 243 | 253 | ||
| 244 | |||
| 245 | /* Assignments to the meta-stack slots should be emitted usign this to always */ | ||
| 246 | /* reset annotation fields. */ | ||
| 247 | |||
| 248 | /* static void */ | ||
| 249 | /* emit_assign_to_stack_slot (basic_block_t *block, stack_el_t *slot, */ | ||
| 250 | /* gcc_jit_rvalue *val) */ | ||
| 251 | /* { */ | ||
| 252 | /* gcc_jit_block_add_assignment (block->gcc_bb, */ | ||
| 253 | /* NULL, */ | ||
| 254 | /* slot->gcc_lval, */ | ||
| 255 | /* val); */ | ||
| 256 | /* slot->type = -1; */ | ||
| 257 | /* slot->const_set = false; */ | ||
| 258 | /* } */ | ||
| 259 | |||
| 260 | /* Declare a function with all args being Lisp_Object and returning a | 254 | /* Declare a function with all args being Lisp_Object and returning a |
| 261 | Lisp_Object. */ | 255 | Lisp_Object. */ |
| 262 | 256 | ||
| @@ -951,7 +945,7 @@ emit_PURE_P (gcc_jit_rvalue *ptr) | |||
| 951 | 945 | ||
| 952 | 946 | ||
| 953 | /*************************************/ | 947 | /*************************************/ |
| 954 | /* Code emittes by LIMPLE statemes. */ | 948 | /* Code emitted by LIMPLE statemes. */ |
| 955 | /*************************************/ | 949 | /*************************************/ |
| 956 | 950 | ||
| 957 | /* Emit an r-value from an mvar meta variable. | 951 | /* Emit an r-value from an mvar meta variable. |
| @@ -984,6 +978,28 @@ emit_mvar_val (Lisp_Object mvar) | |||
| 984 | } | 978 | } |
| 985 | } | 979 | } |
| 986 | 980 | ||
| 981 | static gcc_jit_rvalue * | ||
| 982 | emit_set_internal (Lisp_Object args) | ||
| 983 | { | ||
| 984 | /* | ||
| 985 | Ex: (call set_internal | ||
| 986 | #s(comp-mvar 7 nil t xxx nil) | ||
| 987 | #s(comp-mvar 6 1 t 3 nil)) | ||
| 988 | */ | ||
| 989 | /* TODO: Inline the most common case. */ | ||
| 990 | eassert (list_length (args) == 3); | ||
| 991 | args = XCDR (args); | ||
| 992 | int i = 0; | ||
| 993 | gcc_jit_rvalue *gcc_args[4]; | ||
| 994 | FOR_EACH_TAIL (args) | ||
| 995 | gcc_args[i++] = emit_mvar_val (XCAR (args)); | ||
| 996 | gcc_args[2] = emit_lisp_obj_from_ptr (Qnil); | ||
| 997 | gcc_args[3] = gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 998 | comp.int_type, | ||
| 999 | SET_INTERNAL_SET); | ||
| 1000 | return emit_call ("set_internal", comp.void_type , 4, gcc_args); | ||
| 1001 | } | ||
| 1002 | |||
| 987 | static void | 1003 | static void |
| 988 | emit_limple_ncall_prolog (EMACS_UINT n) | 1004 | emit_limple_ncall_prolog (EMACS_UINT n) |
| 989 | { | 1005 | { |
| @@ -1052,46 +1068,45 @@ emit_limple_ncall_prolog (EMACS_UINT n) | |||
| 1052 | list_args)); | 1068 | list_args)); |
| 1053 | } | 1069 | } |
| 1054 | 1070 | ||
| 1071 | /* This is for a regular function with arguments as m-var. */ | ||
| 1072 | |||
| 1055 | static gcc_jit_rvalue * | 1073 | static gcc_jit_rvalue * |
| 1056 | emit_limple_call (Lisp_Object arg1) | 1074 | emit_simple_limple_call (Lisp_Object args) |
| 1057 | { | 1075 | { |
| 1058 | char *calle = (char *) SDATA (SYMBOL_NAME (SECOND (arg1))); | 1076 | /* |
| 1059 | Lisp_Object call_args = XCDR (XCDR (arg1)); | 1077 | Ex: (call Fcar #s(comp-mvar 4 0 nil nil nil)) |
| 1060 | int i = 0; | ||
| 1061 | 1078 | ||
| 1062 | if (calle[0] == 'F') | 1079 | Ex: (call Fcons #s(comp-mvar 3 0 t 1 nil) |
| 1063 | { | 1080 | #s(comp-mvar 4 nil t nil nil)) |
| 1064 | /* | 1081 | */ |
| 1065 | Ex: (call Fcar #s(comp-mvar 4 0 nil nil nil)) | 1082 | int i = 0; |
| 1083 | char *calle = (char *) SDATA (SYMBOL_NAME (FIRST (args))); | ||
| 1084 | args = XCDR (args); | ||
| 1085 | ptrdiff_t nargs = list_length (args); | ||
| 1086 | gcc_jit_rvalue *gcc_args[nargs]; | ||
| 1087 | FOR_EACH_TAIL (args) | ||
| 1088 | gcc_args[i++] = emit_mvar_val (XCAR (args)); | ||
| 1089 | |||
| 1090 | return emit_call (calle, comp.lisp_obj_type, nargs, gcc_args); | ||
| 1091 | } | ||
| 1066 | 1092 | ||
| 1067 | Ex: (call Fcons #s(comp-mvar 3 0 t 1 nil) | 1093 | /* Entry point to dispatch emission of (call fun ...). */ |
| 1068 | #s(comp-mvar 4 nil t nil nil)) | ||
| 1069 | */ | ||
| 1070 | 1094 | ||
| 1071 | ptrdiff_t nargs = list_length (call_args); | 1095 | static gcc_jit_rvalue * |
| 1072 | gcc_jit_rvalue *gcc_args[nargs]; | 1096 | emit_limple_call (Lisp_Object args) |
| 1073 | FOR_EACH_TAIL (call_args) | 1097 | { |
| 1074 | gcc_args[i++] = emit_mvar_val (XCAR (call_args)); | 1098 | Lisp_Object calle_sym = FIRST (args); |
| 1099 | char *calle = (char *) SDATA (SYMBOL_NAME (calle_sym)); | ||
| 1100 | Lisp_Object emitter = Fgethash (SYMBOL_NAME (calle_sym), comp.routine_dispatcher, Qnil); | ||
| 1075 | 1101 | ||
| 1076 | return emit_call (calle, comp.lisp_obj_type, nargs, gcc_args); | 1102 | if (!NILP (emitter)) |
| 1103 | { | ||
| 1104 | gcc_jit_rvalue * (* emitter_ptr) (Lisp_Object) = XFIXNUMPTR (emitter); | ||
| 1105 | return emitter_ptr (args); | ||
| 1077 | } | 1106 | } |
| 1078 | else if (!strcmp (calle, "set_internal")) | 1107 | else if (calle[0] == 'F') |
| 1079 | { | 1108 | { |
| 1080 | /* | 1109 | return emit_simple_limple_call (args); |
| 1081 | Ex: (call set_internal | ||
| 1082 | #s(comp-mvar 7 nil t xxx nil) | ||
| 1083 | #s(comp-mvar 6 1 t 3 nil)) | ||
| 1084 | */ | ||
| 1085 | /* TODO: Inline the most common case. */ | ||
| 1086 | eassert (list_length (call_args) == 2); | ||
| 1087 | gcc_jit_rvalue *gcc_args[4]; | ||
| 1088 | FOR_EACH_TAIL (call_args) | ||
| 1089 | gcc_args[i++] = emit_mvar_val (XCAR (call_args)); | ||
| 1090 | gcc_args[2] = emit_lisp_obj_from_ptr (Qnil); | ||
| 1091 | gcc_args[3] = gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1092 | comp.int_type, | ||
| 1093 | SET_INTERNAL_SET); | ||
| 1094 | return emit_call ("set_internal", comp.void_type , 4, gcc_args); | ||
| 1095 | } | 1110 | } |
| 1096 | else if (!strcmp (calle, "record_unwind_current_buffer") || | 1111 | else if (!strcmp (calle, "record_unwind_current_buffer") || |
| 1097 | !strcmp (calle, "helper_unwind_protect")) | 1112 | !strcmp (calle, "helper_unwind_protect")) |
| @@ -1258,7 +1273,7 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1258 | { | 1273 | { |
| 1259 | gcc_jit_block_add_eval (comp.block, | 1274 | gcc_jit_block_add_eval (comp.block, |
| 1260 | NULL, | 1275 | NULL, |
| 1261 | emit_limple_call (insn)); | 1276 | emit_limple_call (args)); |
| 1262 | } | 1277 | } |
| 1263 | else if (EQ (op, Qset)) | 1278 | else if (EQ (op, Qset)) |
| 1264 | { | 1279 | { |
| @@ -1268,7 +1283,7 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1268 | if (EQ (Ftype_of (arg1), Qcomp_mvar)) | 1283 | if (EQ (Ftype_of (arg1), Qcomp_mvar)) |
| 1269 | res = emit_mvar_val (arg1); | 1284 | res = emit_mvar_val (arg1); |
| 1270 | else if (EQ (FIRST (arg1), Qcall)) | 1285 | else if (EQ (FIRST (arg1), Qcall)) |
| 1271 | res = emit_limple_call (arg1); | 1286 | res = emit_limple_call (XCDR (arg1)); |
| 1272 | else if (EQ (FIRST (arg1), Qcallref)) | 1287 | else if (EQ (FIRST (arg1), Qcallref)) |
| 1273 | res = emit_limple_call_ref (arg1); | 1288 | res = emit_limple_call_ref (arg1); |
| 1274 | else | 1289 | else |
| @@ -2028,6 +2043,7 @@ DEFUN ("comp-init-ctxt", Fcomp_init_ctxt, Scomp_init_ctxt, | |||
| 2028 | error ("Compiler context already taken."); | 2043 | error ("Compiler context already taken."); |
| 2029 | return Qnil; | 2044 | return Qnil; |
| 2030 | } | 2045 | } |
| 2046 | |||
| 2031 | comp.ctxt = gcc_jit_context_acquire(); | 2047 | comp.ctxt = gcc_jit_context_acquire(); |
| 2032 | comp.funcs = Qnil; | 2048 | comp.funcs = Qnil; |
| 2033 | 2049 | ||
| @@ -2357,9 +2373,15 @@ syms_of_comp (void) | |||
| 2357 | defsubr (&Scomp_add_func_to_ctxt); | 2373 | defsubr (&Scomp_add_func_to_ctxt); |
| 2358 | defsubr (&Scomp_compile_and_load_ctxt); | 2374 | defsubr (&Scomp_compile_and_load_ctxt); |
| 2359 | comp.func_hash = Qnil; | 2375 | comp.func_hash = Qnil; |
| 2376 | comp.routine_dispatcher = Qnil; | ||
| 2360 | staticpro (&comp.func_hash); | 2377 | staticpro (&comp.func_hash); |
| 2361 | staticpro (&comp.func_blocks); | 2378 | staticpro (&comp.func_blocks); |
| 2362 | 2379 | ||
| 2380 | comp.routine_dispatcher = CALLN (Fmake_hash_table, QCtest, Qequal); | ||
| 2381 | register_dispatch ("set_internal", emit_set_internal); | ||
| 2382 | register_dispatch ("helper_unbind_n", emit_simple_limple_call); | ||
| 2383 | staticpro (&comp.routine_dispatcher); | ||
| 2384 | |||
| 2363 | DEFVAR_INT ("comp-speed", comp_speed, | 2385 | DEFVAR_INT ("comp-speed", comp_speed, |
| 2364 | doc: /* From 0 to 3. */); | 2386 | doc: /* From 0 to 3. */); |
| 2365 | comp_speed = DEFAULT_SPEED; | 2387 | comp_speed = DEFAULT_SPEED; |