pan/midgard: Use hint on midgard_instruction for spill_move
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 13 Aug 2019 22:58:49 +0000 (15:58 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 14 Aug 2019 21:58:34 +0000 (14:58 -0700)
This allows us to have multiple spill moves, whereas otherwise for N
spill moves, the first N-1 would be clobbered. Issue found in Krita.

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

index d62157f3be4f2c605a40fad1684b2a9c2a2bba1a..cf7547ccda3e9c4ee80e66c04f8c8c6b85cbc2d3 100644 (file)
@@ -134,6 +134,9 @@ typedef struct midgard_instruction {
 
         bool no_spill;
 
+        /* Generic hint for intra-pass use */
+        bool hint;
+
         union {
                 midgard_load_store_word load_store;
                 midgard_vector_alu alu;
index 486bb38e049381b56c350158651ec0c75ac0a8c6..ce97287d199fd9e03960c03fc7e4627ca7abf25f 100644 (file)
@@ -775,7 +775,6 @@ static void mir_spill_register(
 
         /* Allocate TLS slot (maybe) */
         unsigned spill_slot = !is_special ? (*spill_count)++ : 0;
-        midgard_instruction *spill_move = NULL;
 
         /* For TLS, replace all stores to the spilled node. For
          * special reads, just keep as-is; the class will be demoted
@@ -796,7 +795,10 @@ static void mir_spill_register(
                                 st = v_load_store_scratch(ins->ssa_args.dest, spill_slot, true, ins->mask);
                         }
 
-                        spill_move = mir_insert_instruction_before(mir_next_op(ins), st);
+                        /* Hint: don't rewrite this node */
+                        st.hint = true;
+
+                        mir_insert_instruction_before(mir_next_op(ins), st);
 
                         if (!is_special)
                                 ctx->spills++;
@@ -824,8 +826,9 @@ static void mir_spill_register(
                 unsigned consecutive_index = 0;
 
                 mir_foreach_instr_in_block(block, ins) {
-                        /* We can't rewrite the move used to spill in the first place */
-                        if (ins == spill_move) continue;
+                        /* We can't rewrite the moves used to spill in the
+                         * first place. These moves are hinted. */
+                        if (ins->hint) continue;
 
                         if (!mir_has_arg(ins, spill_node)) {
                                 consecutive_skip = false;
@@ -878,6 +881,12 @@ static void mir_spill_register(
                                 ctx->fills++;
                 }
         }
+
+        /* Reset hints */
+
+        mir_foreach_instr_global(ctx, ins) {
+                ins->hint = false;
+        }
 }
 
 void