freedreno/ir3: fix indirects tracking
authorRob Clark <robclark@freedesktop.org>
Thu, 2 Jul 2015 17:52:38 +0000 (13:52 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 3 Jul 2015 12:56:09 +0000 (08:56 -0400)
cp would update instr->address but not update the indirects array
resulting in sched getting confused when it had to 'spill' the address
register.  Add an ir3_instr_set_address() helper to set instr->address
and also update ir->indirects, and update all places that were writing
instr->address to use helper instead.

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

index 1da6cf0477ecbc5871666e062284b08ecdf1c618..a0cb74498eceeac13ec9db442dd8f74a25d0e75d 100644 (file)
@@ -706,6 +706,17 @@ struct ir3_register * ir3_reg_create(struct ir3_instruction *instr,
        return reg;
 }
 
+void
+ir3_instr_set_address(struct ir3_instruction *instr,
+               struct ir3_instruction *addr)
+{
+       if (instr->address != addr) {
+               struct ir3 *ir = instr->block->shader;
+               instr->address = addr;
+               array_insert(ir->indirects, instr);
+       }
+}
+
 void
 ir3_block_clear_mark(struct ir3_block *block)
 {
index bc0144568a5482f21c1056f43f565195f0c128ed..f11d8eda5f255dbbe173bd1ddd5b04157da4162e 100644 (file)
@@ -285,6 +285,8 @@ struct ir3_instruction {
 
        /* an instruction can reference at most one address register amongst
         * it's src/dst registers.  Beyond that, you need to insert mov's.
+        *
+        * NOTE: do not write this directly, use ir3_instr_set_address()
         */
        struct ir3_instruction *address;
 
@@ -420,6 +422,9 @@ const char *ir3_instr_name(struct ir3_instruction *instr);
 struct ir3_register * ir3_reg_create(struct ir3_instruction *instr,
                int num, int flags);
 
+void ir3_instr_set_address(struct ir3_instruction *instr,
+               struct ir3_instruction *addr);
+
 static inline bool ir3_instr_check_mark(struct ir3_instruction *instr)
 {
        if (instr->flags & IR3_INSTR_MARK)
index fa13c4076dcc0c803d6fa007db236b36bae09340..8d8d4434d9ea91ecef2bf8793e450ab4510d12cd 100644 (file)
@@ -637,9 +637,8 @@ create_uniform_indirect(struct ir3_compile *ctx, unsigned n,
        mov->cat1.dst_type = TYPE_U32;
        ir3_reg_create(mov, 0, 0);
        ir3_reg_create(mov, n, IR3_REG_CONST | IR3_REG_RELATIV);
-       mov->address = address;
 
-       array_insert(ctx->ir->indirects, mov);
+       ir3_instr_set_address(mov, address);
 
        return mov;
 }
@@ -677,9 +676,8 @@ create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
        src->instr = collect;
        src->size  = arrsz;
        src->offset = n;
-       mov->address = address;
 
-       array_insert(ctx->ir->indirects, mov);
+       ir3_instr_set_address(mov, address);
 
        return mov;
 }
@@ -700,10 +698,9 @@ create_indirect_store(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
        dst->size  = arrsz;
        dst->offset = n;
        ir3_reg_create(mov, 0, IR3_REG_SSA)->instr = src;
-       mov->address = address;
        mov->fanin = collect;
 
-       array_insert(ctx->ir->indirects, mov);
+       ir3_instr_set_address(mov, address);
 
        return mov;
 }
index 8c7c80f7aae37b97453663e816ee7954f02129a8..f4c825b2ab602b6a3fe93ac4e5da5fea200c6bf7 100644 (file)
@@ -291,7 +291,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n)
                        instr->regs[n+1] = src_reg;
 
                        if (src_reg->flags & IR3_REG_RELATIV)
-                               instr->address = reg->instr->address;
+                               ir3_instr_set_address(instr, reg->instr->address);
 
                        return;
                }
@@ -300,7 +300,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n)
                                !conflicts(instr->address, reg->instr->address)) {
                        src_reg->flags = new_flags;
                        instr->regs[n+1] = src_reg;
-                       instr->address = reg->instr->address;
+                       ir3_instr_set_address(instr, reg->instr->address);
 
                        return;
                }
@@ -389,7 +389,7 @@ instr_cp(struct ir3_instruction *instr, unsigned *flags)
        }
 
        if (instr->address)
-               instr->address = instr_cp(instr->address, NULL);
+               ir3_instr_set_address(instr, instr_cp(instr->address, NULL));
 
        return instr;
 }
index 49a4426d163cf9d8aea6b24e3eef3fa13df8ab77..01d72301dccd3a0f46e92d50a39ba85c735c5b65 100644 (file)
@@ -312,7 +312,7 @@ split_addr(struct ir3_sched_ctx *ctx)
                                /* original addr is scheduled, but new one isn't: */
                                new_addr->flags &= ~IR3_INSTR_MARK;
                        }
-                       indirect->address = new_addr;
+                       ir3_instr_set_address(indirect, new_addr);
                }
        }