diff options
-rw-r--r-- | src/compiler/nir/nir.h | 9 | ||||
-rw-r--r-- | src/compiler/nir/nir_algebraic.py | 4 | ||||
-rw-r--r-- | src/compiler/nir/nir_instr_set.c | 4 | ||||
-rw-r--r-- | src/compiler/nir/nir_opcodes.py | 91 |
4 files changed, 60 insertions, 48 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 8441c9f26c5..3e408e20f07 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -875,7 +875,14 @@ nir_op_vec(unsigned components) } typedef enum { - NIR_OP_IS_COMMUTATIVE = (1 << 0), + /** + * Operation where the first two sources are commutative. + * + * For 2-source operations, this just mathematical commutativity. Some + * 3-source operations, like ffma, are only commutative in the first two + * sources. + */ + NIR_OP_IS_2SRC_COMMUTATIVE = (1 << 0), NIR_OP_IS_ASSOCIATIVE = (1 << 1), } nir_op_algebraic_property; diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py index 47f374bfabd..d945c1a8075 100644 --- a/src/compiler/nir/nir_algebraic.py +++ b/src/compiler/nir/nir_algebraic.py @@ -340,7 +340,7 @@ class Expression(Value): """ self.comm_exprs = 0 if self.opcode not in conv_opcode_types and \ - "commutative" in opcodes[self.opcode].algebraic_properties: + "2src_commutative" in opcodes[self.opcode].algebraic_properties: self.comm_expr_idx = base_idx self.comm_exprs += 1 else: @@ -797,7 +797,7 @@ class TreeAutomaton(object): def get_item(opcode, children, pattern=None): commutative = len(children) == 2 \ - and "commutative" in opcodes[opcode].algebraic_properties + and "2src_commutative" in opcodes[opcode].algebraic_properties item = self.items.setdefault((opcode, children), self.Item(opcode, children)) if commutative: diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c index bd62bc974ed..c6a69d345c9 100644 --- a/src/compiler/nir/nir_instr_set.c +++ b/src/compiler/nir/nir_instr_set.c @@ -56,7 +56,7 @@ hash_alu(uint32_t hash, const nir_alu_instr *instr) hash = HASH(hash, instr->dest.dest.ssa.bit_size); /* We explicitly don't hash instr->dest.dest.exact */ - if (nir_op_infos[instr->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) { + if (nir_op_infos[instr->op].algebraic_properties & NIR_OP_IS_2SRC_COMMUTATIVE) { assert(nir_op_infos[instr->op].num_inputs == 2); uint32_t hash0 = hash_alu_src(hash, &instr->src[0], nir_ssa_alu_instr_src_components(instr, 0)); @@ -528,7 +528,7 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) /* We explicitly don't hash instr->dest.dest.exact */ - if (nir_op_infos[alu1->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) { + if (nir_op_infos[alu1->op].algebraic_properties & NIR_OP_IS_2SRC_COMMUTATIVE) { assert(nir_op_infos[alu1->op].num_inputs == 2); return (nir_alu_srcs_equal(alu1, alu2, 0, 0) && nir_alu_srcs_equal(alu1, alu2, 1, 1)) || diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 246d3d40381..fee9c221c16 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -134,7 +134,12 @@ def type_base_type(type_): assert m is not None, 'Invalid NIR type string: "{}"'.format(type_) return m.group('type') -commutative = "commutative " +# Operation where the first two sources are commutative. +# +# For 2-source operations, this just mathematical commutativity. Some +# 3-source operations, like ffma, are only commutative in the first two +# sources. +_2src_commutative = "2src_commutative " associative = "associative " # global dictionary of opcodes @@ -471,23 +476,23 @@ def binop_reduce(name, output_size, output_type, src_type, prereduce_expr, src2 = prereduce("src0.z", "src1.z") src3 = prereduce("src0.w", "src1.w") opcode(name + "2", output_size, output_type, - [2, 2], [src_type, src_type], False, commutative, + [2, 2], [src_type, src_type], False, _2src_commutative, final(reduce_(src0, src1))) opcode(name + "3", output_size, output_type, - [3, 3], [src_type, src_type], False, commutative, + [3, 3], [src_type, src_type], False, _2src_commutative, final(reduce_(reduce_(src0, src1), src2))) opcode(name + "4", output_size, output_type, - [4, 4], [src_type, src_type], False, commutative, + [4, 4], [src_type, src_type], False, _2src_commutative, final(reduce_(reduce_(src0, src1), reduce_(src2, src3)))) -binop("fadd", tfloat, commutative + associative, "src0 + src1") -binop("iadd", tint, commutative + associative, "src0 + src1") -binop("iadd_sat", tint, commutative, """ +binop("fadd", tfloat, _2src_commutative + associative, "src0 + src1") +binop("iadd", tint, _2src_commutative + associative, "src0 + src1") +binop("iadd_sat", tint, _2src_commutative, """ src1 > 0 ? (src0 + src1 < src0 ? (1ull << (bit_size - 1)) - 1 : src0 + src1) : (src0 < src0 + src1 ? (1ull << (bit_size - 1)) : src0 + src1) """) -binop("uadd_sat", tuint, commutative, +binop("uadd_sat", tuint, _2src_commutative, "(src0 + src1) < src0 ? MAX_UINT_FOR_SIZE(sizeof(src0) * 8) : (src0 + src1)") binop("isub_sat", tint, "", """ src1 < 0 ? @@ -499,18 +504,18 @@ binop("usub_sat", tuint, "", "src0 < src1 ? 0 : src0 - src1") binop("fsub", tfloat, "", "src0 - src1") binop("isub", tint, "", "src0 - src1") -binop("fmul", tfloat, commutative + associative, "src0 * src1") +binop("fmul", tfloat, _2src_commutative + associative, "src0 * src1") # low 32-bits of signed/unsigned integer multiply -binop("imul", tint, commutative + associative, "src0 * src1") +binop("imul", tint, _2src_commutative + associative, "src0 * src1") # Generate 64 bit result from 2 32 bits quantity -binop_convert("imul_2x32_64", tint64, tint32, commutative, +binop_convert("imul_2x32_64", tint64, tint32, _2src_commutative, "(int64_t)src0 * (int64_t)src1") -binop_convert("umul_2x32_64", tuint64, tuint32, commutative, +binop_convert("umul_2x32_64", tuint64, tuint32, _2src_commutative, "(uint64_t)src0 * (uint64_t)src1") # high 32-bits of signed integer multiply -binop("imul_high", tint, commutative, """ +binop("imul_high", tint, _2src_commutative, """ if (bit_size == 64) { /* We need to do a full 128-bit x 128-bit multiply in order for the sign * extension to work properly. The casts are kind-of annoying but needed @@ -537,7 +542,7 @@ if (bit_size == 64) { """) # high 32-bits of unsigned integer multiply -binop("umul_high", tuint, commutative, """ +binop("umul_high", tuint, _2src_commutative, """ if (bit_size == 64) { /* The casts are kind-of annoying but needed to prevent compiler warnings. */ uint32_t src0_u32[2] = { src0, (uint64_t)src0 >> 32 }; @@ -557,7 +562,7 @@ binop("udiv", tuint, "", "src1 == 0 ? 0 : (src0 / src1)") # returns a boolean representing the carry resulting from the addition of # the two unsigned arguments. -binop_convert("uadd_carry", tuint, tuint, commutative, "src0 + src1 < src0") +binop_convert("uadd_carry", tuint, tuint, _2src_commutative, "src0 + src1 < src0") # returns a boolean representing the borrow resulting from the subtraction # of the two unsigned arguments. @@ -574,8 +579,8 @@ binop_convert("usub_borrow", tuint, tuint, "", "src0 < src1") # # (x + y) >> 1 = (((x & y) << 1) + (x ^ y)) >> 1 # = (x & y) + ((x ^ y) >> 1) -binop("ihadd", tint, commutative, "(src0 & src1) + ((src0 ^ src1) >> 1)") -binop("uhadd", tuint, commutative, "(src0 & src1) + ((src0 ^ src1) >> 1)") +binop("ihadd", tint, _2src_commutative, "(src0 & src1) + ((src0 ^ src1) >> 1)") +binop("uhadd", tuint, _2src_commutative, "(src0 & src1) + ((src0 ^ src1) >> 1)") # rhadd: (a + b + 1) >> 1 (without overflow) # x + y + 1 = x + (~x & y) - (~x & y) + y + (x & ~y) - (x & ~y) + 1 @@ -587,8 +592,8 @@ binop("uhadd", tuint, commutative, "(src0 & src1) + ((src0 ^ src1) >> 1)") # # (x + y + 1) >> 1 = (x | y) + (-(x ^ y) + 1) >> 1) # = (x | y) - ((x ^ y) >> 1) -binop("irhadd", tint, commutative, "(src0 | src1) + ((src0 ^ src1) >> 1)") -binop("urhadd", tuint, commutative, "(src0 | src1) + ((src0 ^ src1) >> 1)") +binop("irhadd", tint, _2src_commutative, "(src0 | src1) + ((src0 ^ src1) >> 1)") +binop("urhadd", tuint, _2src_commutative, "(src0 | src1) + ((src0 ^ src1) >> 1)") binop("umod", tuint, "", "src1 == 0 ? 0 : src0 % src1") @@ -616,22 +621,22 @@ binop("frem", tfloat, "", "src0 - src1 * truncf(src0 / src1)") binop_compare("flt", tfloat, "", "src0 < src1") binop_compare("fge", tfloat, "", "src0 >= src1") -binop_compare("feq", tfloat, commutative, "src0 == src1") -binop_compare("fne", tfloat, commutative, "src0 != src1") +binop_compare("feq", tfloat, _2src_commutative, "src0 == src1") +binop_compare("fne", tfloat, _2src_commutative, "src0 != src1") binop_compare("ilt", tint, "", "src0 < src1") binop_compare("ige", tint, "", "src0 >= src1") -binop_compare("ieq", tint, commutative, "src0 == src1") -binop_compare("ine", tint, commutative, "src0 != src1") +binop_compare("ieq", tint, _2src_commutative, "src0 == src1") +binop_compare("ine", tint, _2src_commutative, "src0 != src1") binop_compare("ult", tuint, "", "src0 < src1") binop_compare("uge", tuint, "", "src0 >= src1") binop_compare32("flt32", tfloat, "", "src0 < src1") binop_compare32("fge32", tfloat, "", "src0 >= src1") -binop_compare32("feq32", tfloat, commutative, "src0 == src1") -binop_compare32("fne32", tfloat, commutative, "src0 != src1") +binop_compare32("feq32", tfloat, _2src_commutative, "src0 == src1") +binop_compare32("fne32", tfloat, _2src_commutative, "src0 != src1") binop_compare32("ilt32", tint, "", "src0 < src1") binop_compare32("ige32", tint, "", "src0 >= src1") -binop_compare32("ieq32", tint, commutative, "src0 == src1") -binop_compare32("ine32", tint, commutative, "src0 != src1") +binop_compare32("ieq32", tint, _2src_commutative, "src0 == src1") +binop_compare32("ine32", tint, _2src_commutative, "src0 != src1") binop_compare32("ult32", tuint, "", "src0 < src1") binop_compare32("uge32", tuint, "", "src0 >= src1") @@ -667,8 +672,8 @@ binop_reduce("fany_nequal", 1, tfloat32, tfloat32, "{src0} != {src1}", binop("slt", tfloat32, "", "(src0 < src1) ? 1.0f : 0.0f") # Set on Less Than binop("sge", tfloat, "", "(src0 >= src1) ? 1.0f : 0.0f") # Set on Greater or Equal -binop("seq", tfloat32, commutative, "(src0 == src1) ? 1.0f : 0.0f") # Set on Equal -binop("sne", tfloat32, commutative, "(src0 != src1) ? 1.0f : 0.0f") # Set on Not Equal +binop("seq", tfloat32, _2src_commutative, "(src0 == src1) ? 1.0f : 0.0f") # Set on Equal +binop("sne", tfloat32, _2src_commutative, "(src0 != src1) ? 1.0f : 0.0f") # Set on Not Equal # SPIRV shifts are undefined for shift-operands >= bitsize, # but SM5 shifts are defined to use the least significant bits, only @@ -686,9 +691,9 @@ opcode("ushr", 0, tuint, [0, 0], [tuint, tuint32], False, "", # integers. -binop("iand", tuint, commutative + associative, "src0 & src1") -binop("ior", tuint, commutative + associative, "src0 | src1") -binop("ixor", tuint, commutative + associative, "src0 ^ src1") +binop("iand", tuint, _2src_commutative + associative, "src0 & src1") +binop("ior", tuint, _2src_commutative + associative, "src0 | src1") +binop("ixor", tuint, _2src_commutative + associative, "src0 ^ src1") # floating point logic operators @@ -696,11 +701,11 @@ binop("ixor", tuint, commutative + associative, "src0 ^ src1") # These use (src != 0.0) for testing the truth of the input, and output 1.0 # for true and 0.0 for false -binop("fand", tfloat32, commutative, +binop("fand", tfloat32, _2src_commutative, "((src0 != 0.0f) && (src1 != 0.0f)) ? 1.0f : 0.0f") -binop("for", tfloat32, commutative, +binop("for", tfloat32, _2src_commutative, "((src0 != 0.0f) || (src1 != 0.0f)) ? 1.0f : 0.0f") -binop("fxor", tfloat32, commutative, +binop("fxor", tfloat32, _2src_commutative, "(src0 != 0.0f && src1 == 0.0f) || (src0 == 0.0f && src1 != 0.0f) ? 1.0f : 0.0f") binop_reduce("fdot", 1, tfloat, tfloat, "{src0} * {src1}", "{src0} + {src1}", @@ -715,14 +720,14 @@ opcode("fdph_replicated", 4, tfloat, [3, 4], [tfloat, tfloat], False, "", "src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w") binop("fmin", tfloat, "", "fminf(src0, src1)") -binop("imin", tint, commutative + associative, "src1 > src0 ? src0 : src1") -binop("umin", tuint, commutative + associative, "src1 > src0 ? src0 : src1") +binop("imin", tint, _2src_commutative + associative, "src1 > src0 ? src0 : src1") +binop("umin", tuint, _2src_commutative + associative, "src1 > src0 ? src0 : src1") binop("fmax", tfloat, "", "fmaxf(src0, src1)") -binop("imax", tint, commutative + associative, "src1 > src0 ? src1 : src0") -binop("umax", tuint, commutative + associative, "src1 > src0 ? src1 : src0") +binop("imax", tint, _2src_commutative + associative, "src1 > src0 ? src1 : src0") +binop("umax", tuint, _2src_commutative + associative, "src1 > src0 ? src1 : src0") # Saturated vector add for 4 8bit ints. -binop("usadd_4x8", tint32, commutative + associative, """ +binop("usadd_4x8", tint32, _2src_commutative + associative, """ dst = 0; for (int i = 0; i < 32; i += 8) { dst |= MIN2(((src0 >> i) & 0xff) + ((src1 >> i) & 0xff), 0xff) << i; @@ -741,7 +746,7 @@ for (int i = 0; i < 32; i += 8) { """) # vector min for 4 8bit ints. -binop("umin_4x8", tint32, commutative + associative, """ +binop("umin_4x8", tint32, _2src_commutative + associative, """ dst = 0; for (int i = 0; i < 32; i += 8) { dst |= MIN2((src0 >> i) & 0xff, (src1 >> i) & 0xff) << i; @@ -749,7 +754,7 @@ for (int i = 0; i < 32; i += 8) { """) # vector max for 4 8bit ints. -binop("umax_4x8", tint32, commutative + associative, """ +binop("umax_4x8", tint32, _2src_commutative + associative, """ dst = 0; for (int i = 0; i < 32; i += 8) { dst |= MAX2((src0 >> i) & 0xff, (src1 >> i) & 0xff) << i; @@ -757,7 +762,7 @@ for (int i = 0; i < 32; i += 8) { """) # unorm multiply: (a * b) / 255. -binop("umul_unorm_4x8", tint32, commutative + associative, """ +binop("umul_unorm_4x8", tint32, _2src_commutative + associative, """ dst = 0; for (int i = 0; i < 32; i += 8) { int src0_chan = (src0 >> i) & 0xff; |