From: Rob Clark Date: Sun, 27 Mar 2016 17:43:45 +0000 (-0400) Subject: freedreno/ir3: remove ir3_instruction::category X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=19739e4fb9024f42a8fc332e6fa94c292bb6bc16;p=mesa.git freedreno/ir3: remove ir3_instruction::category Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index d86dfca9d54..2e7f2008067 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -612,7 +612,7 @@ void * ir3_assemble(struct ir3 *shader, struct ir3_info *info, list_for_each_entry (struct ir3_block, block, &shader->block_list, node) { list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) { - int ret = emit[instr->category](instr, dwords, info); + int ret = emit[opc_cat(instr->opc)](instr, dwords, info); if (ret) goto fail; info->instrs_count += 1 + instr->repeat; @@ -687,7 +687,6 @@ struct ir3_instruction * ir3_instr_create2(struct ir3_block *block, { struct ir3_instruction *instr = instr_create(block, nreg); instr->block = block; - instr->category = category; debug_assert(opc_cat(opc) == category); instr->opc = opc; insert_instr(block, instr); diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index c9a9d29faf7..1391cbd97da 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -130,7 +130,6 @@ struct ir3_register { struct ir3_instruction { struct ir3_block *block; - int category; opc_t opc; enum { /* (sy) flag is set on first instruction, and after sample @@ -508,17 +507,17 @@ static inline uint32_t reg_comp(struct ir3_register *reg) static inline bool is_flow(struct ir3_instruction *instr) { - return (instr->category == 0); + return (opc_cat(instr->opc) == 0); } static inline bool is_kill(struct ir3_instruction *instr) { - return is_flow(instr) && (instr->opc == OPC_KILL); + return instr->opc == OPC_KILL; } static inline bool is_nop(struct ir3_instruction *instr) { - return is_flow(instr) && (instr->opc == OPC_NOP); + return instr->opc == OPC_NOP; } /* Is it a non-transformative (ie. not type changing) mov? This can @@ -538,75 +537,71 @@ static inline bool is_same_type_mov(struct ir3_instruction *instr) if (dst->flags & (IR3_REG_RELATIV | IR3_REG_ARRAY)) return false; - if ((instr->category == 1) && - (instr->cat1.src_type == instr->cat1.dst_type)) - return true; - if ((instr->category == 2) && ((instr->opc == OPC_ABSNEG_F) || - (instr->opc == OPC_ABSNEG_S))) + switch (instr->opc) { + case OPC_MOV: + return instr->cat1.src_type == instr->cat1.dst_type; + case OPC_ABSNEG_F: + case OPC_ABSNEG_S: return true; - return false; + default: + return false; + } } static inline bool is_alu(struct ir3_instruction *instr) { - return (1 <= instr->category) && (instr->category <= 3); + return (1 <= opc_cat(instr->opc)) && (opc_cat(instr->opc) <= 3); } static inline bool is_sfu(struct ir3_instruction *instr) { - return (instr->category == 4); + return (opc_cat(instr->opc) == 4); } static inline bool is_tex(struct ir3_instruction *instr) { - return (instr->category == 5); + return (opc_cat(instr->opc) == 5); } static inline bool is_mem(struct ir3_instruction *instr) { - return (instr->category == 6); + return (opc_cat(instr->opc) == 6); } static inline bool is_store(struct ir3_instruction *instr) { - if (is_mem(instr)) { - /* these instructions, the "destination" register is - * actually a source, the address to store to. - */ - switch (instr->opc) { - case OPC_STG: - case OPC_STP: - case OPC_STL: - case OPC_STLW: - case OPC_L2G: - case OPC_G2L: - return true; - default: - break; - } + /* these instructions, the "destination" register is + * actually a source, the address to store to. + */ + switch (instr->opc) { + case OPC_STG: + case OPC_STP: + case OPC_STL: + case OPC_STLW: + case OPC_L2G: + case OPC_G2L: + return true; + default: + return false; } - return false; } static inline bool is_load(struct ir3_instruction *instr) { - if (is_mem(instr)) { - switch (instr->opc) { - case OPC_LDG: - case OPC_LDL: - case OPC_LDP: - case OPC_L2G: - case OPC_LDLW: - case OPC_LDC_4: - case OPC_LDLV: + switch (instr->opc) { + case OPC_LDG: + case OPC_LDL: + case OPC_LDP: + case OPC_L2G: + case OPC_LDLW: + case OPC_LDC_4: + case OPC_LDLV: /* probably some others too.. */ - return true; - default: - break; - } + return true; + default: + return false; } - return false; } static inline bool is_input(struct ir3_instruction *instr) @@ -615,9 +610,13 @@ static inline bool is_input(struct ir3_instruction *instr) * interpolation.. fortunately inloc is the first src * register in either case */ - if (is_mem(instr) && (instr->opc == OPC_LDLV)) + switch (instr->opc) { + case OPC_LDLV: + case OPC_BARY_F: return true; - return (instr->category == 2) && (instr->opc == OPC_BARY_F); + default: + return false; + } } static inline bool is_meta(struct ir3_instruction *instr) @@ -626,7 +625,7 @@ static inline bool is_meta(struct ir3_instruction *instr) * might actually contribute some instructions to the final * result? */ - return (instr->category == -1); + return (opc_cat(instr->opc) == -1); } static inline bool writes_addr(struct ir3_instruction *instr) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index fafd6beea4b..1f043e5d9d6 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -1651,7 +1651,7 @@ resolve_phis(struct ir3_compile *ctx, struct ir3_block *block) nir_phi_instr *nphi; /* phi's only come at start of block: */ - if (!(is_meta(instr) && (instr->opc == OPC_META_PHI))) + if (instr->opc != OPC_META_PHI) break; if (!instr->phi.nphi) @@ -2323,12 +2323,12 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler, * in which case we need to propagate the half-reg flag * up to the definer so that RA sees it: */ - if (is_meta(out) && (out->opc == OPC_META_FO)) { + if (out->opc == OPC_META_FO) { out = out->regs[1]->instr; out->regs[0]->flags |= IR3_REG_HALF; } - if (out->category == 1) { + if (out->opc == OPC_MOV) { out->cat1.dst_type = half_type(out->cat1.dst_type); } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cp.c b/src/gallium/drivers/freedreno/ir3/ir3_cp.c index 1cc211a7663..48870074514 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cp.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cp.c @@ -58,14 +58,14 @@ static bool is_eligible_mov(struct ir3_instruction *instr, bool allow_flags) return false; /* TODO: remove this hack: */ - if (is_meta(src_instr) && (src_instr->opc == OPC_META_FO)) + if (src_instr->opc == OPC_META_FO) return false; /* TODO: we currently don't handle left/right neighbors * very well when inserting parallel-copies into phi.. * to avoid problems don't eliminate a mov coming out * of phi.. */ - if (is_meta(src_instr) && (src_instr->opc == OPC_META_PHI)) + if (src_instr->opc == OPC_META_PHI) return false; return true; } @@ -96,7 +96,7 @@ static bool valid_flags(struct ir3_instruction *instr, unsigned n, return false; /* clear flags that are 'ok' */ - switch (instr->category) { + switch (opc_cat(instr->opc)) { case 1: valid_flags = IR3_REG_IMMED | IR3_REG_CONST | IR3_REG_RELATIV; if (flags & ~valid_flags) @@ -205,15 +205,6 @@ static void combine_flags(unsigned *dstflags, unsigned srcflags) *dstflags |= srcflags & IR3_REG_ARRAY; } -/* the "plain" MAD's (ie. the ones that don't shift first src prior to - * multiply) can swap their first two srcs if src[0] is !CONST and - * src[1] is CONST: - */ -static bool is_valid_mad(struct ir3_instruction *instr) -{ - return (instr->category == 3) && is_mad(instr->opc); -} - /** * Handle cp for a given src register. This additionally handles * the cases of collapsing immedate/const (which replace the src @@ -257,8 +248,12 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n) if (!valid_flags(instr, n, new_flags)) { /* special case for "normal" mad instructions, we can * try swapping the first two args if that fits better. + * + * the "plain" MAD's (ie. the ones that don't shift first + * src prior to multiply) can swap their first two srcs if + * src[0] is !CONST and src[1] is CONST: */ - if ((n == 1) && is_valid_mad(instr) && + if ((n == 1) && is_mad(instr->opc) && !(instr->regs[0 + 1]->flags & (IR3_REG_CONST | IR3_REG_RELATIV)) && valid_flags(instr, 0, new_flags)) { /* swap src[0] and src[1]: */ @@ -292,7 +287,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n) * just somehow don't work out. This restriction may only * apply if the first src is also CONST. */ - if ((instr->category == 3) && (n == 2) && + if ((opc_cat(instr->opc) == 3) && (n == 2) && (src_reg->flags & IR3_REG_RELATIV) && (src_reg->array.offset == 0)) return; @@ -328,10 +323,9 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n) if (src_reg->flags & IR3_REG_IMMED) { int32_t iim_val = src_reg->iim_val; - debug_assert((instr->category == 1) || - (instr->category == 6) || - ((instr->category == 2) && - ir3_cat2_int(instr->opc))); + debug_assert((opc_cat(instr->opc) == 1) || + (opc_cat(instr->opc) == 6) || + ir3_cat2_int(instr->opc)); if (new_flags & IR3_REG_SABS) iim_val = abs(iim_val); @@ -343,7 +337,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n) iim_val = ~iim_val; /* other than category 1 (mov) we can only encode up to 10 bits: */ - if ((instr->category == 1) || !(iim_val & ~0x3ff)) { + if ((instr->opc == OPC_MOV) || !(iim_val & ~0x3ff)) { new_flags &= ~(IR3_REG_SABS | IR3_REG_SNEG | IR3_REG_BNOT); src_reg = ir3_reg_clone(instr->block->shader, src_reg); src_reg->flags = new_flags; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c index 6d294f1a48c..c3f6de965ce 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c @@ -74,8 +74,7 @@ int ir3_delayslots(struct ir3_instruction *assigner, if (is_flow(consumer) || is_sfu(consumer) || is_tex(consumer) || is_mem(consumer)) { return 6; - } else if ((consumer->category == 3) && - (is_mad(consumer->opc) || is_madsh(consumer->opc)) && + } else if ((is_mad(consumer->opc) || is_madsh(consumer->opc)) && (n == 3)) { /* special case, 3rd src to cat3 not required on first cycle */ return 1; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_group.c b/src/gallium/drivers/freedreno/ir3/ir3_group.c index ca28aefd502..70212968d89 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_group.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_group.c @@ -69,8 +69,7 @@ static void arr_insert_mov_in(void *arr, int idx, struct ir3_instruction *instr) /* create src reg for meta:in and fixup to now be a mov: */ ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = in; - instr->category = 1; - instr->opc = 0; + instr->opc = OPC_MOV; instr->cat1.src_type = TYPE_F32; instr->cat1.dst_type = TYPE_F32; @@ -117,7 +116,7 @@ restart: conflicts(instr->cp.right, right); /* RA can't yet deal very well w/ group'd phi's: */ - if (is_meta(instr) && (instr->opc == OPC_META_PHI)) + if (instr->opc == OPC_META_PHI) conflict = true; /* we also can't have an instr twice in the group: */ @@ -168,7 +167,7 @@ instr_find_neighbors(struct ir3_instruction *instr) if (ir3_instr_check_mark(instr)) return; - if (is_meta(instr) && (instr->opc == OPC_META_FI)) + if (instr->opc == OPC_META_FI) group_n(&instr_ops, instr, instr->regs_count - 1); foreach_ssa_src(src, instr) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c index e94293f6d6b..613588d276f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c @@ -146,7 +146,7 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) * clever if we were aware of this during scheduling, but * this should be a pretty rare case: */ - if ((n->flags & IR3_INSTR_SS) && (n->category >= 5)) { + if ((n->flags & IR3_INSTR_SS) && (opc_cat(n->opc) >= 5)) { struct ir3_instruction *nop; nop = ir3_NOP(block); nop->flags |= IR3_INSTR_SS; @@ -154,7 +154,7 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) } /* need to be able to set (ss) on first instruction: */ - if (list_empty(&block->instr_list) && (n->category >= 5)) + if (list_empty(&block->instr_list) && (opc_cat(n->opc) >= 5)) ir3_NOP(block); if (is_nop(n) && !list_empty(&block->instr_list)) { diff --git a/src/gallium/drivers/freedreno/ir3/ir3_print.c b/src/gallium/drivers/freedreno/ir3/ir3_print.c index ba0c4a57aa3..86418b89820 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_print.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_print.c @@ -35,6 +35,8 @@ static void print_instr_name(struct ir3_instruction *instr) { + if (!instr) + return; #ifdef DEBUG printf("%04u:", instr->serialno); #endif @@ -61,7 +63,7 @@ static void print_instr_name(struct ir3_instruction *instr) } break; } - } else if (instr->category == 1) { + } else if (instr->opc == OPC_MOV) { static const char *type[] = { [TYPE_F16] = "f16", [TYPE_F32] = "f32", @@ -191,10 +193,8 @@ print_instr(struct ir3_instruction *instr, int lvl) printf("]"); } - if (is_meta(instr)) { - if (instr->opc == OPC_META_FO) { - printf(", off=%d", instr->fo.off); - } + if (instr->opc == OPC_META_FO) { + printf(", off=%d", instr->fo.off); } if (is_flow(instr) && instr->cat0.target) { diff --git a/src/gallium/drivers/freedreno/ir3/ir3_ra.c b/src/gallium/drivers/freedreno/ir3/ir3_ra.c index bcad96e8a30..2f369e677e0 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_ra.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_ra.c @@ -342,7 +342,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, return id->defn; } - if (is_meta(instr) && (instr->opc == OPC_META_FI)) { + if (instr->opc == OPC_META_FI) { /* What about the case where collect is subset of array, we * need to find the distance between where actual array starts * and fanin.. that probably doesn't happen currently. @@ -436,7 +436,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, } } - if (is_meta(d) && (d->opc == OPC_META_PHI)) { + if (d->opc == OPC_META_PHI) { /* we have already inserted parallel-copies into * the phi, so we don't need to chase definers */ @@ -456,7 +456,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, d = dd; } - if (is_meta(d) && (d->opc == OPC_META_FO)) { + if (d->opc == OPC_META_FO) { struct ir3_instruction *dd; int dsz, doff; @@ -869,7 +869,7 @@ ra_add_interference(struct ir3_ra_ctx *ctx) /* some instructions need fix-up if dst register is half precision: */ static void fixup_half_instr_dst(struct ir3_instruction *instr) { - switch (instr->category) { + switch (opc_cat(instr->opc)) { case 1: /* move instructions */ instr->cat1.dst_type = half_type(instr->cat1.dst_type); break; @@ -910,10 +910,12 @@ static void fixup_half_instr_dst(struct ir3_instruction *instr) /* some instructions need fix-up if src register is half precision: */ static void fixup_half_instr_src(struct ir3_instruction *instr) { - switch (instr->category) { - case 1: /* move instructions */ + switch (instr->opc) { + case OPC_MOV: instr->cat1.src_type = half_type(instr->cat1.src_type); break; + default: + break; } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index 8f640febc5d..9be5ca34ccd 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -511,8 +511,7 @@ sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block) * occupied), and move remaining to depth sorted list: */ list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node) { - if (is_meta(instr) && ((instr->opc == OPC_META_INPUT) || - (instr->opc == OPC_META_PHI))) { + if ((instr->opc == OPC_META_INPUT) || (instr->opc == OPC_META_PHI)) { schedule(ctx, instr); } else { ir3_insert_by_depth(instr, &ctx->depth_list); @@ -627,7 +626,7 @@ static void sched_insert_parallel_copies(struct ir3_block *block) { list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) { - if (is_meta(instr) && (instr->opc == OPC_META_PHI)) { + if (instr->opc == OPC_META_PHI) { struct ir3_register *reg; foreach_src(reg, instr) { struct ir3_instruction *src = reg->instr;