]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
store_param storetype, parameter value list added to ast_function
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Sun, 22 Jul 2012 10:07:07 +0000 (12:07 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Sun, 22 Jul 2012 10:07:30 +0000 (12:07 +0200)
ast.c
ast.h
gmqcc.h
ir.c

diff --git a/ast.c b/ast.c
index d519919ac10b50504b4c0e7d846be66c6cb5fe90..767dde92badaf54f15bc3e196d42ba38a2ba4270 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -399,6 +399,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
     self->vtype = vtype;
     self->name = name ? util_strdup(name) : NULL;
     MEM_VECTOR_INIT(self, blocks);
+    MEM_VECTOR_INIT(self, params);
 
     self->labelcount = 0;
     self->builtin = 0;
@@ -416,6 +417,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
 }
 
 MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
+MEM_VEC_FUNCTIONS(ast_function, ast_value*, params)
 
 void ast_function_delete(ast_function *self)
 {
@@ -434,6 +436,12 @@ void ast_function_delete(ast_function *self)
     for (i = 0; i < self->blocks_count; ++i)
         ast_delete(self->blocks[i]);
     MEM_VECTOR_CLEAR(self, blocks);
+    /* ast_delete, not unref, there must only have been references
+     * to the parameter values inside the blocks deleted above.
+     */
+    for (i = 0; i < self->params_count; ++i)
+        ast_delete(self->params[i]);
+    MEM_VECTOR_CLEAR(self, params);
     mem_d(self);
 }
 
diff --git a/ast.h b/ast.h
index 458d80f574df7d066ed822212008cd2b1b261fce..ecc2498b3356ba10f535f5bdbc9c140a1b0f7e81 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -360,6 +360,14 @@ struct ast_function_s
     char         labelbuf[64];
 
     MEM_VECTOR_MAKE(ast_block*, blocks);
+
+    /* contrary to the params in ast_value, these are the parameter variables
+     * which are to be used in expressions.
+     * The ast_value for the function contains only the parameter types used
+     * to generate ast_calls, and ast_call contains the parameter values
+     * used in that call.
+     */
+    MEM_VECTOR_MAKE(ast_value*, params);
 };
 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype);
 /* This will NOT delete the underlying ast_value */
@@ -370,6 +378,7 @@ void ast_function_delete(ast_function*);
 const char* ast_function_label(ast_function*, const char *prefix);
 
 MEM_VECTOR_PROTO(ast_function, ast_block*, blocks);
+MEM_VECTOR_PROTO(ast_function, ast_value*, params);
 
 bool ast_function_codegen(ast_function *self, ir_builder *builder);
 
diff --git a/gmqcc.h b/gmqcc.h
index 0ba02deaa9d6740095ffccfdd71422cb5d25c2c5..d8374803ae886773a9ac4b39a352ecbdbc72ab99 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -781,6 +781,7 @@ _MEM_VEC_FUN_FIND(Tself, Twhat, mem)
 enum store_types {
     store_global,
     store_local,  /* local, assignable for now, should get promoted later */
+    store_param,  /* parameters, they are locals with a fixed position */
     store_value,  /* unassignable */
     store_return  /* unassignable, at OFS_RETURN */
 };
diff --git a/ir.c b/ir.c
index 077ac555c9f42ac20de0b2bcdcfcb2e65f621c9f..22119495f7fa83c45983985696c2bbb01c5e479c 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1457,7 +1457,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 +1837,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 */