[Mesa-dev,2/3] nir/search: constant fold as we're building expressions

Submitted by Connor Abbott on Feb. 8, 2015, 1:05 a.m.

Details

Message ID 1423357546-30702-3-git-send-email-cwabbott0@gmail.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Connor Abbott Feb. 8, 2015, 1:05 a.m.
This is useful since later rules can recognize the constant without
needing to go through a constant folding pass. This is especially
important for the upcoming constant reassociation rules, since without
this it would take many runs of the optimization loop, one rule at a
time, to optimize one expression tree.

Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 src/glsl/nir/nir_search.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/src/glsl/nir/nir_search.c b/src/glsl/nir/nir_search.c
index 79cfdba..af41578 100644
--- a/src/glsl/nir/nir_search.c
+++ b/src/glsl/nir/nir_search.c
@@ -26,6 +26,7 @@ 
  */
 
 #include "nir_search.h"
+#include "nir_constant_expressions.h"
 
 struct match_state {
    unsigned variables_seen;
@@ -248,6 +249,9 @@  construct_value(const nir_search_value *value, nir_alu_type type,
       alu->dest.write_mask = (1 << num_components) - 1;
       alu->dest.saturate = false;
 
+      nir_const_value const_src[4];
+      bool all_const = true;
+
       for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) {
          /* If the source is an explicitly sized source, then we need to reset
           * the number of components to match.
@@ -259,12 +263,40 @@  construct_value(const nir_search_value *value, nir_alu_type type,
                                        nir_op_infos[alu->op].input_types[i],
                                        num_components,
                                        state, instr, mem_ctx);
+
+         nir_instr *src_instr = alu->src[i].src.ssa->parent_instr;
+         if (src_instr->type == nir_instr_type_load_const) {
+            nir_load_const_instr *load_const =
+               nir_instr_as_load_const(src_instr);
+            for (unsigned j = 0; j < num_components; j++)
+               const_src[i].u[j] = load_const->value.u[j];
+         } else {
+            all_const = false;
+         }
       }
 
       nir_instr_insert_before(instr, &alu->instr);
 
+      nir_src src = nir_src_for_ssa(&alu->dest.dest.ssa);
+
+      if (all_const) {
+         nir_const_value dst =
+            nir_eval_const_opcode(op, alu->dest.dest.ssa.num_components,
+                                  const_src);
+
+         nir_load_const_instr *load_const =
+            nir_load_const_instr_create(mem_ctx,
+                                        alu->dest.dest.ssa.num_components);
+
+         load_const->value = dst;
+
+         nir_instr_insert_before(instr, &load_const->instr);
+
+         src = nir_src_for_ssa(&load_const->def);
+      }
+
       nir_alu_src val;
-      val.src = nir_src_for_ssa(&alu->dest.dest.ssa);
+      val.src = src;
       val.negate = false;
       val.abs = false,
       memcpy(val.swizzle, identity_swizzle, sizeof val.swizzle);