From 427e5d64f7285af47c5e1966d16233ea32310c74 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Tue, 22 Aug 2017 09:55:52 -0400 Subject: [PATCH] assert branch is last instruction in ir block --- src/jit/passes/control_flow_analysis_pass.c | 34 +++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/jit/passes/control_flow_analysis_pass.c b/src/jit/passes/control_flow_analysis_pass.c index 8236f638..1f9c189c 100644 --- a/src/jit/passes/control_flow_analysis_pass.c +++ b/src/jit/passes/control_flow_analysis_pass.c @@ -4,19 +4,29 @@ void cfa_run(struct cfa *cfa, struct ir *ir) { list_for_each_entry(block, &ir->blocks, struct ir_block, it) { + struct ir_instr *last_instr = + list_last_entry(&block->instrs, struct ir_instr, it); + list_for_each_entry(instr, &block->instrs, struct ir_instr, it) { - /* add edges between blocks for easy traversing */ - if (instr->op == OP_BRANCH) { - if (instr->arg[0]->type == VALUE_BLOCK) { - ir_add_edge(ir, block, instr->arg[0]->blk); - } - } else if (instr->op == OP_BRANCH_COND) { - if (instr->arg[0]->type == VALUE_BLOCK) { - ir_add_edge(ir, block, instr->arg[0]->blk); - } - if (instr->arg[1]->type == VALUE_BLOCK) { - ir_add_edge(ir, block, instr->arg[1]->blk); - } + if (instr == last_instr) { + continue; + } + + CHECK(instr->op != OP_BRANCH && instr->op != OP_BRANCH_COND, + "only the last instruction in the block can branch"); + } + + /* add edges between blocks for easy traversing */ + if (last_instr->op == OP_BRANCH) { + if (last_instr->arg[0]->type == VALUE_BLOCK) { + ir_add_edge(ir, block, last_instr->arg[0]->blk); + } + } else if (last_instr->op == OP_BRANCH_COND) { + if (last_instr->arg[0]->type == VALUE_BLOCK) { + ir_add_edge(ir, block, last_instr->arg[0]->blk); + } + if (last_instr->arg[1]->type == VALUE_BLOCK) { + ir_add_edge(ir, block, last_instr->arg[1]->blk); } } }