From bd43dcc9df7e55445589ccda29e1d9539863863a Mon Sep 17 00:00:00 2001 From: Timo Paulssen Date: Wed, 26 Dec 2018 21:29:17 +0100 Subject: [PATCH] JIT: Double-Devirtualize atpos_i only limited usefulness, since rakudo code mostly generates atposref rather than atpos instructions. Spesh will, at some point, know to turn atposref into atpos, though, and atposref can also be double-devirtualized in much the same way atpos currently is. --- src/6model/reprs/VMArray.c | 24 +++++++++++++++++++++++- src/jit/graph.c | 9 +++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/6model/reprs/VMArray.c b/src/6model/reprs/VMArray.c index 94f0da8ee4..96d5be122a 100644 --- a/src/6model/reprs/VMArray.c +++ b/src/6model/reprs/VMArray.c @@ -1421,18 +1421,40 @@ MVMObject *vmarray_direct_atpos_o_to_o(MVMThreadContext *tc, MVMObject *obj, MVM return found ? found : tc->instance->VMNull; } +MVMint64 vmarray_direct_atpos_i64_to_i(MVMThreadContext *tc, MVMObject *obj, MVMint64 index) { + MVMArrayBody *body = (MVMArrayBody *)OBJECT_BODY(obj); + MVMObject *found; + + if (index < 0) { + index += body->elems; + if (index < 0) + MVM_exception_throw_adhoc(tc, "MVMArray: Index out of bounds"); + } + + if (index >= body->elems) + return 0; + + return (MVMint64)body->slots.i64[body->start + index]; +} + void *MVM_VMArray_devirtualize_ins_for_jit(MVMThreadContext *tc, MVMSTable *st, MVMSpeshIns *ins) { switch (ins->info->opcode) { case MVM_OP_atpos_o: if (((MVMArrayREPRData *)st->REPR_data)->slot_type != MVM_ARRAY_OBJ) { return NULL; } + return vmarray_direct_atpos_o_to_o; + break; + case MVM_OP_atpos_i: + if (((MVMArrayREPRData *)st->REPR_data)->slot_type != MVM_ARRAY_I64) { + return NULL; + } + return vmarray_direct_atpos_i64_to_i; break; default: return NULL; } - return vmarray_direct_atpos_o_to_o; } /* Initializes the representation. */ diff --git a/src/jit/graph.c b/src/jit/graph.c index 89ba1f6c83..45190eff67 100644 --- a/src/jit/graph.c +++ b/src/jit/graph.c @@ -871,10 +871,14 @@ static MVMint32 consume_reprop(MVMThreadContext *tc, MVMJitGraph *jg, void *alternative_function = MVM_VMArray_devirtualize_ins_for_jit(tc, STABLE(type_facts->type), ins); if (alternative_function != NULL) { + MVMuint16 rv_type = op == MVM_OP_atpos_i ? MVM_JIT_RV_INT + : op == MVM_OP_atpos_o ? MVM_JIT_RV_PTR + : 0; + MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR, MVM_JIT_INTERP_TC }, { MVM_JIT_REG_VAL, invocant }, { MVM_JIT_REG_VAL, value } }; - jg_append_call_c(tc, jg, alternative_function, 3, args, MVM_JIT_RV_PTR, dst); + jg_append_call_c(tc, jg, alternative_function, 3, args, rv_type, dst); MVM_spesh_graph_add_comment(tc, iter->graph, ins, "JIT: double-devirtualized");; return 1; } @@ -894,7 +898,8 @@ static MVMint32 consume_reprop(MVMThreadContext *tc, MVMJitGraph *jg, op == MVM_OP_atpos_s || op == MVM_OP_atkey_s ? MVM_reg_str : MVM_reg_obj } }; jg_append_call_c(tc, jg, function, 7, args, MVM_JIT_RV_VOID, -1); - MVM_spesh_graph_add_comment(tc, iter->graph, ins, "JIT: devirtualized");; + MVM_spesh_graph_add_comment(tc, iter->graph, ins, "JIT: devirtualized"); + } return 1; } case MVM_OP_bindkey_i: