From: Jérémie Astor Date: Mon, 16 Aug 2021 10:44:43 +0000 (+0200) Subject: :art: imporve inlining X-Git-Tag: nightly~470^2~80 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=e35082cd5c526ec3e363e4d6f810bf46e4a49e04;p=gwion.git :art: imporve inlining --- diff --git a/src/emit/emit.c b/src/emit/emit.c index cede1865..f80dab13 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1060,8 +1060,8 @@ ANN static inline bool check_inline(const Emitter emit, const Func f) { return f->weight < threshold; } -ANN static inline bool member_inlinable(const Func f, const Exp e) { - if (fflag(f, fflag_recurs)) return false; +ANN static inline bool member_inlinable(const Emitter emit, const Func f, const Exp e) { + if (f!= emit->env->func)return false; const Type owner_class = f->value_ref->from->owner_class; if (!owner_class) return true; return GET_FLAG(owner_class, final) || GET_FLAG(f->def->base, final) || @@ -1076,13 +1076,16 @@ ANN static inline Func is_inlinable(const Emitter emit, !ftype->info->func->code || ftype->info->func->code->builtin) return false; const Func f = ftype->info->func; - return (member_inlinable(f, exp_call->func) && check_inline(emit, f)) ? f + return (member_inlinable(emit, f, exp_call->func) && check_inline(emit, f)) ? f : NULL; } ANN static inline void inline_args_ini(const Emitter emit, const Func f, const Vector v) { - const m_uint start_offset = emit_code_offset(emit); + const bool member = f->value_ref->from->owner_class && vflag(f->value_ref, vflag_member); + if(member) + emit->this_offset = emit_local(emit, emit->gwion->type[et_int]); + const m_uint start_offset = emit_code_offset(emit) - (member ? SZ_INT : 0); Arg_List arg = f->def->base->args; while (arg) { const Value value = arg->var_decl->value; @@ -1116,8 +1119,8 @@ ANN static inline m_bool inline_body(const Emitter emit, const Func f) { vector_init(&emit->code->stack_return); nspc_push_value(emit->gwion->mp, emit->env->curr); const m_bool ret = scoped_stmt(emit, f->def->d.code, 1); - nspc_pop_value(emit->gwion->mp, emit->env->curr); emit_return_pc(emit, emit_code_size(emit)); + nspc_pop_value(emit->gwion->mp, emit->env->curr); vector_release(&emit->code->stack_return); emit->code->stack_return.ptr = v.ptr; return ret; @@ -1126,36 +1129,49 @@ ANN static inline m_bool inline_body(const Emitter emit, const Func f) { ANN static inline m_bool inline_run(const Emitter emit, const Func f) { struct Vector_ arg_offset; vector_init(&arg_offset); - const uint16_t this_offset = emit->this_offset; - const uint16_t vararg_offset = emit->vararg_offset; inline_args_ini(emit, f, &arg_offset); const m_bool ret = inline_body(emit, f); - emit->this_offset = this_offset; - emit->vararg_offset = vararg_offset; inline_args_end(f, &arg_offset); vector_release(&arg_offset); return ret; } -ANN static inline m_bool emit_inline(const Emitter emit, const Func f, +ANN static inline m_bool _emit_inline(const Emitter emit, const Func f, const Exp_Call *exp_call) { if (!f->weight) return GW_OK; - if (f->value_ref->from->owner_class && vflag(f->value_ref, vflag_member)) { + if (f->value_ref->from->owner_class && vflag(f->value_ref, vflag_member)) CHECK_BB(emit_exp(emit, exp_call->func->d.exp_dot.base)); - emit->this_offset = emit_local(emit, emit->gwion->type[et_int]); - } CHECK_BB(emit_func_args(emit, exp_call)); return inline_run(emit, f); } +ANN static inline m_bool emit_inline(const Emitter emit, const Func f, + const Exp_Call *exp_call) { + const uint16_t this_offset = emit->this_offset; + const uint16_t vararg_offset = emit->vararg_offset; + nspc_push_value(emit->gwion->mp, emit->env->curr); + const m_bool ret = _emit_inline(emit, f, exp_call); + nspc_pop_value(emit->gwion->mp, emit->env->curr); + emit->this_offset = this_offset; + emit->vararg_offset = vararg_offset; + return ret; +} + ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { - /* + #ifndef GWION_NOINLINE - const Func f = is_inlinable(emit, exp_call); - if(f) - return emit_inline(emit, f, exp_call); + const Func _f = is_inlinable(emit, exp_call); + if(_f) { + const Func base = emit->env->func; + emit->env->func = _f; + const m_uint scope = emit_push(emit, _f->value_ref->from->owner_class, _f->value_ref->from->owner); + const m_bool ret = emit_inline(emit, _f, exp_call); + emit_pop(emit, scope); + emit->env->func = base; + return ret; + } #endif - */ + // skip when recursing const Type t = actual_type(emit->gwion, exp_call->func->type); const Func f = t->info->func; diff --git a/src/parse/check.c b/src/parse/check.c index 217289bf..915fc604 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -561,7 +561,7 @@ ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) { ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { struct Vector_ v = {}; - const m_uint scope = env->scope->depth; + const m_uint scope = env->scope->depth; env->scope->depth = 0; vector_init(&v); while (vector_size((Vector)&env->curr->info->value->ptr) > 1) @@ -570,7 +570,7 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { for (m_uint i = vector_size(&v) + 1; --i;) vector_add((Vector)&env->curr->info->value->ptr, vector_at(&v, i - 1)); vector_release(&v); - env->scope->depth = scope; + env->scope->depth = scope; return ret; }