r600/sfn: don't use dummy regs in alu ops when no dest register is needed

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37205>
This commit is contained in:
Gert Wollny
2025-09-03 16:06:55 +02:00
committed by Marge Bot
parent 4f1f5aa02d
commit 82dffae611
10 changed files with 69 additions and 57 deletions
+25 -11
View File
@@ -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);
+1 -1
View File
@@ -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); }
@@ -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 == "[");
@@ -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;
+1 -1
View File
@@ -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);
@@ -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<int>::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";
@@ -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);
@@ -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);
@@ -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);
@@ -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}