[Mesa-dev] [RFC 2/5] nir/gcm: Loop over blocks in pin_instructions

Jason Ekstrand jason at jlekstrand.net
Sat Jan 14 22:37:38 UTC 2017


Now that we have the new block iterators, we can simplify things a bit.
---
 src/compiler/nir/nir_opt_gcm.c | 138 ++++++++++++++++++++---------------------
 1 file changed, 68 insertions(+), 70 deletions(-)

diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c
index 72ddc54..a07f2f1 100644
--- a/src/compiler/nir/nir_opt_gcm.c
+++ b/src/compiler/nir/nir_opt_gcm.c
@@ -112,89 +112,89 @@ gcm_build_block_info(struct exec_list *cf_list, struct gcm_state *state,
  * After this is completed, all instructions' pass_flags fields will be set
  * to either GCM_INSTR_PINNED or 0.
  */
-static bool
-gcm_pin_instructions_block(nir_block *block, struct gcm_state *state)
+static void
+gcm_pin_instructions(nir_function_impl *impl, struct gcm_state *state)
 {
-   nir_foreach_instr_safe(instr, block) {
-      switch (instr->type) {
-      case nir_instr_type_alu:
-         switch (nir_instr_as_alu(instr)->op) {
-         case nir_op_fddx:
-         case nir_op_fddy:
-         case nir_op_fddx_fine:
-         case nir_op_fddy_fine:
-         case nir_op_fddx_coarse:
-         case nir_op_fddy_coarse:
-            /* These can only go in uniform control flow; pin them for now */
-            instr->pass_flags = GCM_INSTR_PINNED;
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         switch (instr->type) {
+         case nir_instr_type_alu:
+            switch (nir_instr_as_alu(instr)->op) {
+            case nir_op_fddx:
+            case nir_op_fddy:
+            case nir_op_fddx_fine:
+            case nir_op_fddy_fine:
+            case nir_op_fddx_coarse:
+            case nir_op_fddy_coarse:
+               /* These can only go in uniform control flow; pin them for now */
+               instr->pass_flags = GCM_INSTR_PINNED;
+               break;
+
+            default:
+               instr->pass_flags = 0;
+               break;
+            }
             break;
 
-         default:
+         case nir_instr_type_tex:
+            switch (nir_instr_as_tex(instr)->op) {
+            case nir_texop_tex:
+            case nir_texop_txb:
+            case nir_texop_lod:
+               /* These two take implicit derivatives so they need to be pinned */
+               instr->pass_flags = GCM_INSTR_PINNED;
+               break;
+
+            default:
+               instr->pass_flags = 0;
+               break;
+            }
+            break;
+
+         case nir_instr_type_load_const:
             instr->pass_flags = 0;
             break;
+
+         case nir_instr_type_intrinsic: {
+            const nir_intrinsic_info *info =
+               &nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];
+
+            if ((info->flags & NIR_INTRINSIC_CAN_ELIMINATE) &&
+                (info->flags & NIR_INTRINSIC_CAN_REORDER)) {
+               instr->pass_flags = 0;
+            } else {
+               instr->pass_flags = GCM_INSTR_PINNED;
+            }
+            break;
          }
-         break;
 
-      case nir_instr_type_tex:
-         switch (nir_instr_as_tex(instr)->op) {
-         case nir_texop_tex:
-         case nir_texop_txb:
-         case nir_texop_lod:
-            /* These two take implicit derivatives so they need to be pinned */
+         case nir_instr_type_jump:
+         case nir_instr_type_ssa_undef:
+         case nir_instr_type_phi:
             instr->pass_flags = GCM_INSTR_PINNED;
             break;
 
          default:
-            instr->pass_flags = 0;
-            break;
+            unreachable("Invalid instruction type in GCM");
          }
-         break;
-
-      case nir_instr_type_load_const:
-         instr->pass_flags = 0;
-         break;
 
-      case nir_instr_type_intrinsic: {
-         const nir_intrinsic_info *info =
-            &nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];
-
-         if ((info->flags & NIR_INTRINSIC_CAN_ELIMINATE) &&
-             (info->flags & NIR_INTRINSIC_CAN_REORDER)) {
-            instr->pass_flags = 0;
-         } else {
-            instr->pass_flags = GCM_INSTR_PINNED;
+         if (!(instr->pass_flags & GCM_INSTR_PINNED)) {
+            /* If this is an unpinned instruction, go ahead and pull it out of
+             * the program and put it on the instrs list.  This has a couple
+             * of benifits.  First, it makes the scheduling algorithm more
+             * efficient because we can avoid walking over basic blocks and
+             * pinned instructions.  Second, it keeps us from causing linked
+             * list confusion when we're trying to put everything in its
+             * proper place at the end of the pass.
+             *
+             * Note that we don't use nir_instr_remove here because that also
+             * cleans up uses and defs and we want to keep that information.
+             */
+            exec_node_remove(&instr->node);
+            exec_list_push_tail(&state->instrs, &instr->node);
          }
-         break;
-      }
-
-      case nir_instr_type_jump:
-      case nir_instr_type_ssa_undef:
-      case nir_instr_type_phi:
-         instr->pass_flags = GCM_INSTR_PINNED;
-         break;
-
-      default:
-         unreachable("Invalid instruction type in GCM");
-      }
-
-      if (!(instr->pass_flags & GCM_INSTR_PINNED)) {
-         /* If this is an unpinned instruction, go ahead and pull it out of
-          * the program and put it on the instrs list.  This has a couple
-          * of benifits.  First, it makes the scheduling algorithm more
-          * efficient because we can avoid walking over basic blocks and
-          * pinned instructions.  Second, it keeps us from causing linked
-          * list confusion when we're trying to put everything in its
-          * proper place at the end of the pass.
-          *
-          * Note that we don't use nir_instr_remove here because that also
-          * cleans up uses and defs and we want to keep that information.
-          */
-         exec_node_remove(&instr->node);
-         exec_list_push_tail(&state->instrs, &instr->node);
       }
    }
-
-   return true;
 }
 
 static void
@@ -475,9 +475,7 @@ opt_gcm_impl(nir_function_impl *impl, bool value_number)
 
    gcm_build_block_info(&impl->body, &state, 0, 0);
 
-   nir_foreach_block(block, impl) {
-      gcm_pin_instructions_block(block, &state);
-   }
+   gcm_pin_instructions(impl, &state);
 
    bool progress = false;
    if (value_number) {
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list