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 <robclark@freedesktop.org>
This commit is contained in:
Rob Clark 2015-07-02 13:52:38 -04:00
parent 0a155538eb
commit 6b9f5cd5f7
5 changed files with 23 additions and 10 deletions

View 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)
{

View 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)

View 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;
}

View 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;
}

View 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);
}
}