nir: rename nir_op_fne to nir_op_fneu
[mesa.git] / src / panfrost / midgard / mir_promote_uniforms.c
index 2d7aabed49c05894f4b0f1b489b19332532b7d66..239020dd2192803a20d99f8b49ac4d838f015063 100644 (file)
@@ -43,7 +43,7 @@ mir_is_promoteable_ubo(midgard_instruction *ins)
         /* TODO: promote unaligned access via swizzle? */
 
         return (ins->type == TAG_LOAD_STORE_4) &&
-                (OP_IS_UBO_READ(ins->load_store.op)) &&
+                (OP_IS_UBO_READ(ins->op)) &&
                 !(ins->constants.u32[0] & 0xF) &&
                 !(ins->load_store.arg_1) &&
                 (ins->load_store.arg_2 == 0x1E) &&
@@ -82,8 +82,9 @@ mir_estimate_pressure(compiler_context *ctx)
 
         unsigned max_live = 0;
 
-        mir_foreach_block(ctx, block) {
-                uint16_t *live = mem_dup(block->live_out, ctx->temp_count * sizeof(uint16_t));
+        mir_foreach_block(ctx, _block) {
+                midgard_block *block = (midgard_block *) _block;
+                uint16_t *live = mem_dup(block->base.live_out, ctx->temp_count * sizeof(uint16_t));
 
                 mir_foreach_instr_in_block_rev(block, ins) {
                         unsigned count = mir_count_live(live, ctx->temp_count);
@@ -126,12 +127,46 @@ mir_work_heuristic(compiler_context *ctx)
         return 8;
 }
 
+/* Bitset of indices that will be used as a special register -- inputs to a
+ * non-ALU op. We precompute this set so that testing is efficient, otherwise
+ * we end up O(mn) behaviour for n instructions and m uniform reads */
+
+static BITSET_WORD *
+mir_special_indices(compiler_context *ctx)
+{
+        mir_compute_temp_count(ctx);
+        BITSET_WORD *bset = calloc(BITSET_WORDS(ctx->temp_count), sizeof(BITSET_WORD));
+
+        mir_foreach_instr_global(ctx, ins) {
+                /* Look for special instructions */
+                bool is_ldst = ins->type == TAG_LOAD_STORE_4;
+                bool is_tex = ins->type == TAG_TEXTURE_4;
+                bool is_writeout = ins->compact_branch && ins->writeout;
+
+                if (!(is_ldst || is_tex || is_writeout))
+                        continue;
+
+                /* Anything read by a special instruction is itself special */
+                mir_foreach_src(ins, i) {
+                        unsigned idx = ins->src[i];
+
+                        if (idx < ctx->temp_count)
+                                BITSET_SET(bset, idx);
+                }
+        }
+
+        return bset;
+}
+
 void
 midgard_promote_uniforms(compiler_context *ctx)
 {
         unsigned work_count = mir_work_heuristic(ctx);
         unsigned promoted_count = 24 - work_count;
 
+        /* First, figure out special indices a priori so we don't recompute a lot */
+        BITSET_WORD *special = mir_special_indices(ctx);
+
         mir_foreach_instr_global_safe(ctx, ins) {
                 if (!mir_is_promoteable_ubo(ins)) continue;
 
@@ -151,16 +186,18 @@ midgard_promote_uniforms(compiler_context *ctx)
                 /* We do need the move for safety for a non-SSA dest, or if
                  * we're being fed into a special class */
 
-                bool needs_move = ins->dest & IS_REG;
-                needs_move |= mir_special_index(ctx, ins->dest);
+                bool needs_move = ins->dest & PAN_IS_REG || ins->dest == ctx->blend_src1;
+
+                if (ins->dest < ctx->temp_count)
+                        needs_move |= BITSET_TEST(special, ins->dest);
 
                 if (needs_move) {
+                        unsigned type_size = nir_alu_type_get_type_size(ins->dest_type);
                         midgard_instruction mov = v_mov(promoted, ins->dest);
+                        mov.dest_type = nir_type_uint | type_size;
+                        mov.src_types[0] = mov.dest_type;
 
-                        if (ins->load_64)
-                                mov.alu.reg_mode = midgard_reg_mode_64;
-
-                        uint16_t rounded = mir_round_bytemask_up(mir_bytemask(ins), mov.alu.reg_mode);
+                        uint16_t rounded = mir_round_bytemask_up(mir_bytemask(ins), type_size);
                         mir_set_bytemask(&mov, rounded);
                         mir_insert_instruction_before(ctx, ins, mov);
                 } else {
@@ -169,4 +206,6 @@ midgard_promote_uniforms(compiler_context *ctx)
 
                 mir_remove_instruction(ins);
         }
+
+        free(special);
 }