aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2020-01-19 18:09:05 +0100
committerMarge Bot <[email protected]>2020-04-21 15:10:43 +0000
commit5e036fef1f48d9946385b7fc13ee64e613e2264d (patch)
treeadea54e09172f29c0b81053e6644251c62105863 /src
parentb51ced7306ea18df1c5ded700608f01db4f01e6d (diff)
r600/sfn: Implementing instructions blocks
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4609>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r600/Makefile.sources2
-rw-r--r--src/gallium/drivers/r600/meson.build2
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_instruction_base.h1
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp52
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_instruction_block.h77
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp8
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h2
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_liverange.cpp31
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_nir.cpp4
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_nir.h8
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_shader_base.cpp39
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_shader_base.h9
12 files changed, 199 insertions, 36 deletions
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<const InstructionBlock&>(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 <[email protected]>
+ *
+ * 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<PInstruction>::const_iterator begin() const {
+ return m_block.begin();
+ }
+ std::vector<PInstruction>::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<PInstruction> 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<Instruction::Pointer>& ir)
+bool AssemblyFromShaderLegacy::do_lower(const std::vector<InstructionBlock>& 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<Instruction::Pointer>&
std::vector<Instruction::Pointer> 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<Instruction::Pointer>& ir) override ;
+ bool do_lower(const std::vector<InstructionBlock> &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<const AluInstruction&>(*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<const AluInstruction&>(*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<Instruction::Pointer>& ShaderFromNir::shader_ir() const
+const std::vector<InstructionBlock>& ShaderFromNir::shader_ir() const
{
assert(impl);
return impl->m_output;
@@ -301,7 +301,7 @@ AssemblyFromShader::~AssemblyFromShader()
{
}
-bool AssemblyFromShader::lower(const std::vector<Instruction::Pointer>& ir)
+bool AssemblyFromShader::lower(const std::vector<InstructionBlock>& 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<PInstruction>& m_ir;
+ std::vector<InstructionBlock>& m_ir;
ValueMap m_temp;
};
@@ -64,7 +64,7 @@ public:
bool emit_instruction(nir_instr *instr);
- const std::vector<Instruction::Pointer>& shader_ir() const;
+ const std::vector<InstructionBlock> &shader_ir() const;
Shader shader() const;
private:
@@ -87,9 +87,9 @@ private:
class AssemblyFromShader {
public:
virtual ~AssemblyFromShader();
- bool lower(const std::vector<Instruction::Pointer>& ir);
+ bool lower(const std::vector<InstructionBlock> &ir);
private:
- virtual bool do_lower(const std::vector<Instruction::Pointer>& ir) = 0 ;
+ virtual bool do_lower(const std::vector<InstructionBlock>& 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<PInstruction> m_output;
- std::vector<PInstruction> m_export_output;
+ std::vector<InstructionBlock> m_output;
+ unsigned m_nesting_depth;
+ unsigned m_block_number;
+ InstructionBlock m_export_output;
r600_shader& m_sh_info;
EmitTexInstruction m_tex_instr;