mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-26 09:00:37 +02:00
freedreno/ir3: remove ir3_instruction::category
Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
parent
70735643f4
commit
19739e4fb9
10 changed files with 84 additions and 93 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
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;
|
||||
if ((instr->category == 2) && ((instr->opc == OPC_ABSNEG_F) ||
|
||||
(instr->opc == 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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue