[Mesa-dev] [PATCH 1/2] nir/search: Add support for matching unknown constants

Jason Ekstrand jason at jlekstrand.net
Fri Jan 23 16:20:28 PST 2015


There are some algebraic transformations that we want to do but only if
certain things are constants.  For instance, we may want to replace
a * (b + c) with (a * b) + (a * c) as long as a and either b or c is constant.
While this generates more instructions, some of it will get constant
folded.  This commit allows you to match an arbitrary constant value by
adding a "#" on the front of a variable name.
---
 src/glsl/nir/nir_algebraic.py | 8 ++++++++
 src/glsl/nir/nir_search.c     | 6 ++++++
 src/glsl/nir/nir_search.h     | 7 +++++++
 3 files changed, 21 insertions(+)

diff --git a/src/glsl/nir/nir_algebraic.py b/src/glsl/nir/nir_algebraic.py
index 5be2842..df3ceb3 100644
--- a/src/glsl/nir/nir_algebraic.py
+++ b/src/glsl/nir/nir_algebraic.py
@@ -62,6 +62,7 @@ static const ${val.c_type} ${val.name} = {
 % elif isinstance(val, Variable):
    ${val.index}, /* ${val.var_name} */
    { ${', '.join(str(s) for s in val.swizzle)} },
+   ${'true' if val.is_constant else 'false'},
 % elif isinstance(val, Expression):
    nir_op_${val.opcode},
    { ${', '.join(src.c_ptr for src in val.sources)} },
@@ -116,11 +117,18 @@ class Variable(Value):
 
       match = _swizzle_re.match(val)
       if match:
+         assert not val.startswith('#')
          val = match.group(1)
          self.swizzle = ['xyzw'.find(s) for s in match.group(2)]
       else:
          self.swizzle = range(4)
 
+      if val.startswith('#'):
+         val = val[1:]
+         self.is_constant = True
+      else:
+         self.is_constant = False
+
       self.var_name = val
       self.index = varset[val]
       self.name = name
diff --git a/src/glsl/nir/nir_search.c b/src/glsl/nir/nir_search.c
index 0d83ff5..6589edb 100644
--- a/src/glsl/nir/nir_search.c
+++ b/src/glsl/nir/nir_search.c
@@ -84,6 +84,10 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
 
          return true;
       } else {
+         if (var->is_constant &&
+             instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const)
+            return false;
+
          state->variables_seen |= (1 << var->variable);
          state->variables[var->variable].ssa = instr->src[src].src.ssa;
 
@@ -237,6 +241,8 @@ construct_value(const nir_search_value *value, nir_alu_type type,
       const nir_search_variable *var = nir_search_value_as_variable(value);
       assert(state->variables_seen & (1 << var->variable));
 
+      assert(!var->is_constant);
+
       nir_alu_src val;
       val.src = nir_src_for_ssa(state->variables[var->variable].ssa);
       val.abs = false;
diff --git a/src/glsl/nir/nir_search.h b/src/glsl/nir/nir_search.h
index 8b89dd0..902900f 100644
--- a/src/glsl/nir/nir_search.h
+++ b/src/glsl/nir/nir_search.h
@@ -54,6 +54,13 @@ typedef struct {
     * searches.
     */
    uint8_t swizzle[4];
+
+   /** Indicates that the given variable must be a constant
+    *
+    * This is only alloed in search expressions and indicates that the
+    * given variable is only allowed to match constant values.
+    */
+   bool is_constant;
 } nir_search_variable;
 
 typedef struct {
-- 
2.2.1



More information about the mesa-dev mailing list