]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
ir_values which are members of a vector should know that, so that liferange calc...
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index f60b6496facbe0f5b7a87f21ff083780ace96160..acdaa225264c90b0096799ec239a1343499e680f 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -133,6 +133,24 @@ static void irerror(lex_ctx ctx, const char *msg, ...)
     va_end(ap);
 }
 
+static bool irwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
+{
+       va_list ap;
+       int lvl = LVL_WARNING;
+
+    if (!OPTS_WARN(warntype))
+        return false;
+
+    if (opts_werror)
+           lvl = LVL_ERROR;
+
+       va_start(ap, fmt);
+    vprintmsg(lvl, ctx.file, ctx.line, "warning", fmt, ap);
+       va_end(ap);
+
+       return opts_werror;
+}
+
 /***********************************************************************
  *IR Builder
  */
@@ -623,6 +641,7 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
     self->members[0] = NULL;
     self->members[1] = NULL;
     self->members[2] = NULL;
+    self->memberof = NULL;
 
     MEM_VECTOR_INIT(self, life);
     return self;
@@ -666,6 +685,7 @@ ir_value* ir_value_vector_member(ir_value *self, unsigned int member)
         return NULL;
     }
 
+    m->memberof = self;
     return m;
 }
 
@@ -970,13 +990,8 @@ bool ir_values_overlap(const ir_value *a, const ir_value *b)
         /* check if the entries overlap, for that,
          * both must start before the other one ends.
          */
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-        if (la->start <= lb->end &&
-            lb->start <= la->end)
-#else
-        if (la->start <  lb->end &&
-            lb->start <  la->end)
-#endif
+        if (la->start < lb->end &&
+            lb->start < la->end)
         {
             return true;
         }
@@ -1807,6 +1822,19 @@ bool ir_function_calculate_liferanges(ir_function *self)
             }
         }
     } while (changed);
+    if (self->blocks_count) {
+        ir_block *block = self->blocks[0];
+        for (i = 0; i < block->living_count; ++i) {
+            ir_value *v = block->living[i];
+            if (v->memberof || v->store != store_local)
+                continue;
+            if (irwarning(v->context, WARN_USED_UNINITIALIZED,
+                          "variable `%s` may be used uninitialized in this function", v->name))
+            {
+                return false;
+            }
+        }
+    }
     return true;
 }
 
@@ -2042,17 +2070,9 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
     size_t i, o, p;
     /* bitmasks which operands are read from or written to */
     size_t read, write;
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-    size_t rd;
-    new_reads_t new_reads;
-#endif
     char dbg_ind[16] = { '#', '0' };
     (void)dbg_ind;
 
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-    MEM_VECTOR_INIT(&new_reads, v);
-#endif
-
     if (prev)
     {
         if (!ir_block_life_prop_previous(self, prev, changed))
@@ -2068,38 +2088,26 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
         for (p = 0; p < instr->phi_count; ++p)
         {
             value = instr->phi[p].value;
-#if ! defined(LIFE_RANGE_WITHOUT_LAST_READ)
+            if (value->memberof)
+                value = value->memberof;
             if (!ir_block_living_find(self, value, NULL) &&
                 !ir_block_living_add(self, value))
             {
-                goto on_error;
-            }
-#else
-            if (!new_reads_t_v_find(&new_reads, value, NULL))
-            {
-                if (!new_reads_t_v_add(&new_reads, value))
-                    goto on_error;
+                return false;
             }
-#endif
         }
 
         /* call params are read operands too */
         for (p = 0; p < instr->params_count; ++p)
         {
             value = instr->params[p];
-#if ! defined(LIFE_RANGE_WITHOUT_LAST_READ)
+            if (value->memberof)
+                value = value->memberof;
             if (!ir_block_living_find(self, value, NULL) &&
                 !ir_block_living_add(self, value))
             {
-                goto on_error;
-            }
-#else
-            if (!new_reads_t_v_find(&new_reads, value, NULL))
-            {
-                if (!new_reads_t_v_add(&new_reads, value))
-                    goto on_error;
+                return false;
             }
-#endif
         }
 
         /* See which operands are read and write operands */
@@ -2112,6 +2120,8 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
                 continue;
 
             value = instr->_ops[o];
+            if (value->memberof)
+                value = value->memberof;
 
             /* We only care about locals */
             /* we also calculate parameter liferanges so that locals
@@ -2124,20 +2134,11 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
             /* read operands */
             if (read & (1<<o))
             {
-#if ! defined(LIFE_RANGE_WITHOUT_LAST_READ)
                 if (!ir_block_living_find(self, value, NULL) &&
                     !ir_block_living_add(self, value))
                 {
-                    goto on_error;
-                }
-#else
-                /* fprintf(stderr, "read: %s\n", value->_name); */
-                if (!new_reads_t_v_find(&new_reads, value, NULL))
-                {
-                    if (!new_reads_t_v_add(&new_reads, value))
-                        goto on_error;
+                    return false;
                 }
-#endif
             }
 
             /* write operands */
@@ -2149,13 +2150,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
             {
                 size_t idx;
                 bool in_living = ir_block_living_find(self, value, &idx);
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-                size_t readidx;
-                bool in_reads = new_reads_t_v_find(&new_reads, value, &readidx);
-                if (!in_living && !in_reads)
-#else
                 if (!in_living)
-#endif
                 {
                     /* If the value isn't alive it hasn't been read before... */
                     /* TODO: See if the warning can be emitted during parsing or AST processing
@@ -2184,16 +2179,8 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
                     */
                     *changed = *changed || tempbool;
                     /* Then remove */
-#if ! defined(LIFE_RANGE_WITHOUT_LAST_READ)
                     if (!ir_block_living_remove(self, idx))
-                        goto on_error;
-#else
-                    if (in_reads)
-                    {
-                        if (!new_reads_t_v_remove(&new_reads, readidx))
-                            goto on_error;
-                    }
-#endif
+                        return false;
                 }
             }
         }
@@ -2202,21 +2189,6 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
         /*fprintf(stderr, "living added values\n");*/
         *changed = *changed || tempbool;
 
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-        /* new reads: */
-        for (rd = 0; rd < new_reads.v_count; ++rd)
-        {
-            if (!ir_block_living_find(self, new_reads.v[rd], NULL)) {
-                if (!ir_block_living_add(self, new_reads.v[rd]))
-                    goto on_error;
-            }
-            if (!i && !self->entries_count) {
-                /* fix the top */
-                *changed = *changed || ir_value_life_merge(new_reads.v[rd], instr->eid);
-            }
-        }
-        MEM_VECTOR_CLEAR(&new_reads, v);
-#endif
     }
 
     if (self->run_id == self->owner->run_id)
@@ -2231,11 +2203,6 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
     }
 
     return true;
-on_error:
-#if defined(LIFE_RANGE_WITHOUT_LAST_READ)
-    MEM_VECTOR_CLEAR(&new_reads, v);
-#endif
-    return false;
 }
 
 /***********************************************************************