freedreno/ir3: relax restriction in grouping
authorRob Clark <robclark@freedesktop.org>
Sun, 24 Apr 2016 15:40:12 +0000 (11:40 -0400)
committerRob Clark <robclark@freedesktop.org>
Sun, 24 Apr 2016 17:40:57 +0000 (13:40 -0400)
Currently we were two restrictive, and would insert an output move in
cases like: MOV OUT[0], IN[0].xyzw

Loosen the restriction to allow the current instruction to appear in the
neighbor list but only at it's current possition.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_group.c

index f229fe6eecd09befe4309badad00898edbe4aee6..633d66c58d436cba039bd6441f61cb380c8123ca 100644 (file)
@@ -92,8 +92,10 @@ static struct group_ops instr_ops = { instr_get, instr_insert_mov };
 
 /* verify that cur != instr, but cur is also not in instr's neighbor-list: */
 static bool
-in_neighbor_list(struct ir3_instruction *instr, struct ir3_instruction *cur)
+in_neighbor_list(struct ir3_instruction *instr, struct ir3_instruction *cur, int pos)
 {
+       int idx = 0;
+
        if (!instr)
                return false;
 
@@ -101,7 +103,7 @@ in_neighbor_list(struct ir3_instruction *instr, struct ir3_instruction *cur)
                return true;
 
        for (instr = ir3_neighbor_first(instr); instr; instr = instr->cp.right)
-               if (instr == cur)
+               if ((idx++ != pos) && (instr == cur))
                        return true;
 
        return false;
@@ -137,7 +139,7 @@ restart:
 
                        /* we also can't have an instr twice in the group: */
                        for (j = i + 1; (j < n) && !conflict; j++)
-                               if (in_neighbor_list(ops->get(arr, j), instr))
+                               if (in_neighbor_list(ops->get(arr, j), instr, i))
                                        conflict = true;
 
                        if (conflict) {