Skip to content

Commit

Permalink
[interp] Inline more AggressiveInlining methods (#48513)
Browse files Browse the repository at this point in the history
* [interp] Inline more AggressiveInlining methods

By default, the interpreter stops inlining when encountering a call that it cannot inline or a throw. Inline the method anyway if the aggressive inlining attribute is present.

* [interp] Fix some long conditional branch opcodes
  • Loading branch information
BrzVlad authored Feb 22, 2021
1 parent 82c5bd7 commit 5bc40f5
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3976,7 +3976,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs

#define BRELOP_CAST(datatype, op) \
if (LOCAL_VAR (ip [1], datatype) op LOCAL_VAR (ip [2], datatype)) { \
gint32 br_offset = (gint32) ip [1]; \
gint32 br_offset = (gint32)READ32(ip + 3); \
BACK_BRANCH_PROFILE (br_offset); \
ip += br_offset; \
} else \
Expand Down
13 changes: 9 additions & 4 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -2655,6 +2655,7 @@ interp_inline_method (TransformData *td, MonoMethod *target_method, MonoMethodHe
int prev_n_data_items;
int i;
int prev_sp_offset;
int prev_aggressive_inlining;
MonoGenericContext *generic_context = NULL;
StackInfo *prev_param_area;
InterpBasicBlock **prev_offset_to_bb;
Expand All @@ -2681,6 +2682,7 @@ interp_inline_method (TransformData *td, MonoMethod *target_method, MonoMethodHe
prev_offset_to_bb = td->offset_to_bb;
prev_cbb = td->cbb;
prev_entry_bb = td->entry_bb;
prev_aggressive_inlining = td->aggressive_inlining;
td->inlined_method = target_method;

prev_max_stack_height = td->max_stack_height;
Expand All @@ -2696,7 +2698,7 @@ interp_inline_method (TransformData *td, MonoMethod *target_method, MonoMethodHe

int const prev_code_size = td->code_size;
td->code_size = header->code_size;

td->aggressive_inlining = !!(target_method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING);
if (td->verbose_level)
g_print ("Inline start method %s.%s\n", m_class_get_name (target_method->klass), target_method->name);

Expand Down Expand Up @@ -2741,6 +2743,7 @@ interp_inline_method (TransformData *td, MonoMethod *target_method, MonoMethodHe
td->offset_to_bb = prev_offset_to_bb;
td->code_size = prev_code_size;
td->entry_bb = prev_entry_bb;
td->aggressive_inlining = prev_aggressive_inlining;

g_free (td->in_offsets);
td->in_offsets = prev_in_offsets;
Expand Down Expand Up @@ -2976,7 +2979,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
}

/* Don't inline methods that do calls */
if (op == -1 && td->inlined_method)
if (op == -1 && td->inlined_method && !td->aggressive_inlining)
return FALSE;

/* We need to convert delegate invoke to a indirect call on the interp_invoke_impl field */
Expand Down Expand Up @@ -5462,7 +5465,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
// Inlining failed. Set the method to be executed as part of newobj instruction
newobj_fast->data [0] = get_data_item_index (td, mono_interp_get_imethod (domain, m, error));
/* The constructor was not inlined, abort inlining of current method */
INLINE_FAILURE;
if (!td->aggressive_inlining)
INLINE_FAILURE;
} else {
interp_add_ins (td, MINT_NEWOBJ);
g_assert (!m_class_is_valuetype (klass));
Expand Down Expand Up @@ -5598,7 +5602,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,

break;
case CEE_THROW:
INLINE_FAILURE;
if (!td->aggressive_inlining)
INLINE_FAILURE;
CHECK_STACK (td, 1);
interp_add_ins (td, MINT_THROW);
interp_ins_set_sreg (td->last_ins, td->sp [-1].local);
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/interp/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ typedef struct
GList *dont_inline;
int inline_depth;
int has_localloc : 1;
// If the current method (inlined_method) has the aggressive inlining attribute, we no longer
// bail out of inlining when having to generate certain opcodes (like call, throw).
int aggressive_inlining : 1;
} TransformData;

#define STACK_TYPE_I4 0
Expand Down

0 comments on commit 5bc40f5

Please sign in to comment.