2 * Copyright © 2015 Thomas Helland
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 #include "nir_constant_expressions.h"
26 #include "nir_loop_analyze.h"
33 } nir_loop_variable_type
;
35 struct nir_basic_induction_var
;
38 /* A link for the work list */
39 struct list_head process_link
;
43 /* The ssa_def associated with this info */
46 /* The type of this ssa_def */
47 nir_loop_variable_type type
;
49 /* If this is of type basic_induction */
50 struct nir_basic_induction_var
*ind
;
52 /* True if variable is in an if branch or a nested loop */
57 typedef struct nir_basic_induction_var
{
58 nir_op alu_op
; /* The type of alu-operation */
59 nir_loop_variable
*alu_def
; /* The def of the alu-operation */
60 nir_loop_variable
*invariant
; /* The invariant alu-operand */
61 nir_loop_variable
*def_outside_loop
; /* The phi-src outside the loop */
62 } nir_basic_induction_var
;
65 /* The loop we store information for */
68 /* Loop_variable for all ssa_defs in function */
69 nir_loop_variable
*loop_vars
;
71 /* A list of the loop_vars to analyze */
72 struct list_head process_list
;
74 nir_variable_mode indirect_mask
;
78 static nir_loop_variable
*
79 get_loop_var(nir_ssa_def
*value
, loop_info_state
*state
)
81 return &(state
->loop_vars
[value
->index
]);
85 loop_info_state
*state
;
90 init_loop_def(nir_ssa_def
*def
, void *void_init_loop_state
)
92 init_loop_state
*loop_init_state
= void_init_loop_state
;
93 nir_loop_variable
*var
= get_loop_var(def
, loop_init_state
->state
);
95 if (loop_init_state
->in_control_flow
) {
96 var
->in_control_flow
= true;
98 /* Add to the tail of the list. That way we start at the beginning of
99 * the defs in the loop instead of the end when walking the list. This
100 * means less recursive calls. Only add defs that are not in nested
101 * loops or conditional blocks.
103 list_addtail(&var
->process_link
, &loop_init_state
->state
->process_list
);
112 init_loop_block(nir_block
*block
, loop_info_state
*state
,
113 bool in_control_flow
)
115 init_loop_state init_state
= {.in_control_flow
= in_control_flow
,
118 nir_foreach_instr(instr
, block
) {
119 if (instr
->type
== nir_instr_type_intrinsic
||
120 instr
->type
== nir_instr_type_alu
||
121 instr
->type
== nir_instr_type_tex
) {
122 state
->loop
->info
->num_instructions
++;
125 nir_foreach_ssa_def(instr
, init_loop_def
, &init_state
);
132 is_var_alu(nir_loop_variable
*var
)
134 return var
->def
->parent_instr
->type
== nir_instr_type_alu
;
138 is_var_constant(nir_loop_variable
*var
)
140 return var
->def
->parent_instr
->type
== nir_instr_type_load_const
;
144 is_var_phi(nir_loop_variable
*var
)
146 return var
->def
->parent_instr
->type
== nir_instr_type_phi
;
150 mark_invariant(nir_ssa_def
*def
, loop_info_state
*state
)
152 nir_loop_variable
*var
= get_loop_var(def
, state
);
154 if (var
->type
== invariant
)
158 var
->type
= invariant
;
162 if (var
->type
== not_invariant
)
165 if (is_var_alu(var
)) {
166 nir_alu_instr
*alu
= nir_instr_as_alu(def
->parent_instr
);
168 for (unsigned i
= 0; i
< nir_op_infos
[alu
->op
].num_inputs
; i
++) {
169 if (!mark_invariant(alu
->src
[i
].src
.ssa
, state
)) {
170 var
->type
= not_invariant
;
174 var
->type
= invariant
;
178 /* Phis shouldn't be invariant except if one operand is invariant, and the
179 * other is the phi itself. These should be removed by opt_remove_phis.
180 * load_consts are already set to invariant and constant during init,
181 * and so should return earlier. Remaining op_codes are set undefined.
183 var
->type
= not_invariant
;
188 compute_invariance_information(loop_info_state
*state
)
190 /* An expression is invariant in a loop L if:
193 * – it’s a variable use, all of whose single defs are outside of L
195 * – it’s a pure computation all of whose args are loop invariant
196 * – it’s a variable use whose single reaching def, and the
197 * rhs of that def is loop-invariant
199 list_for_each_entry_safe(nir_loop_variable
, var
, &state
->process_list
,
201 assert(!var
->in_control_flow
);
203 if (mark_invariant(var
->def
, state
))
204 list_del(&var
->process_link
);
209 compute_induction_information(loop_info_state
*state
)
211 bool found_induction_var
= false;
212 list_for_each_entry_safe(nir_loop_variable
, var
, &state
->process_list
,
215 /* It can't be an induction variable if it is invariant. Invariants and
216 * things in nested loops or conditionals should have been removed from
217 * the list by compute_invariance_information().
219 assert(!var
->in_control_flow
&& var
->type
!= invariant
);
221 /* We are only interested in checking phis for the basic induction
222 * variable case as its simple to detect. All basic induction variables
225 if (!is_var_phi(var
))
228 nir_phi_instr
*phi
= nir_instr_as_phi(var
->def
->parent_instr
);
229 nir_basic_induction_var
*biv
= rzalloc(state
, nir_basic_induction_var
);
231 nir_foreach_phi_src(src
, phi
) {
232 nir_loop_variable
*src_var
= get_loop_var(src
->src
.ssa
, state
);
234 /* If one of the sources is in a conditional or nested block then
237 if (src_var
->in_control_flow
)
240 if (!src_var
->in_loop
) {
241 biv
->def_outside_loop
= src_var
;
242 } else if (is_var_alu(src_var
)) {
243 nir_alu_instr
*alu
= nir_instr_as_alu(src_var
->def
->parent_instr
);
245 if (nir_op_infos
[alu
->op
].num_inputs
== 2) {
246 biv
->alu_def
= src_var
;
247 biv
->alu_op
= alu
->op
;
249 for (unsigned i
= 0; i
< 2; i
++) {
250 /* Is one of the operands const, and the other the phi */
251 if (alu
->src
[i
].src
.ssa
->parent_instr
->type
== nir_instr_type_load_const
&&
252 alu
->src
[1-i
].src
.ssa
== &phi
->dest
.ssa
)
253 biv
->invariant
= get_loop_var(alu
->src
[i
].src
.ssa
, state
);
259 if (biv
->alu_def
&& biv
->def_outside_loop
&& biv
->invariant
&&
260 is_var_constant(biv
->def_outside_loop
)) {
261 assert(is_var_constant(biv
->invariant
));
262 biv
->alu_def
->type
= basic_induction
;
263 biv
->alu_def
->ind
= biv
;
264 var
->type
= basic_induction
;
267 found_induction_var
= true;
272 return found_induction_var
;
276 initialize_ssa_def(nir_ssa_def
*def
, void *void_state
)
278 loop_info_state
*state
= void_state
;
279 nir_loop_variable
*var
= get_loop_var(def
, state
);
281 var
->in_loop
= false;
284 if (def
->parent_instr
->type
== nir_instr_type_load_const
) {
285 var
->type
= invariant
;
287 var
->type
= undefined
;
294 ends_in_break(nir_block
*block
)
296 if (exec_list_is_empty(&block
->instr_list
))
299 nir_instr
*instr
= nir_block_last_instr(block
);
300 return instr
->type
== nir_instr_type_jump
&&
301 nir_instr_as_jump(instr
)->type
== nir_jump_break
;
305 find_loop_terminators(loop_info_state
*state
)
307 bool success
= false;
308 foreach_list_typed_safe(nir_cf_node
, node
, node
, &state
->loop
->body
) {
309 if (node
->type
== nir_cf_node_if
) {
310 nir_if
*nif
= nir_cf_node_as_if(node
);
312 nir_block
*break_blk
= NULL
;
313 nir_block
*continue_from_blk
= NULL
;
314 bool continue_from_then
= true;
316 nir_block
*last_then
= nir_if_last_then_block(nif
);
317 nir_block
*last_else
= nir_if_last_else_block(nif
);
318 if (ends_in_break(last_then
)) {
319 break_blk
= last_then
;
320 continue_from_blk
= last_else
;
321 continue_from_then
= false;
322 } else if (ends_in_break(last_else
)) {
323 break_blk
= last_else
;
324 continue_from_blk
= last_then
;
327 /* If there is a break then we should find a terminator. If we can
328 * not find a loop terminator, but there is a break-statement then
329 * we should return false so that we do not try to find trip-count
331 if (!nir_is_trivial_loop_if(nif
, break_blk
))
334 /* Continue if the if contained no jumps at all */
338 if (nif
->condition
.ssa
->parent_instr
->type
== nir_instr_type_phi
)
341 nir_loop_terminator
*terminator
=
342 rzalloc(state
->loop
->info
, nir_loop_terminator
);
344 list_add(&terminator
->loop_terminator_link
,
345 &state
->loop
->info
->loop_terminator_list
);
347 terminator
->nif
= nif
;
348 terminator
->break_block
= break_blk
;
349 terminator
->continue_from_block
= continue_from_blk
;
350 terminator
->continue_from_then
= continue_from_then
;
351 terminator
->conditional_instr
= nif
->condition
.ssa
->parent_instr
;
361 get_iteration(nir_op cond_op
, nir_const_value
*initial
, nir_const_value
*step
,
362 nir_const_value
*limit
)
371 int32_t initial_val
= initial
->i32
[0];
372 int32_t span
= limit
->i32
[0] - initial_val
;
373 iter
= span
/ step
->i32
[0];
378 uint32_t initial_val
= initial
->u32
[0];
379 uint32_t span
= limit
->u32
[0] - initial_val
;
380 iter
= span
/ step
->u32
[0];
387 float initial_val
= initial
->f32
[0];
388 float span
= limit
->f32
[0] - initial_val
;
389 iter
= span
/ step
->f32
[0];
400 test_iterations(int32_t iter_int
, nir_const_value
*step
,
401 nir_const_value
*limit
, nir_op cond_op
, unsigned bit_size
,
402 nir_alu_type induction_base_type
,
403 nir_const_value
*initial
, bool limit_rhs
, bool invert_cond
)
405 assert(nir_op_infos
[cond_op
].num_inputs
== 2);
407 nir_const_value iter_src
= { {0, } };
410 switch (induction_base_type
) {
412 iter_src
.f32
[0] = (float) iter_int
;
413 mul_op
= nir_op_fmul
;
414 add_op
= nir_op_fadd
;
418 iter_src
.i32
[0] = iter_int
;
419 mul_op
= nir_op_imul
;
420 add_op
= nir_op_iadd
;
423 unreachable("Unhandled induction variable base type!");
426 /* Multiple the iteration count we are testing by the number of times we
427 * step the induction variable each iteration.
429 nir_const_value mul_src
[2] = { iter_src
, *step
};
430 nir_const_value mul_result
=
431 nir_eval_const_opcode(mul_op
, 1, bit_size
, mul_src
);
433 /* Add the initial value to the accumulated induction variable total */
434 nir_const_value add_src
[2] = { mul_result
, *initial
};
435 nir_const_value add_result
=
436 nir_eval_const_opcode(add_op
, 1, bit_size
, add_src
);
438 nir_const_value src
[2] = { { {0, } }, { {0, } } };
439 src
[limit_rhs
? 0 : 1] = add_result
;
440 src
[limit_rhs
? 1 : 0] = *limit
;
442 /* Evaluate the loop exit condition */
443 nir_const_value result
= nir_eval_const_opcode(cond_op
, 1, bit_size
, src
);
445 return invert_cond
? (result
.u32
[0] == 0) : (result
.u32
[0] != 0);
449 calculate_iterations(nir_const_value
*initial
, nir_const_value
*step
,
450 nir_const_value
*limit
, nir_loop_variable
*alu_def
,
451 nir_alu_instr
*cond_alu
, bool limit_rhs
, bool invert_cond
)
453 assert(initial
!= NULL
&& step
!= NULL
&& limit
!= NULL
);
455 nir_alu_instr
*alu
= nir_instr_as_alu(alu_def
->def
->parent_instr
);
457 /* nir_op_isub should have been lowered away by this point */
458 assert(alu
->op
!= nir_op_isub
);
460 /* Make sure the alu type for our induction variable is compatible with the
461 * conditional alus input type. If its not something has gone really wrong.
463 nir_alu_type induction_base_type
=
464 nir_alu_type_get_base_type(nir_op_infos
[alu
->op
].output_type
);
465 if (induction_base_type
== nir_type_int
|| induction_base_type
== nir_type_uint
) {
466 assert(nir_alu_type_get_base_type(nir_op_infos
[cond_alu
->op
].input_types
[1]) == nir_type_int
||
467 nir_alu_type_get_base_type(nir_op_infos
[cond_alu
->op
].input_types
[1]) == nir_type_uint
);
469 assert(nir_alu_type_get_base_type(nir_op_infos
[cond_alu
->op
].input_types
[0]) ==
470 induction_base_type
);
473 /* Check for nsupported alu operations */
474 if (alu
->op
!= nir_op_iadd
&& alu
->op
!= nir_op_fadd
)
477 /* do-while loops can increment the starting value before the condition is
484 * Here we check if the induction variable is used directly by the loop
485 * condition and if so we assume we need to step the initial value.
487 unsigned trip_offset
= 0;
488 if (cond_alu
->src
[0].src
.ssa
== alu_def
->def
||
489 cond_alu
->src
[1].src
.ssa
== alu_def
->def
) {
493 int iter_int
= get_iteration(cond_alu
->op
, initial
, step
, limit
);
495 /* If iter_int is negative the loop is ill-formed or is the conditional is
496 * unsigned with a huge iteration count so don't bother going any further.
501 /* An explanation from the GLSL unrolling pass:
503 * Make sure that the calculated number of iterations satisfies the exit
504 * condition. This is needed to catch off-by-one errors and some types of
505 * ill-formed loops. For example, we need to detect that the following
506 * loop does not have a maximum iteration count.
508 * for (float x = 0.0; x != 0.9; x += 0.2);
510 assert(nir_src_bit_size(alu
->src
[0].src
) ==
511 nir_src_bit_size(alu
->src
[1].src
));
512 unsigned bit_size
= nir_src_bit_size(alu
->src
[0].src
);
513 for (int bias
= -1; bias
<= 1; bias
++) {
514 const int iter_bias
= iter_int
+ bias
;
516 if (test_iterations(iter_bias
, step
, limit
, cond_alu
->op
, bit_size
,
517 induction_base_type
, initial
,
518 limit_rhs
, invert_cond
)) {
519 return iter_bias
> 0 ? iter_bias
- trip_offset
: iter_bias
;
526 /* Run through each of the terminators of the loop and try to infer a possible
527 * trip-count. We need to check them all, and set the lowest trip-count as the
528 * trip-count of our loop. If one of the terminators has an undecidable
529 * trip-count we can not safely assume anything about the duration of the
533 find_trip_count(loop_info_state
*state
)
535 bool trip_count_known
= true;
536 nir_loop_terminator
*limiting_terminator
= NULL
;
537 int min_trip_count
= -1;
539 list_for_each_entry(nir_loop_terminator
, terminator
,
540 &state
->loop
->info
->loop_terminator_list
,
541 loop_terminator_link
) {
543 if (terminator
->conditional_instr
->type
!= nir_instr_type_alu
) {
544 /* If we get here the loop is dead and will get cleaned up by the
545 * nir_opt_dead_cf pass.
547 trip_count_known
= false;
551 nir_alu_instr
*alu
= nir_instr_as_alu(terminator
->conditional_instr
);
552 nir_loop_variable
*basic_ind
= NULL
;
553 nir_loop_variable
*limit
= NULL
;
554 bool limit_rhs
= true;
557 case nir_op_fge
: case nir_op_ige
: case nir_op_uge
:
558 case nir_op_flt
: case nir_op_ilt
: case nir_op_ult
:
559 case nir_op_feq
: case nir_op_ieq
:
560 case nir_op_fne
: case nir_op_ine
:
562 /* We assume that the limit is the "right" operand */
563 basic_ind
= get_loop_var(alu
->src
[0].src
.ssa
, state
);
564 limit
= get_loop_var(alu
->src
[1].src
.ssa
, state
);
566 if (basic_ind
->type
!= basic_induction
) {
567 /* We had it the wrong way, flip things around */
568 basic_ind
= get_loop_var(alu
->src
[1].src
.ssa
, state
);
569 limit
= get_loop_var(alu
->src
[0].src
.ssa
, state
);
573 /* The comparison has to have a basic induction variable
574 * and a constant for us to be able to find trip counts
576 if (basic_ind
->type
!= basic_induction
|| !is_var_constant(limit
)) {
577 trip_count_known
= false;
581 /* We have determined that we have the following constants:
582 * (With the typical int i = 0; i < x; i++; as an example)
585 * - Step / iteration size
586 * Thats all thats needed to calculate the trip-count
589 nir_const_value initial_val
=
590 nir_instr_as_load_const(basic_ind
->ind
->def_outside_loop
->
591 def
->parent_instr
)->value
;
593 nir_const_value step_val
=
594 nir_instr_as_load_const(basic_ind
->ind
->invariant
->def
->
595 parent_instr
)->value
;
597 nir_const_value limit_val
=
598 nir_instr_as_load_const(limit
->def
->parent_instr
)->value
;
600 int iterations
= calculate_iterations(&initial_val
, &step_val
,
602 basic_ind
->ind
->alu_def
, alu
,
604 terminator
->continue_from_then
);
606 /* Where we not able to calculate the iteration count */
607 if (iterations
== -1) {
608 trip_count_known
= false;
612 /* If this is the first run or we have found a smaller amount of
613 * iterations than previously (we have identified a more limiting
614 * terminator) set the trip count and limiting terminator.
616 if (min_trip_count
== -1 || iterations
< min_trip_count
) {
617 min_trip_count
= iterations
;
618 limiting_terminator
= terminator
;
623 trip_count_known
= false;
627 state
->loop
->info
->is_trip_count_known
= trip_count_known
;
628 if (min_trip_count
> -1)
629 state
->loop
->info
->trip_count
= min_trip_count
;
630 state
->loop
->info
->limiting_terminator
= limiting_terminator
;
633 /* Checks if we should force the loop to be unrolled regardless of size
634 * due to array access heuristics.
637 force_unroll_array_access(loop_info_state
*state
, nir_shader
*ns
,
638 nir_deref_var
*variable
)
640 nir_deref
*tail
= &variable
->deref
;
642 while (tail
->child
!= NULL
) {
645 if (tail
->deref_type
== nir_deref_type_array
) {
647 nir_deref_array
*deref_array
= nir_deref_as_array(tail
);
648 if (deref_array
->deref_array_type
!= nir_deref_array_type_indirect
)
651 nir_loop_variable
*array_index
=
652 get_loop_var(deref_array
->indirect
.ssa
, state
);
654 if (array_index
->type
!= basic_induction
)
657 /* If an array is indexed by a loop induction variable, and the
658 * array size is exactly the number of loop iterations, this is
659 * probably a simple for-loop trying to access each element in
660 * turn; the application may expect it to be unrolled.
662 if (glsl_get_length(variable
->deref
.type
) ==
663 state
->loop
->info
->trip_count
) {
664 state
->loop
->info
->force_unroll
= true;
665 return state
->loop
->info
->force_unroll
;
668 if (variable
->var
->data
.mode
& state
->indirect_mask
) {
669 state
->loop
->info
->force_unroll
= true;
670 return state
->loop
->info
->force_unroll
;
679 force_unroll_heuristics(loop_info_state
*state
, nir_shader
*ns
,
682 nir_foreach_instr(instr
, block
) {
683 if (instr
->type
!= nir_instr_type_intrinsic
)
686 nir_intrinsic_instr
*intrin
= nir_instr_as_intrinsic(instr
);
688 /* Check for arrays variably-indexed by a loop induction variable.
689 * Unrolling the loop may convert that access into constant-indexing.
691 if (intrin
->intrinsic
== nir_intrinsic_load_var
||
692 intrin
->intrinsic
== nir_intrinsic_store_var
||
693 intrin
->intrinsic
== nir_intrinsic_copy_var
) {
695 nir_intrinsic_infos
[intrin
->intrinsic
].num_variables
;
696 for (unsigned i
= 0; i
< num_vars
; i
++) {
697 if (force_unroll_array_access(state
, ns
, intrin
->variables
[i
]))
707 get_loop_info(loop_info_state
*state
, nir_function_impl
*impl
)
709 /* Initialize all variables to "outside_loop". This also marks defs
710 * invariant and constant if they are nir_instr_type_load_consts
712 nir_foreach_block(block
, impl
) {
713 nir_foreach_instr(instr
, block
)
714 nir_foreach_ssa_def(instr
, initialize_ssa_def
, state
);
717 /* Add all entries in the outermost part of the loop to the processing list
718 * Mark the entries in conditionals or in nested loops accordingly
720 foreach_list_typed_safe(nir_cf_node
, node
, node
, &state
->loop
->body
) {
721 switch (node
->type
) {
723 case nir_cf_node_block
:
724 init_loop_block(nir_cf_node_as_block(node
), state
, false);
728 nir_foreach_block_in_cf_node(block
, node
)
729 init_loop_block(block
, state
, true);
732 case nir_cf_node_loop
:
733 nir_foreach_block_in_cf_node(block
, node
) {
734 init_loop_block(block
, state
, true);
738 case nir_cf_node_function
:
743 /* Induction analysis needs invariance information so get that first */
744 compute_invariance_information(state
);
746 /* We have invariance information so try to find induction variables */
747 if (!compute_induction_information(state
))
750 /* Try to find all simple terminators of the loop. If we can't find any,
751 * or we find possible terminators that have side effects then bail.
753 if (!find_loop_terminators(state
)) {
754 list_for_each_entry_safe(nir_loop_terminator
, terminator
,
755 &state
->loop
->info
->loop_terminator_list
,
756 loop_terminator_link
) {
757 list_del(&terminator
->loop_terminator_link
);
758 ralloc_free(terminator
);
763 /* Run through each of the terminators and try to compute a trip-count */
764 find_trip_count(state
);
766 nir_shader
*ns
= impl
->function
->shader
;
767 foreach_list_typed_safe(nir_cf_node
, node
, node
, &state
->loop
->body
) {
768 if (node
->type
== nir_cf_node_block
) {
769 if (force_unroll_heuristics(state
, ns
, nir_cf_node_as_block(node
)))
772 nir_foreach_block_in_cf_node(block
, node
) {
773 if (force_unroll_heuristics(state
, ns
, block
))
780 static loop_info_state
*
781 initialize_loop_info_state(nir_loop
*loop
, void *mem_ctx
,
782 nir_function_impl
*impl
)
784 loop_info_state
*state
= rzalloc(mem_ctx
, loop_info_state
);
785 state
->loop_vars
= rzalloc_array(mem_ctx
, nir_loop_variable
,
789 list_inithead(&state
->process_list
);
792 ralloc_free(loop
->info
);
794 loop
->info
= rzalloc(loop
, nir_loop_info
);
796 list_inithead(&loop
->info
->loop_terminator_list
);
802 process_loops(nir_cf_node
*cf_node
, nir_variable_mode indirect_mask
)
804 switch (cf_node
->type
) {
805 case nir_cf_node_block
:
807 case nir_cf_node_if
: {
808 nir_if
*if_stmt
= nir_cf_node_as_if(cf_node
);
809 foreach_list_typed(nir_cf_node
, nested_node
, node
, &if_stmt
->then_list
)
810 process_loops(nested_node
, indirect_mask
);
811 foreach_list_typed(nir_cf_node
, nested_node
, node
, &if_stmt
->else_list
)
812 process_loops(nested_node
, indirect_mask
);
815 case nir_cf_node_loop
: {
816 nir_loop
*loop
= nir_cf_node_as_loop(cf_node
);
817 foreach_list_typed(nir_cf_node
, nested_node
, node
, &loop
->body
)
818 process_loops(nested_node
, indirect_mask
);
822 unreachable("unknown cf node type");
825 nir_loop
*loop
= nir_cf_node_as_loop(cf_node
);
826 nir_function_impl
*impl
= nir_cf_node_get_function(cf_node
);
827 void *mem_ctx
= ralloc_context(NULL
);
829 loop_info_state
*state
= initialize_loop_info_state(loop
, mem_ctx
, impl
);
830 state
->indirect_mask
= indirect_mask
;
832 get_loop_info(state
, impl
);
834 ralloc_free(mem_ctx
);
838 nir_loop_analyze_impl(nir_function_impl
*impl
,
839 nir_variable_mode indirect_mask
)
841 nir_index_ssa_defs(impl
);
842 foreach_list_typed(nir_cf_node
, node
, node
, &impl
->body
)
843 process_loops(node
, indirect_mask
);