-
-
Save bdw/5eb866631c6fc6f1a075 to your computer and use it in GitHub Desktop.
graph refactor diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/jit/graph.c b/src/jit/graph.c | |
index ea6dc79..15fc8d9 100644 | |
--- a/src/jit/graph.c | |
+++ b/src/jit/graph.c | |
@@ -1,91 +1,105 @@ | |
#include "moar.h" | |
-static void append_ins(MVMJitGraph *jg, MVMJitIns *ins) { | |
- if (jg->last_ins) { | |
- jg->last_ins->next = ins; | |
- jg->last_ins = ins; | |
+typedef struct { | |
+ MVMSpeshGraph *sg; | |
+ MVMSpeshBB *cur_bb; | |
+ MVMSpeshIns *cur_ins; | |
+ | |
+ MVMJitNode *first_node; | |
+ MVMJitNode *last_node; | |
+ | |
+ MVMint32 num_labels; | |
+ MVMJitLabel *labels; | |
+} JitGraphBuilder; | |
+ | |
+ | |
+static void jgb_append_node(JitGraphBuilder *jgb, MVMJitNode *node) { | |
+ if (jgb->last_node) { | |
+ jgb->last_node->next = node; | |
+ jgb->last_node = node; | |
} else { | |
- jg->first_ins = ins; | |
- jg->last_ins = ins; | |
+ jgb->first_node = node; | |
+ jgb->last_node = node; | |
} | |
- ins->next = NULL; | |
+ node->next = NULL; | |
} | |
-static void append_primitive(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMSpeshIns * moar_ins) { | |
- MVMJitIns * ins = MVM_spesh_alloc(tc, jg->spesh, sizeof(MVMJitIns)); | |
- ins->type = MVM_JIT_INS_PRIMITIVE; | |
- ins->u.prim.ins = moar_ins; | |
- append_ins(jg, ins); | |
+static void jgb_append_primitive(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMSpeshIns * ins) { | |
+ MVMJitNode * node = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitNode)); | |
+ node->type = MVM_JIT_NODE_PRIMITIVE; | |
+ node->u.prim.ins = ins; | |
+ jgb_append_node(jgb, node); | |
} | |
-static void append_call_c(MVMThreadContext *tc, MVMJitGraph *jg, | |
- void * func_ptr, MVMint16 num_args, | |
- MVMJitCallArg *call_args, MVMJitRVMode rv_mode, | |
- MVMint16 rv_idx) { | |
- MVMJitIns * ins = MVM_spesh_alloc(tc, jg->spesh, sizeof(MVMJitIns)); | |
+static void jgb_append_call_c(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ void * func_ptr, MVMint16 num_args, | |
+ MVMJitCallArg *call_args, | |
+ MVMJitRVMode rv_mode, MVMint16 rv_idx) { | |
+ MVMJitNode * node = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitNode)); | |
size_t args_size = num_args * sizeof(MVMJitCallArg); | |
- ins->type = MVM_JIT_INS_CALL_C; | |
- ins->u.call.func_ptr = func_ptr; | |
- ins->u.call.num_args = num_args; | |
- ins->u.call.has_vargs = 0; // don't support them yet | |
+ node->type = MVM_JIT_NODE_CALL_C; | |
+ node->u.call.func_ptr = func_ptr; | |
+ node->u.call.num_args = num_args; | |
+ node->u.call.has_vargs = 0; // don't support them yet | |
/* Call argument array is typically stack allocated, | |
* so they need to be copied */ | |
- ins->u.call.args = MVM_spesh_alloc(tc, jg->spesh, args_size); | |
- memcpy(ins->u.call.args, call_args, args_size); | |
- ins->u.call.rv_mode = rv_mode; | |
- ins->u.call.rv_idx = rv_idx; | |
- append_ins(jg, ins); | |
+ node->u.call.args = MVM_spesh_alloc(tc, jgb->sg, args_size); | |
+ memcpy(node->u.call.args, call_args, args_size); | |
+ node->u.call.rv_mode = rv_mode; | |
+ node->u.call.rv_idx = rv_idx; | |
+ jgb_append_node(jgb, node); | |
} | |
/* Try to assign a label name for a basic block */ | |
-static MVMint32 get_label_name(MVMThreadContext *tc, MVMJitGraph *jg, | |
+static MVMint32 get_label_name(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
MVMSpeshBB *bb) { | |
int i = 0; | |
- for (i = 0; i < jg->num_labels; i++) { | |
- if (jg->labels[i].bb == bb) { | |
+ for (i = 0; i < jgb->num_labels; i++) { | |
+ if (jgb->labels[i].bb == bb) { | |
return i; | |
- } else if (jg->labels[i].bb == NULL) { | |
- jg->labels[i].bb = bb; | |
+ } | |
+ else if (jgb->labels[i].bb == NULL) { | |
+ jgb->labels[i].bb = bb; | |
return i; | |
} | |
} | |
MVM_exception_throw_adhoc(tc, "JIT: Cannot assign %d labels", i); | |
} | |
-static void append_branch(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMint32 name, MVMSpeshIns *sp_ins) { | |
+static void jgb_append_branch(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMint32 name, MVMSpeshIns *ins) { | |
- MVMJitIns * ins = MVM_spesh_alloc(tc, jg->spesh, sizeof(MVMJitIns)); | |
- ins->type = MVM_JIT_INS_BRANCH; | |
- if (sp_ins == NULL) { | |
- ins->u.branch.ins = NULL; | |
- ins->u.branch.dest.bb = NULL; | |
- ins->u.branch.dest.name = name; | |
+ MVMJitNode * node = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitNode)); | |
+ node->type = MVM_JIT_NODE_BRANCH; | |
+ if (ins == NULL) { | |
+ node->u.branch.ins = NULL; | |
+ node->u.branch.dest.bb = NULL; | |
+ node->u.branch.dest.name = name; | |
} | |
else { | |
- ins->u.branch.ins = sp_ins; | |
- if (sp_ins->info->opcode == MVM_OP_goto) { | |
- ins->u.branch.dest.bb = sp_ins->operands[0].ins_bb; | |
+ node->u.branch.ins = ins; | |
+ if (ins->info->opcode == MVM_OP_goto) { | |
+ node->u.branch.dest.bb = ins->operands[0].ins_bb; | |
} | |
else { | |
- ins->u.branch.dest.bb = sp_ins->operands[1].ins_bb; | |
+ node->u.branch.dest.bb = ins->operands[1].ins_bb; | |
} | |
- ins->u.branch.dest.name = get_label_name(tc, jg, ins->u.branch.dest.bb); | |
+ node->u.branch.dest.name = get_label_name(tc, jgb, node->u.branch.dest.bb); | |
} | |
- append_ins(jg, ins); | |
+ jgb_append_node(jgb, node); | |
} | |
-static void append_label(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMSpeshBB *bb) { | |
+static void jgb_append_label(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMSpeshBB *bb) { | |
- MVMJitIns *ins = MVM_spesh_alloc(tc, jg->spesh, sizeof(MVMJitIns)); | |
- ins->type = MVM_JIT_INS_LABEL; | |
- ins->u.label.bb = bb; | |
- ins->u.label.name = get_label_name(tc, jg, bb); | |
- append_ins(jg, ins); | |
- MVM_jit_log(tc, "append label: %d\n", ins->u.label.name); | |
+ MVMJitNode *node = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitNode)); | |
+ node->type = MVM_JIT_NODE_LABEL; | |
+ node->u.label.bb = bb; | |
+ node->u.label.name = get_label_name(tc, jgb, bb); | |
+ jgb_append_node(jgb, node); | |
+ MVM_jit_log(tc, "append label: %d\n", node->u.label.name); | |
} | |
static void * op_to_func(MVMThreadContext *tc, MVMint16 opcode) { | |
@@ -108,14 +122,13 @@ static void * op_to_func(MVMThreadContext *tc, MVMint16 opcode) { | |
} | |
} | |
-static void append_guard(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMSpeshIns *ins) { | |
- MVMSpeshGraph *sg = jg->spesh; | |
- MVMSpeshAnn *ann = ins->annotations; | |
- MVMJitIns *ji = MVM_spesh_alloc(tc, sg, sizeof(MVMJitIns)); | |
- MVMint32 deopt_idx; | |
- ji->type = MVM_JIT_INS_GUARD; | |
- ji->u.guard.ins = ins; | |
+static void jgb_append_guard(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMSpeshIns *ins) { | |
+ MVMSpeshAnn *ann = ins->annotations; | |
+ MVMJitNode *node = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitNode)); | |
+ MVMint32 deopt_idx; | |
+ node->type = MVM_JIT_NODE_GUARD; | |
+ node->u.guard.ins = ins; | |
while (ann) { | |
if (ann->type == MVM_SPESH_ANN_DEOPT_ONE_INS || | |
ann->type == MVM_SPESH_ANN_DEOPT_ALL_INS || | |
@@ -130,13 +143,13 @@ static void append_guard(MVMThreadContext *tc, MVMJitGraph *jg, | |
MVM_exception_throw_adhoc(tc, "Can't find deopt idx annotation" | |
" on spesh ins <%s>", ins->info->name); | |
} | |
- ji->u.guard.deopt_target = sg->deopt_addrs[2 * deopt_idx]; | |
- ji->u.guard.deopt_offset = sg->deopt_addrs[2 * deopt_idx + 1]; | |
- append_ins(jg, ji); | |
+ node->u.guard.deopt_target = jgb->sg->deopt_addrs[2 * deopt_idx]; | |
+ node->u.guard.deopt_offset = jgb->sg->deopt_addrs[2 * deopt_idx + 1]; | |
+ jgb_append_node(jgb, node); | |
} | |
-static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMSpeshIns *ins) { | |
+static MVMint32 jgb_consume_ins(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMSpeshIns *ins) { | |
int op = ins->info->opcode; | |
MVM_jit_log(tc, "append_ins: <%s>\n", ins->info->name); | |
switch(op) { | |
@@ -193,13 +206,13 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
case MVM_OP_gethow: | |
case MVM_OP_getwhere: | |
case MVM_OP_sp_getspeshslot: | |
- append_primitive(tc, jg, ins); | |
+ jgb_append_primitive(tc, jgb, ins); | |
break; | |
/* branches */ | |
case MVM_OP_goto: | |
case MVM_OP_if_i: | |
case MVM_OP_unless_i: | |
- append_branch(tc, jg, 0, ins); | |
+ jgb_append_branch(tc, jgb, 0, ins); | |
break; | |
/* some functions */ | |
case MVM_OP_say: | |
@@ -207,7 +220,7 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
MVMint32 reg = ins->operands[0].reg.orig; | |
MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR, MVM_JIT_INTERP_TC}, | |
{ MVM_JIT_REG_VAL, reg } }; | |
- append_call_c(tc, jg, op_to_func(tc, op), 2, args, MVM_JIT_RV_VOID, -1); | |
+ jgb_append_call_c(tc, jgb, op_to_func(tc, op), 2, args, MVM_JIT_RV_VOID, -1); | |
break; | |
} | |
case MVM_OP_wval: | |
@@ -224,7 +237,7 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
{ MVM_JIT_INTERP_VAR, MVM_JIT_INTERP_CU }, | |
{ MVM_JIT_LITERAL, dep }, | |
{ MVM_JIT_LITERAL, idx } }; | |
- append_call_c(tc, jg, op_to_func(tc, op), 4, args, MVM_JIT_RV_PTR, dst); | |
+ jgb_append_call_c(tc, jgb, op_to_func(tc, op), 4, args, MVM_JIT_RV_PTR, dst); | |
break; | |
} | |
/* coercion */ | |
@@ -242,15 +255,15 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
if (op == MVM_OP_coerce_ns) { | |
args[1].type = MVM_JIT_REG_VAL_F; | |
} | |
- append_call_c(tc, jg, op_to_func(tc, op), 2, args, rv_mode, dst); | |
+ jgb_append_call_c(tc, jgb, op_to_func(tc, op), 2, args, rv_mode, dst); | |
break; | |
} | |
/* returning */ | |
case MVM_OP_return: { | |
MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR, MVM_JIT_INTERP_TC}, | |
{ MVM_JIT_LITERAL, 0 }}; | |
- append_call_c(tc, jg, op_to_func(tc, op), 2, args, MVM_JIT_RV_VOID, -1); | |
- append_branch(tc, jg, MVM_JIT_BRANCH_EXIT, NULL); | |
+ jgb_append_call_c(tc, jgb, op_to_func(tc, op), 2, args, MVM_JIT_RV_VOID, -1); | |
+ jgb_append_branch(tc, jgb, MVM_JIT_BRANCH_EXIT, NULL); | |
break; | |
} | |
case MVM_OP_return_o: | |
@@ -264,13 +277,13 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
if (op == MVM_OP_return_n) { | |
args[1].type == MVM_JIT_REG_VAL_F; | |
} | |
- append_call_c(tc, jg, op_to_func(tc, op), 3, args, MVM_JIT_RV_VOID, -1); | |
- append_branch(tc, jg, MVM_JIT_BRANCH_EXIT, NULL); | |
+ jgb_append_call_c(tc, jgb, op_to_func(tc, op), 3, args, MVM_JIT_RV_VOID, -1); | |
+ jgb_append_branch(tc, jgb, MVM_JIT_BRANCH_EXIT, NULL); | |
break; | |
} | |
case MVM_OP_sp_guardconc: | |
case MVM_OP_sp_guardtype: | |
- append_guard(tc, jg, ins); | |
+ jgb_append_guard(tc, jgb, ins); | |
break; | |
default: | |
MVM_jit_log(tc, "Don't know how to make a graph of opcode <%s>\n", | |
@@ -280,22 +293,33 @@ static MVMint32 append_op(MVMThreadContext *tc, MVMJitGraph *jg, | |
return 1; | |
} | |
-static MVMint32 append_bb(MVMThreadContext *tc, MVMJitGraph *jg, | |
- MVMSpeshBB *bb) { | |
- append_label(tc, jg, bb); | |
- MVMSpeshIns *cur_ins = bb->first_ins; | |
- while (cur_ins) { | |
- if(!append_op(tc, jg, cur_ins)) | |
+static MVMint32 jgb_consume_bb(MVMThreadContext *tc, JitGraphBuilder *jgb, | |
+ MVMSpeshBB *bb) { | |
+ jgb->cur_bb = bb; | |
+ jgb_append_label(tc, jgb, bb); | |
+ jgb->cur_ins = bb->first_ins; | |
+ while (jgb->cur_ins) { | |
+ if(!jgb_consume_ins(tc, jgb, jgb->cur_ins)) | |
return 0; | |
- if (cur_ins == bb->last_ins) | |
+ if (jgb->cur_ins == bb->last_ins) | |
break; | |
- cur_ins = cur_ins->next; | |
+ jgb->cur_ins = jgb->cur_ins->next; | |
} | |
return 1; | |
} | |
+static MVMJitGraph *jgb_build(MVMThreadContext *tc, JitGraphBuilder *jgb) { | |
+ MVMJitGraph * jg = MVM_spesh_alloc(tc, jgb->sg, sizeof(MVMJitGraph)); | |
+ jg->sg = jgb->sg; | |
+ jg->num_labels = jgb->num_labels; | |
+ jg->labels = jgb->labels; | |
+ jg->first_node = jgb->first_node; | |
+ jg->last_node = jgb->last_node; | |
+ return jg; | |
+} | |
+ | |
MVMJitGraph * MVM_jit_try_make_graph(MVMThreadContext *tc, MVMSpeshGraph *sg) { | |
- MVMSpeshBB *cur_bb; | |
+ JitGraphBuilder jgb; | |
MVMJitGraph * jg; | |
int i; | |
if (!MVM_jit_support()) { | |
@@ -304,22 +328,20 @@ MVMJitGraph * MVM_jit_try_make_graph(MVMThreadContext *tc, MVMSpeshGraph *sg) { | |
MVM_jit_log(tc, "Constructing JIT graph\n"); | |
- jg = MVM_spesh_alloc(tc, sg, sizeof(MVMJitGraph)); | |
- jg->spesh = sg; | |
- jg->num_labels = sg->num_bbs; | |
- jg->labels = MVM_spesh_alloc(tc, sg, sizeof(MVMJitLabel) * jg->num_labels); | |
+ jgb.sg = sg; | |
+ jgb.num_labels = sg->num_bbs; | |
+ jgb.labels = MVM_spesh_alloc(tc, sg, sizeof(MVMJitLabel) * sg->num_bbs); | |
+ /* ignore first BB, which always contains a NOP */ | |
+ jgb.cur_bb = sg->entry->linear_next; | |
- /* ignore first (nop) BB, don't need it */ | |
- cur_bb = sg->entry->linear_next; | |
/* loop over basic blocks, adding one after the other */ | |
- while (cur_bb) { | |
- if (!append_bb(tc, jg, cur_bb)) | |
+ while (jgb.cur_bb) { | |
+ if (!jgb_consume_bb(tc, &jgb, jgb.cur_bb)) | |
return NULL; | |
- cur_bb = cur_bb->linear_next; | |
+ jgb.cur_bb = jgb.cur_bb->linear_next; | |
} | |
- | |
/* Check if we've added a instruction at all */ | |
- if (jg->first_ins) | |
- return jg; | |
+ if (jgb.first_node) | |
+ return jgb_build(tc, &jgb); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment