r600/sfn: Implementing instructions blocks

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4609>
This commit is contained in:
Gert Wollny 2020-01-19 18:09:05 +01:00 committed by Marge Bot
parent b51ced7306
commit 5e036fef1f
12 changed files with 199 additions and 36 deletions

View file

@ -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 \

View file

@ -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',

View file

@ -88,6 +88,7 @@ public:
mem_wr_scratch,
gds,
rat,
block,
unknown
};

View file

@ -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";
}
}

View file

@ -0,0 +1,77 @@
/* -*- 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

View file

@ -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) {

View file

@ -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;
};

View file

@ -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);

View file

@ -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);
}

View file

@ -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 ;
};
}

View file

@ -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);
}
}

View file

@ -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;