r600/sfn: change register ID of dummy dest register

Handle it correctly in the assembler, live range evaluation
and RA.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37321>
This commit is contained in:
Gert Wollny
2025-09-11 23:40:00 +02:00
committed by Marge Bot
parent fc5728950b
commit 12d913fe4f
8 changed files with 19 additions and 11 deletions
@@ -18,6 +18,7 @@ namespace r600 {
static const int g_registers_end = 123;
static const int g_clause_local_start = 124;
static const int g_clause_local_end = 128;
static const int g_registers_unused = 0x7fffffff;
/* ALU op2 instructions 17:7 top three bits always zero. */
enum EAluOp {
@@ -1190,7 +1190,7 @@ AssamblerVisitor::emit_loop_cont()
bool
AssamblerVisitor::copy_dst(r600_bytecode_alu_dst& dst, const Register& d, bool write)
{
if (write && d.sel() > g_clause_local_end) {
if (write && d.sel() > g_clause_local_end && d.sel() != g_registers_unused) {
R600_ASM_ERR("shader_from_nir: Don't support more then 123 GPRs + 4 clause "
"local, but try using %d\n",
d.sel());
@@ -1198,7 +1198,7 @@ AssamblerVisitor::copy_dst(r600_bytecode_alu_dst& dst, const Register& d, bool w
return false;
}
dst.sel = d.sel();
dst.sel = d.sel() != g_registers_unused ? d.sel() : g_registers_end;
dst.chan = d.chan();
if (m_last_addr && m_last_addr->equal_to(d))
@@ -296,7 +296,10 @@ AluInstr::do_print(std::ostream& os) const
if (m_dest) {
if (has_alu_flag(alu_write) || m_dest->has_flag(Register::addr_or_idx)) {
os << " " << *m_dest;
if (unlikely(m_dest->sel() == g_registers_unused))
os << " ()" << "." << swzchar[dest_chan()];
else
os << " " << *m_dest;
} else {
os << " __"
<< "." << swzchar[m_dest->chan()];
@@ -442,7 +442,7 @@ LiveRangeInstrVisitor::record_write(int block, const Register *reg)
auto& rav = m_register_access(array(i, reg->chan()));
rav.record_write(block, m_line > 0 ? m_line - 1 : 0, m_current_scope);
}
} else {
} else if (reg->sel() != g_registers_unused) {
auto& ra = m_register_access(*reg);
sfn_log << SfnLog::merge << *reg << " write:" << block << ":" << m_line << "\n";
ra.record_write(block, m_line, m_current_scope);
+2 -2
View File
@@ -210,7 +210,7 @@ scalar_allocation(LiveRangeMap& lrm, const Interference& interference)
for (int comp = 0; comp < 4; ++comp) {
auto& live_ranges = lrm.component(comp);
for (auto& r : live_ranges) {
if (r.m_color != -1)
if (r.m_color != g_registers_unused)
continue;
if (r.m_start == -1 && r.m_end == -1)
@@ -272,7 +272,7 @@ scalar_clause_local_allocation (LiveRangeMap& lrm, const Interference& interfer
<< " ], AC: " << r.m_alu_clause_local
<< " Color; " << r.m_color << "\n";
if (r.m_color != -1)
if (r.m_color != g_registers_unused)
continue;
if (r.m_start == -1 &&
@@ -616,7 +616,7 @@ ValueFactory::dest_from_string(const std::string& s, int *dest_chan)
assert(s.length() >= 4);
assert(strchr("ARS_", s[0]));
assert(strchr("ARS_(", s[0]));
split_register_string(s, index_str, size_str, swizzle_str, pin_str);
@@ -625,6 +625,8 @@ ValueFactory::dest_from_string(const std::string& s, int *dest_chan)
/* Since these instructions still may use or switch to a different
* channel we have to create a new instance for each occurrence */
sel = -1;
} else if (s[0] == '(') {
sel = g_registers_unused;
} else {
std::istringstream n(index_str);
n >> sel;
@@ -644,6 +646,7 @@ ValueFactory::dest_from_string(const std::string& s, int *dest_chan)
case '_':
pool = vp_ignore;
break;
case '(':
case 'S':
pool = vp_ssa;
break;
@@ -982,7 +985,7 @@ ValueFactory::prepare_live_range_map()
result.append_register(a);
}
} else {
if (reg->chan() < 4)
if (reg->chan() < 4 && reg->sel() != g_registers_unused)
result.append_register(reg);
}
}
@@ -33,7 +33,7 @@ struct LiveRangeEntry {
int m_start{-1};
int m_end{-1};
int m_index{-1};
int m_color{-1};
int m_color{g_registers_unused};
bool m_alu_clause_local{false};
std::bitset<use_unspecified> m_use;
Register *m_register;
@@ -311,7 +311,8 @@ private:
uint32_t m_nowrite_idx;
RegisterVec4 m_dummy_dest_pinned{
g_registers_end, pin_chan, {0, 1, 2, 3}
g_registers_unused, true, {0, 1, 2, 3},
pin_chan
};
ChannelCounts m_channel_counts;
uint32_t m_required_array_registers{0};
@@ -49,7 +49,7 @@ VirtualValue::VirtualValue(int sel, int chan, Pin pin):
m_pins(pin)
{
#if __cpp_exceptions >= 199711L
ASSERT_OR_THROW(m_sel < virtual_register_base || pin != pin_fully,
ASSERT_OR_THROW(m_sel < g_registers_end || pin != pin_fully,
"Register is virtual but pinned to sel");
#endif
}