Mesa (master): r600/sfn: Add LDS IO instructions to r600 IR

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 28 08:17:40 UTC 2020


Module: Mesa
Branch: master
Commit: b9d175bed260995affc4aea0b511f8b1f0c1440d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b9d175bed260995affc4aea0b511f8b1f0c1440d

Author: Gert Wollny <gert.wollny at collabora.com>
Date:   Sun Apr 12 16:56:35 2020 +0200

r600/sfn: Add LDS IO instructions to r600 IR

Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>

---

 src/gallium/drivers/r600/Makefile.sources          |   2 +
 src/gallium/drivers/r600/meson.build               |   2 +
 .../drivers/r600/sfn/sfn_instruction_base.h        |   2 +
 .../drivers/r600/sfn/sfn_instruction_lds.cpp       | 110 +++++++++++++++++++++
 src/gallium/drivers/r600/sfn/sfn_instruction_lds.h |  50 ++++++++++
 5 files changed, 166 insertions(+)

diff --git a/src/gallium/drivers/r600/Makefile.sources b/src/gallium/drivers/r600/Makefile.sources
index 068a41f8861..673b8a0ac4d 100644
--- a/src/gallium/drivers/r600/Makefile.sources
+++ b/src/gallium/drivers/r600/Makefile.sources
@@ -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 \
diff --git a/src/gallium/drivers/r600/meson.build b/src/gallium/drivers/r600/meson.build
index 6300dcea2ff..fe369a99dab 100644
--- a/src/gallium/drivers/r600/meson.build
+++ b/src/gallium/drivers/r600/meson.build
@@ -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',
diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_base.h b/src/gallium/drivers/r600/sfn/sfn_instruction_base.h
index fab47f8bf81..f7042b378e2 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instruction_base.h
+++ b/src/gallium/drivers/r600/sfn/sfn_instruction_base.h
@@ -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
index 00000000000..b58b6156725
--- /dev/null
+++ b/src/gallium/drivers/r600/sfn/sfn_instruction_lds.cpp
@@ -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
index 00000000000..925b60ecc35
--- /dev/null
+++ b/src/gallium/drivers/r600/sfn/sfn_instruction_lds.h
@@ -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



More information about the mesa-commit mailing list