diff --git a/src/intel/compiler/brw_inst.cpp b/src/intel/compiler/brw_inst.cpp index 852de8d7c8b..eb5277a561f 100644 --- a/src/intel/compiler/brw_inst.cpp +++ b/src/intel/compiler/brw_inst.cpp @@ -11,17 +11,25 @@ #include "brw_inst.h" #include "brw_isa_info.h" -static brw_inst * -brw_alloc_inst(brw_shader &s, unsigned num_srcs) +static inline unsigned +brw_inst_kind_size(brw_inst_kind kind) { - STATIC_ASSERT((sizeof(brw_inst) % alignof(brw_reg)) == 0); + return sizeof(brw_inst); +} - void *mem = ralloc_size(s.mem_ctx, sizeof(brw_inst) + num_srcs * sizeof(brw_reg)); - memset(mem, 0, sizeof(brw_inst)); +static brw_inst * +brw_alloc_inst(brw_shader &s, brw_inst_kind kind, unsigned num_srcs) +{ + const unsigned inst_size = brw_inst_kind_size(kind); + + assert((inst_size % alignof(brw_reg)) == 0); + + void *mem = ralloc_size(s.mem_ctx, inst_size + num_srcs * sizeof(brw_reg)); + memset(mem, 0, inst_size); brw_inst *inst = (brw_inst *)mem; if (num_srcs) - inst->src = (brw_reg *)((char*)mem + sizeof(brw_inst)); + inst->src = (brw_reg *)((char*)mem + inst_size); inst->sources = num_srcs; return inst; @@ -34,8 +42,10 @@ brw_new_inst(brw_shader &s, enum opcode opcode, unsigned exec_size, assert(exec_size != 0); assert(dst.file != IMM && dst.file != UNIFORM); - brw_inst *inst = brw_alloc_inst(s, num_srcs); + brw_inst_kind kind = brw_inst_kind_for_opcode(opcode); + brw_inst *inst = brw_alloc_inst(s, kind, num_srcs); + inst->kind = kind; inst->opcode = opcode; inst->dst = dst; inst->exec_size = exec_size; @@ -64,10 +74,11 @@ brw_new_inst(brw_shader &s, enum opcode opcode, unsigned exec_size, brw_inst * brw_clone_inst(brw_shader &s, const brw_inst *inst) { - brw_inst *clone = brw_alloc_inst(s, inst->sources); + brw_inst *clone = brw_alloc_inst(s, inst->kind, inst->sources); brw_reg *cloned_src = clone->src; - memcpy((void*)clone, inst, sizeof(brw_inst)); + const unsigned inst_size = brw_inst_kind_size(inst->kind); + memcpy((void*)clone, inst, inst_size); brw_exec_node_init(clone); clone->src = cloned_src; @@ -96,7 +107,15 @@ brw_inst * brw_transform_inst(brw_shader &s, brw_inst *inst, enum opcode new_opcode, unsigned new_num_sources) { - inst->opcode = new_opcode; + const brw_inst_kind kind = inst->kind; + const brw_inst_kind new_kind = brw_inst_kind_for_opcode(new_opcode); + + assert(new_kind == BRW_KIND_BASE); + + const unsigned inst_size = brw_inst_kind_size(kind); + const unsigned new_inst_size = brw_inst_kind_size(new_kind); + assert(new_inst_size <= inst_size); + if (new_num_sources == UINT_MAX) new_num_sources = brw_num_sources_for_opcode(s, new_opcode); assert(new_num_sources != UINT_MAX); @@ -109,10 +128,18 @@ brw_transform_inst(brw_shader &s, brw_inst *inst, enum opcode new_opcode, } inst->sources = new_num_sources; + inst->opcode = new_opcode; + inst->kind = new_kind; return inst; } +brw_inst_kind +brw_inst_kind_for_opcode(enum opcode opcode) +{ + return BRW_KIND_BASE; +} + bool brw_inst::is_send() const { diff --git a/src/intel/compiler/brw_inst.h b/src/intel/compiler/brw_inst.h index bc64c80f6fc..130f8f52141 100644 --- a/src/intel/compiler/brw_inst.h +++ b/src/intel/compiler/brw_inst.h @@ -39,8 +39,13 @@ struct bblock_t; struct brw_shader; -struct brw_inst : public brw_exec_node { -public: +enum ENUM_PACKED brw_inst_kind { + BRW_KIND_BASE, +}; + +brw_inst_kind brw_inst_kind_for_opcode(enum opcode opcode); + +struct brw_inst : brw_exec_node { brw_inst() = delete; brw_inst(const brw_inst&) = delete; @@ -153,6 +158,7 @@ public: enum opcode opcode; /* BRW_OPCODE_* or FS_OPCODE_* */ enum brw_conditional_mod conditional_mod; /**< BRW_CONDITIONAL_* */ enum brw_predicate predicate; + brw_inst_kind kind; tgl_swsb sched; /**< Scheduling info. */ diff --git a/src/intel/compiler/brw_opt_cse.cpp b/src/intel/compiler/brw_opt_cse.cpp index bbddb08446e..91f5bbca42e 100644 --- a/src/intel/compiler/brw_opt_cse.cpp +++ b/src/intel/compiler/brw_opt_cse.cpp @@ -241,6 +241,8 @@ operands_match(const brw_inst *a, const brw_inst *b, bool *negate) static bool instructions_match(brw_inst *a, brw_inst *b, bool *negate) { + /* `Kind` is derived from opcode, so skipped. */ + return a->opcode == b->opcode && a->exec_size == b->exec_size && a->group == b->group && @@ -291,6 +293,8 @@ hash_inst(const void *v) /* Skip ir and annotation - we don't care for equivalency purposes. */ + /* Skip `kind` since it is derived from the opcode. */ + const uint8_t u8data[] = { inst->sources, inst->exec_size, diff --git a/src/intel/compiler/brw_validate.cpp b/src/intel/compiler/brw_validate.cpp index 057d78a472c..92527ead7a1 100644 --- a/src/intel/compiler/brw_validate.cpp +++ b/src/intel/compiler/brw_validate.cpp @@ -304,6 +304,8 @@ brw_validate(const brw_shader &s) uint32_t last_used_address_register[16] = {}; foreach_inst_in_block (brw_inst, inst, block) { + VAL_ASSERT_EQ(inst->kind, brw_inst_kind_for_opcode(inst->opcode)); + brw_validate_instruction_phase(s, inst); switch (inst->opcode) {