diff options
author | Rob Clark <[email protected]> | 2015-07-02 13:52:38 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2015-07-03 08:56:09 -0400 |
commit | 6b9f5cd5f7b25e9e03104fe279df74817f69fe87 (patch) | |
tree | f73fcf483f51dcff5d4eded53718bb2147f1e27b /src | |
parent | 0a155538eb7e7870b99fb8b3fd8e2a268361d2c8 (diff) |
freedreno/ir3: fix indirects tracking
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_cp.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_sched.c | 2 |
5 files changed, 23 insertions, 10 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index 1da6cf0477e..a0cb74498ec 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -707,6 +707,17 @@ struct ir3_register * ir3_reg_create(struct ir3_instruction *instr, } 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) { list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index bc0144568a5..f11d8eda5f2 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -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) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index fa13c4076dc..8d8d4434d9e 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -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; } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cp.c b/src/gallium/drivers/freedreno/ir3/ir3_cp.c index 8c7c80f7aae..f4c825b2ab6 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cp.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cp.c @@ -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; } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index 49a4426d163..01d72301dcc 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -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); } } |