if (is_store) {
/* r0 = r26, r1 = r27 */
assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
- ins.ssa_args.src[0] = (srcdest == SSA_FIXED_REGISTER(27)) ? SSA_FIXED_REGISTER(1) : SSA_FIXED_REGISTER(0);
+ ins.ssa_args.src[0] = srcdest;
} else {
ins.ssa_args.dest = srcdest;
}
}
}
+ /* For special reads, figure out how many components we need */
+ unsigned read_mask = 0;
+
+ mir_foreach_instr_global_safe(ctx, ins) {
+ read_mask |= mir_mask_of_read_components(ins, spill_node);
+ }
+
/* Insert a load from TLS before the first consecutive
* use of the node, rewriting to use spilled indices to
* break up the live range. Or, for special, insert a
st = v_load_store_scratch(consecutive_index, spill_slot, false, 0xF);
}
+ /* Mask the load based on the component count
+ * actually needed to prvent RA loops */
+
+ st.mask = read_mask;
+
mir_insert_instruction_before(before, st);
// consecutive_skip = true;
} else {
*/
#include "compiler.h"
+#include "util/u_math.h"
/* This pass promotes reads from uniforms from load/store ops to uniform
* registers if it is beneficial to do so. Normally, this saves both
bool needs_move = ins->ssa_args.dest & IS_REG;
needs_move |= mir_special_index(ctx, ins->ssa_args.dest);
+ /* Ensure this is a contiguous X-bound mask. It should be since
+ * we haven't done RA and per-component masked UBO reads don't
+ * make much sense. */
+
+ assert(((ins->mask + 1) & ins->mask) == 0);
+
+ /* Check the component count from the mask so we can setup a
+ * swizzle appropriately when promoting. The idea is to ensure
+ * the component count is preserved so RA can be smarter if we
+ * need to spill */
+
+ unsigned nr_components = util_bitcount(ins->mask);
+
if (needs_move) {
midgard_instruction mov = v_mov(promoted, blank_alu_src, ins->ssa_args.dest);
+ mov.mask = ins->mask;
mir_insert_instruction_before(ins, mov);
} else {
- mir_rewrite_index_src(ctx, ins->ssa_args.dest, promoted);
+ mir_rewrite_index_src_swizzle(ctx, ins->ssa_args.dest,
+ promoted, swizzle_of(nr_components));
}
mir_remove_instruction(ins);