X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fpanfrost%2Fmidgard%2Fmir.c;h=2d100728724fdf7be659951b593c4f559510d253;hb=159abd527ec191e8274876162b30079c4ea39600;hp=93262f4b13f7beb4a9e6da5f8c53504823fc7a5e;hpb=eedd6c1dd0040c0a3573000003730a8a3f2e4b78;p=mesa.git diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c index 93262f4b13f..2d100728724 100644 --- a/src/panfrost/midgard/mir.c +++ b/src/panfrost/midgard/mir.c @@ -65,6 +65,20 @@ mir_rewrite_index_dst(compiler_context *ctx, unsigned old, unsigned new) } } +void +mir_rewrite_index_dst_tag(compiler_context *ctx, unsigned old, unsigned new, unsigned tag) +{ + mir_foreach_instr_global(ctx, ins) { + if (ins->type != tag) + continue; + + if (ins->ssa_args.dest == old) + ins->ssa_args.dest = new; + } +} + + + void mir_rewrite_index(compiler_context *ctx, unsigned old, unsigned new) { @@ -72,35 +86,41 @@ mir_rewrite_index(compiler_context *ctx, unsigned old, unsigned new) mir_rewrite_index_dst(ctx, old, new); } -/* Checks if a value is used only once (or totally dead), which is an important - * heuristic to figure out if certain optimizations are Worth It (TM) */ - -bool -mir_single_use(compiler_context *ctx, unsigned value) +unsigned +mir_use_count(compiler_context *ctx, unsigned value) { unsigned used_count = 0; mir_foreach_instr_global(ctx, ins) { if (mir_has_arg(ins, value)) ++used_count; - - /* Short circuit for speed */ - if (used_count > 1) - return false; } - return used_count <= 1; + return used_count; +} + +/* Checks if a value is used only once (or totally dead), which is an important + * heuristic to figure out if certain optimizations are Worth It (TM) */ +bool +mir_single_use(compiler_context *ctx, unsigned value) +{ + return mir_use_count(ctx, value) <= 1; } bool -mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask) +mir_nontrivial_raw_mod(midgard_vector_alu_src src, bool is_int) { - /* abs or neg */ - if (!is_int && src.mod) return true; + if (is_int) + return src.mod == midgard_int_shift; + else + return src.mod; +} - /* Other int mods don't matter in isolation */ - if (is_int && src.mod == midgard_int_shift) return true; +bool +mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask) +{ + if (mir_nontrivial_raw_mod(src, is_int)) return true; /* size-conversion */ if (src.half) return true; @@ -113,7 +133,6 @@ mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask) return false; } - bool mir_nontrivial_source2_mod(midgard_instruction *ins) { @@ -125,4 +144,101 @@ mir_nontrivial_source2_mod(midgard_instruction *ins) return mir_nontrivial_mod(src2, is_int, ins->mask); } +bool +mir_nontrivial_outmod(midgard_instruction *ins) +{ + bool is_int = midgard_is_integer_op(ins->alu.op); + unsigned mod = ins->alu.outmod; + + /* Pseudo-outmod */ + if (ins->invert) + return true; + + /* Type conversion is a sort of outmod */ + if (ins->alu.dest_override != midgard_dest_override_none) + return true; + + if (is_int) + return mod != midgard_outmod_int_wrap; + else + return mod != midgard_outmod_none; +} + +/* Checks if an index will be used as a special register -- basically, if we're + * used as the input to a non-ALU op */ +bool +mir_special_index(compiler_context *ctx, unsigned idx) +{ + mir_foreach_instr_global(ctx, ins) { + bool is_ldst = ins->type == TAG_LOAD_STORE_4; + bool is_tex = ins->type == TAG_TEXTURE_4; + + if (!(is_ldst || is_tex)) + continue; + + if (mir_has_arg(ins, idx)) + return true; + } + + return false; +} + +/* Is a node written before a given instruction? */ + +bool +mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node) +{ + if ((node < 0) || (node >= SSA_FIXED_MINIMUM)) + return true; + + mir_foreach_instr_global(ctx, q) { + if (q == ins) + break; + + if (q->ssa_args.dest == node) + return true; + } + + return false; +} + +/* Creates a mask of the components of a node read by an instruction, by + * analyzing the swizzle with respect to the instruction's mask. E.g.: + * + * fadd r0.xz, r1.yyyy, r2.zwyx + * + * will return a mask of Z/Y for r2 + */ + +static unsigned +mir_mask_of_read_components_single(unsigned src, unsigned outmask) +{ + midgard_vector_alu_src s = vector_alu_from_unsigned(src); + unsigned mask = 0; + + for (unsigned c = 0; c < 4; ++c) { + if (!(outmask & (1 << c))) continue; + + unsigned comp = (s.swizzle >> (2*c)) & 3; + mask |= (1 << comp); + } + + return mask; +} + +unsigned +mir_mask_of_read_components(midgard_instruction *ins, unsigned node) +{ + assert(ins->type == TAG_ALU_4); + + unsigned mask = 0; + + if (ins->ssa_args.src0 == node) + mask |= mir_mask_of_read_components_single(ins->alu.src1, ins->mask); + + if (ins->ssa_args.src1 == node && !ins->ssa_args.inline_constant) + mask |= mir_mask_of_read_components_single(ins->alu.src2, ins->mask); + + return mask; +}