diff options
author | Rhys Perry <pendingchaos02@gmail.com> | 2021-10-15 16:39:35 +0100 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-01-20 22:54:42 +0000 |
commit | 312a2849807f577f0bbdf10b4e5e5fd1c3546b02 (patch) | |
tree | 138c696d3774f06e7c315f87aac7631c3b65c7f7 | |
parent | f68797ead72c29678a54aae457dbd9e9b7946588 (diff) | |
download | mesa-312a2849807f577f0bbdf10b4e5e5fd1c3546b02.tar.gz |
nir/algebraic: add ignore_exact() wrapper
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13436>
-rw-r--r-- | src/compiler/nir/nir_algebraic.py | 40 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_algebraic.py | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_search.c | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_search.h | 5 |
4 files changed, 42 insertions, 7 deletions
diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py index bfe00d6ed85..9a4e8054345 100644 --- a/src/compiler/nir/nir_algebraic.py +++ b/src/compiler/nir/nir_algebraic.py @@ -98,13 +98,33 @@ class VarSet(object): def lock(self): self.immutable = True +class SearchExpression(object): + def __init__(self, expr): + self.opcode = expr[0] + self.sources = expr[1:] + self.ignore_exact = False + + @staticmethod + def create(val): + if isinstance(val, tuple): + return SearchExpression(val) + else: + assert(isinstance(val, SearchExpression)) + return val + + def __repr__(self): + l = [self.opcode, *self.sources] + if self.ignore_exact: + l.append('ignore_exact') + return repr((*l,)) + class Value(object): @staticmethod def create(val, name_base, varset, algebraic_pass): if isinstance(val, bytes): val = val.decode('utf-8') - if isinstance(val, tuple): + if isinstance(val, tuple) or isinstance(val, SearchExpression): return Expression(val, name_base, varset, algebraic_pass) elif isinstance(val, Expression): return val @@ -185,7 +205,9 @@ class Value(object): ${val.cond_index}, ${val.swizzle()}, % elif isinstance(val, Expression): - ${'true' if val.inexact else 'false'}, ${'true' if val.exact else 'false'}, + ${'true' if val.inexact else 'false'}, + ${'true' if val.exact else 'false'}, + ${'true' if val.ignore_exact else 'false'}, ${val.c_opcode()}, ${val.comm_expr_idx}, ${val.comm_exprs}, { ${', '.join(src.array_index for src in val.sources)} }, @@ -339,15 +361,17 @@ _opcode_re = re.compile(r"(?P<inexact>~)?(?P<exact>!)?(?P<opcode>\w+)(?:@(?P<bit class Expression(Value): def __init__(self, expr, name_base, varset, algebraic_pass): Value.__init__(self, expr, name_base, "expression") - assert isinstance(expr, tuple) - m = _opcode_re.match(expr[0]) + expr = SearchExpression.create(expr) + + m = _opcode_re.match(expr.opcode) assert m and m.group('opcode') is not None self.opcode = m.group('opcode') self._bit_size = int(m.group('bits')) if m.group('bits') else None self.inexact = m.group('inexact') is not None self.exact = m.group('exact') is not None + self.ignore_exact = expr.ignore_exact self.cond = m.group('cond') assert not self.inexact or not self.exact, \ @@ -372,7 +396,7 @@ class Expression(Value): self.cond_index = get_cond_index(algebraic_pass.expression_cond, self.cond) self.sources = [ Value.create(src, "{0}_{1}".format(name_base, i), varset, algebraic_pass) - for (i, src) in enumerate(expr[1:]) ] + for (i, src) in enumerate(expr.sources) ] # nir_search_expression::srcs is hard-coded to 4 assert len(self.sources) <= 4 @@ -1235,3 +1259,9 @@ class AlgebraicPass(object): variable_cond = sorted(self.variable_cond.items(), key=lambda kv: kv[1]), get_c_opcode=get_c_opcode, itertools=itertools) + +# The replacement expression isn't necessarily exact if the search expression is exact. +def ignore_exact(*expr): + expr = SearchExpression.create(expr) + expr.ignore_exact = True + return expr diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 949e0f24278..147e0dd345d 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -41,6 +41,8 @@ e = 'e' signed_zero_inf_nan_preserve_16 = 'nir_is_float_control_signed_zero_inf_nan_preserve(info->float_controls_execution_mode, 16)' signed_zero_inf_nan_preserve_32 = 'nir_is_float_control_signed_zero_inf_nan_preserve(info->float_controls_execution_mode, 32)' +ignore_exact = nir_algebraic.ignore_exact + # Written in the form (<search>, <replace>) where <search> is an expression # and <replace> is either an expression or a value. An expression is # defined as a tuple of the form ([~]<op>, <src0>, <src1>, <src2>, <src3>) diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c index 3246d13ec8a..4fd7ad66143 100644 --- a/src/compiler/nir/nir_search.c +++ b/src/compiler/nir/nir_search.c @@ -408,7 +408,7 @@ match_expression(const nir_algebraic_table *table, const nir_search_expression * return false; state->inexact_match = expr->inexact || state->inexact_match; - state->has_exact_alu = instr->exact || state->has_exact_alu; + state->has_exact_alu = (instr->exact && !expr->ignore_exact) || state->has_exact_alu; if (state->inexact_match && state->has_exact_alu) return false; diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h index 2a7e9a2f0fe..fb56592cdd4 100644 --- a/src/compiler/nir/nir_search.h +++ b/src/compiler/nir/nir_search.h @@ -142,8 +142,11 @@ typedef struct { /** In a replacement, requests that the instruction be marked exact. */ bool exact : 1; + /** Don't make the replacement exact if the search expression is exact. */ + bool ignore_exact : 1; + /* One of nir_op or nir_search_op */ - uint16_t opcode : 14; + uint16_t opcode : 13; /* Commutative expression index. This is assigned by opt_algebraic.py when * search structures are constructed and is a unique (to this structure) |