From b9d175bed260995affc4aea0b511f8b1f0c1440d Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Sun, 12 Apr 2020 16:56:35 +0200 Subject: [PATCH] r600/sfn: Add LDS IO instructions to r600 IR Signed-off-by: Gert Wollny Part-of: --- 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 ++++++++++++++++++ .../drivers/r600/sfn/sfn_instruction_lds.h | 50 ++++++++ 5 files changed, 166 insertions(+) create mode 100644 src/gallium/drivers/r600/sfn/sfn_instruction_lds.cpp create mode 100644 src/gallium/drivers/r600/sfn/sfn_instruction_lds.h 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& address, std::vector& 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(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(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& value, std::vector& 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 m_address; + std::vector 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 -- 2.30.2