Module: Mesa
Branch: main
Commit: 66500c28d257edf72b41422b3e12376f78e8ff00
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=66500c28d257edf72b41422b3e12376f78e8ff00

Author: Simon Perretta <[email protected]>
Date:   Fri Feb 17 17:29:08 2023 +0000

pvr: Add late op lowering pass and conditional execution

Signed-off-by: Simon Perretta <[email protected]>
Acked-by: Frank Binns <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>

---

 src/imagination/rogue/meson.build                  |   1 +
 .../rogue/passes/rogue_lower_late_ops.c            | 101 +++++++++++++++++++++
 .../rogue/passes/rogue_schedule_instr_groups.c     |  14 ++-
 src/imagination/rogue/rogue.c                      |   1 +
 src/imagination/rogue/rogue.h                      |   2 +
 src/imagination/rogue/rogue_compile.c              |   1 +
 6 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/src/imagination/rogue/meson.build 
b/src/imagination/rogue/meson.build
index 855f0295fae..bb10220bcf4 100644
--- a/src/imagination/rogue/meson.build
+++ b/src/imagination/rogue/meson.build
@@ -44,6 +44,7 @@ libpowervr_rogue_files = files(
   'passes/rogue_constreg.c',
   'passes/rogue_copy_prop.c',
   'passes/rogue_dce.c',
+  'passes/rogue_lower_late_ops.c',
   'passes/rogue_lower_pseudo_ops.c',
   'passes/rogue_regalloc.c',
   'passes/rogue_schedule_instr_groups.c',
diff --git a/src/imagination/rogue/passes/rogue_lower_late_ops.c 
b/src/imagination/rogue/passes/rogue_lower_late_ops.c
new file mode 100644
index 00000000000..833d1d26061
--- /dev/null
+++ b/src/imagination/rogue/passes/rogue_lower_late_ops.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2023 Imagination Technologies Ltd.
+ *
+ * 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 the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include "rogue.h"
+#include "rogue_builder.h"
+#include "util/macros.h"
+
+#include <stdbool.h>
+
+/**
+ * \file rogue_lower_late_ops.c
+ *
+ * \brief Contains the rogue_lower_late_ops pass.
+ */
+
+/* TODO NEXT!: Check if registers are being written to that require special
+ * behaviour, like vertex out.
+ */
+/* TODO NEXT!: Make sure that SSA regs aren't being used, late passes must
+ * happen after SSA.
+ */
+static inline bool rogue_lower_CMOV(rogue_builder *b, rogue_alu_instr *cmov)
+{
+   rogue_instr *instr_true =
+      &rogue_MBYP(b, cmov->dst[0].ref, cmov->src[1].ref)->instr;
+   rogue_instr *instr_false =
+      &rogue_MBYP(b, cmov->dst[0].ref, cmov->src[2].ref)->instr;
+
+   rogue_set_instr_exec_cond(instr_true, ROGUE_EXEC_COND_P0_TRUE);
+   rogue_set_instr_exec_cond(instr_false, ROGUE_EXEC_COND_P0_FALSE);
+
+   rogue_merge_instr_comment(instr_true, &cmov->instr, "cmov (true)");
+   rogue_merge_instr_comment(instr_false, &cmov->instr, "cmov (false)");
+
+   rogue_instr_delete(&cmov->instr);
+
+   return true;
+}
+
+static inline bool rogue_lower_alu_instr(rogue_builder *b, rogue_alu_instr 
*alu)
+{
+   switch (alu->op) {
+   case ROGUE_ALU_OP_CMOV:
+      return rogue_lower_CMOV(b, alu);
+
+   default:
+      break;
+   }
+
+   return false;
+}
+
+PUBLIC
+bool rogue_lower_late_ops(rogue_shader *shader)
+{
+   if (shader->is_grouped)
+      return false;
+
+   bool progress = false;
+
+   rogue_builder b;
+   rogue_builder_init(&b, shader);
+
+   rogue_foreach_instr_in_shader_safe (instr, shader) {
+      /* Skip real ops. */
+      if (rogue_instr_supported_phases(instr))
+         continue;
+
+      b.cursor = rogue_cursor_before_instr(instr);
+      switch (instr->type) {
+      case ROGUE_INSTR_TYPE_ALU:
+         progress |= rogue_lower_alu_instr(&b, rogue_instr_as_alu(instr));
+         break;
+
+      default:
+         continue;
+      }
+   }
+
+   return progress;
+}
diff --git a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c 
b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
index 77719c77f52..c4fb63da73f 100644
--- a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
+++ b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
@@ -287,9 +287,13 @@ static inline void rogue_instr_group_put(rogue_instr 
*instr,
    /* Set end flag. */
    group->header.end = instr->end;
 
+   /* Ensure we're not mixing and matching execution conditions! */
+   assert(group->header.exec_cond == ROGUE_EXEC_COND_INVALID ||
+          group->header.exec_cond == instr->exec_cond);
+
    /* Set conditional execution flag. */
-   /* TODO: Set this from the instruction. */
-   group->header.exec_cond = ROGUE_EXEC_COND_PE_TRUE;
+   group->header.exec_cond = instr->exec_cond;
+   instr->exec_cond = ROGUE_EXEC_COND_INVALID;
 
    /* Lower I/O to sources/destinations/ISS. */
    rogue_lower_instr_group_io(instr, group);
@@ -366,8 +370,10 @@ static void rogue_calc_dsts_size(rogue_instr_group *group)
 {
    const rogue_instr_group_io_sel *io_sel = &group->io_sel;
 
-   unsigned num_dsts = !rogue_ref_is_null(&io_sel->dsts[0]) +
-                       !rogue_ref_is_null(&io_sel->dsts[1]);
+   unsigned num_dsts = (!rogue_ref_is_null(&io_sel->dsts[0]) &&
+                        !rogue_ref_is_io_none(&io_sel->dsts[0])) +
+                       (!rogue_ref_is_null(&io_sel->dsts[1]) &&
+                        !rogue_ref_is_io_none(&io_sel->dsts[1]));
    unsigned bank_bits[ROGUE_ISA_DSTS] = { 0 };
    unsigned index_bits[ROGUE_ISA_DSTS] = { 0 };
 
diff --git a/src/imagination/rogue/rogue.c b/src/imagination/rogue/rogue.c
index c3563f39ce4..9e5c54da108 100644
--- a/src/imagination/rogue/rogue.c
+++ b/src/imagination/rogue/rogue.c
@@ -632,6 +632,7 @@ static inline void rogue_instr_init(rogue_instr *instr,
                                     rogue_block *block)
 {
    instr->type = type;
+   instr->exec_cond = ROGUE_EXEC_COND_PE_TRUE;
    instr->repeat = 1;
    instr->index = block->shader->next_instr++;
    instr->block = block;
diff --git a/src/imagination/rogue/rogue.h b/src/imagination/rogue/rogue.h
index d66be6cee0b..e9b22c153b6 100644
--- a/src/imagination/rogue/rogue.h
+++ b/src/imagination/rogue/rogue.h
@@ -2738,6 +2738,8 @@ bool rogue_copy_prop(rogue_shader *shader);
 
 bool rogue_dce(rogue_shader *shader);
 
+bool rogue_lower_late_ops(rogue_shader *shader);
+
 bool rogue_lower_pseudo_ops(rogue_shader *shader);
 
 bool rogue_regalloc(rogue_shader *shader);
diff --git a/src/imagination/rogue/rogue_compile.c 
b/src/imagination/rogue/rogue_compile.c
index f6bdf5c4f39..1beeccb128a 100644
--- a/src/imagination/rogue/rogue_compile.c
+++ b/src/imagination/rogue/rogue_compile.c
@@ -806,6 +806,7 @@ void rogue_shader_passes(rogue_shader *shader)
    ROGUE_PASS_V(shader, rogue_schedule_uvsw, false);
    ROGUE_PASS_V(shader, rogue_trim);
    ROGUE_PASS_V(shader, rogue_regalloc);
+   ROGUE_PASS_V(shader, rogue_lower_late_ops);
    ROGUE_PASS_V(shader, rogue_dce);
    ROGUE_PASS_V(shader, rogue_schedule_instr_groups, false);
 

Reply via email to