r600/sfn: try all possible configurations when splitting multi-slot instructions
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

With that we can better schedule these instructions into groups.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36921>
This commit is contained in:
Gert Wollny 2025-08-21 14:25:59 +02:00 committed by Marge Bot
parent 1cd125f982
commit 44c07c93d0
3 changed files with 48 additions and 2 deletions

View file

@ -956,8 +956,31 @@ BlockScheduler::schedule_alu_multislot_to_group_vec(AluGroup *group, ValueFactor
auto e = alu_multi_slot_ready.end();
while (i != e && util_bitcount(group->free_slot_mask()) > 1) {
auto required_mask = (*i)->required_channels_mask();
if ((group->free_slot_mask() & required_mask) != required_mask) {
auto dest = (*i)->dest();
assert(dest);
bool can_merge = false;
unsigned allowed_dest_chan_mask = (*i)->allowed_dest_chan_mask();
while (allowed_dest_chan_mask) {
auto required_mask = (*i)->required_channels_mask();
if ((group->free_slot_mask() & required_mask) == required_mask) {
can_merge = true;
break;
}
allowed_dest_chan_mask &= ~BITFIELD_BIT((*i)->dest_chan());
int new_chan = u_bit_scan(&allowed_dest_chan_mask);
if (!dest->can_switch_to_chan(new_chan))
break;
dest->set_chan(new_chan);
}
if (!can_merge) {
++i;
continue;
}

View file

@ -241,6 +241,27 @@ Register::accept(ConstRegisterVisitor& visitor) const
visitor.visit(*this);
}
bool
Register::can_switch_to_chan(int c)
{
if (pin() != pin_free && pin() != pin_group)
return false;
int free_mask = BITSET_BIT(c);
for (auto p : parents()) {
auto alu = p->as_alu();
if (alu)
free_mask &= alu->allowed_dest_chan_mask();
}
for (auto u : uses()) {
free_mask &= u->allowed_src_chan_mask();
if (!free_mask)
return false;
}
return true;
}
void
Register::print(std::ostream& os) const
{

View file

@ -169,6 +169,8 @@ public:
bool has_uses() const { return !m_uses.empty() || pin() == pin_array; }
void set_chan(int c) { do_set_chan(c); }
bool can_switch_to_chan(int c);
virtual VirtualValue *addr() const { return nullptr; }
int index() const { return m_index; }