glsl/linker: Check the invariance of built-in special variables
[mesa.git] / src / compiler / nir / nir_loop_analyze.c
index bc0c44ab1bb7e17153e0721cff789352d542397a..9c3fd2f286fbc7f43304b10b4831a3fe36a41238 100644 (file)
@@ -317,21 +317,25 @@ find_loop_terminators(loop_info_state *state)
           * not find a loop terminator, but there is a break-statement then
           * we should return false so that we do not try to find trip-count
           */
-         if (!nir_is_trivial_loop_if(nif, break_blk))
+         if (!nir_is_trivial_loop_if(nif, break_blk)) {
+            state->loop->info->complex_loop = true;
             return false;
+         }
 
          /* Continue if the if contained no jumps at all */
          if (!break_blk)
             continue;
 
-         if (nif->condition.ssa->parent_instr->type == nir_instr_type_phi)
+         if (nif->condition.ssa->parent_instr->type == nir_instr_type_phi) {
+            state->loop->info->complex_loop = true;
             return false;
+         }
 
          nir_loop_terminator *terminator =
             rzalloc(state->loop->info, nir_loop_terminator);
 
-         list_add(&terminator->loop_terminator_link,
-                  &state->loop->info->loop_terminator_list);
+         list_addtail(&terminator->loop_terminator_link,
+                      &state->loop->info->loop_terminator_list);
 
          terminator->nif = nif;
          terminator->break_block = break_blk;
@@ -619,51 +623,6 @@ find_trip_count(loop_info_state *state)
    state->loop->info->limiting_terminator = limiting_terminator;
 }
 
-/* Checks if we should force the loop to be unrolled regardless of size
- * due to array access heuristics.
- */
-static bool
-force_unroll_array_access_var(loop_info_state *state, nir_shader *ns,
-                              nir_deref_var *variable)
-{
-   nir_deref *tail = &variable->deref;
-
-   while (tail->child != NULL) {
-      tail = tail->child;
-
-      if (tail->deref_type == nir_deref_type_array) {
-
-         nir_deref_array *deref_array = nir_deref_as_array(tail);
-         if (deref_array->deref_array_type != nir_deref_array_type_indirect)
-            continue;
-
-         nir_loop_variable *array_index =
-            get_loop_var(deref_array->indirect.ssa, state);
-
-         if (array_index->type != basic_induction)
-            continue;
-
-         /* If an array is indexed by a loop induction variable, and the
-          * array size is exactly the number of loop iterations, this is
-          * probably a simple for-loop trying to access each element in
-          * turn; the application may expect it to be unrolled.
-          */
-         if (glsl_get_length(variable->deref.type) ==
-             state->loop->info->trip_count) {
-            state->loop->info->force_unroll = true;
-            return state->loop->info->force_unroll;
-         }
-
-         if (variable->var->data.mode & state->indirect_mask) {
-            state->loop->info->force_unroll = true;
-            return state->loop->info->force_unroll;
-         }
-      }
-   }
-
-   return false;
-}
-
 static bool
 force_unroll_array_access(loop_info_state *state, nir_shader *ns,
                           nir_deref_instr *deref)
@@ -708,17 +667,6 @@ force_unroll_heuristics(loop_info_state *state, nir_shader *ns,
       /* Check for arrays variably-indexed by a loop induction variable.
        * Unrolling the loop may convert that access into constant-indexing.
        */
-      if (intrin->intrinsic == nir_intrinsic_load_var ||
-          intrin->intrinsic == nir_intrinsic_store_var ||
-          intrin->intrinsic == nir_intrinsic_copy_var) {
-         unsigned num_vars =
-            nir_intrinsic_infos[intrin->intrinsic].num_variables;
-         for (unsigned i = 0; i < num_vars; i++) {
-            if (force_unroll_array_access_var(state, ns, intrin->variables[i]))
-               return true;
-         }
-      }
-
       if (intrin->intrinsic == nir_intrinsic_load_deref ||
           intrin->intrinsic == nir_intrinsic_store_deref ||
           intrin->intrinsic == nir_intrinsic_copy_deref) {
@@ -773,13 +721,6 @@ get_loop_info(loop_info_state *state, nir_function_impl *impl)
       }
    }
 
-   /* Induction analysis needs invariance information so get that first */
-   compute_invariance_information(state);
-
-   /* We have invariance information so try to find induction variables */
-   if (!compute_induction_information(state))
-      return;
-
    /* Try to find all simple terminators of the loop. If we can't find any,
     * or we find possible terminators that have side effects then bail.
     */
@@ -793,6 +734,13 @@ get_loop_info(loop_info_state *state, nir_function_impl *impl)
       return;
    }
 
+   /* Induction analysis needs invariance information so get that first */
+   compute_invariance_information(state);
+
+   /* We have invariance information so try to find induction variables */
+   if (!compute_induction_information(state))
+      return;
+
    /* Run through each of the terminators and try to compute a trip-count */
    find_trip_count(state);