Mesa (master): ir3: Set up full/half register conflicts correctly

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jan 10 00:08:26 UTC 2020


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

Author: Kristian H. Kristensen <hoegsberg at google.com>
Date:   Thu Jan  9 09:37:35 2020 -0800

ir3: Set up full/half register conflicts correctly

Setting up transitive conflicts between a full register and its two
half registers (eg r0.x and hr0.x and hr0.y) will make the half
registers conflict.  They don't actually conflict and this prevents us
from using both at the same time.

Add and use a new ra helper that sets up transitive conflicts between
a register and its subregisters, except it carefully avoids the
subregister conflict.

Signed-off-by: Kristian H. Kristensen <hoegsberg at google.com>
Reviewed-by: Rob Clark <robdclark at chromium.org>

---

 src/freedreno/ir3/ir3_ra.c   |  3 +--
 src/util/register_allocate.c | 25 +++++++++++++++++++++++++
 src/util/register_allocate.h |  5 +++++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c
index 9f0d71f9f4e..789c08f42ed 100644
--- a/src/freedreno/ir3/ir3_ra.c
+++ b/src/freedreno/ir3/ir3_ra.c
@@ -297,8 +297,7 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler)
 				unsigned hreg0 = set->gpr_to_ra_reg[i + HALF_OFFSET][(j * 2) + 0];
 				unsigned hreg1 = set->gpr_to_ra_reg[i + HALF_OFFSET][(j * 2) + 1];
 
-				ra_add_transitive_reg_conflict(set->regs, freg, hreg0);
-				ra_add_transitive_reg_conflict(set->regs, freg, hreg1);
+				ra_add_transitive_reg_pair_conflict(set->regs, freg, hreg0, hreg1);
 			}
 		}
 
diff --git a/src/util/register_allocate.c b/src/util/register_allocate.c
index b23bb377292..35273630459 100644
--- a/src/util/register_allocate.c
+++ b/src/util/register_allocate.c
@@ -304,6 +304,31 @@ ra_add_transitive_reg_conflict(struct ra_regs *regs,
    }
 }
 
+/**
+ * Set up conflicts between base_reg and it's two half registers reg0 and
+ * reg1, but take care to not add conflicts between reg0 and reg1.
+ *
+ * This is useful for architectures where full size registers are aliased by
+ * two half size registers (eg 32 bit float and 16 bit float registers).
+ */
+void
+ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
+                                    unsigned int base_reg, unsigned int reg0, unsigned int reg1)
+{
+   unsigned int i;
+
+   ra_add_reg_conflict(regs, reg0, base_reg);
+   ra_add_reg_conflict(regs, reg1, base_reg);
+
+   for (i = 0; i < regs->regs[base_reg].num_conflicts; i++) {
+      unsigned int conflict = regs->regs[base_reg].conflict_list[i];
+      if (conflict != reg1)
+         ra_add_reg_conflict(regs, reg0, regs->regs[base_reg].conflict_list[i]);
+      if (conflict != reg0)
+         ra_add_reg_conflict(regs, reg1, regs->regs[base_reg].conflict_list[i]);
+   }
+}
+
 /**
  * Makes every conflict on the given register transitive.  In other words,
  * every register that conflicts with r will now conflict with every other
diff --git a/src/util/register_allocate.h b/src/util/register_allocate.h
index 2cb57a1f0be..fcd4d9394e0 100644
--- a/src/util/register_allocate.h
+++ b/src/util/register_allocate.h
@@ -55,6 +55,11 @@ void ra_add_reg_conflict(struct ra_regs *regs,
                          unsigned int r1, unsigned int r2);
 void ra_add_transitive_reg_conflict(struct ra_regs *regs,
                                     unsigned int base_reg, unsigned int reg);
+
+void
+ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
+                                    unsigned int base_reg, unsigned int reg0, unsigned int reg1);
+
 void ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int reg);
 void ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int reg);
 void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a,




More information about the mesa-commit mailing list