panfrost: introduce LDST_ATOMIC property
[mesa.git] / src / panfrost / midgard / midgard_opt_dce.c
index f55db21cef268ce3d6f0c87f1874e886f855fc59..da3f0b7b5f05a1ffefc276cfc5492a5993ad87a9 100644 (file)
@@ -36,8 +36,11 @@ can_cull_mask(compiler_context *ctx, midgard_instruction *ins)
         if (ins->dest >= ctx->temp_count)
                 return false;
 
+        if (ins->dest == ctx->blend_src1)
+                return false;
+
         if (ins->type == TAG_LOAD_STORE_4)
-                if (load_store_opcode_props[ins->load_store.op].props & LDST_SPECIAL_MASK)
+                if (load_store_opcode_props[ins->op].props & LDST_SPECIAL_MASK)
                         return false;
 
         return true;
@@ -53,33 +56,35 @@ can_dce(midgard_instruction *ins)
                 return false;
 
         if (ins->type == TAG_LOAD_STORE_4)
-                if (load_store_opcode_props[ins->load_store.op].props & LDST_SIDE_FX)
+                if (load_store_opcode_props[ins->op].props & LDST_SIDE_FX)
                         return false;
 
         if (ins->type == TAG_TEXTURE_4)
-                if (ins->texture.op == TEXTURE_OP_BARRIER)
+                if (ins->op == TEXTURE_OP_BARRIER)
                         return false;
 
         return true;
 }
 
-bool
-midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
+static bool
+midgard_opt_dead_code_eliminate_block(compiler_context *ctx, midgard_block *block)
 {
         bool progress = false;
 
-        mir_invalidate_liveness(ctx);
-        mir_compute_liveness(ctx);
-
-        uint16_t *live = mem_dup(block->live_out, ctx->temp_count * sizeof(uint16_t));
+        uint16_t *live = mem_dup(block->base.live_out, ctx->temp_count * sizeof(uint16_t));
 
         mir_foreach_instr_in_block_rev(block, ins) {
                 if (can_cull_mask(ctx, ins)) {
-                        midgard_reg_mode mode = mir_typesize(ins);
+                        unsigned type_size = nir_alu_type_get_type_size(ins->dest_type);
+                        unsigned round_size = type_size;
                         unsigned oldmask = ins->mask;
 
-                        unsigned rounded = mir_round_bytemask_up(live[ins->dest], mode);
-                        unsigned cmask = mir_from_bytemask(rounded, mode);
+                        /* Make sure we're packable */
+                        if (type_size == 16 && ins->type == TAG_LOAD_STORE_4)
+                                round_size = 32;
+
+                        unsigned rounded = mir_round_bytemask_up(live[ins->dest], round_size);
+                        unsigned cmask = mir_from_bytemask(rounded, type_size);
 
                         ins->mask &= cmask;
                         progress |= (ins->mask != oldmask);
@@ -100,6 +105,27 @@ midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
         return progress;
 }
 
+bool
+midgard_opt_dead_code_eliminate(compiler_context *ctx)
+{
+        /* We track liveness. In fact, it's ok if we assume more things are
+         * live than they actually are, that just reduces the effectiveness of
+         * this iterations lightly. And DCE has the effect of strictly reducing
+         * liveness, so we can run DCE across all blocks while only computing
+         * liveness at the beginning. */
+
+        mir_invalidate_liveness(ctx);
+        mir_compute_liveness(ctx);
+
+        bool progress = false;
+
+        mir_foreach_block(ctx, block) {
+                progress |= midgard_opt_dead_code_eliminate_block(ctx, (midgard_block *) block);
+        }
+
+        return progress;
+}
+
 /* Removes dead moves, that is, moves with a destination overwritten before
  * being read. Normally handled implicitly as part of DCE, but this has to run
  * after the out-of-SSA pass */
@@ -112,7 +138,7 @@ midgard_opt_dead_move_eliminate(compiler_context *ctx, midgard_block *block)
         mir_foreach_instr_in_block_safe(block, ins) {
                 if (ins->type != TAG_ALU_4) continue;
                 if (ins->compact_branch) continue;
-                if (!OP_IS_MOVE(ins->alu.op)) continue;
+                if (!OP_IS_MOVE(ins->op)) continue;
 
                 /* Check if it's overwritten in this block before being read */
                 bool overwritten = false;