Skip to content

Commit

Permalink
[jit] Perform inlining earlier during call processing to avoid loadin…
Browse files Browse the repository at this point in the history
…g vtable/rgctx args which are not needed. (dotnet#33951)

Co-authored-by: vargaz <[email protected]>
  • Loading branch information
monojenkins and vargaz authored Mar 23, 2020
1 parent f79afdb commit 39df362
Showing 1 changed file with 43 additions and 43 deletions.
86 changes: 43 additions & 43 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -7332,6 +7332,49 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_TYPELOAD (cmethod->klass);
}

/* Inlining */
if ((cfg->opt & MONO_OPT_INLINE) && !inst_tailcall &&
(!virtual_ || !(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod)) &&
mono_method_check_inlining (cfg, cmethod)) {
int costs;
gboolean always = FALSE;

if ((cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
/* Prevent inlining of methods that call wrappers */
INLINE_FAILURE ("wrapper call");
// FIXME? Does this write to cmethod impact tailcall_supported? Probably not.
// Neither pinvoke or icall are likely to be tailcalled.
cmethod = mono_marshal_get_native_wrapper (cmethod, TRUE, FALSE);
always = TRUE;
}

costs = inline_method (cfg, cmethod, fsig, sp, ip, cfg->real_offset, always);
if (costs) {
cfg->real_offset += 5;

if (!MONO_TYPE_IS_VOID (fsig->ret))
/* *sp is already set by inline_method */
ins = *sp;

inline_costs += costs;
// FIXME This is missed if the inlinee contains tail calls that
// would work, but not once inlined into caller.
// This matchingness could be a factor in inlining.
// i.e. Do not inline if it hurts tailcall, do inline
// if it helps and/or or is neutral, and helps performance
// using usual heuristics.
// Note that inlining will expose multiple tailcall opportunities
// so the tradeoff is not obvious. If we can tailcall anything
// like desktop, then this factor mostly falls away, except
// that inlining can affect tailcall performance due to
// signature match/mismatch.
if (inst_tailcall) // FIXME
mono_tailcall_print ("missed tailcall inline %s -> %s\n", method->name, cmethod->name);
goto call_end;
}
}

check_method_sharing (cfg, cmethod, &pass_vtable, &pass_mrgctx);

if (cfg->gshared) {
Expand Down Expand Up @@ -7539,49 +7582,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
goto call_end;
}
CHECK_CFG_ERROR;

/* Inlining */
if ((cfg->opt & MONO_OPT_INLINE) &&
(!virtual_ || !(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod)) &&
mono_method_check_inlining (cfg, cmethod)) {
int costs;
gboolean always = FALSE;

if ((cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
/* Prevent inlining of methods that call wrappers */
INLINE_FAILURE ("wrapper call");
// FIXME? Does this write to cmethod impact tailcall_supported? Probably not.
// Neither pinvoke or icall are likely to be tailcalled.
cmethod = mono_marshal_get_native_wrapper (cmethod, TRUE, FALSE);
always = TRUE;
}

costs = inline_method (cfg, cmethod, fsig, sp, ip, cfg->real_offset, always);
if (costs) {
cfg->real_offset += 5;

if (!MONO_TYPE_IS_VOID (fsig->ret))
/* *sp is already set by inline_method */
ins = *sp;

inline_costs += costs;
// FIXME This is missed if the inlinee contains tail calls that
// would work, but not once inlined into caller.
// This matchingness could be a factor in inlining.
// i.e. Do not inline if it hurts tailcall, do inline
// if it helps and/or or is neutral, and helps performance
// using usual heuristics.
// Note that inlining will expose multiple tailcall opportunities
// so the tradeoff is not obvious. If we can tailcall anything
// like desktop, then this factor mostly falls away, except
// that inlining can affect tailcall performance due to
// signature match/mismatch.
if (inst_tailcall) // FIXME
mono_tailcall_print ("missed tailcall inline %s -> %s\n", method->name, cmethod->name);
goto call_end;
}
}

/* Tail recursion elimination */
if (((cfg->opt & MONO_OPT_TAILCALL) || inst_tailcall) && il_op == MONO_CEE_CALL && cmethod == method && next_ip < end && next_ip [0] == CEE_RET && !vtable_arg) {
Expand Down

0 comments on commit 39df362

Please sign in to comment.