Mesa (master): r600/sfn: C++ lower-instruct implementation

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 12 19:37:15 UTC 2021


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

Author: Gert Wollny <gert.wollny at collabora.com>
Date:   Sun Jan 10 11:34:43 2021 +0100

r600/sfn: C++ lower-instruct implementation

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

---

 src/gallium/drivers/r600/sfn/sfn_nir.cpp | 96 ++++++++++++++++++++++++++++++++
 src/gallium/drivers/r600/sfn/sfn_nir.h   | 18 ++++++
 2 files changed, 114 insertions(+)

diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.cpp b/src/gallium/drivers/r600/sfn/sfn_nir.cpp
index 8a30acd0698..5c950da988e 100644
--- a/src/gallium/drivers/r600/sfn/sfn_nir.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_nir.cpp
@@ -47,6 +47,102 @@ namespace r600 {
 
 using std::vector;
 
+
+NirLowerInstruction::NirLowerInstruction():
+	b(nullptr)
+{
+
+}
+
+bool NirLowerInstruction::run(nir_shader *shader)
+{
+   bool progress = false;
+
+   nir_metadata preserved = nir_metadata_block_index |
+                            nir_metadata_dominance;
+
+   nir_foreach_function(function, shader) {
+      if (function->impl) {
+         nir_builder builder;
+         b = &builder;
+         nir_builder_init(b, function->impl);
+         nir_foreach_block(block, function->impl) {
+            nir_foreach_instr_safe(instr, block) {
+               if (!filter(instr))
+                  continue;
+
+               nir_ssa_def *old_def = nir_instr_ssa_def(instr);
+               struct list_head old_uses, old_if_uses;
+               if (old_def != nullptr) {
+                  list_replace(&old_def->uses, &old_uses);
+                  list_inithead(&old_def->uses);
+                  list_replace(&old_def->if_uses, &old_if_uses);
+                  list_inithead(&old_def->if_uses);
+               }
+
+               b->cursor = nir_after_instr(instr);
+               nir_ssa_def *new_def = lower(instr);
+               if (new_def && new_def != progress_keep &&
+                   new_def != progress_replace) {
+                  assert(old_def != NULL);
+                  if (new_def->parent_instr->block != instr->block)
+                     preserved = nir_metadata_none;
+
+                  nir_src new_src = nir_src_for_ssa(new_def);
+                  list_for_each_entry_safe(nir_src, use_src, &old_uses, use_link)
+                        nir_instr_rewrite_src(use_src->parent_instr, use_src, new_src);
+
+                  list_for_each_entry_safe(nir_src, use_src, &old_if_uses, use_link)
+                        nir_if_rewrite_condition(use_src->parent_if, new_src);
+
+                  if (list_is_empty(&old_def->uses) &&
+                      list_is_empty(&old_def->if_uses)) {
+                     nir_instr_remove(instr);
+                  }
+                  progress = true;
+               } else {
+                  /* We didn't end up lowering after all.  Put the uses back */
+                  if (old_def) {
+                     list_replace(&old_uses, &old_def->uses);
+                     list_replace(&old_if_uses, &old_def->if_uses);
+                  }
+                  if (new_def == progress_replace) {
+                     /* Only instructions without a return value can be removed like this */
+                     assert(!old_def);
+                     nir_instr_remove(instr);
+                     progress = true;
+                  }
+
+                  if (new_def == progress_keep)
+                     progress = true;
+               }
+            }
+
+            if (progress) {
+               nir_metadata_preserve(function->impl, preserved);
+            } else {
+               nir_metadata_preserve(function->impl, nir_metadata_all);
+            }
+         }
+      }
+   }
+   return progress;
+}
+
+nir_ssa_def *NirLowerInstruction::progress_keep = (nir_ssa_def *)1;
+nir_ssa_def *NirLowerInstruction::progress_replace = (nir_ssa_def *)2;
+
+
+bool NirLowerInstruction::run(nir_instr *instr)
+{
+	bool progress = false;
+	if (filter(instr)) {
+		progress = lower(instr);
+	}
+	return progress;
+}
+
+
 ShaderFromNir::ShaderFromNir():sh(nullptr),
    chip_class(CLASS_UNKNOWN),
    m_current_if_id(0),
diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.h b/src/gallium/drivers/r600/sfn/sfn_nir.h
index 2b6f19fe58d..f3209109319 100644
--- a/src/gallium/drivers/r600/sfn/sfn_nir.h
+++ b/src/gallium/drivers/r600/sfn/sfn_nir.h
@@ -36,6 +36,24 @@
 
 namespace r600 {
 
+class NirLowerInstruction {
+public:
+	NirLowerInstruction();
+
+	bool run(nir_shader *shader);
+
+private:
+	bool run(nir_instr *instr);
+
+	virtual bool filter(const nir_instr *instr) const = 0;
+	virtual nir_ssa_def *lower(nir_instr *instr) = 0;
+protected:
+	nir_builder *b;
+
+        static nir_ssa_def *progress_keep;
+        static nir_ssa_def *progress_replace;
+};
+
 bool r600_nir_lower_pack_unpack_2x16(nir_shader *shader);
 
 bool r600_lower_scratch_addresses(nir_shader *shader);



More information about the mesa-commit mailing list