r600/sfn: Implementing instructions blocks
authorGert Wollny <gert.wollny@collabora.com>
Sun, 19 Jan 2020 17:09:05 +0000 (18:09 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 21 Apr 2020 15:10:43 +0000 (15:10 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4609>

12 files changed:
src/gallium/drivers/r600/Makefile.sources
src/gallium/drivers/r600/meson.build
src/gallium/drivers/r600/sfn/sfn_instruction_base.h
src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp [new file with mode: 0644]
src/gallium/drivers/r600/sfn/sfn_instruction_block.h [new file with mode: 0644]
src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.h
src/gallium/drivers/r600/sfn/sfn_liverange.cpp
src/gallium/drivers/r600/sfn/sfn_nir.cpp
src/gallium/drivers/r600/sfn/sfn_nir.h
src/gallium/drivers/r600/sfn/sfn_shader_base.cpp
src/gallium/drivers/r600/sfn/sfn_shader_base.h

index 03d1bf101612861f761ff50624d90a651ae933f4..068a41f88615632a4d0d4b8876d8516b712ac0d4 100644 (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 \
index 55d842412768ee848829770030fc048f35f950c6..6300dcea2ffa4ca10b0e2d63a041931812937272 100644 (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',
index c655de96ed512ca92bd68bef8206487e96d1583f..fab47f8bf814eb73040dd2a74b86c64a983d46e4 100644 (file)
@@ -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 (file)
index 0000000..df01fbb
--- /dev/null
@@ -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 (file)
index 0000000..f47a9e2
--- /dev/null
@@ -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
index 56a134c3e724f326753bfcedfa2044a45fc4cf84..cc20d9fbe3035e6f074a363e8d65ccd87cbbad03 100644 (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) {
index 075ea3b728af07c44749182ddd2c4e28c102c521..0c82032e6f495b8becf45c8cad2b7034915d5da8 100644 (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;
 };
index 1c95c3bc4d16cb24cab5c111ede08f619422eccd..55159233a14afe7781f87c3aa09338e441d9b0b0 100644 (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);
index 9fc272c6089a7e9cc833848d06acb71c73dd3902..a32a61465d9a4068557ee05d1c04764761227686 100644 (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);
 }
index b3cb4554f53ba7cad77ffbdfa1abef8e2de45b26..ee80d37c25a5f4417dd80d9953563517e94d8517 100644 (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 ;
 };
 
 }
index 25db8db8b162830741e1fd17a597f70fa383831a..e0aeb887083c749a64cebb973e38e9e9cf533000 100644 (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);
 }
 
 }
index 5b027329093a6f6e2eebefab14cf71413e0ddd93..1074a3f5edb7149d99547fc9535c7f4781a391ae 100644 (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;