From 5e036fef1f48d9946385b7fc13ee64e613e2264d Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Sun, 19 Jan 2020 18:09:05 +0100 Subject: [PATCH] r600/sfn: Implementing instructions blocks Part-of: --- src/gallium/drivers/r600/Makefile.sources | 2 + src/gallium/drivers/r600/meson.build | 2 + .../drivers/r600/sfn/sfn_instruction_base.h | 1 + .../r600/sfn/sfn_instruction_block.cpp | 52 +++++++++++++ .../drivers/r600/sfn/sfn_instruction_block.h | 77 +++++++++++++++++++ .../drivers/r600/sfn/sfn_ir_to_assembly.cpp | 8 +- .../drivers/r600/sfn/sfn_ir_to_assembly.h | 2 +- .../drivers/r600/sfn/sfn_liverange.cpp | 31 ++++---- src/gallium/drivers/r600/sfn/sfn_nir.cpp | 4 +- src/gallium/drivers/r600/sfn/sfn_nir.h | 8 +- .../drivers/r600/sfn/sfn_shader_base.cpp | 39 +++++++--- .../drivers/r600/sfn/sfn_shader_base.h | 9 ++- 12 files changed, 199 insertions(+), 36 deletions(-) create mode 100644 src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp create mode 100644 src/gallium/drivers/r600/sfn/sfn_instruction_block.h diff --git a/src/gallium/drivers/r600/Makefile.sources b/src/gallium/drivers/r600/Makefile.sources index 03d1bf10161..068a41f8861 100644 --- a/src/gallium/drivers/r600/Makefile.sources +++ b/src/gallium/drivers/r600/Makefile.sources @@ -110,6 +110,8 @@ CXX_SOURCES = \ sfn/sfn_instruction_alu.h \ sfn/sfn_instruction_base.cpp \ sfn/sfn_instruction_base.h \ + sfn/sfn_instruction_block.cpp \ + sfn/sfn_instruction_block.h \ sfn/sfn_instruction_cf.cpp \ sfn/sfn_instruction_cf.h \ sfn/sfn_instruction_export.cpp \ diff --git a/src/gallium/drivers/r600/meson.build b/src/gallium/drivers/r600/meson.build index 55d84241276..6300dcea2ff 100644 --- a/src/gallium/drivers/r600/meson.build +++ b/src/gallium/drivers/r600/meson.build @@ -127,6 +127,8 @@ files_r600 = files( 'sfn/sfn_instruction_alu.h', 'sfn/sfn_instruction_base.cpp', 'sfn/sfn_instruction_base.h', + 'sfn/sfn_instruction_block.cpp', + 'sfn/sfn_instruction_block.h', 'sfn/sfn_instruction_cf.cpp', 'sfn/sfn_instruction_cf.h', 'sfn/sfn_instruction_export.cpp', diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_base.h b/src/gallium/drivers/r600/sfn/sfn_instruction_base.h index c655de96ed5..fab47f8bf81 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instruction_base.h +++ b/src/gallium/drivers/r600/sfn/sfn_instruction_base.h @@ -88,6 +88,7 @@ public: mem_wr_scratch, gds, rat, + block, unknown }; diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp b/src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp new file mode 100644 index 00000000000..df01fbb3e8f --- /dev/null +++ b/src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp @@ -0,0 +1,52 @@ +#include "sfn_instruction_block.h" + +namespace r600 { + + +InstructionBlock::InstructionBlock(unsigned nesting_depth, unsigned block_number): + Instruction(block), + m_block_number(block_number), + m_nesting_depth(nesting_depth) +{ +} + +void InstructionBlock::emit(PInstruction instr) +{ + m_block.push_back(instr); +} + +void InstructionBlock::remap_registers(ValueRemapper& map) +{ + for(auto& i: m_block) + i->remap_registers(map); +} + +void InstructionBlock::do_evalue_liveness(LiverangeEvaluator& eval) const +{ + for(auto& i: m_block) + i->evalue_liveness(eval); +} + +bool InstructionBlock::is_equal_to(const Instruction& lhs) const +{ + assert(lhs.type() == block); + auto& l = static_cast(lhs); + + if (m_block.size() != l.m_block.size()) + return false; + + if (m_block_number != l.m_block_number) + return false; + + return std::equal(m_block.begin(), m_block.end(), l.m_block.begin(), + [](PInstruction ri, PInstruction li) {return *ri == *li;}); +} + +void InstructionBlock::do_print(std::ostream& os) const +{ + std::string space(" ", 2 * m_nesting_depth); + for(auto& i: m_block) + os << space << *i << "\n"; +} + +} diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_block.h b/src/gallium/drivers/r600/sfn/sfn_instruction_block.h new file mode 100644 index 00000000000..f47a9e2ca92 --- /dev/null +++ b/src/gallium/drivers/r600/sfn/sfn_instruction_block.h @@ -0,0 +1,77 @@ +/* -*- mesa-c++ -*- + * + * Copyright (c) 2018-2019 Collabora LTD + * + * Author: Gert Wollny + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef sfn_instruction_block_h +#define sfn_instruction_block_h + +#include "sfn_instruction_base.h" + +namespace r600 { + +class InstructionBlock : public Instruction +{ +public: + InstructionBlock(unsigned nesting_depth, unsigned block_number); + + void emit(PInstruction instr); + + + std::vector::const_iterator begin() const { + return m_block.begin(); + } + std::vector::const_iterator end() const { + return m_block.end(); + } + + void remap_registers(ValueRemapper& map); + + size_t size() const { + return m_block.size(); + } + + const PInstruction& operator [] (int i) const { + return m_block[i]; + } + + unsigned number() const { + return m_block_number; + } + +private: + void do_evalue_liveness(LiverangeEvaluator& eval) const override; + bool is_equal_to(const Instruction& lhs) const override; + void do_print(std::ostream& os) const override; + + std::vector m_block; + + unsigned m_block_number; + unsigned m_nesting_depth; +}; + +} + +#endif // INSTRUCTIONBLOCK_H diff --git a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp index 56a134c3e72..cc20d9fbe30 100644 --- a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp @@ -102,7 +102,7 @@ AssemblyFromShaderLegacy::~AssemblyFromShaderLegacy() delete impl; } -bool AssemblyFromShaderLegacy::do_lower(const std::vector& ir) +bool AssemblyFromShaderLegacy::do_lower(const std::vector& ir) { if (impl->m_shader->processor_type == PIPE_SHADER_VERTEX && impl->m_shader->ninput > 0) @@ -111,11 +111,13 @@ bool AssemblyFromShaderLegacy::do_lower(const std::vector& std::vector exports; - for (const auto& i : ir) { - if (!impl->emit(i)) + for (const auto& block : ir) { + for (const auto& i : block) { + if (!impl->emit(i)) return false; if (i->type() != Instruction::alu) impl->reset_addr_register(); + } } /* for (const auto& i : exports) { diff --git a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h index 075ea3b728a..0c82032e6f4 100644 --- a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h +++ b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h @@ -37,7 +37,7 @@ public: AssemblyFromShaderLegacy(struct r600_shader *sh, r600_shader_key *key); ~AssemblyFromShaderLegacy() override; private: - bool do_lower(const std::vector& ir) override ; + bool do_lower(const std::vector &ir) override ; struct AssemblyFromShaderLegacyImpl *impl; }; diff --git a/src/gallium/drivers/r600/sfn/sfn_liverange.cpp b/src/gallium/drivers/r600/sfn/sfn_liverange.cpp index 1c95c3bc4d1..55159233a14 100644 --- a/src/gallium/drivers/r600/sfn/sfn_liverange.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_liverange.cpp @@ -754,14 +754,16 @@ void LiverangeEvaluator::run(const Shader& shader, sfn_log << SfnLog::merge << "have " << temp_acc.size() << " temps\n"; - for (const auto& ir: shader.m_ir) { - switch (ir->type()) { - case Instruction::cond_if: - case Instruction::cond_else: - case Instruction::loop_begin: - ++n_scopes; - default: - ; + for (const auto& block: shader.m_ir) { + for (const auto& ir: block) { + switch (ir->type()) { + case Instruction::cond_if: + case Instruction::cond_else: + case Instruction::loop_begin: + ++n_scopes; + default: + ; + } } } @@ -783,12 +785,13 @@ void LiverangeEvaluator::run(const Shader& shader, } } - for (const auto& ir: shader.m_ir) { - ir->evalue_liveness(*this); - if (ir->type() != Instruction::alu || - static_cast(*ir).flag(alu_last_instr)) - ++line; - } + for (const auto& block: shader.m_ir) + for (const auto& ir: block) { + ir->evalue_liveness(*this); + if (ir->type() != Instruction::alu || + static_cast(*ir).flag(alu_last_instr)) + ++line; + } assert(cur_scope->type() == outer_scope); cur_scope->set_end(line); diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.cpp b/src/gallium/drivers/r600/sfn/sfn_nir.cpp index 9fc272c6089..a32a61465d9 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir.cpp @@ -290,7 +290,7 @@ bool ShaderFromNir::process_declaration() return true; } -const std::vector& ShaderFromNir::shader_ir() const +const std::vector& ShaderFromNir::shader_ir() const { assert(impl); return impl->m_output; @@ -301,7 +301,7 @@ AssemblyFromShader::~AssemblyFromShader() { } -bool AssemblyFromShader::lower(const std::vector& ir) +bool AssemblyFromShader::lower(const std::vector& ir) { return do_lower(ir); } diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.h b/src/gallium/drivers/r600/sfn/sfn_nir.h index b3cb4554f53..ee80d37c25a 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.h +++ b/src/gallium/drivers/r600/sfn/sfn_nir.h @@ -43,7 +43,7 @@ bool r600_lower_ubo_to_align16(nir_shader *shader); class Shader { public: - std::vector& m_ir; + std::vector& m_ir; ValueMap m_temp; }; @@ -64,7 +64,7 @@ public: bool emit_instruction(nir_instr *instr); - const std::vector& shader_ir() const; + const std::vector &shader_ir() const; Shader shader() const; private: @@ -87,9 +87,9 @@ private: class AssemblyFromShader { public: virtual ~AssemblyFromShader(); - bool lower(const std::vector& ir); + bool lower(const std::vector &ir); private: - virtual bool do_lower(const std::vector& ir) = 0 ; + virtual bool do_lower(const std::vector& ir) = 0 ; }; } diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp index 25db8db8b16..e0aeb887083 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp @@ -59,6 +59,9 @@ ShaderFromNirProcessor::ShaderFromNirProcessor(pipe_shader_type ptype, r600_pipe_shader_selector& sel, r600_shader &sh_info, int scratch_size): m_processor_type(ptype), + m_nesting_depth(0), + m_block_number(0), + m_export_output(0, -1), m_sh_info(sh_info), m_tex_instr(*this), m_alu_instr(*this), @@ -135,10 +138,9 @@ void ShaderFromNirProcessor::remap_registers() if (register_map[i].valid) sfn_log << SfnLog::merge << "Map:" << i << " -> " << register_map[i].new_reg << "\n"; - ValueRemapper vmap0(register_map, temp_register_map); - for (auto ir: m_output) - ir->remap_registers(vmap0); + for (auto& block: m_output) + block.remap_registers(vmap0); remap_shader_info(m_sh_info, register_map, temp_register_map); @@ -159,8 +161,8 @@ void ShaderFromNirProcessor::remap_registers() } ValueRemapper vmap1(register_map, temp_register_map); - for (auto ir: m_output) - ir->remap_registers(vmap1); + for (auto& ir: m_output) + ir.remap_registers(vmap1); remap_shader_info(m_sh_info, register_map, temp_register_map); } @@ -280,12 +282,17 @@ bool ShaderFromNirProcessor::emit_tex_instruction(nir_instr* instr) void ShaderFromNirProcessor::emit_instruction(Instruction *ir) { if (m_pending_else) { - m_output.push_back(PInstruction(m_pending_else)); + append_block(-1); + m_output.back().emit(PInstruction(m_pending_else)); + append_block(1); m_pending_else = nullptr; } r600::sfn_log << SfnLog::instr << " as '" << *ir << "'\n"; - m_output.push_back(Instruction::Pointer(ir)); + if (m_output.empty()) + append_block(0); + + m_output.back().emit(Instruction::Pointer(ir)); } void ShaderFromNirProcessor::emit_shader_start() @@ -330,6 +337,7 @@ bool ShaderFromNirProcessor::emit_loop_start(int loop_id) LoopBeginInstruction *loop = new LoopBeginInstruction(); emit_instruction(loop); m_loop_begin_block_map[loop_id] = loop; + append_block(1); return true; } bool ShaderFromNirProcessor::emit_loop_end(int loop_id) @@ -340,6 +348,9 @@ bool ShaderFromNirProcessor::emit_loop_end(int loop_id) << loop_id << " not found\n"; return false; } + m_nesting_depth--; + m_block_number++; + m_output.push_back(InstructionBlock(m_nesting_depth, m_block_number)); LoopEndInstruction *loop = new LoopEndInstruction(start->second); emit_instruction(loop); @@ -357,6 +368,8 @@ bool ShaderFromNirProcessor::emit_if_start(int if_id, nir_if *if_stmt) pred->set_flag(alu_update_pred); pred->set_cf_type(cf_alu_push_before); + append_block(1); + IfInstruction *ir = new IfInstruction(pred); emit_instruction(ir); assert(m_if_block_start_map.find(if_id) == m_if_block_start_map.end()); @@ -401,6 +414,7 @@ bool ShaderFromNirProcessor::emit_ifelse_end(int if_id) m_pending_else = nullptr; + append_block(-1); IfElseEndInstruction *ir = new IfElseEndInstruction(); emit_instruction(ir); @@ -860,7 +874,7 @@ void ShaderFromNirProcessor::add_param_output_reg(int loc, const GPRVector *gpr) void ShaderFromNirProcessor::emit_export_instruction(WriteoutInstruction *ir) { r600::sfn_log << SfnLog::instr << " as '" << *ir << "'\n"; - m_export_output.push_back(PInstruction(ir)); + m_export_output.emit(PInstruction(ir)); } const GPRVector * ShaderFromNirProcessor::output_register(unsigned location) const @@ -884,6 +898,12 @@ void ShaderFromNirProcessor::set_output(unsigned pos, PValue var) m_outputs[pos] = var; } +void ShaderFromNirProcessor::append_block(int nesting_change) +{ + m_nesting_depth += nesting_change; + m_output.push_back(InstructionBlock(m_nesting_depth, m_block_number++)); +} + void ShaderFromNirProcessor::finalize() { do_finalize(); @@ -894,8 +914,7 @@ void ShaderFromNirProcessor::finalize() for (auto& i : m_outputs) m_sh_info.output[i.first].gpr = i.second->sel(); - m_output.insert(m_output.end(), m_export_output.begin(), m_export_output.end()); - m_export_output.clear(); + m_output.push_back(m_export_output); } } diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_base.h b/src/gallium/drivers/r600/sfn/sfn_shader_base.h index 5b027329093..1074a3f5edb 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_base.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader_base.h @@ -33,6 +33,7 @@ #include "compiler/nir/nir.h" #include "compiler/nir_types.h" +#include "sfn_instruction_block.h" #include "sfn_instruction_export.h" #include "sfn_alu_defines.h" #include "sfn_valuepool.h" @@ -141,6 +142,8 @@ private: void add_array_deref(nir_deref_instr* instr); + void append_block(int nesting_change); + virtual void emit_shader_start(); virtual bool emit_deref_instruction_override(nir_deref_instr* instr); virtual bool do_process_inputs(nir_variable *input) = 0; @@ -169,8 +172,10 @@ private: pipe_shader_type m_processor_type; - std::vector m_output; - std::vector m_export_output; + std::vector m_output; + unsigned m_nesting_depth; + unsigned m_block_number; + InstructionBlock m_export_output; r600_shader& m_sh_info; EmitTexInstruction m_tex_instr; -- 2.30.2