Skip to content

Commit

Permalink
Teach Spesh Inline About Returning By Unboxing
Browse files Browse the repository at this point in the history
Needed whenever an inlinee has a return_o op that
matches up to an invoke_i/n/s in the inliner.

Interestingly, seems to only happen once during
the entirety of rakudo's build process: in the
optimizer's "simplify_refs" routine.

Also, it only happens once smart_strify/_numify
can become a method call for .Str/.Num that also
gets inlined, which is what the following commits
implement.
  • Loading branch information
timo committed Jan 24, 2019
1 parent 34fac5f commit f30a806
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/spesh/inline.c
Expand Up @@ -895,6 +895,29 @@ static void return_to_box(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *re
MVM_spesh_manipulate_release_temp_reg(tc, g, type_temp);
}

static void return_to_unbox(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *return_bb,
MVMSpeshIns *return_ins, MVMSpeshOperand target, MVMuint16 unbox_op) {
/*MVMSpeshOperand type_temp = MVM_spesh_manipulate_get_temp_reg(tc, g, MVM_reg_obj);*/

/* Create and insert unboxing instruction after current return instruction. */
MVMSpeshOperand ver_target = MVM_spesh_manipulate_new_version(tc, g, target.reg.orig);
MVMSpeshIns *unbox_ins = MVM_spesh_alloc(tc, g, sizeof(MVMSpeshIns));
MVMSpeshOperand *unbox_operands = MVM_spesh_alloc(tc, g, 2 * sizeof(MVMSpeshOperand));
unbox_ins->info = MVM_op_get_op(unbox_op);
unbox_ins->operands = unbox_operands;
unbox_operands[0] = ver_target;
unbox_operands[1] = return_ins->operands[0];
MVM_spesh_manipulate_insert_ins(tc, return_bb, return_ins, unbox_ins);
MVM_spesh_get_facts(tc, g, ver_target)->writer = unbox_ins;
MVM_spesh_usages_add_by_reg(tc, g, unbox_operands[1], unbox_ins);

MVM_spesh_graph_add_comment(tc, g, unbox_ins, "unbox for return from inline");

/* Now turn return instruction node into lookup of appropriate box
* type. */
MVM_spesh_manipulate_delete_ins(tc, g, return_bb, return_ins);
}

static void rewrite_int_return(MVMThreadContext *tc, MVMSpeshGraph *g,
MVMSpeshBB *return_bb, MVMSpeshIns *return_ins,
MVMSpeshBB *invoke_bb, MVMSpeshIns *invoke_ins) {
Expand Down Expand Up @@ -964,6 +987,18 @@ static void rewrite_obj_return(MVMThreadContext *tc, MVMSpeshGraph *g,
case MVM_OP_invoke_o:
return_to_set(tc, g, return_ins, invoke_ins->operands[0]);
break;
case MVM_OP_invoke_i:
return_to_unbox(tc, g, return_bb, return_ins, invoke_ins->operands[0],
MVM_OP_unbox_i);
break;
case MVM_OP_invoke_n:
return_to_unbox(tc, g, return_bb, return_ins, invoke_ins->operands[0],
MVM_OP_unbox_n);
break;
case MVM_OP_invoke_s:
return_to_unbox(tc, g, return_bb, return_ins, invoke_ins->operands[0],
MVM_OP_unbox_s);
break;
default:
MVM_oops(tc,
"Spesh inline: unhandled case of return_o");
Expand Down

0 comments on commit f30a806

Please sign in to comment.