From 82dffae611f532ae35dbd52ac6939ddfaa12ad35 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 3 Sep 2025 16:06:55 +0200 Subject: [PATCH] r600/sfn: don't use dummy regs in alu ops when no dest register is needed Signed-off-by: Gert Wollny Part-of: --- .../drivers/r600/sfn/sfn_instr_alu.cpp | 36 ++++++++++----- src/gallium/drivers/r600/sfn/sfn_instr_alu.h | 2 +- .../drivers/r600/sfn/sfn_instr_lds.cpp | 4 +- .../drivers/r600/sfn/sfn_scheduler.cpp | 8 ++-- src/gallium/drivers/r600/sfn/sfn_shader.cpp | 2 +- .../drivers/r600/sfn/sfn_valuefactory.cpp | 10 ++++- .../drivers/r600/sfn/sfn_valuefactory.h | 2 +- .../drivers/r600/sfn/tests/sfn_instr_test.cpp | 11 ++--- .../sfn/tests/sfn_instrfromstring_test.cpp | 45 ++++++++----------- .../r600/sfn/tests/sfn_test_shaders.cpp | 6 +-- 10 files changed, 69 insertions(+), 57 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp index 55f5f44404c..fade2fb1523 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp @@ -883,7 +883,7 @@ r600_multislot_get_last_opcode_and_slot(EAluOp opcode, int dest_chan) } bool -AluInstr::split(ValueFactory& vf, AluGroup& group) +AluInstr::split(AluGroup& group) { if (m_alu_slots == 1) return false; @@ -910,15 +910,18 @@ AluInstr::split(ValueFactory& vf, AluGroup& group) } } - m_dest->del_parent(this); + if (m_dest) + m_dest->del_parent(this); auto [last_opcode, start_slot] = - r600_multislot_get_last_opcode_and_slot(m_opcode, m_dest->chan()); + r600_multislot_get_last_opcode_and_slot(m_opcode, dest_chan()); + + assert(start_slot + m_alu_slots <= 4); for (int k = 0; k < m_alu_slots; ++k) { int dest_slot = k + start_slot; - PRegister dst = dest_slot == m_dest->chan() ? m_dest : vf.dummy_dest(dest_slot); + PRegister dst = (m_dest && (dest_slot == m_dest->chan())) ? m_dest : nullptr; SrcValues src; int nsrc = alu_ops.at(m_opcode).nsrc; @@ -928,7 +931,11 @@ AluInstr::split(ValueFactory& vf, AluGroup& group) auto opcode = k < m_alu_slots -1 ? m_opcode : last_opcode; - auto instr = new AluInstr(opcode, dst, src, {}, 1); + AluInstr *instr; + if (dst) + instr = new AluInstr(opcode, dst, src, {}, 1); + else + instr = new AluInstr(opcode, dest_slot, src, {}); instr->set_blockid(block_id(), index()); instr->pin_dest_to_chan(); @@ -947,15 +954,18 @@ AluInstr::split(ValueFactory& vf, AluGroup& group) if (has_alu_flag(alu_dst_clamp)) instr->set_alu_flag(alu_dst_clamp); - if (dest_slot == m_dest->chan()) + if (has_alu_flag(alu_write) && m_dest && (dest_slot == m_dest->chan())) instr->set_alu_flag(alu_write); - m_dest->add_parent(instr); + if (m_dest) + m_dest->add_parent(instr); if (!group.add_instruction(instr)) { std::cerr << "Unable to schedule '" << *instr << "' into\n" << group << "\n"; UNREACHABLE("Invalid group instruction"); } + + instr->set_cf_type(cf_type()); } group.set_blockid(block_id(), index()); @@ -1291,17 +1301,21 @@ AluInstr::from_string(istream& is, ValueFactory& value_factory, AluGroup *group, PRegister dest = nullptr; // construct instruction + int chan = -1; if (deststr != "(null)") - dest = value_factory.dest_from_string(deststr); + dest = value_factory.dest_from_string(deststr, &chan); AluInstr *retval = nullptr; if (is_lds) retval = new AluInstr(op_descr.lds_opcode, sources, flags); else { - if (op_descr.alu_opcode != op0_nop && op_descr.alu_opcode != op0_group_barrier) - retval = new AluInstr(op_descr.alu_opcode, dest, sources, flags, slots); - else { + if (op_descr.alu_opcode != op0_nop && op_descr.alu_opcode != op0_group_barrier) { + if (dest) + retval = new AluInstr(op_descr.alu_opcode, dest, sources, flags, slots); + else + retval = new AluInstr(op_descr.alu_opcode, chan, sources, flags); + } else { retval = new AluInstr(op_descr.alu_opcode, 0); for (auto f : flags) retval->set_alu_flag(f); diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.h b/src/gallium/drivers/r600/sfn/sfn_instr_alu.h index 243a4916fde..65a1457788c 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.h +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.h @@ -152,7 +152,7 @@ public: int alu_slots() const { return m_alu_slots; } - bool split(ValueFactory& vf, AluGroup& dest_group); + bool split(AluGroup& dest_group); bool end_group() const override { return m_alu_flags.test(alu_last_instr); } diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_lds.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_lds.cpp index 3866286d10c..16877a10183 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_lds.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_lds.cpp @@ -185,7 +185,7 @@ LDSReadInstr::from_string(istream& is, ValueFactory& value_factory) -> Pointer is >> temp_str; while (temp_str != "]") { - auto dst = value_factory.dest_from_string(temp_str); + auto dst = value_factory.dest_from_string(temp_str, nullptr); assert(dst); dests.push_back(dst); is >> temp_str; @@ -447,7 +447,7 @@ LDSAtomicInstr::from_string(istream& is, ValueFactory& value_factory) -> Pointer PRegister dest = nullptr; if (temp_str[0] != '_') - dest = value_factory.dest_from_string(temp_str); + dest = value_factory.dest_from_string(temp_str, nullptr); is >> temp_str; assert(temp_str == "["); diff --git a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp index 8934cb5a915..7f847caf572 100644 --- a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp @@ -965,7 +965,6 @@ BlockScheduler::schedule_alu_multislot_to_group_vec(AluGroup *group, ValueFactor while (i != e && util_bitcount(group->free_slot_mask()) > 1) { auto dest = (*i)->dest(); - assert(dest); bool can_merge = false; unsigned allowed_dest_chan_mask = (*i)->allowed_dest_chan_mask(); @@ -984,7 +983,10 @@ BlockScheduler::schedule_alu_multislot_to_group_vec(AluGroup *group, ValueFactor if (!dest->can_switch_to_chan(new_chan)) break; - dest->set_chan(new_chan); + if (dest) + dest->set_chan(new_chan); + else + (*i)->set_allowed_dest_chan_mask(BITSET_BIT(new_chan)); } if (!can_merge) { @@ -1003,7 +1005,7 @@ BlockScheduler::schedule_alu_multislot_to_group_vec(AluGroup *group, ValueFactor continue; } - if ((*i)->split(vf, *group)) { + if ((*i)->split(*group)) { success = true; auto old_i = i; ++i; diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.cpp b/src/gallium/drivers/r600/sfn/sfn_shader.cpp index ef8014a4131..a7d169add9c 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader.cpp @@ -729,7 +729,7 @@ Shader::process_if(nir_if *if_stmt) auto flags = {alu_update_exec, alu_last_instr, alu_update_pred}; AluInstr *pred = new AluInstr(op, - value_factory().temp_register(), + 0, value, value_factory().zero(), flags); diff --git a/src/gallium/drivers/r600/sfn/sfn_valuefactory.cpp b/src/gallium/drivers/r600/sfn/sfn_valuefactory.cpp index 6d194a8ceb1..b86bd267fc6 100644 --- a/src/gallium/drivers/r600/sfn/sfn_valuefactory.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_valuefactory.cpp @@ -593,7 +593,7 @@ split_register_string(const string& s, } PRegister -ValueFactory::dest_from_string(const std::string& s) +ValueFactory::dest_from_string(const std::string& s, int *dest_chan) { if (s == "AR") { if (!m_ar) @@ -624,7 +624,7 @@ ValueFactory::dest_from_string(const std::string& s) if (s[0] == '_') { /* Since these instructions still may use or switch to a different * channel we have to create a new instance for each occurrence */ - sel = std::numeric_limits::max() - m_nowrite_idx++; + sel = -1; } else { std::istringstream n(index_str); n >> sel; @@ -653,6 +653,12 @@ ValueFactory::dest_from_string(const std::string& s) bool is_ssa = s[0] == 'S'; + if (pool == vp_ignore) { + assert(dest_chan); + *dest_chan = chan; + return nullptr; + } + RegisterKey key(sel, chan, pool); sfn_log << SfnLog::reg << "Search register with key " << key << "\n"; diff --git a/src/gallium/drivers/r600/sfn/sfn_valuefactory.h b/src/gallium/drivers/r600/sfn/sfn_valuefactory.h index bcf67a59f4e..cb3ee50c1ca 100644 --- a/src/gallium/drivers/r600/sfn/sfn_valuefactory.h +++ b/src/gallium/drivers/r600/sfn/sfn_valuefactory.h @@ -250,7 +250,7 @@ public: void allocate_const(nir_load_const_instr *load_const); - PRegister dest_from_string(const std::string& s); + PRegister dest_from_string(const std::string& s, int *dest_chan = nullptr); RegisterVec4 dest_vec4_from_string(const std::string& s, RegisterVec4::Swizzle& swz, Pin pin = pin_none); diff --git a/src/gallium/drivers/r600/sfn/tests/sfn_instr_test.cpp b/src/gallium/drivers/r600/sfn/tests/sfn_instr_test.cpp index 32684a82914..0becdaa7444 100644 --- a/src/gallium/drivers/r600/sfn/tests/sfn_instr_test.cpp +++ b/src/gallium/drivers/r600/sfn/tests/sfn_instr_test.cpp @@ -321,9 +321,6 @@ TEST_F(InstrTest, test_alu_dot4_grouped) auto R131w = new Register(131, 3, pin_none); auto R132x = new Register(132, 0, pin_chan); - auto R132y = new Register(132, 1, pin_chan); - auto R132z = new Register(132, 2, pin_chan); - auto R132w = new Register(132, 3, pin_chan); AluInstr::SrcValues src({R130x, R130y, R130z, R130w, R131x, R131y, R131z, R131w}); @@ -334,7 +331,7 @@ TEST_F(InstrTest, test_alu_dot4_grouped) ValueFactory vf; auto group = new AluGroup(); - bool result = alu.split(vf, *group); + bool result = alu.split(*group); group->fix_last_flag(); ASSERT_TRUE(result); @@ -345,15 +342,15 @@ TEST_F(InstrTest, test_alu_dot4_grouped) ++i; EXPECT_NE(i, group->end()); ASSERT_TRUE(*i); - check(**i, AluInstr(op2_dot4_ieee, R132y, R130z, R130w, AluInstr::empty)); + check(**i, AluInstr(op2_dot4_ieee, 1, {R130z, R130w}, AluInstr::empty)); ++i; EXPECT_NE(i, group->end()); ASSERT_TRUE(*i); - check(**i, AluInstr(op2_dot4_ieee, R132z, R131x, R131y, AluInstr::empty)); + check(**i, AluInstr(op2_dot4_ieee, 2, {R131x, R131y}, AluInstr::empty)); ++i; EXPECT_NE(i, group->end()); ASSERT_TRUE(*i); - check(**i, AluInstr(op2_dot4_ieee, R132w, R131z, R131w, {alu_last_instr})); + check(**i, AluInstr(op2_dot4_ieee, 3, {R131z, R131w}, {alu_last_instr})); ++i; EXPECT_NE(i, group->end()); ASSERT_FALSE(*i); diff --git a/src/gallium/drivers/r600/sfn/tests/sfn_instrfromstring_test.cpp b/src/gallium/drivers/r600/sfn/tests/sfn_instrfromstring_test.cpp index 3e7be1f4a07..642c64669cf 100644 --- a/src/gallium/drivers/r600/sfn/tests/sfn_instrfromstring_test.cpp +++ b/src/gallium/drivers/r600/sfn/tests/sfn_instrfromstring_test.cpp @@ -109,9 +109,8 @@ TEST_F(TestInstrFromString, test_alu_add) add_dest_from_string("R1999.w"); AluInstr expect(op2_add, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 1, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr}); check("ALU ADD __.y : R1999.w R1998.z {L}", expect); } @@ -121,9 +120,8 @@ TEST_F(TestInstrFromString, test_alu_add_clmap) add_dest_from_string("R1998.z"); add_dest_from_string("R1999.w"); AluInstr expect(op2_add, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 1, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr, alu_dst_clamp}); check("ALU ADD CLAMP __.y : R1999.w R1998.z {L}", expect); } @@ -133,9 +131,8 @@ TEST_F(TestInstrFromString, test_alu_add_neg2) add_dest_from_string("R1998.z"); add_dest_from_string("R1999.w"); AluInstr expect(op2_add, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 1, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr}); expect.set_source_mod(1, AluInstr::mod_neg); @@ -147,9 +144,8 @@ TEST_F(TestInstrFromString, test_alu_sete_update_pref) add_dest_from_string("R1998.z"); add_dest_from_string("R1999.w"); AluInstr expect(op2_sete, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 1, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr, alu_update_pred}); expect.set_source_mod(1, AluInstr::mod_neg); check("ALU SETE __.y : R1999.w -R1998.z {LP}", expect); @@ -160,9 +156,8 @@ TEST_F(TestInstrFromString, test_alu_sete_update_pref_empty_dest) add_dest_from_string("R1998.z"); add_dest_from_string("R1999.w"); AluInstr expect(op2_sete, - new Register(2000, 0, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 0, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr, alu_update_pred}); check("ALU SETE __.x : R1999.w R1998.z {LP}", expect); } @@ -172,9 +167,8 @@ TEST_F(TestInstrFromString, test_alu_setne_update_exec) add_dest_from_string("R1998.z"); add_dest_from_string("R1999.w"); AluInstr expect(op2_setne, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), + 1, + {new Register(1999, 3, pin_none), new Register(1998, 2, pin_none)}, {alu_last_instr, alu_update_exec}); expect.set_source_mod(1, AluInstr::mod_neg); check("ALU SETNE __.y : R1999.w -R1998.z {LE}", expect); @@ -228,10 +222,10 @@ TEST_F(TestInstrFromString, test_alu_muladd_neg3) add_dest_from_string("R1999.w"); add_dest_from_string("R2000.y"); AluInstr expect(op3_muladd_ieee, - new Register(2000, 1, pin_none), - new Register(1999, 3, pin_none), - new Register(1998, 2, pin_none), - new Register(2000, 1, pin_none), + 1, + {new Register(1999, 3, pin_none), + new Register(1998, 2, pin_none), + new Register(2000, 1, pin_none)}, {alu_last_instr}); check("ALU MULADD_IEEE __.y : R1999.w R1998.z -R2000.y {L}", expect); } @@ -360,15 +354,14 @@ TEST_F(TestInstrFromString, test_alu_interp_xy) TEST_F(TestInstrFromString, test_alu_interp_xy_no_write) { add_dest_from_string("R0.x@fully"); - auto init = std::string("ALU INTERP_XY __.x@chan : R0.x@fully Param0.z {} VEC_210"); + auto init = std::string("ALU INTERP_XY __.x : R0.x@fully Param0.z {} VEC_210"); auto r0x = new Register(0, 0, pin_fully); r0x->set_flag(Register::pin_start); AluInstr expect(op2_interp_xy, - new Register(1024, 0, pin_chan), - r0x, - new InlineConstant(ALU_SRC_PARAM_BASE, 2), + 0, + {r0x, new InlineConstant(ALU_SRC_PARAM_BASE, 2)}, AluInstr::empty); expect.set_bank_swizzle(alu_vec_210); diff --git a/src/gallium/drivers/r600/sfn/tests/sfn_test_shaders.cpp b/src/gallium/drivers/r600/sfn/tests/sfn_test_shaders.cpp index f6e360f5968..b7ecc21882d 100644 --- a/src/gallium/drivers/r600/sfn/tests/sfn_test_shaders.cpp +++ b/src/gallium/drivers/r600/sfn/tests/sfn_test_shaders.cpp @@ -1415,9 +1415,9 @@ ALU_GROUP_BEGIN ALU_GROUP_END ALU_GROUP_BEGIN ALU DOT4_IEEE S5.x@chan : S4.x@chan S4.x@chan {W} - ALU DOT4_IEEE __.y@chgr : S4.y@chan S4.y@chan {} - ALU DOT4_IEEE __.z@chgr : I[0] I[0] {} - ALU DOT4_IEEE __.w@chgr : I[0] I[0] {L} + ALU DOT4_IEEE __.y : S4.y@chan S4.y@chan {} + ALU DOT4_IEEE __.z : I[0] I[0] {} + ALU DOT4_IEEE __.w : I[0] I[0] {L} ALU_GROUP_END ALU_GROUP_BEGIN ALU SQRT_IEEE S6.x@chan : S5.x@chan {WL}