r600/sfn: Add LDS IO instructions to r600 IR
authorGert Wollny <gert.wollny@collabora.com>
Sun, 12 Apr 2020 14:56:35 +0000 (16:56 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 28 Apr 2020 08:06:33 +0000 (08:06 +0000)
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>

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_lds.cpp [new file with mode: 0644]
src/gallium/drivers/r600/sfn/sfn_instruction_lds.h [new file with mode: 0644]

index 068a41f88615632a4d0d4b8876d8516b712ac0d4..673b8a0ac4da53d197c1dce4e60311c1e252bf58 100644 (file)
@@ -118,6 +118,8 @@ CXX_SOURCES = \
        sfn/sfn_instruction_export.h \
        sfn/sfn_instruction_fetch.cpp \
        sfn/sfn_instruction_fetch.h \
+       sfn/sfn_instruction_lds.cpp \
+       sfn/sfn_instruction_lds.h \
        sfn/sfn_instruction_gds.cpp \
        sfn/sfn_instruction_gds.h \
        sfn/sfn_instruction_misc.cpp \
index 6300dcea2ffa4ca10b0e2d63a041931812937272..fe369a99dab94644602946e02b4165abccb4588f 100644 (file)
@@ -137,6 +137,8 @@ files_r600 = files(
   'sfn/sfn_instruction_fetch.h',
   'sfn/sfn_instruction_gds.cpp',
   'sfn/sfn_instruction_gds.h',
+  'sfn/sfn_instruction_lds.cpp',
+  'sfn/sfn_instruction_lds.h',
   'sfn/sfn_instruction_misc.cpp',
   'sfn/sfn_instruction_misc.h',
   'sfn/sfn_instruction_tex.cpp',
index fab47f8bf814eb73040dd2a74b86c64a983d46e4..f7042b378e2f86f0173937466c723db055fb2b67 100644 (file)
@@ -77,6 +77,8 @@ public:
       cond_if,
       cond_else,
       cond_endif,
+      lds_read,
+      lds_write,
       loop_begin,
       loop_end,
       loop_break,
diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_lds.cpp b/src/gallium/drivers/r600/sfn/sfn_instruction_lds.cpp
new file mode 100644 (file)
index 0000000..b58b615
--- /dev/null
@@ -0,0 +1,110 @@
+#include "sfn_instruction_lds.h"
+
+namespace r600 {
+
+void LDSReadInstruction::do_print(std::ostream& os) const
+{
+   os << "LDS Read  [";
+   for (unsigned i = 0; i < m_address.size(); ++i)
+      os << *m_dest_value[i] << " ";
+   os << "], ";
+   for (unsigned i = 0; i < m_address.size(); ++i)
+      os << *m_address[i] << " ";
+}
+
+LDSReadInstruction::LDSReadInstruction(std::vector<PValue>& address, std::vector<PValue>& value):
+   Instruction(lds_read),
+   m_address(address),
+   m_dest_value(value)
+{
+   assert(address.size() == value.size());
+
+   for (unsigned i = 0; i < address.size(); ++i) {
+      add_remappable_src_value(&m_address[i]);
+      add_remappable_dst_value(&m_dest_value[i]);
+   }
+}
+
+void LDSReadInstruction::replace_values(const ValueSet& candiates, PValue new_value)
+{
+   for (auto& c : candiates) {
+      for (auto& d: m_dest_value) {
+         if (*c == *d)
+            d = new_value;
+      }
+
+      for (auto& a: m_address) {
+         if (*c == *a)
+            a = new_value;
+      }
+   }
+}
+
+bool LDSReadInstruction::is_equal_to(const Instruction& lhs) const
+{
+   auto& other = static_cast<const LDSReadInstruction&>(lhs);
+   return m_address == other.m_address &&
+         m_dest_value == other.m_dest_value;
+}
+
+LDSWriteInstruction::LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0):
+   LDSWriteInstruction::LDSWriteInstruction(address, idx_offset, value0, PValue())
+
+{
+}
+
+LDSWriteInstruction::LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0, PValue value1):
+   Instruction(lds_write),
+   m_address(address),
+   m_value0(value0),
+   m_value1(value1),
+   m_idx_offset(idx_offset)
+{
+   add_remappable_src_value(&m_address);
+   add_remappable_src_value(&m_value0);
+   if (m_value1)
+      add_remappable_src_value(&m_value1);
+}
+
+
+void LDSWriteInstruction::do_print(std::ostream& os) const
+{
+   os << "LDS Write" << num_components()
+      << " " << address() << ", " << value0();
+   if (num_components() > 1)
+      os << ", " << value1();
+}
+
+void LDSWriteInstruction::replace_values(const ValueSet& candiates, PValue new_value)
+{
+   for (auto c: candiates) {
+      if (*c == *m_address)
+         m_address = new_value;
+
+      if (*c == *m_value0)
+         m_value0 = new_value;
+
+      if (*c == *m_value1)
+         m_value1 = new_value;
+   }
+}
+
+bool LDSWriteInstruction::is_equal_to(const Instruction& lhs) const
+{
+   auto& other = static_cast<const LDSWriteInstruction&>(lhs);
+
+   if (m_value1) {
+      if (!other.m_value1)
+         return false;
+      if (*m_value1 != *other.m_value1)
+         return false;
+   } else {
+      if (other.m_value1)
+         return false;
+   }
+
+   return (m_value0 != other.m_value0 &&
+           *m_address != *other.m_address);
+}
+
+} // namespace r600
diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_lds.h b/src/gallium/drivers/r600/sfn/sfn_instruction_lds.h
new file mode 100644 (file)
index 0000000..925b60e
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef LDSINSTRUCTION_H
+#define LDSINSTRUCTION_H
+
+#include "sfn_instruction_base.h"
+
+namespace r600 {
+
+class LDSReadInstruction : public Instruction {
+public:
+   LDSReadInstruction(std::vector<PValue>& value, std::vector<PValue>& address);
+   void replace_values(const ValueSet& candiates, PValue new_value) override;
+
+   unsigned num_values() const { return m_dest_value.size();}
+   const Value& address(unsigned i) const { return *m_address[i];}
+   const Value& dest(unsigned i) const { return *m_dest_value[i];}
+private:
+   void do_print(std::ostream& os) const override;
+   bool is_equal_to(const Instruction& lhs) const override;
+
+   std::vector<PValue> m_address;
+   std::vector<PValue> m_dest_value;
+};
+
+class LDSWriteInstruction : public Instruction {
+public:
+   LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0);
+   LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0, PValue value1);
+
+   const Value& address() const {return *m_address;};
+   const Value& value0() const { return *m_value0;}
+   const Value& value1() const { return *m_value1;}
+   unsigned num_components() const { return m_value1 ? 2 : 1;}
+   unsigned idx_offset() const {return m_idx_offset;};
+
+   void replace_values(const ValueSet& candiates, PValue new_value) override;
+
+private:
+   void do_print(std::ostream& os) const override;
+   bool is_equal_to(const Instruction& lhs) const override;
+
+   PValue m_address;
+   PValue m_value0;
+   PValue m_value1;
+   unsigned m_idx_offset;
+
+};
+
+}
+
+#endif // LDSINSTRUCTION_H