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 \
'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',
mem_wr_scratch,
gds,
rat,
+ block,
unknown
};
--- /dev/null
+#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";
+}
+
+}
--- /dev/null
+/* -*- mesa-c++ -*-
+ *
+ * Copyright (c) 2018-2019 Collabora LTD
+ *
+ * Author: Gert Wollny <gert.wollny@collabora.com>
+ *
+ * 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
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)
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) {
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;
};
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:
+ ;
+ }
}
}
}
}
- 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);
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;
{
}
-bool AssemblyFromShader::lower(const std::vector<Instruction::Pointer>& ir)
+bool AssemblyFromShader::lower(const std::vector<InstructionBlock>& ir)
{
return do_lower(ir);
}
class Shader {
public:
- std::vector<PInstruction>& m_ir;
+ std::vector<InstructionBlock>& m_ir;
ValueMap m_temp;
};
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:
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 ;
};
}
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),
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);
}
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);
}
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()
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)
<< 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);
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());
m_pending_else = nullptr;
+ append_block(-1);
IfElseEndInstruction *ir = new IfElseEndInstruction();
emit_instruction(ir);
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
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();
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);
}
}
#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"
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;
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;