summaryrefslogtreecommitdiff
path: root/src/compiler/nir/nir_search.c
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2019-02-19 21:11:20 -0800
committerIan Romanick <ian.d.romanick@intel.com>2019-03-26 10:29:21 -0700
commit1cf05f9d762219626f0d9b168961319ec1eb0fc8 (patch)
treebf019d69f551b3d70f5a9dcd0dda8a348ebd0038 /src/compiler/nir/nir_search.c
parente16ac33f374bb23e4f2e9a2cb87261e0939ab0c7 (diff)
WIP: nir/search: Slightly relax restriction that all sources must be SSA
Matching ('fadd', a, b) if one or both of 'a' and 'b' is not SSA is fine. Matching ('fadd', a, a) if 'a' is not SSA is not. Relaxing this restriction makes some of the nir_search infrastructure useable after the program is transitioned out of SSA form. TODO: Add some unit tests.
Diffstat (limited to 'src/compiler/nir/nir_search.c')
-rw-r--r--src/compiler/nir/nir_search.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c
index d257b6391892..7c7f1a0afe79 100644
--- a/src/compiler/nir/nir_search.c
+++ b/src/compiler/nir/nir_search.c
@@ -35,6 +35,9 @@ struct match_state {
bool has_exact_alu;
unsigned variables_seen;
nir_alu_src variables[NIR_SEARCH_MAX_VARIABLES];
+
+ /** For each entry in variables, is it SSA? */
+ bool is_ssa[NIR_SEARCH_MAX_VARIABLES];
};
static bool
@@ -193,15 +196,6 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
{
uint8_t new_swizzle[NIR_MAX_VEC_COMPONENTS];
- /* Searching only works on SSA values because, if it's not SSA, we can't
- * know if the value changed between one instance of that value in the
- * expression and another. Also, the replace operation will place reads of
- * that value right before the last instruction in the expression we're
- * replacing so those reads will happen after the original reads and may
- * not be valid if they're register reads.
- */
- assert(instr->src[src].src.is_ssa);
-
/* If the source is an explicitly sized source, then we need to reset
* both the number of components and the swizzle.
*/
@@ -220,6 +214,9 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
switch (value->type) {
case nir_search_value_expression:
+ if (!instr->src[src].src.is_ssa)
+ return false;
+
if (instr->src[src].src.ssa->parent_instr->type != nir_instr_type_alu)
return false;
@@ -232,6 +229,9 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
assert(var->variable < NIR_SEARCH_MAX_VARIABLES);
if (state->variables_seen & (1 << var->variable)) {
+ if (!instr->src[src].src.is_ssa || !state->is_ssa[var->variable])
+ return false;
+
if (state->variables[var->variable].src.ssa != instr->src[src].src.ssa)
return false;
@@ -259,6 +259,7 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
state->variables[var->variable].src = instr->src[src].src;
state->variables[var->variable].abs = false;
state->variables[var->variable].negate = false;
+ state->is_ssa[var->variable] = instr->src[src].src.is_ssa;
for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; ++i) {
if (i < num_components)
@@ -511,9 +512,7 @@ nir_replace_instr(nir_builder *build, nir_alu_instr *instr,
assert(instr->dest.dest.is_ssa);
struct match_state state;
- state.inexact_match = false;
- state.has_exact_alu = false;
- state.variables_seen = 0;
+ memset(&state, 0, sizeof(state));
if (!match_expression(search, instr, instr->dest.dest.ssa.num_components,
swizzle, &state))