From 930fd477e6467af7deddc044f64c7c7401c18ad6 Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Fri, 6 Jul 2018 15:31:50 +0200 Subject: [PATCH] More precise handling of reads of deopt-marked ins Previously, we would consider reads by an instruction that might deopt post-optimization as if they were being read after that deoptimization, and so could preserve write instructions for the sake of deopt when there was no need to do so. With this change, we will not. This allows a small number of additional instruction deletions. For example, the post-optimized bytecode for a "read a million line file" benchmark is 32 bytes smaller after this, which amounts to a little less code to JIT and a little less work every iteration. According to callgrind, for that benchmark - and with JIT enabled - it's worth 15 million CPU insturctions saved, or 15 per iteration of the loop. --- src/spesh/facts.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/spesh/facts.c b/src/spesh/facts.c index 1566d0707e..e34e8edece 100644 --- a/src/spesh/facts.c +++ b/src/spesh/facts.c @@ -446,15 +446,16 @@ static void add_bb_facts(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb, MVMSpeshAnn *ann_deopt_one = NULL; MVMSpeshAnn *ann_logged = NULL; MVMint32 is_deopt_ins = 0; + MVMuint32 next_deopt_idx = cur_deopt_idx; while (ann) { switch (ann->type) { case MVM_SPESH_ANN_DEOPT_ONE_INS: ann_deopt_one = ann; - cur_deopt_idx = ann->data.deopt_idx; + next_deopt_idx = ann->data.deopt_idx; is_deopt_ins = 1; break; case MVM_SPESH_ANN_DEOPT_ALL_INS: - cur_deopt_idx = ann->data.deopt_idx; + next_deopt_idx = ann->data.deopt_idx; break; case MVM_SPESH_ANN_LOGGED: ann_logged = ann; @@ -485,13 +486,17 @@ static void add_bb_facts(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb, if ((is_phi && i == 0) || (!is_phi && (ins->info->operands[i] & MVM_operand_rw_mask) == MVM_operand_write_reg)) { MVMSpeshFacts *facts = &(g->facts[ins->operands[i].reg.orig][ins->operands[i].reg.i]); - facts->deopt_idx = cur_deopt_idx; + facts->deopt_idx = next_deopt_idx; facts->writer = ins; if (is_deopt_ins) facts->usages++; } } + /* Now that we processed the reads of this instruction under the + * prior deopt index, update the current one to the next one. */ + cur_deopt_idx = next_deopt_idx; + /* Look for ops that are fact-interesting. */ switch (ins->info->opcode) { case MVM_OP_inc_i: