From 384446316a3c5cc8145c7f73a39628f2bbcda855 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Wed, 19 Dec 2012 20:38:32 +0100 Subject: [PATCH] VINSTR_NRCALL, translated like any other call for now; to be used to mark a call which never returns, ie the error builtin --- ast.c | 8 ++++---- gmqcc.h | 7 ++++++- ir.c | 10 ++++++---- ir.h | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ast.c b/ast.c index 58206cc..ede92f4 100644 --- a/ast.c +++ b/ast.c @@ -1640,7 +1640,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu 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); @@ -1878,7 +1878,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i 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); @@ -2110,7 +2110,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva 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); @@ -2905,7 +2905,7 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value 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; diff --git a/gmqcc.h b/gmqcc.h index e2878f9..b1e0cde 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -546,7 +546,12 @@ enum { */ 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; diff --git a/ir.c b/ir.c index defbd40..411fcdc 100644 --- a/ir.c +++ b/ir.c @@ -1566,11 +1566,11 @@ void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v) } /* 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); @@ -2793,7 +2793,9 @@ tailcall: 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, @@ -3663,7 +3665,7 @@ void ir_instr_dump(ir_instr *in, char *ind, 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)); diff --git a/ir.h b/ir.h index 5379ee0..6532a5e 100644 --- a/ir.h +++ b/ir.h @@ -209,7 +209,7 @@ ir_value* ir_block_create_div(ir_block*, lex_ctx, const char *label, ir_value *l 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*); -- 2.39.2