diff options
| author | Andrea Corallo | 2019-06-30 16:10:17 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:33:48 +0100 |
| commit | 9e71843f6301cff6e3f0d06e46c47bc5a5c7b177 (patch) | |
| tree | d4a0555c7748ae8cb1d9922984d9392d7ccd3b23 /src | |
| parent | 5c47cb9600de25a1e8e8e975795480044b866042 (diff) | |
| download | emacs-9e71843f6301cff6e3f0d06e46c47bc5a5c7b177.tar.gz emacs-9e71843f6301cff6e3f0d06e46c47bc5a5c7b177.zip | |
optimize primitve native call
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/src/comp.c b/src/comp.c index 491fcefe454..73a76ea8911 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -50,7 +50,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 50 | stack->gcc_lval, \ | 50 | stack->gcc_lval, \ |
| 51 | gcc_jit_lvalue_as_rvalue(obj)); \ | 51 | gcc_jit_lvalue_as_rvalue(obj)); \ |
| 52 | stack->type = -1; \ | 52 | stack->type = -1; \ |
| 53 | stack->sym_val = NULL; \ | 53 | stack->const_set = false; \ |
| 54 | stack++; \ | 54 | stack++; \ |
| 55 | } while (0) | 55 | } while (0) |
| 56 | 56 | ||
| @@ -62,7 +62,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 62 | stack->gcc_lval, \ | 62 | stack->gcc_lval, \ |
| 63 | (obj)); \ | 63 | (obj)); \ |
| 64 | stack->type = -1; \ | 64 | stack->type = -1; \ |
| 65 | stack->sym_val = NULL; \ | 65 | stack->const_set = false; \ |
| 66 | stack++; \ | 66 | stack++; \ |
| 67 | } while (0) | 67 | } while (0) |
| 68 | 68 | ||
| @@ -76,7 +76,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 76 | stack->gcc_lval, \ | 76 | stack->gcc_lval, \ |
| 77 | gcc_jit_param_as_rvalue(obj)); \ | 77 | gcc_jit_param_as_rvalue(obj)); \ |
| 78 | stack->type = -1; \ | 78 | stack->type = -1; \ |
| 79 | stack->sym_val = NULL; \ | 79 | stack->const_set = false; \ |
| 80 | stack++; \ | 80 | stack++; \ |
| 81 | } while (0) | 81 | } while (0) |
| 82 | 82 | ||
| @@ -186,7 +186,8 @@ do { \ | |||
| 186 | typedef struct { | 186 | typedef struct { |
| 187 | gcc_jit_lvalue *gcc_lval; | 187 | gcc_jit_lvalue *gcc_lval; |
| 188 | enum Lisp_Type type; /* -1 if not set. */ | 188 | enum Lisp_Type type; /* -1 if not set. */ |
| 189 | char *sym_val; | 189 | Lisp_Object constant; /* This is used for constant propagation. */ |
| 190 | bool const_set; | ||
| 190 | } stack_el_t; | 191 | } stack_el_t; |
| 191 | 192 | ||
| 192 | typedef struct { | 193 | typedef struct { |
| @@ -2274,22 +2275,57 @@ compile_f (const char *lisp_f_name, const char *c_f_name, | |||
| 2274 | op -= Bcall; | 2275 | op -= Bcall; |
| 2275 | docall: | 2276 | docall: |
| 2276 | { | 2277 | { |
| 2278 | res = NULL; | ||
| 2277 | ptrdiff_t nargs = op + 1; | 2279 | ptrdiff_t nargs = op + 1; |
| 2278 | pop (nargs, &stack, args); | 2280 | pop (nargs, &stack, args); |
| 2279 | if (stack->type == Lisp_Symbol && | 2281 | if (stack->const_set && |
| 2280 | !strcmp (stack->sym_val, lisp_f_name)) | 2282 | stack->type == Lisp_Symbol) |
| 2281 | { | 2283 | { |
| 2282 | /* Optimize self calls. */ | 2284 | ptrdiff_t native_nargs = nargs - 1; |
| 2283 | res = gcc_jit_context_new_call (comp.ctxt, | 2285 | char *sym_name = (char *) SDATA (SYMBOL_NAME (stack->constant)); |
| 2284 | NULL, | 2286 | if (!strcmp (sym_name, |
| 2285 | comp.func, | 2287 | lisp_f_name)) |
| 2286 | nargs - 1, | 2288 | { |
| 2287 | args + 1); | 2289 | /* Optimize self calls. */ |
| 2288 | } | 2290 | res = gcc_jit_context_new_call (comp.ctxt, |
| 2289 | else | 2291 | NULL, |
| 2290 | { | 2292 | comp.func, |
| 2291 | res = emit_call_n_ref ("Ffuncall", nargs, stack->gcc_lval); | 2293 | native_nargs, |
| 2294 | args + 1); | ||
| 2295 | } else if (SUBRP ((XSYMBOL (stack->constant)->u.s.function))) | ||
| 2296 | { | ||
| 2297 | /* Optimize primitive native calls. */ | ||
| 2298 | emit_comment (format_string ("Calling primitive %s", | ||
| 2299 | sym_name)); | ||
| 2300 | struct Lisp_Subr *subr = | ||
| 2301 | XSUBR ((XSYMBOL (stack->constant)->u.s.function)); | ||
| 2302 | gcc_jit_type *types[native_nargs]; | ||
| 2303 | |||
| 2304 | for (int i = 0; i < native_nargs; i++) | ||
| 2305 | types[i] = comp.lisp_obj_type; | ||
| 2306 | |||
| 2307 | gcc_jit_type *fn_ptr_type = | ||
| 2308 | gcc_jit_context_new_function_ptr_type (comp.ctxt, | ||
| 2309 | NULL, | ||
| 2310 | comp.lisp_obj_type, | ||
| 2311 | native_nargs, | ||
| 2312 | types, | ||
| 2313 | 0); | ||
| 2314 | res = | ||
| 2315 | gcc_jit_context_new_call_through_ptr ( | ||
| 2316 | comp.ctxt, | ||
| 2317 | NULL, | ||
| 2318 | gcc_jit_context_new_rvalue_from_ptr (comp.ctxt, | ||
| 2319 | fn_ptr_type, | ||
| 2320 | subr->function.a0), | ||
| 2321 | native_nargs, | ||
| 2322 | args + 1); | ||
| 2323 | } | ||
| 2292 | } | 2324 | } |
| 2325 | /* Fall back to regular funcall dispatch. */ | ||
| 2326 | if (!res) | ||
| 2327 | res = emit_call_n_ref ("Ffuncall", nargs, stack->gcc_lval); | ||
| 2328 | |||
| 2293 | PUSH_RVAL (res); | 2329 | PUSH_RVAL (res); |
| 2294 | break; | 2330 | break; |
| 2295 | } | 2331 | } |
| @@ -3133,9 +3169,12 @@ compile_f (const char *lisp_f_name, const char *c_f_name, | |||
| 3133 | PUSH_RVAL (c); | 3169 | PUSH_RVAL (c); |
| 3134 | TOS.type = XTYPE (vectorp[op]); | 3170 | TOS.type = XTYPE (vectorp[op]); |
| 3135 | if (TOS.type == Lisp_Symbol) | 3171 | if (TOS.type == Lisp_Symbol) |
| 3136 | /* Store the symbol value for later use is used while | 3172 | { |
| 3137 | optimizing native and self calls. */ | 3173 | /* Store the symbol value for later use is used while |
| 3138 | TOS.sym_val = (char *) SDATA (SYMBOL_NAME (vectorp[op])); | 3174 | optimizing native and self calls. */ |
| 3175 | TOS.constant = vectorp[op]; | ||
| 3176 | TOS.const_set = true; | ||
| 3177 | } | ||
| 3139 | break; | 3178 | break; |
| 3140 | } | 3179 | } |
| 3141 | 3180 | ||