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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user