pan/midgard: Use no_spill bitmask
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 6 Dec 2019 20:17:44 +0000 (15:17 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 12 Dec 2019 16:42:07 +0000 (11:42 -0500)
We would like no_spill decisions to be class-specific -- spilling from
special register to a work register doesn't preclude also spilling that
work register to stack.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/midgard_ra.c

index a6facae4422839071b1d32169f45d3edabea84ee..faeecf0150c7cdfa375417b2d2750563e0e2fc89 100644 (file)
@@ -127,9 +127,10 @@ typedef struct midgard_instruction {
         bool invert;
 
         /* Hint for the register allocator not to spill the destination written
-         * from this instruction (because it is a spill/unspill node itself) */
+         * from this instruction (because it is a spill/unspill node itself).
+         * Bitmask of spilled classes */
 
-        bool no_spill;
+        unsigned no_spill;
 
         /* Generic hint for intra-pass use */
         bool hint;
@@ -565,6 +566,14 @@ v_mov(unsigned src, unsigned dest)
         return ins;
 }
 
+/* Broad types of register classes so we can handle special
+ * registers */
+
+#define REG_CLASS_WORK          0
+#define REG_CLASS_LDST          1
+#define REG_CLASS_TEXR          3
+#define REG_CLASS_TEXW          4
+
 /* Like a move, but to thread local storage! */
 
 static inline midgard_instruction
@@ -592,7 +601,7 @@ v_load_store_scratch(
                 },
 
                 /* If we spill an unspill, RA goes into an infinite loop */
-                .no_spill = true
+                .no_spill = (1 << REG_CLASS_WORK)
         };
 
         ins.constants[0] = byte;
@@ -631,14 +640,6 @@ mir_has_arg(midgard_instruction *ins, unsigned arg)
 
 void schedule_program(compiler_context *ctx);
 
-/* Broad types of register classes so we can handle special
- * registers */
-
-#define REG_CLASS_WORK          0
-#define REG_CLASS_LDST          1
-#define REG_CLASS_TEXR          3
-#define REG_CLASS_TEXW          4
-
 void mir_ra(compiler_context *ctx);
 void mir_squeeze_index(compiler_context *ctx);
 void mir_lower_special_reads(compiler_context *ctx);
index d5cfd6214a25c1f4ea1eb633e925b9ff770c098a..9749ebb9ceba0566e1aa0d04c84e17ce3bf852f2 100644 (file)
@@ -688,7 +688,7 @@ mir_choose_spill_node(
         /* We can't spill a previously spilled value or an unspill */
 
         mir_foreach_instr_global(ctx, ins) {
-                if (ins->no_spill) {
+                if (ins->no_spill & (1 << l->spill_class)) {
                         lcra_set_node_spill_cost(l, ins->dest, -1);
 
                         mir_foreach_src(ins, s)
@@ -736,10 +736,10 @@ mir_spill_register(
 
                         if (is_special_w) {
                                 st = v_mov(spill_node, spill_slot);
-                                st.no_spill = true;
+                                st.no_spill |= (1 << spill_class);
                         } else {
                                 ins->dest = spill_index++;
-                                ins->no_spill = true;
+                                ins->no_spill |= (1 << spill_class);
                                 st = v_load_store_scratch(ins->dest, spill_slot, true, ins->mask);
                         }
 
@@ -790,7 +790,7 @@ mir_spill_register(
                                 if (is_special) {
                                         /* Move */
                                         st = v_mov(spill_node, index);
-                                        st.no_spill = true;
+                                        st.no_spill |= (1 << spill_class);
                                 } else {
                                         /* TLS load */
                                         st = v_load_store_scratch(index, spill_slot, false, 0xF);