From 48f5f3be5f7a2ebbefdb66d69d11cfef73aa20eb Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 25 Jun 2021 10:51:25 +0200 Subject: [PATCH] ir3: Stop creating dummy dest registers These were a holdover from before the src/dst split and are no longer necessary. Just don't create any dest registers for instructions that never have a destination. This has the side-effect that it becomes easier to replace uses of dest_regs() with a per-register thing, once we start adding support for multiple destinations. Part-of: --- src/freedreno/ir3/ir3.c | 2 +- src/freedreno/ir3/ir3.h | 74 +++++++++++++++------------- src/freedreno/ir3/ir3_compiler_nir.c | 6 +-- src/freedreno/ir3/ir3_legalize.c | 9 ++-- src/freedreno/ir3/ir3_ra.c | 3 -- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 7a340b78eb7..f401745216e 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -711,7 +711,7 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n, /* If destination is indirect, then source cannot be.. at least * I don't think so.. */ - if ((instr->dsts[0]->flags & IR3_REG_RELATIV) && + if (instr->dsts_count > 0 && (instr->dsts[0]->flags & IR3_REG_RELATIV) && (flags & IR3_REG_RELATIV)) return false; diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 6dac29a78fe..daa2d815d8a 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -963,7 +963,7 @@ reg_size(const struct ir3_register *reg) static inline unsigned dest_regs(struct ir3_instruction *instr) { - if ((instr->dsts_count == 0) || is_store(instr) || is_flow(instr)) + if (instr->dsts_count == 0) return 0; return util_last_bit(instr->dsts[0]->wrmask); @@ -1661,20 +1661,22 @@ ir3_##name(struct ir3_block *block) \ #define INSTR0F(f, name) __INSTR0(IR3_INSTR_##f, name##_##f, OPC_##name) #define INSTR0(name) __INSTR0(0, name, OPC_##name) -#define __INSTR1(flag, name, opc) \ +#define __INSTR1(flag, dst_count, name, opc) \ static inline struct ir3_instruction * \ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *a, unsigned aflags) \ { \ struct ir3_instruction *instr = \ - ir3_instr_create(block, opc, 1, 1); \ - __ssa_dst(instr); \ + ir3_instr_create(block, opc, dst_count, 1); \ + for (unsigned i = 0; i < dst_count; i++) \ + __ssa_dst(instr); \ __ssa_src(instr, a, aflags); \ instr->flags |= flag; \ return instr; \ } -#define INSTR1F(f, name) __INSTR1(IR3_INSTR_##f, name##_##f, OPC_##name) -#define INSTR1(name) __INSTR1(0, name, OPC_##name) +#define INSTR1F(f, name) __INSTR1(IR3_INSTR_##f, 1, name##_##f, OPC_##name) +#define INSTR1(name) __INSTR1(0, 1, name, OPC_##name) +#define INSTR1NODST(name) __INSTR1(0, 0, name, OPC_##name) #define __INSTR2(flag, name, opc) \ static inline struct ir3_instruction * \ @@ -1684,7 +1686,7 @@ ir3_##name(struct ir3_block *block, \ { \ struct ir3_instruction *instr = \ ir3_instr_create(block, opc, 1, 2); \ - __ssa_dst(instr); \ + __ssa_dst(instr); \ __ssa_src(instr, a, aflags); \ __ssa_src(instr, b, bflags); \ instr->flags |= flag; \ @@ -1693,7 +1695,7 @@ ir3_##name(struct ir3_block *block, \ #define INSTR2F(f, name) __INSTR2(IR3_INSTR_##f, name##_##f, OPC_##name) #define INSTR2(name) __INSTR2(0, name, OPC_##name) -#define __INSTR3(flag, name, opc) \ +#define __INSTR3(flag, dst_count, name, opc) \ static inline struct ir3_instruction * \ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *a, unsigned aflags, \ @@ -1701,18 +1703,20 @@ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *c, unsigned cflags) \ { \ struct ir3_instruction *instr = \ - ir3_instr_create(block, opc, 1, 3); \ - __ssa_dst(instr); \ + ir3_instr_create(block, opc, dst_count, 3); \ + for (unsigned i = 0; i < dst_count; i++) \ + __ssa_dst(instr); \ __ssa_src(instr, a, aflags); \ __ssa_src(instr, b, bflags); \ __ssa_src(instr, c, cflags); \ instr->flags |= flag; \ return instr; \ } -#define INSTR3F(f, name) __INSTR3(IR3_INSTR_##f, name##_##f, OPC_##name) -#define INSTR3(name) __INSTR3(0, name, OPC_##name) +#define INSTR3F(f, name) __INSTR3(IR3_INSTR_##f, 1, name##_##f, OPC_##name) +#define INSTR3(name) __INSTR3(0, 1, name, OPC_##name) +#define INSTR3NODST(name) __INSTR3(0, 0, name, OPC_##name) -#define __INSTR4(flag, name, opc) \ +#define __INSTR4(flag, dst_count, name, opc) \ static inline struct ir3_instruction * \ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *a, unsigned aflags, \ @@ -1721,8 +1725,9 @@ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *d, unsigned dflags) \ { \ struct ir3_instruction *instr = \ - ir3_instr_create(block, opc, 1, 4); \ - __ssa_dst(instr); \ + ir3_instr_create(block, opc, dst_count, 4); \ + for (unsigned i = 0; i < dst_count; i++) \ + __ssa_dst(instr); \ __ssa_src(instr, a, aflags); \ __ssa_src(instr, b, bflags); \ __ssa_src(instr, c, cflags); \ @@ -1730,8 +1735,9 @@ ir3_##name(struct ir3_block *block, \ instr->flags |= flag; \ return instr; \ } -#define INSTR4F(f, name) __INSTR4(IR3_INSTR_##f, name##_##f, OPC_##name) -#define INSTR4(name) __INSTR4(0, name, OPC_##name) +#define INSTR4F(f, name) __INSTR4(IR3_INSTR_##f, 1, name##_##f, OPC_##name) +#define INSTR4(name) __INSTR4(0, 1, name, OPC_##name) +#define INSTR4NODST(name) __INSTR4(0, 0, name, OPC_##name) #define __INSTR5(flag, name, opc) \ static inline struct ir3_instruction * \ @@ -1756,7 +1762,7 @@ ir3_##name(struct ir3_block *block, \ #define INSTR5F(f, name) __INSTR5(IR3_INSTR_##f, name##_##f, OPC_##name) #define INSTR5(name) __INSTR5(0, name, OPC_##name) -#define __INSTR6(flag, name, opc) \ +#define __INSTR6(flag, dst_count, name, opc) \ static inline struct ir3_instruction * \ ir3_##name(struct ir3_block *block, \ struct ir3_instruction *a, unsigned aflags, \ @@ -1768,7 +1774,8 @@ ir3_##name(struct ir3_block *block, \ { \ struct ir3_instruction *instr = \ ir3_instr_create(block, opc, 1, 6); \ - __ssa_dst(instr); \ + for (unsigned i = 0; i < dst_count; i++) \ + __ssa_dst(instr); \ __ssa_src(instr, a, aflags); \ __ssa_src(instr, b, bflags); \ __ssa_src(instr, c, cflags); \ @@ -1778,18 +1785,19 @@ ir3_##name(struct ir3_block *block, \ instr->flags |= flag; \ return instr; \ } -#define INSTR6F(f, name) __INSTR6(IR3_INSTR_##f, name##_##f, OPC_##name) -#define INSTR6(name) __INSTR6(0, name, OPC_##name) +#define INSTR6F(f, name) __INSTR6(IR3_INSTR_##f, 1, name##_##f, OPC_##name) +#define INSTR6(name) __INSTR6(0, 1, name, OPC_##name) +#define INSTR6NODST(name) __INSTR6(0, 0, name, OPC_##name) /* cat0 instructions: */ -INSTR1(B) +INSTR1NODST(B) INSTR0(JUMP) -INSTR1(KILL) -INSTR1(DEMOTE) +INSTR1NODST(KILL) +INSTR1NODST(DEMOTE) INSTR0(END) INSTR0(CHSH) INSTR0(CHMASK) -INSTR1(PREDT) +INSTR1NODST(PREDT) INSTR0(PREDF) INSTR0(PREDE) @@ -1922,10 +1930,10 @@ INSTR3(LDG) INSTR3(LDL) INSTR3(LDLW) INSTR3(LDP) -INSTR4(STG) -INSTR3(STL) -INSTR3(STLW) -INSTR3(STP) +INSTR4NODST(STG) +INSTR3NODST(STL) +INSTR3NODST(STLW) +INSTR3NODST(STP) INSTR1(RESINFO) INSTR1(RESFMT) INSTR2(ATOMIC_ADD) @@ -1941,10 +1949,10 @@ INSTR2(ATOMIC_OR) INSTR2(ATOMIC_XOR) INSTR2(LDC) #if GPU >= 600 -INSTR3(STIB); +INSTR3NODST(STIB); INSTR2(LDIB); INSTR5(LDG_A); -INSTR6(STG_A); +INSTR6NODST(STG_A); INSTR3F(G, ATOMIC_ADD) INSTR3F(G, ATOMIC_SUB) INSTR3F(G, ATOMIC_XCHG) @@ -1958,8 +1966,8 @@ INSTR3F(G, ATOMIC_OR) INSTR3F(G, ATOMIC_XOR) #elif GPU >= 400 INSTR3(LDGB) -INSTR4(STGB) -INSTR4(STIB) +INSTR4NODST(STGB) +INSTR4NODST(STIB) INSTR4F(G, ATOMIC_ADD) INSTR4F(G, ATOMIC_SUB) INSTR4F(G, ATOMIC_XCHG) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 88cc9251b7b..3134dda6a42 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -3819,11 +3819,10 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler, } struct ir3_instruction *chmask = - ir3_instr_create(ctx->block, OPC_CHMASK, 1, outputs_count); + ir3_instr_create(ctx->block, OPC_CHMASK, 0, outputs_count); chmask->barrier_class = IR3_BARRIER_EVERYTHING; chmask->barrier_conflict = IR3_BARRIER_EVERYTHING; - __ssa_dst(chmask); for (unsigned i = 0; i < outputs_count; i++) __ssa_src(chmask, outputs[i], 0)->num = regids[i]; @@ -3915,9 +3914,8 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler, ctx->block = old_block; struct ir3_instruction *end = ir3_instr_create(ctx->block, OPC_END, - 1, outputs_count); + 0, outputs_count); - __ssa_dst(end); for (unsigned i = 0; i < outputs_count; i++) { __ssa_src(end, outputs[i], 0); } diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 6574c9b3ddd..b354cda886d 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -631,15 +631,13 @@ block_sched(struct ir3 *ir) /* create "else" branch first (since "then" block should * frequently/always end up being a fall-thru): */ - br = ir3_instr_create(block, OPC_B, 1, 1); - ir3_dst_create(br, INVALID_REG, 0); + br = ir3_instr_create(block, OPC_B, 0, 1); ir3_src_create(br, regid(REG_P0, 0), 0)->def = block->condition->dsts[0]; br->cat0.inv1 = true; br->cat0.target = block->successors[1]; /* "then" branch: */ - br = ir3_instr_create(block, OPC_B, 1, 1); - ir3_dst_create(br, INVALID_REG, 0); + br = ir3_instr_create(block, OPC_B, 0, 1); ir3_src_create(br, regid(REG_P0, 0), 0)->def = block->condition->dsts[0]; br->cat0.target = block->successors[0]; @@ -694,8 +692,7 @@ kill_sched(struct ir3 *ir, struct ir3_shader_variant *so) if (instr->opc != OPC_KILL) continue; - struct ir3_instruction *br = ir3_instr_create(block, OPC_B, 1, 1); - ir3_dst_create(br, INVALID_REG, 0); + struct ir3_instruction *br = ir3_instr_create(block, OPC_B, 0, 1); ir3_src_create(br, instr->srcs[0]->num, instr->srcs[0]->flags)->wrmask = 1; br->cat0.target = list_last_entry(&ir->block_list, struct ir3_block, node); diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index c354acf86d4..8cea35df9d1 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -1467,9 +1467,6 @@ handle_chmask(struct ra_ctx *ctx, struct ir3_instruction *instr) ra_file_remove(file, interval); } - /* add dummy destination for validation */ - assign_reg(instr, instr->dsts[0], 0); - insert_parallel_copy_instr(ctx, instr); }