2 * Copyright © 2016 Intel Corporation
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/nir_builder.h"
26 #include "nir_constant_expressions.h"
27 #include "nir_control_flow.h"
28 #include "nir_loop_analyze.h"
31 * Gets the single block that jumps back to the loop header. Already assumes
32 * there is exactly one such block.
35 find_continue_block(nir_loop
*loop
)
37 nir_block
*header_block
= nir_loop_first_block(loop
);
38 nir_block
*prev_block
=
39 nir_cf_node_as_block(nir_cf_node_prev(&loop
->cf_node
));
41 assert(header_block
->predecessors
->entries
== 2);
43 set_foreach(header_block
->predecessors
, pred_entry
) {
44 if (pred_entry
->key
!= prev_block
)
45 return (nir_block
*)pred_entry
->key
;
48 unreachable("Continue block not found!");
52 * Does a phi have one constant value from outside a loop and one from inside?
55 phi_has_constant_from_outside_and_one_from_inside_loop(nir_phi_instr
*phi
,
56 const nir_block
*entry_block
,
58 uint32_t *continue_val
)
60 /* We already know we have exactly one continue */
61 assert(exec_list_length(&phi
->srcs
) == 2);
66 nir_foreach_phi_src(src
, phi
) {
67 assert(src
->src
.is_ssa
);
68 nir_const_value
*const_src
= nir_src_as_const_value(src
->src
);
72 if (src
->pred
!= entry_block
) {
73 *continue_val
= const_src
->u32
[0];
75 *entry_val
= const_src
->u32
[0];
83 * This optimization detects if statements at the tops of loops where the
84 * condition is a phi node of two constants and moves half of the if to above
85 * the loop and the other half of the if to the end of the loop. A simple for
86 * loop "for (int i = 0; i < 4; i++)", when run through the SPIR-V front-end,
87 * ends up looking something like this:
89 * vec1 32 ssa_0 = load_const (0x00000000)
90 * vec1 32 ssa_1 = load_const (0xffffffff)
93 * vec1 32 ssa_2 = phi block_0: ssa_0, block_7: ssa_5
94 * vec1 32 ssa_3 = phi block_0: ssa_0, block_7: ssa_1
97 * vec1 32 ssa_4 = load_const (0x00000001)
98 * vec1 32 ssa_5 = iadd ssa_2, ssa_4
103 * vec1 32 ssa_6 = load_const (0x00000004)
104 * vec1 32 ssa_7 = ilt ssa_5, ssa_6
114 * This turns it into something like this:
116 * // Stuff from block 1
117 * // Stuff from block 3
120 * vec1 32 ssa_3 = phi block_0: ssa_0, block_7: ssa_1
121 * vec1 32 ssa_6 = load_const (0x00000004)
122 * vec1 32 ssa_7 = ilt ssa_5, ssa_6
130 * // Stuff from block 1
131 * // Stuff from block 2
132 * vec1 32 ssa_4 = load_const (0x00000001)
133 * vec1 32 ssa_5 = iadd ssa_2, ssa_4
137 opt_peel_loop_initial_if(nir_loop
*loop
)
139 nir_block
*header_block
= nir_loop_first_block(loop
);
140 nir_block
*const prev_block
=
141 nir_cf_node_as_block(nir_cf_node_prev(&loop
->cf_node
));
143 /* It would be insane if this were not true */
144 assert(_mesa_set_search(header_block
->predecessors
, prev_block
));
146 /* The loop must have exactly one continue block which could be a block
147 * ending in a continue instruction or the "natural" continue from the
148 * last block in the loop back to the top.
150 if (header_block
->predecessors
->entries
!= 2)
153 nir_cf_node
*if_node
= nir_cf_node_next(&header_block
->cf_node
);
154 if (!if_node
|| if_node
->type
!= nir_cf_node_if
)
157 nir_if
*nif
= nir_cf_node_as_if(if_node
);
158 assert(nif
->condition
.is_ssa
);
160 nir_ssa_def
*cond
= nif
->condition
.ssa
;
161 if (cond
->parent_instr
->type
!= nir_instr_type_phi
)
164 nir_phi_instr
*cond_phi
= nir_instr_as_phi(cond
->parent_instr
);
165 if (cond
->parent_instr
->block
!= header_block
)
168 uint32_t entry_val
= 0, continue_val
= 0;
169 if (!phi_has_constant_from_outside_and_one_from_inside_loop(cond_phi
,
175 /* If they both execute or both don't execute, this is a job for
176 * nir_dead_cf, not this pass.
178 if ((entry_val
&& continue_val
) || (!entry_val
&& !continue_val
))
181 struct exec_list
*continue_list
, *entry_list
;
183 continue_list
= &nif
->then_list
;
184 entry_list
= &nif
->else_list
;
186 continue_list
= &nif
->else_list
;
187 entry_list
= &nif
->then_list
;
190 /* We want to be moving the contents of entry_list to above the loop so it
191 * can't contain any break or continue instructions.
193 foreach_list_typed(nir_cf_node
, cf_node
, node
, entry_list
) {
194 nir_foreach_block_in_cf_node(block
, cf_node
) {
195 nir_instr
*last_instr
= nir_block_last_instr(block
);
196 if (last_instr
&& last_instr
->type
== nir_instr_type_jump
)
201 /* We're about to re-arrange a bunch of blocks so make sure that we don't
202 * have deref uses which cross block boundaries. We don't want a deref
203 * accidentally ending up in a phi.
205 nir_rematerialize_derefs_in_use_blocks_impl(
206 nir_cf_node_get_function(&loop
->cf_node
));
208 /* Before we do anything, convert the loop to LCSSA. We're about to
209 * replace a bunch of SSA defs with registers and this will prevent any of
210 * it from leaking outside the loop.
212 nir_convert_loop_to_lcssa(loop
);
214 nir_block
*after_if_block
=
215 nir_cf_node_as_block(nir_cf_node_next(&nif
->cf_node
));
217 /* Get rid of phis in the header block since we will be duplicating it */
218 nir_lower_phis_to_regs_block(header_block
);
219 /* Get rid of phis after the if since dominance will change */
220 nir_lower_phis_to_regs_block(after_if_block
);
222 /* Get rid of SSA defs in the pieces we're about to move around */
223 nir_lower_ssa_defs_to_regs_block(header_block
);
224 nir_foreach_block_in_cf_node(block
, &nif
->cf_node
)
225 nir_lower_ssa_defs_to_regs_block(block
);
227 nir_cf_list header
, tmp
;
228 nir_cf_extract(&header
, nir_before_block(header_block
),
229 nir_after_block(header_block
));
231 nir_cf_list_clone(&tmp
, &header
, &loop
->cf_node
, NULL
);
232 nir_cf_reinsert(&tmp
, nir_before_cf_node(&loop
->cf_node
));
233 nir_cf_extract(&tmp
, nir_before_cf_list(entry_list
),
234 nir_after_cf_list(entry_list
));
235 nir_cf_reinsert(&tmp
, nir_before_cf_node(&loop
->cf_node
));
237 nir_cf_reinsert(&header
,
238 nir_after_block_before_jump(find_continue_block(loop
)));
240 nir_cf_extract(&tmp
, nir_before_cf_list(continue_list
),
241 nir_after_cf_list(continue_list
));
243 /* Get continue block again as the previous reinsert might have removed the block. */
244 nir_cf_reinsert(&tmp
,
245 nir_after_block_before_jump(find_continue_block(loop
)));
247 nir_cf_node_remove(&nif
->cf_node
);
253 is_block_empty(nir_block
*block
)
255 return nir_cf_node_is_last(&block
->cf_node
) &&
256 exec_list_is_empty(&block
->instr_list
);
260 nir_block_ends_in_continue(nir_block
*block
)
262 if (exec_list_is_empty(&block
->instr_list
))
265 nir_instr
*instr
= nir_block_last_instr(block
);
266 return instr
->type
== nir_instr_type_jump
&&
267 nir_instr_as_jump(instr
)->type
== nir_jump_continue
;
271 * This optimization turns:
295 * The continue should then be removed by nir_opt_trivial_continues() and the
296 * loop can potentially be unrolled.
298 * Note: do_work_2() is only ever blocks and nested loops. We could also nest
299 * other if-statments in the branch which would allow further continues to
300 * be removed. However in practice this can result in increased register
304 opt_if_loop_last_continue(nir_loop
*loop
)
306 /* Get the last if-stament in the loop */
307 nir_block
*last_block
= nir_loop_last_block(loop
);
308 nir_cf_node
*if_node
= nir_cf_node_prev(&last_block
->cf_node
);
310 if (if_node
->type
== nir_cf_node_if
)
313 if_node
= nir_cf_node_prev(if_node
);
316 if (!if_node
|| if_node
->type
!= nir_cf_node_if
)
319 nir_if
*nif
= nir_cf_node_as_if(if_node
);
320 nir_block
*then_block
= nir_if_last_then_block(nif
);
321 nir_block
*else_block
= nir_if_last_else_block(nif
);
323 bool then_ends_in_continue
= nir_block_ends_in_continue(then_block
);
324 bool else_ends_in_continue
= nir_block_ends_in_continue(else_block
);
326 /* If both branches end in a continue do nothing, this should be handled
327 * by nir_opt_dead_cf().
329 if (then_ends_in_continue
&& else_ends_in_continue
)
332 if (!then_ends_in_continue
&& !else_ends_in_continue
)
335 /* Move the last block of the loop inside the last if-statement */
337 nir_cf_extract(&tmp
, nir_after_cf_node(if_node
),
338 nir_after_block(last_block
));
339 if (then_ends_in_continue
) {
340 nir_cursor last_blk_cursor
= nir_after_cf_list(&nif
->else_list
);
341 nir_cf_reinsert(&tmp
,
342 nir_after_block_before_jump(last_blk_cursor
.block
));
344 nir_cursor last_blk_cursor
= nir_after_cf_list(&nif
->then_list
);
345 nir_cf_reinsert(&tmp
,
346 nir_after_block_before_jump(last_blk_cursor
.block
));
349 /* In order to avoid running nir_lower_regs_to_ssa_impl() every time an if
350 * opt makes progress we leave nir_opt_trivial_continues() to remove the
351 * continue now that the end of the loop has been simplified.
357 /* Walk all the phis in the block immediately following the if statement and
361 rewrite_phi_predecessor_blocks(nir_if
*nif
,
362 nir_block
*old_then_block
,
363 nir_block
*old_else_block
,
364 nir_block
*new_then_block
,
365 nir_block
*new_else_block
)
367 nir_block
*after_if_block
=
368 nir_cf_node_as_block(nir_cf_node_next(&nif
->cf_node
));
370 nir_foreach_instr(instr
, after_if_block
) {
371 if (instr
->type
!= nir_instr_type_phi
)
374 nir_phi_instr
*phi
= nir_instr_as_phi(instr
);
376 foreach_list_typed(nir_phi_src
, src
, node
, &phi
->srcs
) {
377 if (src
->pred
== old_then_block
) {
378 src
->pred
= new_then_block
;
379 } else if (src
->pred
== old_else_block
) {
380 src
->pred
= new_else_block
;
387 * This optimization turns:
402 opt_if_simplification(nir_builder
*b
, nir_if
*nif
)
404 /* Only simplify if the then block is empty and the else block is not. */
405 if (!is_block_empty(nir_if_first_then_block(nif
)) ||
406 is_block_empty(nir_if_first_else_block(nif
)))
409 /* Make sure the condition is a comparison operation. */
410 nir_instr
*src_instr
= nif
->condition
.ssa
->parent_instr
;
411 if (src_instr
->type
!= nir_instr_type_alu
)
414 nir_alu_instr
*alu_instr
= nir_instr_as_alu(src_instr
);
415 if (!nir_alu_instr_is_comparison(alu_instr
))
418 /* Insert the inverted instruction and rewrite the condition. */
419 b
->cursor
= nir_after_instr(&alu_instr
->instr
);
421 nir_ssa_def
*new_condition
=
422 nir_inot(b
, &alu_instr
->dest
.dest
.ssa
);
424 nir_if_rewrite_condition(nif
, nir_src_for_ssa(new_condition
));
426 /* Grab pointers to the last then/else blocks for fixing up the phis. */
427 nir_block
*then_block
= nir_if_last_then_block(nif
);
428 nir_block
*else_block
= nir_if_last_else_block(nif
);
430 rewrite_phi_predecessor_blocks(nif
, then_block
, else_block
, else_block
,
433 /* Finally, move the else block to the then block. */
435 nir_cf_extract(&tmp
, nir_before_cf_list(&nif
->else_list
),
436 nir_after_cf_list(&nif
->else_list
));
437 nir_cf_reinsert(&tmp
, nir_before_cf_list(&nif
->then_list
));
443 * This optimization simplifies potential loop terminators which then allows
444 * other passes such as opt_if_simplification() and loop unrolling to progress
448 * ... then block instructions ...
461 * ... then block instructions ...
464 opt_if_loop_terminator(nir_if
*nif
)
466 nir_block
*break_blk
= NULL
;
467 nir_block
*continue_from_blk
= NULL
;
468 bool continue_from_then
= true;
470 nir_block
*last_then
= nir_if_last_then_block(nif
);
471 nir_block
*last_else
= nir_if_last_else_block(nif
);
473 if (nir_block_ends_in_break(last_then
)) {
474 break_blk
= last_then
;
475 continue_from_blk
= last_else
;
476 continue_from_then
= false;
477 } else if (nir_block_ends_in_break(last_else
)) {
478 break_blk
= last_else
;
479 continue_from_blk
= last_then
;
482 /* Continue if the if-statement contained no jumps at all */
486 /* If the continue from block is empty then return as there is nothing to
489 nir_block
*first_continue_from_blk
= continue_from_then
?
490 nir_if_first_then_block(nif
) :
491 nir_if_first_else_block(nif
);
492 if (is_block_empty(first_continue_from_blk
))
495 if (!nir_is_trivial_loop_if(nif
, break_blk
))
498 /* Finally, move the continue from branch after the if-statement. */
500 nir_cf_extract(&tmp
, nir_before_block(first_continue_from_blk
),
501 nir_after_block(continue_from_blk
));
502 nir_cf_reinsert(&tmp
, nir_after_cf_node(&nif
->cf_node
));
508 evaluate_if_condition(nir_if
*nif
, nir_cursor cursor
, bool *value
)
510 nir_block
*use_block
= nir_cursor_current_block(cursor
);
511 if (nir_block_dominates(nir_if_first_then_block(nif
), use_block
)) {
514 } else if (nir_block_dominates(nir_if_first_else_block(nif
), use_block
)) {
523 clone_alu_and_replace_src_defs(nir_builder
*b
, const nir_alu_instr
*alu
,
524 nir_ssa_def
**src_defs
)
526 nir_alu_instr
*nalu
= nir_alu_instr_create(b
->shader
, alu
->op
);
527 nalu
->exact
= alu
->exact
;
529 nir_ssa_dest_init(&nalu
->instr
, &nalu
->dest
.dest
,
530 alu
->dest
.dest
.ssa
.num_components
,
531 alu
->dest
.dest
.ssa
.bit_size
, alu
->dest
.dest
.ssa
.name
);
533 nalu
->dest
.saturate
= alu
->dest
.saturate
;
534 nalu
->dest
.write_mask
= alu
->dest
.write_mask
;
536 for (unsigned i
= 0; i
< nir_op_infos
[alu
->op
].num_inputs
; i
++) {
537 assert(alu
->src
[i
].src
.is_ssa
);
538 nalu
->src
[i
].src
= nir_src_for_ssa(src_defs
[i
]);
539 nalu
->src
[i
].negate
= alu
->src
[i
].negate
;
540 nalu
->src
[i
].abs
= alu
->src
[i
].abs
;
541 memcpy(nalu
->src
[i
].swizzle
, alu
->src
[i
].swizzle
,
542 sizeof(nalu
->src
[i
].swizzle
));
545 nir_builder_instr_insert(b
, &nalu
->instr
);
547 return &nalu
->dest
.dest
.ssa
;;
551 * This propagates if condition evaluation down the chain of some alu
552 * instructions. For example by checking the use of some of the following alu
553 * instruction we can eventually replace ssa_107 with NIR_TRUE.
557 * vec1 32 ssa_85 = load_const (0x00000002)
558 * vec1 32 ssa_86 = ieq ssa_48, ssa_85
559 * vec1 32 ssa_87 = load_const (0x00000001)
560 * vec1 32 ssa_88 = ieq ssa_48, ssa_87
561 * vec1 32 ssa_89 = ior ssa_86, ssa_88
562 * vec1 32 ssa_90 = ieq ssa_48, ssa_0
563 * vec1 32 ssa_91 = ior ssa_89, ssa_90
588 * vec1 32 ssa_107 = inot ssa_91
598 propagate_condition_eval(nir_builder
*b
, nir_if
*nif
, nir_src
*use_src
,
599 nir_src
*alu_use
, nir_alu_instr
*alu
,
600 bool is_if_condition
)
603 b
->cursor
= nir_before_src(alu_use
, is_if_condition
);
604 if (!evaluate_if_condition(nif
, b
->cursor
, &bool_value
))
607 nir_ssa_def
*def
[4] = {0};
608 for (unsigned i
= 0; i
< nir_op_infos
[alu
->op
].num_inputs
; i
++) {
609 if (alu
->src
[i
].src
.ssa
== use_src
->ssa
) {
610 def
[i
] = nir_imm_bool(b
, bool_value
);
612 def
[i
] = alu
->src
[i
].src
.ssa
;
616 nir_ssa_def
*nalu
= clone_alu_and_replace_src_defs(b
, alu
, def
);
618 /* Rewrite use to use new alu instruction */
619 nir_src new_src
= nir_src_for_ssa(nalu
);
622 nir_if_rewrite_condition(alu_use
->parent_if
, new_src
);
624 nir_instr_rewrite_src(alu_use
->parent_instr
, alu_use
, new_src
);
630 can_propagate_through_alu(nir_src
*src
)
632 if (src
->parent_instr
->type
!= nir_instr_type_alu
)
635 nir_alu_instr
*alu
= nir_instr_as_alu(src
->parent_instr
);
643 return src
== &alu
->src
[0].src
;
650 evaluate_condition_use(nir_builder
*b
, nir_if
*nif
, nir_src
*use_src
,
651 bool is_if_condition
)
653 bool progress
= false;
655 b
->cursor
= nir_before_src(use_src
, is_if_condition
);
658 if (evaluate_if_condition(nif
, b
->cursor
, &bool_value
)) {
659 /* Rewrite use to use const */
660 nir_src imm_src
= nir_src_for_ssa(nir_imm_bool(b
, bool_value
));
662 nir_if_rewrite_condition(use_src
->parent_if
, imm_src
);
664 nir_instr_rewrite_src(use_src
->parent_instr
, use_src
, imm_src
);
669 if (!is_if_condition
&& can_propagate_through_alu(use_src
)) {
670 nir_alu_instr
*alu
= nir_instr_as_alu(use_src
->parent_instr
);
672 nir_foreach_use_safe(alu_use
, &alu
->dest
.dest
.ssa
) {
673 progress
|= propagate_condition_eval(b
, nif
, use_src
, alu_use
, alu
,
677 nir_foreach_if_use_safe(alu_use
, &alu
->dest
.dest
.ssa
) {
678 progress
|= propagate_condition_eval(b
, nif
, use_src
, alu_use
, alu
,
687 opt_if_evaluate_condition_use(nir_builder
*b
, nir_if
*nif
)
689 bool progress
= false;
691 /* Evaluate any uses of the if condition inside the if branches */
692 assert(nif
->condition
.is_ssa
);
693 nir_foreach_use_safe(use_src
, nif
->condition
.ssa
) {
694 progress
|= evaluate_condition_use(b
, nif
, use_src
, false);
697 nir_foreach_if_use_safe(use_src
, nif
->condition
.ssa
) {
698 if (use_src
->parent_if
!= nif
)
699 progress
|= evaluate_condition_use(b
, nif
, use_src
, true);
706 simple_merge_if(nir_if
*dest_if
, nir_if
*src_if
, bool dest_if_then
,
709 /* Now merge the if branch */
710 nir_block
*dest_blk
= dest_if_then
? nir_if_last_then_block(dest_if
)
711 : nir_if_last_else_block(dest_if
);
713 struct exec_list
*list
= src_if_then
? &src_if
->then_list
714 : &src_if
->else_list
;
716 nir_cf_list if_cf_list
;
717 nir_cf_extract(&if_cf_list
, nir_before_cf_list(list
),
718 nir_after_cf_list(list
));
719 nir_cf_reinsert(&if_cf_list
, nir_after_block(dest_blk
));
723 opt_if_merge(nir_if
*nif
)
725 bool progress
= false;
727 nir_block
*next_blk
= nir_cf_node_cf_tree_next(&nif
->cf_node
);
728 if (next_blk
&& nif
->condition
.is_ssa
) {
729 nir_if
*next_if
= nir_block_get_following_if(next_blk
);
730 if (next_if
&& next_if
->condition
.is_ssa
) {
732 /* Here we merge two consecutive ifs that have the same
746 * Note: This only merges if-statements when the block between them
747 * is empty. The reason we don't try to merge ifs that just have phis
748 * between them is because this can results in increased register
749 * pressure. For example when merging if ladders created by indirect
752 if (nif
->condition
.ssa
== next_if
->condition
.ssa
&&
753 exec_list_is_empty(&next_blk
->instr_list
)) {
755 simple_merge_if(nif
, next_if
, true, true);
756 simple_merge_if(nif
, next_if
, false, false);
758 nir_block
*new_then_block
= nir_if_last_then_block(nif
);
759 nir_block
*new_else_block
= nir_if_last_else_block(nif
);
761 nir_block
*old_then_block
= nir_if_last_then_block(next_if
);
762 nir_block
*old_else_block
= nir_if_last_else_block(next_if
);
764 /* Rewrite the predecessor block for any phis following the second
767 rewrite_phi_predecessor_blocks(next_if
, old_then_block
,
772 /* Move phis after merged if to avoid them being deleted when we
773 * remove the merged if-statement.
775 nir_block
*after_next_if_block
=
776 nir_cf_node_as_block(nir_cf_node_next(&next_if
->cf_node
));
778 nir_foreach_instr_safe(instr
, after_next_if_block
) {
779 if (instr
->type
!= nir_instr_type_phi
)
782 exec_node_remove(&instr
->node
);
783 exec_list_push_tail(&next_blk
->instr_list
, &instr
->node
);
784 instr
->block
= next_blk
;
787 nir_cf_node_remove(&next_if
->cf_node
);
798 opt_if_cf_list(nir_builder
*b
, struct exec_list
*cf_list
)
800 bool progress
= false;
801 foreach_list_typed(nir_cf_node
, cf_node
, node
, cf_list
) {
802 switch (cf_node
->type
) {
803 case nir_cf_node_block
:
806 case nir_cf_node_if
: {
807 nir_if
*nif
= nir_cf_node_as_if(cf_node
);
808 progress
|= opt_if_cf_list(b
, &nif
->then_list
);
809 progress
|= opt_if_cf_list(b
, &nif
->else_list
);
810 progress
|= opt_if_loop_terminator(nif
);
811 progress
|= opt_if_merge(nif
);
812 progress
|= opt_if_simplification(b
, nif
);
816 case nir_cf_node_loop
: {
817 nir_loop
*loop
= nir_cf_node_as_loop(cf_node
);
818 progress
|= opt_if_cf_list(b
, &loop
->body
);
819 progress
|= opt_peel_loop_initial_if(loop
);
820 progress
|= opt_if_loop_last_continue(loop
);
824 case nir_cf_node_function
:
825 unreachable("Invalid cf type");
833 * These optimisations depend on nir_metadata_block_index and therefore must
834 * not do anything to cause the metadata to become invalid.
837 opt_if_safe_cf_list(nir_builder
*b
, struct exec_list
*cf_list
)
839 bool progress
= false;
840 foreach_list_typed(nir_cf_node
, cf_node
, node
, cf_list
) {
841 switch (cf_node
->type
) {
842 case nir_cf_node_block
:
845 case nir_cf_node_if
: {
846 nir_if
*nif
= nir_cf_node_as_if(cf_node
);
847 progress
|= opt_if_safe_cf_list(b
, &nif
->then_list
);
848 progress
|= opt_if_safe_cf_list(b
, &nif
->else_list
);
849 progress
|= opt_if_evaluate_condition_use(b
, nif
);
853 case nir_cf_node_loop
: {
854 nir_loop
*loop
= nir_cf_node_as_loop(cf_node
);
855 progress
|= opt_if_safe_cf_list(b
, &loop
->body
);
859 case nir_cf_node_function
:
860 unreachable("Invalid cf type");
868 nir_opt_if(nir_shader
*shader
)
870 bool progress
= false;
872 nir_foreach_function(function
, shader
) {
873 if (function
->impl
== NULL
)
877 nir_builder_init(&b
, function
->impl
);
879 nir_metadata_require(function
->impl
, nir_metadata_block_index
|
880 nir_metadata_dominance
);
881 progress
= opt_if_safe_cf_list(&b
, &function
->impl
->body
);
882 nir_metadata_preserve(function
->impl
, nir_metadata_block_index
|
883 nir_metadata_dominance
);
885 if (opt_if_cf_list(&b
, &function
->impl
->body
)) {
886 nir_metadata_preserve(function
->impl
, nir_metadata_none
);
888 /* If that made progress, we're no longer really in SSA form. We
889 * need to convert registers back into SSA defs and clean up SSA defs
890 * that don't dominate their uses.
892 nir_lower_regs_to_ssa_impl(function
->impl
);
897 function
->impl
->valid_metadata
&= ~nir_metadata_not_properly_reset
;