[Mesa-dev] [PATCH 1/9] nir: tidy up swizzle handling in nir_search
Timothy Arceri
timothy.arceri at collabora.com
Tue Jan 10 09:41:50 UTC 2017
If we just check that we are not dealing with an identity swizzle
in match_value() before calling match_expression() we can avoid
a bunch of temp swizzle arrays and the passing it around and
resetting craziness.
---
src/compiler/nir/nir_search.c | 89 ++++++++++++++++++-------------------------
1 file changed, 38 insertions(+), 51 deletions(-)
diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c
index b34b13f..7a84b18 100644
--- a/src/compiler/nir/nir_search.c
+++ b/src/compiler/nir/nir_search.c
@@ -37,8 +37,7 @@ struct match_state {
static bool
match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
- unsigned num_components, const uint8_t *swizzle,
- struct match_state *state);
+ unsigned num_components, struct match_state *state);
static const uint8_t identity_swizzle[] = { 0, 1, 2, 3 };
@@ -93,22 +92,15 @@ src_is_type(nir_src src, nir_alu_type type)
static bool
match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
- unsigned num_components, const uint8_t *swizzle,
- struct match_state *state)
+ unsigned num_components, struct match_state *state)
{
- uint8_t new_swizzle[4];
-
/* If the source is an explicitly sized source, then we need to reset
- * both the number of components and the swizzle.
+ * the number of components.
*/
if (nir_op_infos[instr->op].input_sizes[src] != 0) {
num_components = nir_op_infos[instr->op].input_sizes[src];
- swizzle = identity_swizzle;
}
- for (unsigned i = 0; i < num_components; ++i)
- new_swizzle[i] = instr->src[src].swizzle[swizzle[i]];
-
/* If the value has a specific bit size and it doesn't match, bail */
if (value->bit_size &&
nir_src_bit_size(instr->src[src].src) != value->bit_size)
@@ -122,9 +114,23 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
if (instr->src[src].src.ssa->parent_instr->type != nir_instr_type_alu)
return false;
+ /* If we have an explicitly sized destination, we can only handle the
+ * identity swizzle. While dot(vec3(a, b, c).zxy) is a valid
+ * expression, we don't have the information right now to propagate that
+ * swizzle through. We can only properly propagate swizzles if the
+ * instruction is vectorized.
+ */
+ nir_alu_instr *alu_instr =
+ nir_instr_as_alu(instr->src[src].src.ssa->parent_instr);
+ if (nir_op_infos[alu_instr->op].output_size != 0) {
+ for (unsigned i = 0; i < num_components; i++) {
+ if (instr->src[src].swizzle[i] != i)
+ return false;
+ }
+ }
+
return match_expression(nir_search_value_as_expression(value),
- nir_instr_as_alu(instr->src[src].src.ssa->parent_instr),
- num_components, new_swizzle, state);
+ alu_instr, num_components, state);
case nir_search_value_variable: {
nir_search_variable *var = nir_search_value_as_variable(value);
@@ -138,7 +144,8 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
assert(!instr->src[src].abs && !instr->src[src].negate);
for (unsigned i = 0; i < num_components; ++i) {
- if (state->variables[var->variable].swizzle[i] != new_swizzle[i])
+ if (state->variables[var->variable].swizzle[i] !=
+ instr->src[src].swizzle[i])
return false;
}
@@ -148,7 +155,8 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const)
return false;
- if (var->cond && !var->cond(instr, src, num_components, new_swizzle))
+ if (var->cond && !var->cond(instr, src, num_components,
+ instr->src[src].swizzle))
return false;
if (var->type != nir_type_invalid &&
@@ -161,9 +169,10 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
state->variables[var->variable].negate = false;
for (unsigned i = 0; i < 4; ++i) {
- if (i < num_components)
- state->variables[var->variable].swizzle[i] = new_swizzle[i];
- else
+ if (i < num_components) {
+ state->variables[var->variable].swizzle[i] =
+ instr->src[src].swizzle[i];
+ } else
state->variables[var->variable].swizzle[i] = 0;
}
@@ -189,10 +198,10 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
double val;
switch (load->def.bit_size) {
case 32:
- val = load->value.f32[new_swizzle[i]];
+ val = load->value.f32[instr->src[src].swizzle[i]];
break;
case 64:
- val = load->value.f64[new_swizzle[i]];
+ val = load->value.f64[instr->src[src].swizzle[i]];
break;
default:
unreachable("unknown bit size");
@@ -208,10 +217,10 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
int64_t val;
switch (load->def.bit_size) {
case 32:
- val = load->value.i32[new_swizzle[i]];
+ val = load->value.i32[instr->src[src].swizzle[i]];
break;
case 64:
- val = load->value.i64[new_swizzle[i]];
+ val = load->value.i64[instr->src[src].swizzle[i]];
break;
default:
unreachable("unknown bit size");
@@ -228,10 +237,10 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
uint64_t val;
switch (load->def.bit_size) {
case 32:
- val = load->value.u32[new_swizzle[i]];
+ val = load->value.u32[instr->src[src].swizzle[i]];
break;
case 64:
- val = load->value.u64[new_swizzle[i]];
+ val = load->value.u64[instr->src[src].swizzle[i]];
break;
default:
unreachable("unknown bit size");
@@ -254,8 +263,7 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
static bool
match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
- unsigned num_components, const uint8_t *swizzle,
- struct match_state *state)
+ unsigned num_components, struct match_state *state)
{
if (instr->op != expr->opcode)
return false;
@@ -274,19 +282,6 @@ match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
assert(!instr->dest.saturate);
assert(nir_op_infos[instr->op].num_inputs > 0);
- /* If we have an explicitly sized destination, we can only handle the
- * identity swizzle. While dot(vec3(a, b, c).zxy) is a valid
- * expression, we don't have the information right now to propagate that
- * swizzle through. We can only properly propagate swizzles if the
- * instruction is vectorized.
- */
- if (nir_op_infos[instr->op].output_size != 0) {
- for (unsigned i = 0; i < num_components; i++) {
- if (swizzle[i] != i)
- return false;
- }
- }
-
/* Stash off the current variables_seen bitmask. This way we can
* restore it prior to matching in the commutative case below.
*/
@@ -294,8 +289,7 @@ match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
bool matched = true;
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
- if (!match_value(expr->srcs[i], instr, i, num_components,
- swizzle, state)) {
+ if (!match_value(expr->srcs[i], instr, i, num_components, state)) {
matched = false;
break;
}
@@ -313,12 +307,10 @@ match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
*/
state->variables_seen = variables_seen_stash;
- if (!match_value(expr->srcs[0], instr, 1, num_components,
- swizzle, state))
+ if (!match_value(expr->srcs[0], instr, 1, num_components, state))
return false;
- return match_value(expr->srcs[1], instr, 0, num_components,
- swizzle, state);
+ return match_value(expr->srcs[1], instr, 0, num_components, state);
} else {
return false;
}
@@ -578,11 +570,6 @@ nir_alu_instr *
nir_replace_instr(nir_alu_instr *instr, const nir_search_expression *search,
const nir_search_value *replace, void *mem_ctx)
{
- uint8_t swizzle[4] = { 0, 0, 0, 0 };
-
- for (unsigned i = 0; i < instr->dest.dest.ssa.num_components; ++i)
- swizzle[i] = i;
-
assert(instr->dest.dest.is_ssa);
struct match_state state;
@@ -591,7 +578,7 @@ nir_replace_instr(nir_alu_instr *instr, const nir_search_expression *search,
state.variables_seen = 0;
if (!match_expression(search, instr, instr->dest.dest.ssa.num_components,
- swizzle, &state))
+ &state))
return NULL;
void *bitsize_ctx = ralloc_context(NULL);
--
2.9.3
More information about the mesa-dev
mailing list