freedreno/ir3: remove ir3_instruction::category

Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
Rob Clark 2016-03-27 13:43:45 -04:00
parent 70735643f4
commit 19739e4fb9
10 changed files with 84 additions and 93 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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)) {

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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;