if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
vec_push(params, param);
}
- callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval);
+ callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval, false);
if (!callinstr)
goto error;
*/
VINSTR_PHI,
VINSTR_JUMP,
- VINSTR_COND
+ VINSTR_COND,
+ /* A never returning CALL.
+ * Creating this causes IR blocks to be marked as 'final'.
+ * No-Return-Call
+ */
+ VINSTR_NRCALL
};
extern prog_section_statement *code_statements;
}
/* call related code */
-ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, ir_value *func)
+ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, ir_value *func, bool noreturn)
{
ir_value *out;
ir_instr *in;
- in = ir_instr_new(ctx, self, INSTR_CALL0);
+ in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
if (!in)
return NULL;
out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
goto tailcall;
}
- if (instr->opcode >= INSTR_CALL0 && instr->opcode <= INSTR_CALL8) {
+ if ( (instr->opcode >= INSTR_CALL0 && instr->opcode <= INSTR_CALL8)
+ || instr->opcode == VINSTR_NRCALL)
+ {
/* Trivial call translation:
* copy all params to OFS_PARM*
* if the output's storetype is not store_return,
if (in->_ops[1] || in->_ops[2])
oprintf(" <- ");
}
- if (in->opcode == INSTR_CALL0) {
+ if (in->opcode == INSTR_CALL0 || in->opcode == VINSTR_NRCALL) {
oprintf("CALL%i\t", vec_size(in->params));
} else
oprintf("%s\t", qc_opname(in->opcode));
ir_instr* ir_block_create_phi(ir_block*, lex_ctx, const char *label, int vtype);
ir_value* ir_phi_value(ir_instr*);
void ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
-ir_instr* ir_block_create_call(ir_block*, lex_ctx, const char *label, ir_value *func);
+ir_instr* ir_block_create_call(ir_block*, lex_ctx, const char *label, ir_value *func, bool noreturn);
ir_value* ir_call_value(ir_instr*);
void ir_call_param(ir_instr*, ir_value*);