]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Life Ranges: First deal with all writes, then with all reads, since writes will remov...
authorWolfgang Bumiller <blub@speed.at>
Sun, 23 Dec 2012 19:50:21 +0000 (20:50 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sun, 23 Dec 2012 19:50:21 +0000 (20:50 +0100)
ir.c

diff --git a/ir.c b/ir.c
index 6d436f1e5d8af305a9135c564577c3c6934329ee..60d0c44704027de9728d7fac25379aed3c282710 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -2292,9 +2292,7 @@ bool ir_function_allocate_locals(ir_function *self)
 
     for (i = 0; i < vec_size(self->locals); ++i)
     {
-#if 0
         if (!OPTS_OPTIMIZATION(OPTIM_LOCALTEMPS))
-#endif
             self->locals[i]->unique_life = true;
         if (!function_allocator_alloc(&alloc, self->locals[i]))
             goto error;
@@ -2500,22 +2498,6 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
     { --i;
         instr = self->instr[i];
 
-        /* PHI operands are always read operands */
-        for (p = 0; p < vec_size(instr->phi); ++p)
-        {
-            value = instr->phi[p].value;
-            if (!vec_ir_value_find(self->living, value, NULL))
-                vec_push(self->living, value);
-        }
-
-        /* call params are read operands too */
-        for (p = 0; p < vec_size(instr->params); ++p)
-        {
-            value = instr->params[p];
-            if (!vec_ir_value_find(self->living, value, NULL))
-                vec_push(self->living, value);
-        }
-
         /* See which operands are read and write operands */
         ir_op_read_write(instr->opcode, &read, &write);
 
@@ -2532,7 +2514,9 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
             *changed = *changed || tempbool;
         }
 
-        /* Go through the 3 main operands */
+        /* Go through the 3 main operands
+         * writes first, then reads
+         */
         for (o = 0; o < 3; ++o)
         {
             if (!instr->_ops[o]) /* no such operand */
@@ -2548,13 +2532,6 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
                 value->store != store_param)
                 continue;
 
-            /* read operands */
-            if (read & (1<<o))
-            {
-                if (!vec_ir_value_find(self->living, value, NULL))
-                    vec_push(self->living, value);
-            }
-
             /* write operands */
             /* When we write to a local, we consider it "dead" for the
              * remaining upper part of the function, since in SSA a value
@@ -2597,6 +2574,45 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
                 }
             }
         }
+
+        for (o = 0; o < 3; ++o)
+        {
+            if (!instr->_ops[o]) /* no such operand */
+                continue;
+
+            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_param)
+                continue;
+
+            /* read operands */
+            if (read & (1<<o))
+            {
+                if (!vec_ir_value_find(self->living, value, NULL))
+                    vec_push(self->living, value);
+            }
+        }
+        /* PHI operands are always read operands */
+        for (p = 0; p < vec_size(instr->phi); ++p)
+        {
+            value = instr->phi[p].value;
+            if (!vec_ir_value_find(self->living, value, NULL))
+                vec_push(self->living, value);
+        }
+
+        /* call params are read operands too */
+        for (p = 0; p < vec_size(instr->params); ++p)
+        {
+            value = instr->params[p];
+            if (!vec_ir_value_find(self->living, value, NULL))
+                vec_push(self->living, value);
+        }
+
         /* (A) */
         tempbool = ir_block_living_add_instr(self, instr->eid);
         /*con_err( "living added values\n");*/