]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
Fixing GMQCC_SUPPRESS_EMPTY_BODY typo
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index d81cdcecf1a838c963189c5990692da9767b213a..74363f8df0188565c3704934837b3e93749e1e48 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -44,6 +44,8 @@ size_t type_sizeof[TYPE_COUNT] = {
     3, /* TYPE_VARIANT  */
 };
 
+MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
+
 /***********************************************************************
  *IR Builder
  */
@@ -356,11 +358,13 @@ ir_instr* ir_instr_new(ir_block* owner, int op)
     self->bops[0] = NULL;
     self->bops[1] = NULL;
     MEM_VECTOR_INIT(self, phi);
+    MEM_VECTOR_INIT(self, params);
 
     self->eid = 0;
     return self;
 }
 MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi)
+MEM_VEC_FUNCTIONS(ir_instr, ir_value*, params)
 
 void ir_instr_delete(ir_instr *self)
 {
@@ -374,14 +378,22 @@ void ir_instr_delete(ir_instr *self)
     for (i = 0; i < self->phi_count; ++i) {
         size_t idx;
         if (ir_value_writes_find(self->phi[i].value, self, &idx))
-            if (ir_value_writes_remove(self->phi[i].value, idx)) GMQCC_SUPRESS_EMPTY_BODY;
+            if (ir_value_writes_remove(self->phi[i].value, idx)) GMQCC_SUPPRESS_EMPTY_BODY;
         if (ir_value_reads_find(self->phi[i].value, self, &idx))
-            if (ir_value_reads_remove (self->phi[i].value, idx)) GMQCC_SUPRESS_EMPTY_BODY;
+            if (ir_value_reads_remove (self->phi[i].value, idx)) GMQCC_SUPPRESS_EMPTY_BODY;
     }
     MEM_VECTOR_CLEAR(self, phi);
-    if (ir_instr_op(self, 0, NULL, false)) GMQCC_SUPRESS_EMPTY_BODY;
-    if (ir_instr_op(self, 1, NULL, false)) GMQCC_SUPRESS_EMPTY_BODY;
-    if (ir_instr_op(self, 2, NULL, false)) GMQCC_SUPRESS_EMPTY_BODY;
+    for (i = 0; i < self->params_count; ++i) {
+        size_t idx;
+        if (ir_value_writes_find(self->params[i], self, &idx))
+            if (ir_value_writes_remove(self->params[i], idx)) GMQCC_SUPPRESS_EMPTY_BODY;
+        if (ir_value_reads_find(self->params[i], self, &idx))
+            if (ir_value_reads_remove (self->params[i], idx)) GMQCC_SUPPRESS_EMPTY_BODY;
+    }
+    MEM_VECTOR_CLEAR(self, params);
+    if (ir_instr_op(self, 0, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY;
+    if (ir_instr_op(self, 1, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY;
+    if (ir_instr_op(self, 2, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY;
     mem_d(self);
 }
 
@@ -423,6 +435,7 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
     self = (ir_value*)mem_a(sizeof(*self));
     self->vtype = vtype;
     self->fieldtype = TYPE_VOID;
+    self->outtype = TYPE_VOID;
     self->store = storetype;
     MEM_VECTOR_INIT(self, reads);
     MEM_VECTOR_INIT(self, writes);
@@ -1017,6 +1030,47 @@ bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
     return ir_instr_phi_add(self, pe);
 }
 
+/* call related code */
+ir_instr* ir_block_create_call(ir_block *self, const char *label, ir_value *func, int ot)
+{
+    ir_value *out;
+    ir_instr *in;
+    in = ir_instr_new(self, INSTR_CALL0);
+    if (!in)
+        return NULL;
+    out = ir_value_out(self->owner, label, store_value, ot);
+    if (!out) {
+        ir_instr_delete(in);
+        return NULL;
+    }
+    if (!ir_instr_op(in, 0, out, true) ||
+        !ir_instr_op(in, 1, func, false) ||
+        !ir_block_instr_add(self, in))
+    {
+        ir_instr_delete(in);
+        ir_value_delete(out);
+        return NULL;
+    }
+    return in;
+}
+
+ir_value* ir_call_value(ir_instr *self)
+{
+    return self->_ops[0];
+}
+
+bool ir_call_param(ir_instr* self, ir_value *v)
+{
+    if (!ir_instr_params_add(self, v))
+        return false;
+    if (!ir_value_reads_add(v, self)) {
+        if (!ir_instr_params_remove(self, self->params_count-1))
+            GMQCC_SUPPRESS_EMPTY_BODY;
+        return false;
+    }
+    return true;
+}
+
 /* binary op related code */
 
 ir_value* ir_block_create_binop(ir_block *self,
@@ -2109,6 +2163,17 @@ tailcall:
         }
 
         if (instr->opcode >= INSTR_CALL0 && instr->opcode <= INSTR_CALL8) {
+            /* Trivial call translation:
+             * copy all params to OFS_PARM*
+             *
+             * NOTES on how to do it better without much trouble:
+             * -) The liferanges!
+             *      Simply check the liferange of all parameters for
+             *      other CALLs. For each param with no CALL in its
+             *      liferange, we can store it in an OFS_PARM at
+             *      generation already. This would even include later
+             *      reuse.... probably... :)
+             */
             printf("TODO: call instruction\n");
             return false;
         }