freedreno/ir3: avoid fan-in sources referring to same instruction
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 1 Oct 2014 03:27:25 +0000 (23:27 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 3 Oct 2014 01:05:50 +0000 (21:05 -0400)
Since the RA has to be done s.t. each one gets its own (adjacent)
register, it would complicate matters if instructions were allowed to be
repeated. This enables copy-propagation use in situations where
previously that might have happened.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_cp.c

index 73c2a27c6eb6f4cc3db07ea36aec51ed03f8bf8f..83bcb7a742bda6605f0e6d71867badbaae9c75e6 100644 (file)
@@ -70,7 +70,7 @@ static void walk_children(struct ir3_instruction *instr, bool keep)
 static struct ir3_instruction *
 instr_cp_fanin(struct ir3_instruction *instr)
 {
-       unsigned i;
+       unsigned i, j;
 
        /* we need to handle fanin specially, to detect cases
         * when we need to keep a mov
@@ -92,7 +92,15 @@ instr_cp_fanin(struct ir3_instruction *instr)
                        if (is_meta(cand) && (cand->opc == OPC_META_FO))
                                cand = instr_cp(src->instr, true);
 
-                       src->instr = cand;
+                       /* we can't have 2 registers referring to the same instruction, so
+                        * go through and check if any already refer to the candidate
+                        * instruction. if so, don't do the propagation.
+                        */
+                       for (j = 1; j < instr->regs_count; j++)
+                               if (instr->regs[j]->instr == cand)
+                                       break;
+                       if (j == instr->regs_count)
+                               src->instr = cand;
                }
        }