diff options
author | Rob Clark <robclark@freedesktop.org> | 2016-04-04 17:38:01 -0400 |
---|---|---|
committer | Rob Clark <robclark@freedesktop.org> | 2016-04-04 20:18:18 -0400 |
commit | 3e135728268cf36a176dcd915108ad7dc0f4e457 (patch) | |
tree | 95570c663fb0f352457c79bc6f37dfc2b24e823f /src | |
parent | f8feb97ba5be50cd9bfe63a4d3b0ba35010a0d32 (diff) |
freedreno/ir3: deal with duplicate phi sources
Otherwise we end up with funny things like:
mov.f32f32 r0.x, r1.y
mov.f32f32 r0.x, r1.y
(It doesn't happen as much after fixing the problem w/ CP into phi src,
but it can still happen since we aren't too clever about generating phi
sources in the first place.)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_sched.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index 9be5ca34ccd..b56da304f92 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -627,13 +627,28 @@ sched_insert_parallel_copies(struct ir3_block *block) { list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) { if (instr->opc == OPC_META_PHI) { - struct ir3_register *reg; + struct ir3_register *reg, *reg2; foreach_src(reg, instr) { struct ir3_instruction *src = reg->instr; - struct ir3_instruction *mov = - ir3_MOV(src->block, src, TYPE_U32); - mov->regs[0]->flags |= IR3_REG_PHI_SRC; - mov->regs[0]->instr = instr; + struct ir3_instruction *mov = NULL; + + /* after CP we could end up w/ duplicate phi srcs: */ + foreach_src(reg2, instr) { + if (reg == reg2) + break; + /* reg2 is before reg1 so already an inserted mov: */ + else if (reg2->instr->regs[1]->instr == src) { + mov = reg2->instr; + break; + } + } + + if (!mov) { + mov = ir3_MOV(src->block, src, TYPE_U32); + mov->regs[0]->flags |= IR3_REG_PHI_SRC; + mov->regs[0]->instr = instr; + } + reg->instr = mov; } } |