freedreno/ir3: do idiv lowering after main opt loop
authorRob Clark <robclark@freedesktop.org>
Mon, 9 May 2016 16:41:00 +0000 (12:41 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 3 Jun 2016 20:05:03 +0000 (16:05 -0400)
Give algebraic-opt pass a chance to catch udiv by const power-of-two,
before running lower-idiv pass.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_nir.c

index 58bef169ad09bbcad92d88afcda6eb363a833f69..023da3be292aa1eb6c1669295f7d2ea7ea22d3ec 100644 (file)
@@ -82,6 +82,27 @@ ir3_key_lowers_nir(const struct ir3_shader_key *key)
 
 #define OPT_V(nir, pass, ...) NIR_PASS_V(nir, pass, ##__VA_ARGS__)
 
+static void
+ir3_optimize_loop(nir_shader *s)
+{
+       bool progress;
+       do {
+               progress = false;
+
+               OPT_V(s, nir_lower_vars_to_ssa);
+               OPT_V(s, nir_lower_alu_to_scalar);
+               OPT_V(s, nir_lower_phis_to_scalar);
+
+               progress |= OPT(s, nir_copy_prop);
+               progress |= OPT(s, nir_opt_dce);
+               progress |= OPT(s, nir_opt_cse);
+               progress |= OPT(s, ir3_nir_lower_if_else);
+               progress |= OPT(s, nir_opt_algebraic);
+               progress |= OPT(s, nir_opt_constant_folding);
+
+       } while (progress);
+}
+
 struct nir_shader *
 ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
                const struct ir3_shader_key *key)
@@ -89,7 +110,6 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
        struct nir_lower_tex_options tex_options = {
                        .lower_rect = 0,
        };
-       bool progress;
 
        if (key) {
                switch (shader->type) {
@@ -145,24 +165,15 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
        }
 
        OPT_V(s, nir_lower_tex, &tex_options);
-       OPT_V(s, nir_lower_idiv);
        OPT_V(s, nir_lower_load_const_to_scalar);
 
-       do {
-               progress = false;
-
-               OPT_V(s, nir_lower_vars_to_ssa);
-               OPT_V(s, nir_lower_alu_to_scalar);
-               OPT_V(s, nir_lower_phis_to_scalar);
+       ir3_optimize_loop(s);
 
-               progress |= OPT(s, nir_copy_prop);
-               progress |= OPT(s, nir_opt_dce);
-               progress |= OPT(s, nir_opt_cse);
-               progress |= OPT(s, ir3_nir_lower_if_else);
-               progress |= OPT(s, nir_opt_algebraic);
-               progress |= OPT(s, nir_opt_constant_folding);
-
-       } while (progress);
+       /* do idiv lowering after first opt loop to give a chance for
+        * divide by immed power-of-two to be caught first:
+        */
+       if (OPT(s, nir_lower_idiv))
+               ir3_optimize_loop(s);
 
        OPT_V(s, nir_remove_dead_variables, nir_var_local);