]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
VINSTR_NRCALL, translated like any other call for now; to be used to mark a call...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 19 Dec 2012 19:38:32 +0000 (20:38 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 19 Dec 2012 19:38:32 +0000 (20:38 +0100)
ast.c
gmqcc.h
ir.c
ir.h

diff --git a/ast.c b/ast.c
index 58206ccc0b5a09810110e7154e81f6709db1de86..ede92f42cc49c9ad49a0e66cb5fd2133da1711db 100644 (file)
--- 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 e2878f9b5eeb1e6f8ea308ed79b1148ad5820128..b1e0cdef1709ca37e977e8f4a152f8f7ea0d6f98 100644 (file)
--- 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 defbd407ca6e153cf2b0594ed4156aeff8805048..411fcdc55377c8cf3d8277e123355224920fe0b4 100644 (file)
--- 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 5379ee0d4bf5f9bdceade3ea5a27cb840ac0cb37..6532a5ea3a9c0cec236bd5f96f93ba1be6636ef8 100644 (file)
--- 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*);