Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][interp] Improve precision of native offset estimation #103956

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/transform-opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3387,7 +3387,7 @@ can_propagate_var_def (TransformData *td, int var, InterpLivenessPosition cur_li
static void
interp_super_instructions (TransformData *td)
{
interp_compute_native_offset_estimates (td);
interp_compute_native_offset_estimates (td, FALSE);

// Add some actual super instructions
for (int bb_dfs_index = 0; bb_dfs_index < td->bblocks_count_eh; bb_dfs_index++) {
Expand Down
24 changes: 22 additions & 2 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -8791,12 +8791,18 @@ interp_foreach_ins_var (TransformData *td, InterpInst *ins, gpointer data, void
}

int
interp_compute_native_offset_estimates (TransformData *td)
interp_compute_native_offset_estimates (TransformData *td, gboolean final_code)
{
InterpBasicBlock *bb;
int noe = 0;

for (bb = td->entry_bb; bb != NULL; bb = bb->next_bb) {
InterpInst *ins;
// FIXME This doesn't currently hold because of bblock reordering potentially
// inserting additional instructions after the estimate is computed.
//
// if (bb->native_offset_estimate)
// g_assert (bb->native_offset_estimate >= noe);
bb->native_offset_estimate = noe;
if (!td->optimized && bb->patchpoint_bb)
noe += 2;
Expand All @@ -8815,6 +8821,20 @@ interp_compute_native_offset_estimates (TransformData *td)
if (MINT_IS_EMIT_NOP (opcode))
continue;
noe += interp_get_ins_length (ins);

if (!final_code && td->optimized &&
(ins->flags & INTERP_INST_FLAG_CALL) &&
ins->info.call_info &&
ins->info.call_info->call_args) {
// When code is optimized, for a call, the offset allocator
// might end up inserting additional moves for the arguments
int *call_args = ins->info.call_info->call_args;
while (*call_args != -1) {
noe += 4; // mono_interp_oplen [MINT_MOV_VT];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it always a single MINT_MOV_VT per argument?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is either a scalar mov (size 3) or a vt move (which also has size embedded so it is size 4). We are being conservative here since it is not worth checking the signature.

call_args++;
}
}

if (!td->optimized)
interp_foreach_ins_var (td, ins, NULL, alloc_unopt_global_local);
}
Expand Down Expand Up @@ -9255,7 +9275,7 @@ generate_compacted_code (InterpMethod *rtm, TransformData *td)

// This iteration could be avoided at the cost of less precise size result, following
// super instruction pass
size = interp_compute_native_offset_estimates (td);
size = interp_compute_native_offset_estimates (td, TRUE);

// Generate the compacted stream of instructions
td->new_code = ip = (guint16*)imethod_alloc0 (td, size * sizeof (guint16));
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ void
interp_link_bblocks (TransformData *td, InterpBasicBlock *from, InterpBasicBlock *to);

int
interp_compute_native_offset_estimates (TransformData *td);
interp_compute_native_offset_estimates (TransformData *td, gboolean final_code);

void
interp_optimize_code (TransformData *td);
Expand Down
Loading