From ebf45153d87a4bf3d63ca65689d8f372b6d6e6e4 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 10 Oct 2022 17:44:08 +0200 Subject: [PATCH] r600/sfn: Track whether a register is ALU clause local Signed-off-by: Gert Wollny Part-of: --- .../drivers/r600/sfn/sfn_liverangeevaluator.cpp | 108 +++++++++++---------- .../r600/sfn/sfn_liverangeevaluator_helpers.cpp | 16 ++- .../r600/sfn/sfn_liverangeevaluator_helpers.h | 14 ++- src/gallium/drivers/r600/sfn/sfn_valuefactory.h | 1 + 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator.cpp b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator.cpp index f2cc60e..f551aaa 100644 --- a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator.cpp @@ -65,12 +65,12 @@ public: void finalize(); -private: - void record_write(const Register *reg); - void record_read(const Register *reg, LiveRangeEntry::EUse use); - void record_write(const RegisterVec4& reg, const RegisterVec4::Swizzle& swizzle); - void record_read(const RegisterVec4& reg, LiveRangeEntry::EUse use); + void record_write(int block, const Register *reg); + void record_read(int block, const Register *reg, LiveRangeEntry::EUse use); + + void record_write(int block, const RegisterVec4& reg, const RegisterVec4::Swizzle& swizzle); + void record_read(int block, const RegisterVec4 ®, LiveRangeEntry::EUse use); void scope_if(); void scope_else(); @@ -86,9 +86,12 @@ private: LiveRangeMap& m_live_range_map; RegisterAccess m_register_access; + int m_block{0}; int m_line{0}; int m_if_id{1}; int m_loop_id{1}; + + const static int NO_ALU_BLOCK = -1; }; LiveRangeEvaluator::LiveRangeEvaluator() {} @@ -117,22 +120,29 @@ LiveRangeInstrVisitor::finalize() for (int i = 0; i < 4; ++i) { auto& live_ranges = m_live_range_map.component(i); + for (const auto& r : live_ranges) { if (r.m_register->has_flag(Register::pin_end)) - record_read(r.m_register, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, r.m_register, LiveRangeEntry::use_unspecified); } auto& comp_access = m_register_access.component(i); for (size_t i = 0; i < comp_access.size(); ++i) { - sfn_log << SfnLog::merge << "Evaluae access for " << *live_ranges[i].m_register - << "\n"; + sfn_log << SfnLog::merge << "Evaluae access for " << *live_ranges[i].m_register << ":"; auto& rca = comp_access[i]; rca.update_required_live_range(); live_ranges[i].m_start = rca.range().start; live_ranges[i].m_end = rca.range().end; live_ranges[i].m_use = rca.use_type(); + live_ranges[i].m_alu_clause_local = rca.alu_clause_local(); + + + sfn_log << SfnLog::merge << " [" << live_ranges[i].m_start + << ", ] " << live_ranges[i].m_end + << "ACL: " << live_ranges[i].m_alu_clause_local + << "\n"; } } } @@ -155,28 +165,27 @@ LiveRangeInstrVisitor::LiveRangeInstrVisitor(LiveRangeMap& live_range_map): const auto& comp = live_range_map.component(i); for (const auto& r : comp) { if (r.m_register->has_flag(Register::pin_start)) - record_write(r.m_register); + record_write(NO_ALU_BLOCK, r.m_register); } } m_line = 1; } void -LiveRangeInstrVisitor::record_write(const RegisterVec4& reg, - const RegisterVec4::Swizzle& swizzle) +LiveRangeInstrVisitor::record_write(int block, const RegisterVec4& reg, const RegisterVec4::Swizzle &swizzle) { for (int i = 0; i < 4; ++i) { if (swizzle[i] < 6 && reg[i]->chan() < 4) - record_write(reg[i]); + record_write(block, reg[i]); } } void -LiveRangeInstrVisitor::record_read(const RegisterVec4& reg, LiveRangeEntry::EUse use) +LiveRangeInstrVisitor::record_read(int block, const RegisterVec4& reg, LiveRangeEntry::EUse use) { for (int i = 0; i < 4; ++i) { if (reg[i]->chan() < 4) - record_read(reg[i], use); + record_read(block, reg[i], use); } } @@ -249,12 +258,12 @@ LiveRangeInstrVisitor::visit(AluInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; if (instr->has_alu_flag(alu_write)) - record_write(instr->dest()); + record_write(m_block, instr->dest()); for (unsigned i = 0; i < instr->n_sources(); ++i) { - record_read(instr->src(i).as_register(), LiveRangeEntry::use_unspecified); + record_read(m_block, instr->src(i).as_register(), LiveRangeEntry::use_unspecified); auto uniform = instr->src(i).as_uniform(); if (uniform && uniform->buf_addr()) { - record_read(uniform->buf_addr()->as_register(), LiveRangeEntry::use_unspecified); + record_read(m_block, uniform->buf_addr()->as_register(), LiveRangeEntry::use_unspecified); } } } @@ -271,13 +280,13 @@ void LiveRangeInstrVisitor::visit(TexInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; - record_write(instr->dst(), instr->all_dest_swizzle()); + record_write(NO_ALU_BLOCK, instr->dst(), instr->all_dest_swizzle()); auto src = instr->src(); - record_read(src, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, src, LiveRangeEntry::use_unspecified); if (instr->resource_offset()) - record_read(instr->resource_offset(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, instr->resource_offset(), LiveRangeEntry::use_unspecified); } void @@ -285,23 +294,24 @@ LiveRangeInstrVisitor::visit(ExportInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; auto src = instr->value(); - record_read(src, LiveRangeEntry::use_export); + record_read(NO_ALU_BLOCK, src, LiveRangeEntry::use_export); } void LiveRangeInstrVisitor::visit(FetchInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; - record_write(instr->dst(), instr->all_dest_swizzle()); + record_write(NO_ALU_BLOCK, instr->dst(), instr->all_dest_swizzle()); auto& src = instr->src(); if (src.chan() < 4) /* Channel can be 7 to disable source */ - record_read(&src, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, &src, LiveRangeEntry::use_unspecified); } void LiveRangeInstrVisitor::visit(Block *instr) { - sfn_log << SfnLog::merge << "Visit block\n"; + m_block = instr->id(); + sfn_log << SfnLog::merge << "Visit block " << m_block << "\n"; for (auto i : *instr) { i->accept(*this); if (i->end_group()) @@ -317,15 +327,15 @@ LiveRangeInstrVisitor::visit(ScratchIOInstr *instr) for (int i = 0; i < 4; ++i) { if ((1 << i) & instr->write_mask()) { if (instr->is_read()) - record_write(src[i]); + record_write(NO_ALU_BLOCK, src[i]); else - record_read(src[i], LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, src[i], LiveRangeEntry::use_unspecified); } } auto addr = instr->address(); if (addr) - record_read(addr, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, addr, LiveRangeEntry::use_unspecified); } void @@ -333,7 +343,7 @@ LiveRangeInstrVisitor::visit(StreamOutInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; auto src = instr->value(); - record_read(src, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, src, LiveRangeEntry::use_unspecified); } void @@ -341,11 +351,11 @@ LiveRangeInstrVisitor::visit(MemRingOutInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; auto src = instr->value(); - record_read(src, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, src, LiveRangeEntry::use_unspecified); auto idx = instr->export_index(); if (idx && idx->as_register()) - record_read(idx->as_register(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, idx->as_register(), LiveRangeEntry::use_unspecified); } void @@ -387,29 +397,29 @@ void LiveRangeInstrVisitor::visit(GDSInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; - record_read(instr->src(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, instr->src(), LiveRangeEntry::use_unspecified); if (instr->resource_offset()) - record_read(instr->resource_offset(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, instr->resource_offset(), LiveRangeEntry::use_unspecified); if (instr->dest()) - record_write(instr->dest()); + record_write(NO_ALU_BLOCK, instr->dest()); } void LiveRangeInstrVisitor::visit(RatInstr *instr) { sfn_log << SfnLog::merge << "Visit " << *instr << "\n"; - record_read(instr->value(), LiveRangeEntry::use_unspecified); - record_read(instr->addr(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, instr->value(), LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, instr->addr(), LiveRangeEntry::use_unspecified); auto idx = instr->resource_offset(); if (idx) - record_read(idx, LiveRangeEntry::use_unspecified); + record_read(NO_ALU_BLOCK, idx, LiveRangeEntry::use_unspecified); } void LiveRangeInstrVisitor::visit(WriteTFInstr *instr) { - record_read(instr->value(), LiveRangeEntry::use_export); + record_read(NO_ALU_BLOCK, instr->value(), LiveRangeEntry::use_export); } void @@ -427,7 +437,7 @@ LiveRangeInstrVisitor::visit(UNUSED LDSReadInstr *instr) } void -LiveRangeInstrVisitor::record_write(const Register *reg) +LiveRangeInstrVisitor::record_write(int block, const Register *reg) { if (reg->has_flag(Register::addr_or_idx)) return; @@ -436,26 +446,26 @@ LiveRangeInstrVisitor::record_write(const Register *reg) if (addr) { if (addr->as_register() && !addr->as_register()->has_flag(Register::addr_or_idx)) - record_read(addr->as_register(), LiveRangeEntry::use_unspecified); + record_read(block, addr->as_register(), LiveRangeEntry::use_unspecified); const auto av = static_cast(reg); auto& array = av->array(); - sfn_log << SfnLog::merge << array << " write:" << m_line << "\n"; + sfn_log << SfnLog::merge << array << " write:" << block << ":" << m_line << "\n"; for (auto i = 0u; i < array.size(); ++i) { auto& rav = m_register_access(array(i, reg->chan())); - rav.record_write(m_line > 0 ? m_line - 1 : 0, m_current_scope); + rav.record_write(block, m_line > 0 ? m_line - 1 : 0, m_current_scope); } } else { auto& ra = m_register_access(*reg); - sfn_log << SfnLog::merge << *reg << " write:" << m_line << "\n"; - ra.record_write(m_line, m_current_scope); + sfn_log << SfnLog::merge << *reg << " write:" << block << ":" << m_line << "\n"; + ra.record_write(block, m_line, m_current_scope); } } void -LiveRangeInstrVisitor::record_read(const Register *reg, LiveRangeEntry::EUse use) +LiveRangeInstrVisitor::record_read(int block, const Register *reg, LiveRangeEntry::EUse use) { if (!reg) return; @@ -467,21 +477,21 @@ LiveRangeInstrVisitor::record_read(const Register *reg, LiveRangeEntry::EUse use if (addr) { if (addr->as_register() && !addr->as_register()->has_flag(Register::addr_or_idx)) { auto& ra = m_register_access(*addr->as_register()); - ra.record_read(m_line, m_current_scope, use); + ra.record_read(block, m_line, m_current_scope, use); } const auto av = static_cast(reg); auto& array = av->array(); - sfn_log << SfnLog::merge << array << " read:" << m_line << "\n"; + sfn_log << SfnLog::merge << array << " read:" << block << ":" << m_line << "\n"; for (auto i = 0u; i < array.size(); ++i) { auto& rav = m_register_access(array(i, reg->chan())); - rav.record_read(m_line + 1, m_current_scope, use); + rav.record_read(block, m_line + 1, m_current_scope, use); } } else { - sfn_log << SfnLog::merge << *reg << " read:" << m_line << "\n"; + sfn_log << SfnLog::merge << *reg << " read:" << block << ":" << m_line << "\n"; auto& ra = m_register_access(*reg); - ra.record_read(m_line, m_current_scope, use); + ra.record_read(block, m_line, m_current_scope, use); } } diff --git a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.cpp b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.cpp index 7a692dd..ba4fd95 100644 --- a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.cpp @@ -289,9 +289,16 @@ RegisterCompAccess::RegisterCompAccess(): } void -RegisterCompAccess::record_read(int line, ProgramScope *scope, LiveRangeEntry::EUse use) +RegisterCompAccess::record_read(int block, int line, ProgramScope *scope, LiveRangeEntry::EUse use) { last_read_scope = scope; + + if (alu_block_id == block_id_uninitalized) { + alu_block_id = block; + } else if (alu_block_id != block) { + alu_block_id = block_id_not_unique; + } + if (use != LiveRangeEntry::use_unspecified) m_use_type.set(use); if (last_read < line) @@ -349,9 +356,14 @@ RegisterCompAccess::record_read(int line, ProgramScope *scope, LiveRangeEntry::E } void -RegisterCompAccess::record_write(int line, ProgramScope *scope) +RegisterCompAccess::record_write(int block, int line, ProgramScope *scope) { last_write = line; + if (alu_block_id == block_id_uninitalized) { + alu_block_id = block; + } else if (alu_block_id != block) { + alu_block_id = block_id_not_unique; + } if (first_write < 0) { first_write = line; diff --git a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.h b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.h index 6ff938c..f3910ff 100644 --- a/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.h +++ b/src/gallium/drivers/r600/sfn/sfn_liverangeevaluator_helpers.h @@ -94,8 +94,8 @@ public: RegisterCompAccess(); RegisterCompAccess(LiveRange range); - void record_read(int line, ProgramScope *scope, LiveRangeEntry::EUse use); - void record_write(int line, ProgramScope *scope); + void record_read(int block,int line, ProgramScope *scope, LiveRangeEntry::EUse use); + void record_write(int block, int line, ProgramScope *scope); void update_required_live_range(); @@ -103,6 +103,8 @@ public: const auto& use_type() { return m_use_type; } + auto alu_clause_local() { return alu_block_id > block_id_uninitalized;} + private: void propagate_live_range_to_dominant_write_scope(); bool conditional_ifelse_write_in_loop() const; @@ -120,8 +122,10 @@ private: int last_write; int first_read; - /* This member variable tracks the current resolution of conditional - * writing to this temporary in IF/ELSE clauses. + int alu_block_id{block_id_uninitalized}; + + /* This member variable tracks the current resolution of conditional writing + * to this temporary in IF/ELSE clauses. * * The initial value "conditionality_untouched" indicates that this * temporary has not yet been written to within an if clause. @@ -148,6 +152,8 @@ private: static const int conditionality_unresolved = 0; static const int conditionality_untouched; static const int write_is_unconditional; + static const int block_id_not_unique = -1; + static const int block_id_uninitalized = 0; /* A bit field tracking the nexting levels of if-else clauses where the * temporary has (so far) been written to in the if branch, but not in the diff --git a/src/gallium/drivers/r600/sfn/sfn_valuefactory.h b/src/gallium/drivers/r600/sfn/sfn_valuefactory.h index cc7769a..953fce7 100644 --- a/src/gallium/drivers/r600/sfn/sfn_valuefactory.h +++ b/src/gallium/drivers/r600/sfn/sfn_valuefactory.h @@ -54,6 +54,7 @@ struct LiveRangeEntry { int m_end{-1}; int m_index{-1}; int m_color{-1}; + bool m_alu_clause_local{false}; std::bitset m_use; Register *m_register; -- 2.7.4