From 414dba9f5c294532463d1c965dcd5e16451a16d5 Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Tue, 18 Jun 2024 11:24:42 -0300 Subject: [PATCH] panfrost: use an accessor function to read from bi_opcode_props Use an accessor function to read opcode properties or to change the opcode. This would allow for different instruction descriptions to be used for different architectures. Not necessary now, but may be useful groundwork. Reviewed-by: Erik Faye-Lund Part-of: --- src/panfrost/compiler/bi_lower_swizzle.c | 10 ++--- src/panfrost/compiler/bi_opt_copy_prop.c | 4 +- src/panfrost/compiler/bi_opt_cse.c | 2 +- src/panfrost/compiler/bi_opt_dce.c | 2 +- src/panfrost/compiler/bi_opt_mod_props.c | 16 ++++---- src/panfrost/compiler/bi_opt_push_ubo.c | 6 +-- src/panfrost/compiler/bi_pressure_schedule.c | 4 +- src/panfrost/compiler/bi_printer.c.py | 2 +- src/panfrost/compiler/bifrost/bi_pack.c | 10 ++--- src/panfrost/compiler/bifrost/bi_schedule.c | 38 +++++++++---------- src/panfrost/compiler/bifrost/bi_scoreboard.c | 8 ++-- src/panfrost/compiler/bir.c | 13 ++++--- src/panfrost/compiler/compiler.h | 22 ++++++++++- .../compiler/valhall/va_insert_flow.c | 10 ++--- src/panfrost/compiler/valhall/va_lower_isel.c | 11 +++--- src/panfrost/compiler/valhall/va_merge_flow.c | 2 +- src/panfrost/compiler/valhall/va_optimize.c | 4 +- src/panfrost/compiler/valhall/va_pack.c | 4 +- 18 files changed, 95 insertions(+), 73 deletions(-) diff --git a/src/panfrost/compiler/bi_lower_swizzle.c b/src/panfrost/compiler/bi_lower_swizzle.c index 99c004b7469..593a16d3b8d 100644 --- a/src/panfrost/compiler/bi_lower_swizzle.c +++ b/src/panfrost/compiler/bi_lower_swizzle.c @@ -174,8 +174,8 @@ lower_swizzle(bi_context *ctx, bi_instr *ins, unsigned src) /* Lower it away */ bi_builder b = bi_init_builder(ctx, bi_before_instr(ins)); - bool is_8 = (bi_opcode_props[ins->op].size == BI_SIZE_8) || - (bi_opcode_props[ins->op].size == BI_SIZE_32 && + bool is_8 = (bi_get_opcode_props(ins)->size == BI_SIZE_8) || + (bi_get_opcode_props(ins)->size == BI_SIZE_32 && ins->src[src].swizzle >= BI_SWIZZLE_B0000); bi_index orig = ins->src[src]; @@ -241,13 +241,13 @@ bi_instr_replicates(bi_instr *I, BITSET_WORD *replicates_16) } /* Replication analysis only makes sense for ALU instructions */ - if (bi_opcode_props[I->op].message != BIFROST_MESSAGE_NONE) + if (bi_get_opcode_props(I)->message != BIFROST_MESSAGE_NONE) return false; /* We only analyze 16-bit instructions for 16-bit replication. We could * maybe do better. */ - if (bi_opcode_props[I->op].size != BI_SIZE_16) + if (bi_get_opcode_props(I)->size != BI_SIZE_16) return false; bi_foreach_src(I, s) { @@ -296,7 +296,7 @@ bi_lower_swizzle(bi_context *ctx) if (ins->op == BI_OPCODE_SWZ_V2I16 && bi_is_ssa(ins->src[0]) && BITSET_TEST(replicates_16, ins->src[0].value)) { - ins->op = BI_OPCODE_MOV_I32; + bi_set_opcode(ins, BI_OPCODE_MOV_I32); ins->src[0].swizzle = BI_SWIZZLE_H01; } diff --git a/src/panfrost/compiler/bi_opt_copy_prop.c b/src/panfrost/compiler/bi_opt_copy_prop.c index 1a3bc5ae042..faaba39a818 100644 --- a/src/panfrost/compiler/bi_opt_copy_prop.c +++ b/src/panfrost/compiler/bi_opt_copy_prop.c @@ -50,13 +50,13 @@ bi_opt_copy_prop(bi_context *ctx) if (I->op == BI_OPCODE_COLLECT_I32) { /* Rewrite trivial collects while we're at it */ if (I->nr_srcs == 1) - I->op = BI_OPCODE_MOV_I32; + bi_set_opcode(I, BI_OPCODE_MOV_I32); collects[I->dest[0].value] = I; } else if (I->op == BI_OPCODE_SPLIT_I32) { /* Rewrite trivial splits while we're at it */ if (I->nr_dests == 1) - I->op = BI_OPCODE_MOV_I32; + bi_set_opcode(I, BI_OPCODE_MOV_I32); bi_instr *collect = collects[I->src[0].value]; if (!collect) diff --git a/src/panfrost/compiler/bi_opt_cse.c b/src/panfrost/compiler/bi_opt_cse.c index 28e3519c338..16f27cb802b 100644 --- a/src/panfrost/compiler/bi_opt_cse.c +++ b/src/panfrost/compiler/bi_opt_cse.c @@ -136,7 +136,7 @@ instr_can_cse(const bi_instr *I) /* Be conservative about which message-passing instructions we CSE, * since most are not pure even within a thread. */ - if (bi_opcode_props[I->op].message && I->op != BI_OPCODE_LEA_BUF_IMM) + if (bi_get_opcode_props(I)->message && I->op != BI_OPCODE_LEA_BUF_IMM) return false; if (I->branch_target) diff --git a/src/panfrost/compiler/bi_opt_dce.c b/src/panfrost/compiler/bi_opt_dce.c index 2a74eab6c11..4af84c12461 100644 --- a/src/panfrost/compiler/bi_opt_dce.c +++ b/src/panfrost/compiler/bi_opt_dce.c @@ -172,7 +172,7 @@ bi_opt_dce_post_ra(bi_context *ctx) unsigned reg = ins->dest[d].value; uint64_t mask = (BITFIELD64_MASK(nr) << reg); bool cullable = (ins->op != BI_OPCODE_BLEND); - cullable &= !bi_opcode_props[ins->op].sr_write; + cullable &= !bi_get_opcode_props(ins)->sr_write; if (!(live & mask) && cullable) ins->dest[d] = bi_null(); diff --git a/src/panfrost/compiler/bi_opt_mod_props.c b/src/panfrost/compiler/bi_opt_mod_props.c index 35a172a113b..edcf7d887ed 100644 --- a/src/panfrost/compiler/bi_opt_mod_props.c +++ b/src/panfrost/compiler/bi_opt_mod_props.c @@ -60,7 +60,7 @@ bi_takes_fabs(unsigned arch, bi_instr *I, bi_index repl, unsigned s) /* TODO: Need to check mode */ return false; default: - return bi_opcode_props[I->op].abs & BITFIELD_BIT(s); + return bi_get_opcode_props(I)->abs & BITFIELD_BIT(s); } } @@ -79,7 +79,7 @@ bi_takes_fneg(unsigned arch, bi_instr *I, unsigned s) /* TODO: Need to check mode */ return false; default: - return bi_opcode_props[I->op].neg & BITFIELD_BIT(s); + return bi_get_opcode_props(I)->neg & BITFIELD_BIT(s); } } @@ -188,7 +188,7 @@ bi_fuse_small_int_to_f32(bi_instr *I, bi_instr *mod) assert(I->src[0].swizzle == BI_SWIZZLE_H01); I->src[0] = mod->src[0]; I->round = BI_ROUND_NONE; - I->op = bi_small_int_patterns[i].replacement; + bi_set_opcode(I, bi_small_int_patterns[i].replacement); } } @@ -221,7 +221,7 @@ bi_opt_mod_prop_forward(bi_context *ctx) if (!mod) continue; - unsigned size = bi_opcode_props[I->op].size; + unsigned size = bi_get_opcode_props(I)->size; /* All small int instructions we were relying on here are gone on v11 */ if (ctx->arch < 11) @@ -258,7 +258,7 @@ bi_takes_clamp(bi_instr *I) return !(I->src[0].abs && I->src[1].abs && bi_is_word_equiv(I->src[0], I->src[1])); default: - return bi_opcode_props[I->op].clamp; + return bi_get_opcode_props(I)->clamp; } } @@ -272,7 +272,7 @@ bi_is_fclamp(enum bi_opcode op, enum bi_size size) static bool bi_optimizer_clamp(bi_instr *I, bi_instr *use) { - if (!bi_is_fclamp(use->op, bi_opcode_props[I->op].size)) + if (!bi_is_fclamp(use->op, bi_get_opcode_props(I)->size)) return false; if (!bi_takes_clamp(I)) return false; @@ -337,7 +337,7 @@ bi_takes_float_result_type(enum bi_opcode op) static bool bi_optimizer_result_type(bi_instr *I, bi_instr *mux) { - if (bi_opcode_props[I->op].size != bi_opcode_props[mux->op].size) + if (bi_get_opcode_props(I)->size != bi_get_opcode_props(mux)->size) return false; if (bi_is_fixed_mux(mux, 32, bi_imm_f32(1.0)) || @@ -392,7 +392,7 @@ bi_optimizer_var_tex(bi_context *ctx, bi_instr *var, bi_instr *tex) I->skip = tex->skip; if (tex->op == BI_OPCODE_TEXS_2D_F16) - I->op = BI_OPCODE_VAR_TEX_F16; + bi_set_opcode(I, BI_OPCODE_VAR_TEX_F16); /* Dead code elimination will clean up for us */ return true; diff --git a/src/panfrost/compiler/bi_opt_push_ubo.c b/src/panfrost/compiler/bi_opt_push_ubo.c index 6e69e3c11c7..9a4f3c527a7 100644 --- a/src/panfrost/compiler/bi_opt_push_ubo.c +++ b/src/panfrost/compiler/bi_opt_push_ubo.c @@ -32,7 +32,7 @@ static bool bi_is_ubo(bi_instr *ins) { - return (bi_opcode_props[ins->op].message == BIFROST_MESSAGE_LOAD) && + return (bi_get_opcode_props(ins)->message == BIFROST_MESSAGE_LOAD) && (ins->seg == BI_SEG_UBO); } @@ -74,7 +74,7 @@ bi_analyze_ranges(bi_context *ctx) unsigned ubo = pan_res_handle_get_index(ins->src[1].value); unsigned word = ins->src[0].value / 4; - unsigned channels = bi_opcode_props[ins->op].sr_count; + unsigned channels = bi_get_opcode_props(ins)->sr_count; assert(ubo < res.nr_blocks); assert(channels > 0 && channels <= 4); @@ -163,7 +163,7 @@ bi_opt_push_ubo(bi_context *ctx) /* Replace the UBO load with moves from FAU */ bi_builder b = bi_init_builder(ctx, bi_after_instr(ins)); - unsigned nr = bi_opcode_props[ins->op].sr_count; + unsigned nr = bi_get_opcode_props(ins)->sr_count; bi_instr *vec = bi_collect_i32_to(&b, ins->dest[0], nr); bi_foreach_src(vec, w) { diff --git a/src/panfrost/compiler/bi_pressure_schedule.c b/src/panfrost/compiler/bi_pressure_schedule.c index 96cd9e2b19a..db29e973445 100644 --- a/src/panfrost/compiler/bi_pressure_schedule.c +++ b/src/panfrost/compiler/bi_pressure_schedule.c @@ -69,7 +69,7 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx) bi_foreach_instr_in_block(block, I) { /* Leave branches at the end */ - if (I->op == BI_OPCODE_JUMP || bi_opcode_props[I->op].branch) + if (I->op == BI_OPCODE_JUMP || bi_get_opcode_props(I)->branch) break; assert(I->branch_target == NULL); @@ -87,7 +87,7 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx) add_dep(node, preload); - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_LOAD: /* Regular memory loads needs to be serialized against * other memory access. However, UBO memory is read-only diff --git a/src/panfrost/compiler/bi_printer.c.py b/src/panfrost/compiler/bi_printer.c.py index 9501601d5b9..cb9226d6fc7 100644 --- a/src/panfrost/compiler/bi_printer.c.py +++ b/src/panfrost/compiler/bi_printer.c.py @@ -169,7 +169,7 @@ bi_print_instr(const bi_instr *I, FILE *fp) if (I->nr_dests > 0) fputs(" = ", fp); - fprintf(fp, "%s", bi_opcode_props[I->op].name); + fprintf(fp, "%s", bi_get_opcode_props(I)->name); if (I->table) fprintf(fp, ".table%u", I->table); diff --git a/src/panfrost/compiler/bifrost/bi_pack.c b/src/panfrost/compiler/bifrost/bi_pack.c index 7782c07ecd6..948560bd657 100644 --- a/src/panfrost/compiler/bifrost/bi_pack.c +++ b/src/panfrost/compiler/bifrost/bi_pack.c @@ -110,8 +110,8 @@ bi_assign_slots(bi_tuple *now, bi_tuple *prev) * use the data registers, which has its own mechanism entirely * and thus gets skipped over here. */ - bool read_dreg = now->add && bi_opcode_props[now->add->op].sr_read; - bool write_dreg = prev->add && bi_opcode_props[prev->add->op].sr_write; + bool read_dreg = now->add && bi_get_opcode_props(now->add)->sr_read; + bool write_dreg = prev->add && bi_get_opcode_props(prev->add)->sr_write; /* First, assign reads */ @@ -327,7 +327,7 @@ bi_pack_tuple(bi_clause *clause, bi_tuple *tuple, bi_tuple *prev, bi_flip_slots(&tuple->regs); - bool sr_read = tuple->add && bi_opcode_props[(tuple->add)->op].sr_read; + bool sr_read = tuple->add && bi_get_opcode_props(tuple->add)->sr_read; uint64_t reg = bi_pack_registers(tuple->regs); uint64_t fma = @@ -345,7 +345,7 @@ bi_pack_tuple(bi_clause *clause, bi_tuple *tuple, bi_tuple *prev, bi_instr *add = tuple->add; bool sr_write = - bi_opcode_props[add->op].sr_write && !bi_is_null(add->dest[0]); + bi_get_opcode_props(add)->sr_write && !bi_is_null(add->dest[0]); if (sr_read && !bi_is_null(add->src[0])) { assert(add->src[0].type == BI_INDEX_REGISTER); @@ -713,7 +713,7 @@ bi_lower_texc_dual(bi_context *ctx) bi_foreach_instr_global(ctx, I) { if (I->op == BI_OPCODE_TEXC_DUAL) { /* In hardware, TEXC has 1 destination */ - I->op = BI_OPCODE_TEXC; + bi_set_opcode(I, BI_OPCODE_TEXC); bi_drop_dests(I, 1); } } diff --git a/src/panfrost/compiler/bifrost/bi_schedule.c b/src/panfrost/compiler/bifrost/bi_schedule.c index f55e364f928..c1d162a3b58 100644 --- a/src/panfrost/compiler/bifrost/bi_schedule.c +++ b/src/panfrost/compiler/bifrost/bi_schedule.c @@ -148,7 +148,7 @@ struct bi_clause_state { static enum bifrost_message_type bi_message_type_for_instr(bi_instr *ins) { - enum bifrost_message_type msg = bi_opcode_props[ins->op].message; + enum bifrost_message_type msg = bi_get_opcode_props(ins)->message; bool ld_var_special = (ins->op == BI_OPCODE_LD_VAR_SPECIAL); if (ld_var_special && ins->varying_name == BI_VARYING_NAME_FRAG_Z) @@ -337,7 +337,7 @@ bi_lower_cubeface(bi_context *ctx, struct bi_clause_state *clause, bi_instr *cubeface1 = bi_cubeface1_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->src[1], pinstr->src[2]); - pinstr->op = BI_OPCODE_CUBEFACE2; + bi_set_opcode(pinstr, BI_OPCODE_CUBEFACE2); pinstr->dest[0] = pinstr->dest[1]; bi_drop_dests(pinstr, 1); @@ -361,7 +361,7 @@ bi_lower_atom_c(bi_context *ctx, struct bi_clause_state *clause, pinstr->src[0], pinstr->atom_opc); if (bi_is_null(pinstr->dest[0])) - atom_c->op = BI_OPCODE_ATOM_C_I32; + bi_set_opcode(atom_c, BI_OPCODE_ATOM_C_I32); bi_instr *atom_cx = bi_atom_cx_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->src[1], @@ -382,7 +382,7 @@ bi_lower_atom_c1(bi_context *ctx, struct bi_clause_state *clause, pinstr->atom_opc); if (bi_is_null(pinstr->dest[0])) - atom_c->op = BI_OPCODE_ATOM_C1_I32; + bi_set_opcode(atom_c, BI_OPCODE_ATOM_C1_I32); bi_instr *atom_cx = bi_atom_cx_to(&b, pinstr->dest[0], bi_null(), pinstr->src[0], @@ -403,7 +403,7 @@ bi_lower_seg_add(bi_context *ctx, struct bi_clause_state *clause, bi_instr *fma = bi_seg_add_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->preserve_null, pinstr->seg); - pinstr->op = BI_OPCODE_SEG_ADD; + bi_set_opcode(pinstr, BI_OPCODE_SEG_ADD); pinstr->src[0] = pinstr->src[1]; bi_drop_srcs(pinstr, 1); @@ -546,7 +546,7 @@ bi_can_fma(bi_instr *ins) return false; /* TODO: some additional fp16 constraints */ - return bi_opcode_props[ins->op].fma; + return bi_get_opcode_props(ins)->fma; } static bool @@ -576,7 +576,7 @@ bi_can_add(bi_instr *ins) return false; /* TODO: some additional fp16 constraints */ - return bi_opcode_props[ins->op].add; + return bi_get_opcode_props(ins)->add; } /* Architecturally, no single instruction has a "not last" constraint. However, @@ -604,7 +604,7 @@ bi_must_not_last(bi_instr *ins) bool bi_must_message(bi_instr *ins) { - return (bi_opcode_props[ins->op].message != BIFROST_MESSAGE_NONE) || + return (bi_get_opcode_props(ins)->message != BIFROST_MESSAGE_NONE) || (ins->op == BI_OPCODE_DISCARD_F32); } @@ -730,11 +730,11 @@ bool bi_reads_t(bi_instr *ins, unsigned src) { /* Branch offset cannot come from passthrough */ - if (bi_opcode_props[ins->op].branch) + if (bi_get_opcode_props(ins)->branch) return src != 2; /* Table can never read passthrough */ - if (bi_opcode_props[ins->op].table) + if (bi_get_opcode_props(ins)->table) return false; /* Staging register reads may happen before the succeeding register @@ -1005,7 +1005,7 @@ bi_write_count(bi_instr *instr, uint64_t live_after_temp) unsigned count = 0; bi_foreach_dest(instr, d) { - if (d == 0 && bi_opcode_props[instr->op].sr_write) + if (d == 0 && bi_get_opcode_props(instr)->sr_write) continue; assert(instr->dest[0].type == BI_INDEX_REGISTER); @@ -1060,7 +1060,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, return false; /* Some instructions have placement requirements */ - if (bi_opcode_props[instr->op].last && !tuple->last) + if (bi_get_opcode_props(instr)->last && !tuple->last) return false; if (bi_must_not_last(instr) && tuple->last) @@ -1074,7 +1074,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, * same clause (most likely they will not), so if a later instruction * in the clause accesses the destination, the message-passing * instruction can't be scheduled */ - if (bi_opcode_props[instr->op].sr_write) { + if (bi_get_opcode_props(instr)->sr_write) { bi_foreach_dest(instr, d) { unsigned nr = bi_count_write_registers(instr, d); assert(instr->dest[d].type == BI_INDEX_REGISTER); @@ -1090,7 +1090,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, } } - if (bi_opcode_props[instr->op].sr_read && !bi_is_null(instr->src[0])) { + if (bi_get_opcode_props(instr)->sr_read && !bi_is_null(instr->src[0])) { unsigned nr = bi_count_read_registers(instr, 0); assert(instr->src[0].type == BI_INDEX_REGISTER); unsigned reg = instr->src[0].value; @@ -1183,7 +1183,7 @@ bi_instr_cost(bi_instr *instr, struct bi_tuple_state *tuple) cost--; /* Last instructions are big constraints (XXX: no effect on shader-db) */ - if (bi_opcode_props[instr->op].last) + if (bi_get_opcode_props(instr)->last) cost -= 2; return cost; @@ -1361,7 +1361,7 @@ bi_use_passthrough(bi_instr *ins, bi_index old, enum bifrost_packed_src new, static void bi_rewrite_passthrough(bi_tuple prec, bi_tuple succ) { - bool sr_read = succ.add ? bi_opcode_props[succ.add->op].sr_read : false; + bool sr_read = succ.add ? bi_get_opcode_props(succ.add)->sr_read : false; if (prec.add && prec.add->nr_dests) { bi_use_passthrough(succ.fma, prec.add->dest[0], BIFROST_SRC_PASS_ADD, @@ -1738,7 +1738,7 @@ bi_schedule_clause(bi_context *ctx, bi_block *block, struct bi_worklist st, tuple = &clause->tuples[idx]; - if (clause->message && bi_opcode_props[clause->message->op].sr_read && + if (clause->message && bi_get_opcode_props(clause->message)->sr_read && !bi_is_null(clause->message->src[0])) { unsigned nr = bi_count_read_registers(clause->message, 0); live_after_temp |= @@ -2008,7 +2008,7 @@ bi_check_fau_src(bi_instr *ins, unsigned s, uint32_t *constants, if (src.type == BI_INDEX_CONSTANT) { /* Allow fast zero */ - if (src.value == 0 && bi_opcode_props[ins->op].fma && bi_reads_zero(ins)) + if (src.value == 0 && bi_get_opcode_props(ins)->fma && bi_reads_zero(ins)) return true; if (!bi_is_null(*fau)) @@ -2104,7 +2104,7 @@ bi_add_nop_for_atest(bi_context *ctx) * clause */ bi_instr *I = rzalloc(ctx, bi_instr); - I->op = BI_OPCODE_NOP; + bi_set_opcode(I, BI_OPCODE_NOP); bi_clause *new_clause = ralloc(ctx, bi_clause); *new_clause = (bi_clause){ diff --git a/src/panfrost/compiler/bifrost/bi_scoreboard.c b/src/panfrost/compiler/bifrost/bi_scoreboard.c index 735bcf4a677..a1edd4222e5 100644 --- a/src/panfrost/compiler/bifrost/bi_scoreboard.c +++ b/src/panfrost/compiler/bifrost/bi_scoreboard.c @@ -76,7 +76,7 @@ bi_should_serialize(bi_instr *I) if (I->op == BI_OPCODE_LD_ATTR_TEX) return true; - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_VARYING: case BIFROST_MESSAGE_LOAD: case BIFROST_MESSAGE_STORE: @@ -113,7 +113,7 @@ bi_read_mask(bi_instr *I, bool staging_only) { uint64_t mask = 0; - if (staging_only && !bi_opcode_props[I->op].sr_read) + if (staging_only && !bi_get_opcode_props(I)->sr_read) return mask; bi_foreach_src(I, s) { @@ -154,7 +154,7 @@ bi_write_mask(bi_instr *I) * Obscurely, ATOM_CX is sr_write but can ignore the staging register in * certain circumstances; this does not require consideration. */ - if (bi_opcode_props[I->op].sr_write && I->nr_dests && I->nr_srcs && + if (bi_get_opcode_props(I)->sr_write && I->nr_dests && I->nr_srcs && bi_is_null(I->dest[0]) && !bi_is_null(I->src[0])) { unsigned reg = I->src[0].value; @@ -179,7 +179,7 @@ bi_push_clause(struct bi_scoreboard_state *st, bi_clause *clause) st->read[slot] |= bi_read_mask(I, true); - if (bi_opcode_props[I->op].sr_write) + if (bi_get_opcode_props(I)->sr_write) st->write[slot] |= bi_write_mask(I); } diff --git a/src/panfrost/compiler/bir.c b/src/panfrost/compiler/bir.c index 9520eb8af3b..abc55612afa 100644 --- a/src/panfrost/compiler/bir.c +++ b/src/panfrost/compiler/bir.c @@ -66,7 +66,7 @@ bi_is_regfmt_16(enum bi_register_format fmt) static unsigned bi_count_staging_registers(const bi_instr *ins) { - enum bi_sr_count count = bi_opcode_props[ins->op].sr_count; + enum bi_sr_count count = bi_get_opcode_props(ins)->sr_count; unsigned vecsize = ins->vecsize + 1; /* XXX: off-by-one */ switch (count) { @@ -90,7 +90,7 @@ bi_count_read_registers(const bi_instr *ins, unsigned s) /* ATOM reads 1 but writes 2. Exception for ACMPXCHG */ if (s == 0 && ins->op == BI_OPCODE_ATOM_RETURN_I32) return (ins->atom_opc == BI_ATOM_OPC_ACMPXCHG) ? 2 : 1; - else if (s == 0 && bi_opcode_props[ins->op].sr_read) + else if (s == 0 && bi_get_opcode_props(ins)->sr_read) return bi_count_staging_registers(ins); else if (s == 4 && ins->op == BI_OPCODE_BLEND) return ins->sr_count_2; /* Dual source blending */ @@ -103,7 +103,7 @@ bi_count_read_registers(const bi_instr *ins, unsigned s) unsigned bi_count_write_registers(const bi_instr *ins, unsigned d) { - if (d == 0 && bi_opcode_props[ins->op].sr_write) { + if (d == 0 && bi_get_opcode_props(ins)->sr_write) { switch (ins->op) { case BI_OPCODE_TEXC: case BI_OPCODE_TEXC_DUAL: @@ -185,7 +185,7 @@ bi_next_clause(bi_context *ctx, bi_block *block, bi_clause *clause) bool bi_side_effects(const bi_instr *I) { - if (bi_opcode_props[I->op].last) + if (bi_get_opcode_props(I)->last) return true; switch (I->op) { @@ -196,7 +196,7 @@ bi_side_effects(const bi_instr *I) break; } - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_NONE: case BIFROST_MESSAGE_VARYING: case BIFROST_MESSAGE_ATTRIBUTE: @@ -288,6 +288,7 @@ bi_csel_from_mux(bi_builder *b, const bi_instr *I, bool must_sign) I->src[0], I->src[1], cmpf); /* Fixup the opcode and use it */ - csel->op = bi_csel_for_mux(must_sign, I->op == BI_OPCODE_MUX_I32, I->mux); + bi_set_opcode(csel, + bi_csel_for_mux(must_sign, I->op == BI_OPCODE_MUX_I32, I->mux)); return csel; } diff --git a/src/panfrost/compiler/compiler.h b/src/panfrost/compiler/compiler.h index b4dc34c47b1..672699add68 100644 --- a/src/panfrost/compiler/compiler.h +++ b/src/panfrost/compiler/compiler.h @@ -559,10 +559,30 @@ typedef struct { }; } bi_instr; +/* + * Helpers to set opcode and to get properties related to + * the opcode. In principle this would allow different + * properties to be used based on the architecture. In practice + * we've unified the valhall/bifrost descriptions so this + * isn't necessary now. We may want it for a future architecture + * though. + */ +static inline void +bi_set_opcode(bi_instr *I, enum bi_opcode opc) +{ + I->op = opc; +} + +static inline struct bi_op_props * +bi_get_opcode_props(const bi_instr *I) +{ + return &bi_opcode_props[I->op]; +} + static inline bool bi_is_staging_src(const bi_instr *I, unsigned s) { - return (s == 0 || s == 4) && bi_opcode_props[I->op].sr_read; + return (s == 0 || s == 4) && bi_get_opcode_props(I)->sr_read; } /* diff --git a/src/panfrost/compiler/valhall/va_insert_flow.c b/src/panfrost/compiler/valhall/va_insert_flow.c index 00560c60b31..5296338d2ea 100644 --- a/src/panfrost/compiler/valhall/va_insert_flow.c +++ b/src/panfrost/compiler/valhall/va_insert_flow.c @@ -105,7 +105,7 @@ static bool bi_ld_vary_writes_hidden_register(const bi_instr *I) { /* Only varying loads can write the hidden register */ - if (bi_opcode_props[I->op].message != BIFROST_MESSAGE_VARYING) + if (bi_get_opcode_props(I)->message != BIFROST_MESSAGE_VARYING) return false; /* They only write in some update modes */ @@ -130,7 +130,7 @@ bi_is_memory_access(const bi_instr *I) if (I->seg == BI_SEG_UBO) return false; - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_LOAD: case BIFROST_MESSAGE_STORE: case BIFROST_MESSAGE_ATOMIC: @@ -145,13 +145,13 @@ bi_is_memory_access(const bi_instr *I) static void bi_push_instr(struct bi_scoreboard_state *st, bi_instr *I) { - if (bi_opcode_props[I->op].sr_write) + if (bi_get_opcode_props(I)->sr_write) st->write[I->slot] |= bi_write_mask(I); if (bi_is_memory_access(I)) st->memory |= BITFIELD_BIT(I->slot); - if (bi_opcode_props[I->op].message == BIFROST_MESSAGE_VARYING) + if (bi_get_opcode_props(I)->message == BIFROST_MESSAGE_VARYING) st->varying |= BITFIELD_BIT(I->slot); } @@ -528,7 +528,7 @@ va_assign_slots(bi_context *ctx) I->slot = 7; } else if (I->op == BI_OPCODE_ZS_EMIT || I->op == BI_OPCODE_ATEST) { I->slot = 0; - } else if (bi_opcode_props[I->op].message) { + } else if (bi_get_opcode_props(I)->message) { I->slot = counter++; if (counter == 3) diff --git a/src/panfrost/compiler/valhall/va_lower_isel.c b/src/panfrost/compiler/valhall/va_lower_isel.c index 9f74a9a8cfe..d69b37f6e10 100644 --- a/src/panfrost/compiler/valhall/va_lower_isel.c +++ b/src/panfrost/compiler/valhall/va_lower_isel.c @@ -95,8 +95,9 @@ lower(bi_builder *b, bi_instr *I) case BI_OPCODE_CSEL_V2I16: assert(I->cmpf == BI_CMPF_EQ || I->cmpf == BI_CMPF_NE); - I->op = (I->op == BI_OPCODE_CSEL_I32) ? BI_OPCODE_CSEL_U32 - : BI_OPCODE_CSEL_V2U16; + bi_set_opcode(I, + (I->op == BI_OPCODE_CSEL_I32) ? BI_OPCODE_CSEL_U32 + : BI_OPCODE_CSEL_V2U16); return NULL; /* Jump -> conditional branch with condition tied to true. */ @@ -110,13 +111,13 @@ lower(bi_builder *b, bi_instr *I) } case BI_OPCODE_AXCHG_I32: - I->op = BI_OPCODE_ATOM_RETURN_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_RETURN_I32); I->atom_opc = BI_ATOM_OPC_AXCHG; I->sr_count = 1; return NULL; case BI_OPCODE_ACMPXCHG_I32: - I->op = BI_OPCODE_ATOM_RETURN_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_RETURN_I32); I->atom_opc = BI_ATOM_OPC_ACMPXCHG; /* Reads 2, this is special cased in bir.c */ I->sr_count = 1; @@ -124,7 +125,7 @@ lower(bi_builder *b, bi_instr *I) case BI_OPCODE_ATOM_RETURN_I32: if (bi_is_null(I->dest[0])) - I->op = BI_OPCODE_ATOM_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_I32); return NULL; diff --git a/src/panfrost/compiler/valhall/va_merge_flow.c b/src/panfrost/compiler/valhall/va_merge_flow.c index 05de5109260..99cd0abc7b3 100644 --- a/src/panfrost/compiler/valhall/va_merge_flow.c +++ b/src/panfrost/compiler/valhall/va_merge_flow.c @@ -149,7 +149,7 @@ merge_waits(bi_block *block) * we're waiting for. If we wanted to optimize this case, we could check * the signaled slots. */ - if (bi_opcode_props[I->op].message) + if (bi_get_opcode_props(I)->message) last_free = NULL; /* We can only merge with instructions whose flow control is a wait. diff --git a/src/panfrost/compiler/valhall/va_optimize.c b/src/panfrost/compiler/valhall/va_optimize.c index 4eab8d6cbf6..ebd55e6c2c4 100644 --- a/src/panfrost/compiler/valhall/va_optimize.c +++ b/src/panfrost/compiler/valhall/va_optimize.c @@ -74,7 +74,7 @@ va_lower_mov_imm(bi_instr *I) assert(I->nr_srcs == 1); if (I->src[0].type == BI_INDEX_CONSTANT) { - I->op = BI_OPCODE_IADD_IMM_I32; + bi_set_opcode(I, BI_OPCODE_IADD_IMM_I32); I->index = I->src[0].value; I->src[0] = bi_zero(); } @@ -104,7 +104,7 @@ va_fuse_add_imm(bi_instr *I) if (!va_is_add_imm(I, 1 - s)) return; - I->op = op; + bi_set_opcode(I, op); I->index = bi_apply_swizzle(I->src[s].value, I->src[s].swizzle); assert(!I->src[s].abs && "redundant .abs set"); diff --git a/src/panfrost/compiler/valhall/va_pack.c b/src/panfrost/compiler/valhall/va_pack.c index 8ebe3002091..3bc1ac25a73 100644 --- a/src/panfrost/compiler/valhall/va_pack.c +++ b/src/panfrost/compiler/valhall/va_pack.c @@ -566,7 +566,7 @@ va_pack_alu(const bi_instr *I, unsigned arch) bool swap12 = va_swap_12(I->op); /* First src is staging if we read, skip it when packing sources */ - unsigned src_offset = bi_opcode_props[I->op].sr_read ? 1 : 0; + unsigned src_offset = bi_get_opcode_props(I)->sr_read ? 1 : 0; for (unsigned i = 0; i < info.nr_srcs; ++i) { unsigned logical_i = (swap12 && i == 1) ? 2 : (swap12 && i == 2) ? 1 : i; @@ -805,7 +805,7 @@ va_pack_instr(const bi_instr *I, unsigned arch) hex |= ((uint64_t)I->slot << 30); if (info.sr_count) { - bool read = bi_opcode_props[I->op].sr_read; + bool read = bi_get_opcode_props(I)->sr_read; bi_index sr = read ? I->src[0] : I->dest[0]; unsigned count =