r600/sfn: Simplify scheduling

Group together instructions that are
   * emitted at CF level
   * in a GDS block.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37096>
This commit is contained in:
Gert Wollny 2025-08-28 14:04:55 +02:00 committed by Marge Bot
parent 11c91aa5fb
commit fc40002de7

View file

@ -71,15 +71,15 @@ public:
m_cf_instr = instr; m_cf_instr = instr;
} }
void visit(ScratchIOInstr *instr) override { mem_write_instr.push_back(instr); } void visit(ScratchIOInstr *instr) override { free_instr.push_back(instr); }
void visit(StreamOutInstr *instr) override { mem_write_instr.push_back(instr); } void visit(StreamOutInstr *instr) override { free_instr.push_back(instr); }
void visit(MemRingOutInstr *instr) override { mem_ring_writes.push_back(instr); } void visit(MemRingOutInstr *instr) override { free_instr.push_back(instr); }
void visit(GDSInstr *instr) override { gds_op.push_back(instr); } void visit(GDSInstr *instr) override { gds_instr.push_back(instr); }
void visit(WriteTFInstr *instr) override { write_tf.push_back(instr); } void visit(WriteTFInstr *instr) override { gds_instr.push_back(instr); }
void visit(LDSReadInstr *instr) override void visit(LDSReadInstr *instr) override
{ {
@ -99,7 +99,7 @@ public:
} }
} }
void visit(RatInstr *instr) override { rat_instr.push_back(instr); } void visit(RatInstr *instr) override { free_instr.push_back(instr); }
std::list<AluInstr *> alu_trans; std::list<AluInstr *> alu_trans;
std::list<AluInstr *> alu_vec; std::list<AluInstr *> alu_vec;
@ -108,11 +108,8 @@ public:
std::list<AluGroup *> alu_groups; std::list<AluGroup *> alu_groups;
std::list<ExportInstr *> exports; std::list<ExportInstr *> exports;
std::list<FetchInstr *> fetches; std::list<FetchInstr *> fetches;
std::list<WriteOutInstr *> mem_write_instr; std::list<Instr *> free_instr;
std::list<MemRingOutInstr *> mem_ring_writes; std::list<Instr *> gds_instr;
std::list<GDSInstr *> gds_op;
std::list<WriteTFInstr *> write_tf;
std::list<RatInstr *> rat_instr;
Instr *m_cf_instr{nullptr}; Instr *m_cf_instr{nullptr};
ValueFactory& m_value_factory; ValueFactory& m_value_factory;
@ -187,21 +184,15 @@ private:
std::list<TexInstr *> tex_ready; std::list<TexInstr *> tex_ready;
std::list<ExportInstr *> exports_ready; std::list<ExportInstr *> exports_ready;
std::list<FetchInstr *> fetches_ready; std::list<FetchInstr *> fetches_ready;
std::list<WriteOutInstr *> memops_ready; std::list<Instr *> free_ready;
std::list<MemRingOutInstr *> mem_ring_writes_ready; std::list<Instr *> gds_ready;
std::list<GDSInstr *> gds_ready;
std::list<WriteTFInstr *> write_tf_ready;
std::list<RatInstr *> rat_instr_ready;
enum { enum {
sched_alu, sched_alu,
sched_tex, sched_tex,
sched_fetch, sched_fetch,
sched_free, sched_free,
sched_mem_ring,
sched_gds, sched_gds,
sched_write_tf,
sched_rat,
} current_shed; } current_shed;
ExportInstr *m_last_pos; ExportInstr *m_last_pos;
@ -337,21 +328,15 @@ BlockScheduler::schedule_block(Block& in_block,
sfn_log << SfnLog::schedule << " TEX:" << tex_ready.size() << "\n"; sfn_log << SfnLog::schedule << " TEX:" << tex_ready.size() << "\n";
if (fetches_ready.size()) if (fetches_ready.size())
sfn_log << SfnLog::schedule << " FETCH:" << fetches_ready.size() << "\n"; sfn_log << SfnLog::schedule << " FETCH:" << fetches_ready.size() << "\n";
if (mem_ring_writes_ready.size()) if (free_ready.size())
sfn_log << SfnLog::schedule << " MEM_RING:" << mem_ring_writes_ready.size() sfn_log << SfnLog::schedule << " GENERIC:" << free_ready.size() << "\n";
<< "\n"; if (gds_ready.size())
if (memops_ready.size()) sfn_log << SfnLog::schedule << " GDS:" << gds_ready.size() << "\n";
sfn_log << SfnLog::schedule << " MEM_OPS:" << mem_ring_writes_ready.size()
<< "\n";
if (!m_current_block->lds_group_active() && if (!m_current_block->lds_group_active() &&
m_current_block->expected_ar_uses() == 0) { m_current_block->expected_ar_uses() == 0) {
if (last_shed != sched_free && memops_ready.size() > 8) if (last_shed != sched_free && free_ready.size() > 8)
current_shed = sched_free; current_shed = sched_free;
else if (mem_ring_writes_ready.size() > 15)
current_shed = sched_mem_ring;
else if (rat_instr_ready.size() > 3)
current_shed = sched_rat;
else if (tex_ready.size() > (m_chip_class >= ISA_CC_EVERGREEN ? 15 : 7)) else if (tex_ready.size() > (m_chip_class >= ISA_CC_EVERGREEN ? 15 : 7))
current_shed = sched_tex; current_shed = sched_tex;
} }
@ -384,32 +369,10 @@ BlockScheduler::schedule_block(Block& in_block,
schedule_gds(out_blocks, gds_ready); schedule_gds(out_blocks, gds_ready);
last_shed = current_shed; last_shed = current_shed;
} }
current_shed = sched_mem_ring; current_shed = sched_free;
continue; continue;
case sched_mem_ring:
if (mem_ring_writes_ready.empty() ||
!schedule_cf(out_blocks, mem_ring_writes_ready)) {
current_shed = sched_write_tf;
continue;
}
last_shed = current_shed;
break;
case sched_write_tf:
if (write_tf_ready.empty() || !schedule_gds(out_blocks, write_tf_ready)) {
current_shed = sched_rat;
continue;
}
last_shed = current_shed;
break;
case sched_rat:
if (rat_instr_ready.empty() || !schedule_cf(out_blocks, rat_instr_ready)) {
current_shed = sched_free;
continue;
}
last_shed = current_shed;
break;
case sched_free: case sched_free:
if (memops_ready.empty() || !schedule_cf(out_blocks, memops_ready)) { if (free_ready.empty() || !schedule_cf(out_blocks, free_ready)) {
current_shed = sched_alu; current_shed = sched_alu;
break; break;
} }
@ -466,9 +429,9 @@ BlockScheduler::schedule_block(Block& in_block,
} }
fail = true; fail = true;
} }
if (!cir.mem_write_instr.empty()) { if (!cir.free_instr.empty()) {
std::cerr << "Unscheduled MEM ops:\n"; std::cerr << "Unscheduled MEM ops:\n";
for (auto& a : cir.mem_write_instr) { for (auto& a : cir.free_instr) {
std::cerr << " " << *a << "\n"; std::cerr << " " << *a << "\n";
} }
fail = true; fail = true;
@ -507,8 +470,7 @@ BlockScheduler::schedule_block(Block& in_block,
assert(cir.exports.empty()); assert(cir.exports.empty());
assert(cir.fetches.empty()); assert(cir.fetches.empty());
assert(cir.alu_vec.empty()); assert(cir.alu_vec.empty());
assert(cir.mem_write_instr.empty()); assert(cir.free_instr.empty());
assert(cir.mem_ring_writes.empty());
assert(!fail); assert(!fail);
@ -1132,13 +1094,10 @@ BlockScheduler::collect_ready(CollectInstructions& available)
result |= collect_ready_type(alu_trans_ready, available.alu_trans); result |= collect_ready_type(alu_trans_ready, available.alu_trans);
result |= collect_ready_type(alu_multi_slot_ready, available.alu_multi_slot); result |= collect_ready_type(alu_multi_slot_ready, available.alu_multi_slot);
result |= collect_ready_type(alu_groups_ready, available.alu_groups); result |= collect_ready_type(alu_groups_ready, available.alu_groups);
result |= collect_ready_type(gds_ready, available.gds_op); result |= collect_ready_type(gds_ready, available.gds_instr);
result |= collect_ready_type(tex_ready, available.tex); result |= collect_ready_type(tex_ready, available.tex);
result |= collect_ready_type(fetches_ready, available.fetches); result |= collect_ready_type(fetches_ready, available.fetches);
result |= collect_ready_type(memops_ready, available.mem_write_instr); result |= collect_ready_type(free_ready, available.free_instr);
result |= collect_ready_type(mem_ring_writes_ready, available.mem_ring_writes);
result |= collect_ready_type(write_tf_ready, available.write_tf);
result |= collect_ready_type(rat_instr_ready, available.rat_instr);
sfn_log << SfnLog::schedule << "\n"; sfn_log << SfnLog::schedule << "\n";
return result; return result;
@ -1260,7 +1219,7 @@ template <> struct type_char<GDSInstr> {
static char value() { return 'S';}; static char value() { return 'S';};
}; };
template <> struct type_char<RatInstr> { template <> struct type_char<Instr> {
static char value() { return 'I';}; static char value() { return 'I';};
}; };