]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
ast_function generates parameter locals, ir_function_create_local now allows adding...
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index f2c0f14dac64b3d50f9c3d4ec199753d18e5673f..0c0517a54d791cfdd248efcd98d8b4433fa8e9f4 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -59,7 +59,7 @@ uint16_t type_store_instr[TYPE_COUNT] = {
     INSTR_STORE_V, /* variant, should never be accessed */
 };
 
-uint16_t type_store_instr[TYPE_COUNT] = {
+uint16_t type_storep_instr[TYPE_COUNT] = {
     INSTR_STOREP_F, /* should use I when having integer support */
     INSTR_STOREP_S,
     INSTR_STOREP_F,
@@ -311,14 +311,21 @@ ir_value* ir_function_get_local(ir_function *self, const char *name)
     return NULL;
 }
 
-ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype)
+ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype, bool param)
 {
     ir_value *ve = ir_function_get_local(self, name);
     if (ve) {
         return NULL;
     }
 
-    ve = ir_value_var(name, store_local, vtype);
+    if (param &&
+        self->locals_count &&
+        self->locals[self->locals_count-1]->store != store_param) {
+        printf("cannot add parameters after adding locals\n");
+        return NULL;
+    }
+
+    ve = ir_value_var(name, (param ? store_param : store_local), vtype);
     if (!ir_function_locals_add(self, ve)) {
         ir_value_delete(ve);
         return NULL;
@@ -1457,7 +1464,7 @@ static bool ir_block_naive_phi(ir_block *self)
                 if (v->writes[w]->_ops[0] == v)
                     v->writes[w]->_ops[0] = instr->_ops[0];
 
-                if (old->store != store_value && old->store != store_local)
+                if (old->store != store_value && old->store != store_local && old->store != store_param)
                 {
                     /* If it originally wrote to a global we need to store the value
                      * there as welli
@@ -1837,8 +1844,11 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
             value = instr->_ops[o];
 
             /* We only care about locals */
+            /* we also calculate parameter liferanges so that locals
+             * can take up parameter slots */
             if (value->store != store_value &&
-                value->store != store_local)
+                value->store != store_local &&
+                value->store != store_param)
                 continue;
 
             /* read operands */
@@ -2511,6 +2521,10 @@ void ir_function_dump(ir_function *f, char *ind,
                       int (*oprintf)(const char*, ...))
 {
        size_t i;
+       if (f->builtin != 0) {
+           oprintf("%sfunction %s = builtin %i\n", ind, f->name, -f->builtin);
+           return;
+       }
        oprintf("%sfunction %s\n", ind, f->name);
        strncat(ind, "\t", IND_BUFSZ);
        if (f->locals_count)