1/*
2 * Copyright © 2014 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Connor Abbott (cwabbott0@gmail.com)
25 *
26 */
27
28#include "nir_control_flow_private.h"
29
30/**
31 * \name Control flow modification
32 *
33 * These functions modify the control flow tree while keeping the control flow
34 * graph up-to-date. The invariants respected are:
35 * 1. Each then statement, else statement, or loop body must have at least one
36 *    control flow node.
37 * 2. Each if-statement and loop must have one basic block before it and one
38 *    after.
39 * 3. Two basic blocks cannot be directly next to each other.
40 * 4. If a basic block has a jump instruction, there must be only one and it
41 *    must be at the end of the block.
42 *
43 * The purpose of the second one is so that we have places to insert code during
44 * GCM, as well as eliminating the possibility of critical edges.
45 */
46/*@{*/
47
48static inline void
49block_add_pred(nir_block *block, nir_block *pred)
50{
51   _mesa_set_add(block->predecessors, pred);
52}
53
54static inline void
55block_remove_pred(nir_block *block, nir_block *pred)
56{
57   struct set_entry *entry = _mesa_set_search(block->predecessors, pred);
58
59   assert(entry);
60
61   _mesa_set_remove(block->predecessors, entry);
62}
63
64static void
65link_blocks(nir_block *pred, nir_block *succ1, nir_block *succ2)
66{
67   pred->successors[0] = succ1;
68   if (succ1 != NULL)
69      block_add_pred(succ1, pred);
70
71   pred->successors[1] = succ2;
72   if (succ2 != NULL)
73      block_add_pred(succ2, pred);
74}
75
76static void
77unlink_blocks(nir_block *pred, nir_block *succ)
78{
79   if (pred->successors[0] == succ) {
80      pred->successors[0] = pred->successors[1];
81      pred->successors[1] = NULL;
82   } else {
83      assert(pred->successors[1] == succ);
84      pred->successors[1] = NULL;
85   }
86
87   block_remove_pred(succ, pred);
88}
89
90static void
91unlink_block_successors(nir_block *block)
92{
93   if (block->successors[1] != NULL)
94      unlink_blocks(block, block->successors[1]);
95   if (block->successors[0] != NULL)
96      unlink_blocks(block, block->successors[0]);
97}
98
99static void
100link_non_block_to_block(nir_cf_node *node, nir_block *block)
101{
102   if (node->type == nir_cf_node_if) {
103      /*
104       * We're trying to link an if to a block after it; this just means linking
105       * the last block of the then and else branches.
106       */
107
108      nir_if *if_stmt = nir_cf_node_as_if(node);
109
110      nir_block *last_then_block = nir_if_last_then_block(if_stmt);
111      nir_block *last_else_block = nir_if_last_else_block(if_stmt);
112
113      if (!nir_block_ends_in_jump(last_then_block)) {
114         unlink_block_successors(last_then_block);
115         link_blocks(last_then_block, block, NULL);
116      }
117
118      if (!nir_block_ends_in_jump(last_else_block)) {
119         unlink_block_successors(last_else_block);
120         link_blocks(last_else_block, block, NULL);
121      }
122   } else {
123      assert(node->type == nir_cf_node_loop);
124   }
125}
126
127static void
128link_block_to_non_block(nir_block *block, nir_cf_node *node)
129{
130   if (node->type == nir_cf_node_if) {
131      /*
132       * We're trying to link a block to an if after it; this just means linking
133       * the block to the first block of the then and else branches.
134       */
135
136      nir_if *if_stmt = nir_cf_node_as_if(node);
137
138      nir_block *first_then_block = nir_if_first_then_block(if_stmt);
139      nir_block *first_else_block = nir_if_first_else_block(if_stmt);
140
141      unlink_block_successors(block);
142      link_blocks(block, first_then_block, first_else_block);
143   } else if (node->type == nir_cf_node_loop) {
144      /*
145       * For similar reasons as the corresponding case in
146       * link_non_block_to_block(), don't worry about if the loop header has
147       * any predecessors that need to be unlinked.
148       */
149
150      nir_loop *loop = nir_cf_node_as_loop(node);
151
152      nir_block *loop_header_block = nir_loop_first_block(loop);
153
154      unlink_block_successors(block);
155      link_blocks(block, loop_header_block, NULL);
156   }
157
158}
159
160/**
161 * Replace a block's successor with a different one.
162 */
163static void
164replace_successor(nir_block *block, nir_block *old_succ, nir_block *new_succ)
165{
166   if (block->successors[0] == old_succ) {
167      block->successors[0] = new_succ;
168   } else {
169      assert(block->successors[1] == old_succ);
170      block->successors[1] = new_succ;
171   }
172
173   block_remove_pred(old_succ, block);
174   block_add_pred(new_succ, block);
175}
176
177/**
178 * Takes a basic block and inserts a new empty basic block before it, making its
179 * predecessors point to the new block. This essentially splits the block into
180 * an empty header and a body so that another non-block CF node can be inserted
181 * between the two. Note that this does *not* link the two basic blocks, so
182 * some kind of cleanup *must* be performed after this call.
183 */
184
185static nir_block *
186split_block_beginning(nir_block *block)
187{
188   nir_block *new_block = nir_block_create(ralloc_parent(block));
189   new_block->cf_node.parent = block->cf_node.parent;
190   exec_node_insert_node_before(&block->cf_node.node, &new_block->cf_node.node);
191
192   set_foreach(block->predecessors, entry) {
193      nir_block *pred = (nir_block *) entry->key;
194      replace_successor(pred, block, new_block);
195   }
196
197   /* Any phi nodes must stay part of the new block, or else their
198    * sources will be messed up.
199    */
200   nir_foreach_instr_safe(instr, block) {
201      if (instr->type != nir_instr_type_phi)
202         break;
203
204      exec_node_remove(&instr->node);
205      instr->block = new_block;
206      exec_list_push_tail(&new_block->instr_list, &instr->node);
207   }
208
209   return new_block;
210}
211
212static void
213rewrite_phi_preds(nir_block *block, nir_block *old_pred, nir_block *new_pred)
214{
215   nir_foreach_instr_safe(instr, block) {
216      if (instr->type != nir_instr_type_phi)
217         break;
218
219      nir_phi_instr *phi = nir_instr_as_phi(instr);
220      nir_foreach_phi_src(src, phi) {
221         if (src->pred == old_pred) {
222            src->pred = new_pred;
223            break;
224         }
225      }
226   }
227}
228
229void
230nir_insert_phi_undef(nir_block *block, nir_block *pred)
231{
232   nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
233   nir_foreach_instr(instr, block) {
234      if (instr->type != nir_instr_type_phi)
235         break;
236
237      nir_phi_instr *phi = nir_instr_as_phi(instr);
238      nir_ssa_undef_instr *undef =
239         nir_ssa_undef_instr_create(impl->function->shader,
240                                    phi->dest.ssa.num_components,
241                                    phi->dest.ssa.bit_size);
242      nir_instr_insert_before_cf_list(&impl->body, &undef->instr);
243      nir_phi_src *src = nir_phi_instr_add_src(phi, pred, nir_src_for_ssa(&undef->def));
244      list_addtail(&src->src.use_link, &undef->def.uses);
245   }
246}
247
248/**
249 * Moves the successors of source to the successors of dest, leaving both
250 * successors of source NULL.
251 */
252
253static void
254move_successors(nir_block *source, nir_block *dest)
255{
256   nir_block *succ1 = source->successors[0];
257   nir_block *succ2 = source->successors[1];
258
259   if (succ1) {
260      unlink_blocks(source, succ1);
261      rewrite_phi_preds(succ1, source, dest);
262   }
263
264   if (succ2) {
265      unlink_blocks(source, succ2);
266      rewrite_phi_preds(succ2, source, dest);
267   }
268
269   unlink_block_successors(dest);
270   link_blocks(dest, succ1, succ2);
271}
272
273/* Given a basic block with no successors that has been inserted into the
274 * control flow tree, gives it the successors it would normally have assuming
275 * it doesn't end in a jump instruction. Also inserts phi sources with undefs
276 * if necessary.
277 */
278static void
279block_add_normal_succs(nir_block *block)
280{
281   if (exec_node_is_tail_sentinel(block->cf_node.node.next)) {
282      nir_cf_node *parent = block->cf_node.parent;
283      if (parent->type == nir_cf_node_if) {
284         nir_cf_node *next = nir_cf_node_next(parent);
285         nir_block *next_block = nir_cf_node_as_block(next);
286
287         link_blocks(block, next_block, NULL);
288      } else if (parent->type == nir_cf_node_loop) {
289         nir_loop *loop = nir_cf_node_as_loop(parent);
290
291         nir_block *head_block = nir_loop_first_block(loop);
292
293         link_blocks(block, head_block, NULL);
294         nir_insert_phi_undef(head_block, block);
295      } else {
296         nir_function_impl *impl = nir_cf_node_as_function(parent);
297         link_blocks(block, impl->end_block, NULL);
298      }
299   } else {
300      nir_cf_node *next = nir_cf_node_next(&block->cf_node);
301      if (next->type == nir_cf_node_if) {
302         nir_if *next_if = nir_cf_node_as_if(next);
303
304         nir_block *first_then_block = nir_if_first_then_block(next_if);
305         nir_block *first_else_block = nir_if_first_else_block(next_if);
306
307         link_blocks(block, first_then_block, first_else_block);
308      } else if (next->type == nir_cf_node_loop) {
309         nir_loop *next_loop = nir_cf_node_as_loop(next);
310
311         nir_block *first_block = nir_loop_first_block(next_loop);
312
313         link_blocks(block, first_block, NULL);
314         nir_insert_phi_undef(first_block, block);
315      }
316   }
317}
318
319static nir_block *
320split_block_end(nir_block *block)
321{
322   nir_block *new_block = nir_block_create(ralloc_parent(block));
323   new_block->cf_node.parent = block->cf_node.parent;
324   exec_node_insert_after(&block->cf_node.node, &new_block->cf_node.node);
325
326   if (nir_block_ends_in_jump(block)) {
327      /* Figure out what successor block would've had if it didn't have a jump
328       * instruction, and make new_block have that successor.
329       */
330      block_add_normal_succs(new_block);
331   } else {
332      move_successors(block, new_block);
333   }
334
335   return new_block;
336}
337
338static nir_block *
339split_block_before_instr(nir_instr *instr)
340{
341   assert(instr->type != nir_instr_type_phi);
342   nir_block *new_block = split_block_beginning(instr->block);
343
344   nir_foreach_instr_safe(cur_instr, instr->block) {
345      if (cur_instr == instr)
346         break;
347
348      exec_node_remove(&cur_instr->node);
349      cur_instr->block = new_block;
350      exec_list_push_tail(&new_block->instr_list, &cur_instr->node);
351   }
352
353   return new_block;
354}
355
356/* Splits a basic block at the point specified by the cursor. The "before" and
357 * "after" arguments are filled out with the blocks resulting from the split
358 * if non-NULL. Note that the "beginning" of the block is actually interpreted
359 * as before the first non-phi instruction, and it's illegal to split a block
360 * before a phi instruction.
361 */
362
363static void
364split_block_cursor(nir_cursor cursor,
365                   nir_block **_before, nir_block **_after)
366{
367   nir_block *before, *after;
368   switch (cursor.option) {
369   case nir_cursor_before_block:
370      after = cursor.block;
371      before = split_block_beginning(cursor.block);
372      break;
373
374   case nir_cursor_after_block:
375      before = cursor.block;
376      after = split_block_end(cursor.block);
377      break;
378
379   case nir_cursor_before_instr:
380      after = cursor.instr->block;
381      before = split_block_before_instr(cursor.instr);
382      break;
383
384   case nir_cursor_after_instr:
385      /* We lower this to split_block_before_instr() so that we can keep the
386       * after-a-jump-instr case contained to split_block_end().
387       */
388      if (nir_instr_is_last(cursor.instr)) {
389         before = cursor.instr->block;
390         after = split_block_end(cursor.instr->block);
391      } else {
392         after = cursor.instr->block;
393         before = split_block_before_instr(nir_instr_next(cursor.instr));
394      }
395      break;
396
397   default:
398      unreachable("not reached");
399   }
400
401   if (_before)
402      *_before = before;
403   if (_after)
404      *_after = after;
405}
406
407/**
408 * Inserts a non-basic block between two basic blocks and links them together.
409 */
410
411static void
412insert_non_block(nir_block *before, nir_cf_node *node, nir_block *after)
413{
414   node->parent = before->cf_node.parent;
415   exec_node_insert_after(&before->cf_node.node, &node->node);
416   if (!nir_block_ends_in_jump(before))
417      link_block_to_non_block(before, node);
418   link_non_block_to_block(node, after);
419}
420
421/* walk up the control flow tree to find the innermost enclosed loop */
422static nir_loop *
423nearest_loop(nir_cf_node *node)
424{
425   while (node->type != nir_cf_node_loop) {
426      node = node->parent;
427   }
428
429   return nir_cf_node_as_loop(node);
430}
431
432static void
433remove_phi_src(nir_block *block, nir_block *pred)
434{
435   nir_foreach_instr(instr, block) {
436      if (instr->type != nir_instr_type_phi)
437         break;
438
439      nir_phi_instr *phi = nir_instr_as_phi(instr);
440      nir_foreach_phi_src_safe(src, phi) {
441         if (src->pred == pred) {
442            list_del(&src->src.use_link);
443            exec_node_remove(&src->node);
444            free(src);
445         }
446      }
447   }
448}
449
450/*
451 * update the CFG after a jump instruction has been added to the end of a block
452 */
453
454void
455nir_handle_add_jump(nir_block *block)
456{
457   nir_instr *instr = nir_block_last_instr(block);
458   nir_jump_instr *jump_instr = nir_instr_as_jump(instr);
459
460   if (block->successors[0])
461      remove_phi_src(block->successors[0], block);
462   if (block->successors[1])
463      remove_phi_src(block->successors[1], block);
464   unlink_block_successors(block);
465
466   nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
467   nir_metadata_preserve(impl, nir_metadata_none);
468
469   switch (jump_instr->type) {
470   case nir_jump_return:
471   case nir_jump_halt:
472      link_blocks(block, impl->end_block, NULL);
473      break;
474
475   case nir_jump_break: {
476      nir_loop *loop = nearest_loop(&block->cf_node);
477      nir_cf_node *after = nir_cf_node_next(&loop->cf_node);
478      nir_block *after_block = nir_cf_node_as_block(after);
479      link_blocks(block, after_block, NULL);
480      break;
481   }
482
483   case nir_jump_continue: {
484      nir_loop *loop = nearest_loop(&block->cf_node);
485      nir_block *first_block = nir_loop_first_block(loop);
486      link_blocks(block, first_block, NULL);
487      break;
488   }
489
490   case nir_jump_goto:
491      link_blocks(block, jump_instr->target, NULL);
492      break;
493
494   case nir_jump_goto_if:
495      link_blocks(block, jump_instr->else_target, jump_instr->target);
496      break;
497
498   default:
499      unreachable("Invalid jump type");
500   }
501}
502
503/* Removes the successor of a block with a jump. Note that the jump to be
504 * eliminated may be free-floating.
505 */
506
507static void
508unlink_jump(nir_block *block, nir_jump_type type, bool add_normal_successors)
509{
510   if (block->successors[0])
511      remove_phi_src(block->successors[0], block);
512   if (block->successors[1])
513      remove_phi_src(block->successors[1], block);
514
515   unlink_block_successors(block);
516   if (add_normal_successors)
517      block_add_normal_succs(block);
518}
519
520void
521nir_handle_remove_jump(nir_block *block, nir_jump_type type)
522{
523   unlink_jump(block, type, true);
524
525   nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
526   nir_metadata_preserve(impl, nir_metadata_none);
527}
528
529static void
530update_if_uses(nir_cf_node *node)
531{
532   if (node->type != nir_cf_node_if)
533      return;
534
535   nir_if *if_stmt = nir_cf_node_as_if(node);
536
537   if_stmt->condition.parent_if = if_stmt;
538   if (if_stmt->condition.is_ssa) {
539      list_addtail(&if_stmt->condition.use_link,
540                   &if_stmt->condition.ssa->if_uses);
541   } else {
542      list_addtail(&if_stmt->condition.use_link,
543                   &if_stmt->condition.reg.reg->if_uses);
544   }
545}
546
547/**
548 * Stitch two basic blocks together into one. The aggregate must have the same
549 * predecessors as the first and the same successors as the second.
550 *
551 * Returns a cursor pointing at the end of the before block (i.e.m between the
552 * two blocks) once stiched together.
553 */
554
555static nir_cursor
556stitch_blocks(nir_block *before, nir_block *after)
557{
558   /*
559    * We move after into before, so we have to deal with up to 2 successors vs.
560    * possibly a large number of predecessors.
561    *
562    * TODO: special case when before is empty and after isn't?
563    */
564
565   if (nir_block_ends_in_jump(before)) {
566      assert(exec_list_is_empty(&after->instr_list));
567      if (after->successors[0])
568         remove_phi_src(after->successors[0], after);
569      if (after->successors[1])
570         remove_phi_src(after->successors[1], after);
571      unlink_block_successors(after);
572      exec_node_remove(&after->cf_node.node);
573
574      return nir_after_block(before);
575   } else {
576      nir_instr *last_before_instr = nir_block_last_instr(before);
577
578      move_successors(after, before);
579
580      foreach_list_typed(nir_instr, instr, node, &after->instr_list) {
581         instr->block = before;
582      }
583
584      exec_list_append(&before->instr_list, &after->instr_list);
585      exec_node_remove(&after->cf_node.node);
586
587      return last_before_instr ? nir_after_instr(last_before_instr) :
588                                 nir_before_block(before);
589   }
590}
591
592void
593nir_cf_node_insert(nir_cursor cursor, nir_cf_node *node)
594{
595   nir_block *before, *after;
596
597   split_block_cursor(cursor, &before, &after);
598
599   if (node->type == nir_cf_node_block) {
600      nir_block *block = nir_cf_node_as_block(node);
601      exec_node_insert_after(&before->cf_node.node, &block->cf_node.node);
602      block->cf_node.parent = before->cf_node.parent;
603      /* stitch_blocks() assumes that any block that ends with a jump has
604       * already been setup with the correct successors, so we need to set
605       * up jumps here as the block is being inserted.
606       */
607      if (nir_block_ends_in_jump(block))
608         nir_handle_add_jump(block);
609
610      stitch_blocks(block, after);
611      stitch_blocks(before, block);
612   } else {
613      update_if_uses(node);
614      insert_non_block(before, node, after);
615   }
616}
617
618static bool
619replace_ssa_def_uses(nir_ssa_def *def, void *void_impl)
620{
621   nir_function_impl *impl = void_impl;
622
623   nir_ssa_undef_instr *undef =
624      nir_ssa_undef_instr_create(impl->function->shader,
625                                 def->num_components,
626                                 def->bit_size);
627   nir_instr_insert_before_cf_list(&impl->body, &undef->instr);
628   nir_ssa_def_rewrite_uses(def, &undef->def);
629   return true;
630}
631
632static void
633cleanup_cf_node(nir_cf_node *node, nir_function_impl *impl)
634{
635   switch (node->type) {
636   case nir_cf_node_block: {
637      nir_block *block = nir_cf_node_as_block(node);
638      /* We need to walk the instructions and clean up defs/uses */
639      nir_foreach_instr_safe(instr, block) {
640         if (instr->type == nir_instr_type_jump) {
641            nir_jump_instr *jump = nir_instr_as_jump(instr);
642            unlink_jump(block, jump->type, false);
643            if (jump->type == nir_jump_goto_if)
644               nir_instr_rewrite_src(instr, &jump->condition, NIR_SRC_INIT);
645         } else {
646            nir_foreach_ssa_def(instr, replace_ssa_def_uses, impl);
647            nir_instr_remove(instr);
648         }
649      }
650      break;
651   }
652
653   case nir_cf_node_if: {
654      nir_if *if_stmt = nir_cf_node_as_if(node);
655      foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list)
656         cleanup_cf_node(child, impl);
657      foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
658         cleanup_cf_node(child, impl);
659
660      list_del(&if_stmt->condition.use_link);
661      break;
662   }
663
664   case nir_cf_node_loop: {
665      nir_loop *loop = nir_cf_node_as_loop(node);
666      foreach_list_typed(nir_cf_node, child, node, &loop->body)
667         cleanup_cf_node(child, impl);
668      break;
669   }
670   case nir_cf_node_function: {
671      nir_function_impl *impl = nir_cf_node_as_function(node);
672      foreach_list_typed(nir_cf_node, child, node, &impl->body)
673         cleanup_cf_node(child, impl);
674      break;
675   }
676   default:
677      unreachable("Invalid CF node type");
678   }
679}
680
681/**
682 * Extracts everything between two cursors.  Returns the cursor which is
683 * equivalent to the old begin/end curosors.
684 */
685nir_cursor
686nir_cf_extract(nir_cf_list *extracted, nir_cursor begin, nir_cursor end)
687{
688   nir_block *block_begin, *block_end, *block_before, *block_after;
689
690   if (nir_cursors_equal(begin, end)) {
691      exec_list_make_empty(&extracted->list);
692      extracted->impl = NULL; /* we shouldn't need this */
693      return begin;
694   }
695
696   split_block_cursor(begin, &block_before, &block_begin);
697
698   /* Splitting a block twice with two cursors created before either split is
699    * tricky and there are a couple of places it can go wrong if both cursors
700    * point to the same block.  One is if the second cursor is an block-based
701    * cursor and, thanks to the split above, it ends up pointing to the wrong
702    * block.  If it's a before_block cursor and it's in the same block as
703    * begin, then begin must also be a before_block cursor and it should be
704    * caught by the nir_cursors_equal check above and we won't get here.  If
705    * it's an after_block cursor, we need to re-adjust to ensure that it
706    * points to the second one of the split blocks, regardless of which it is.
707    */
708   if (end.option == nir_cursor_after_block && end.block == block_before)
709      end.block = block_begin;
710
711   split_block_cursor(end, &block_end, &block_after);
712
713   /* The second place this can all go wrong is that it could be that the
714    * second split places the original block after the new block in which case
715    * the block_begin pointer that we saved off above is pointing to the block
716    * at the end rather than the block in the middle like it's supposed to be.
717    * In this case, we have to re-adjust begin_block to point to the middle
718    * one.
719    */
720   if (block_begin == block_after)
721      block_begin = block_end;
722
723   extracted->impl = nir_cf_node_get_function(&block_begin->cf_node);
724   exec_list_make_empty(&extracted->list);
725
726   /* Dominance and other block-related information is toast. */
727   nir_metadata_preserve(extracted->impl, nir_metadata_none);
728
729   nir_cf_node *cf_node = &block_begin->cf_node;
730   nir_cf_node *cf_node_end = &block_end->cf_node;
731   while (true) {
732      nir_cf_node *next = nir_cf_node_next(cf_node);
733
734      exec_node_remove(&cf_node->node);
735      cf_node->parent = NULL;
736      exec_list_push_tail(&extracted->list, &cf_node->node);
737
738      if (cf_node == cf_node_end)
739         break;
740
741      cf_node = next;
742   }
743
744   return stitch_blocks(block_before, block_after);
745}
746
747static void
748relink_jump_halt_cf_node(nir_cf_node *node, nir_block *end_block)
749{
750   switch (node->type) {
751   case nir_cf_node_block: {
752      nir_block *block = nir_cf_node_as_block(node);
753      nir_instr *last_instr = nir_block_last_instr(block);
754      if (last_instr == NULL || last_instr->type != nir_instr_type_jump)
755         break;
756
757      nir_jump_instr *jump = nir_instr_as_jump(last_instr);
758      /* We can't move a CF list from one function to another while we still
759       * have returns.
760       */
761      assert(jump->type != nir_jump_return);
762
763      if (jump->type == nir_jump_halt) {
764         unlink_block_successors(block);
765         link_blocks(block, end_block, NULL);
766      }
767      break;
768   }
769
770   case nir_cf_node_if: {
771      nir_if *if_stmt = nir_cf_node_as_if(node);
772      foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list)
773         relink_jump_halt_cf_node(child, end_block);
774      foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
775         relink_jump_halt_cf_node(child, end_block);
776      break;
777   }
778
779   case nir_cf_node_loop: {
780      nir_loop *loop = nir_cf_node_as_loop(node);
781      foreach_list_typed(nir_cf_node, child, node, &loop->body)
782         relink_jump_halt_cf_node(child, end_block);
783      break;
784   }
785
786   case nir_cf_node_function:
787      unreachable("Cannot insert a function in a function");
788
789   default:
790      unreachable("Invalid CF node type");
791   }
792}
793
794/**
795 * Inserts a list at a given cursor. Returns the cursor at the end of the
796 * insertion (i.e., at the end of the instructions contained in cf_list).
797 */
798nir_cursor
799nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor)
800{
801   nir_block *before, *after;
802
803   if (exec_list_is_empty(&cf_list->list))
804      return cursor;
805
806   nir_function_impl *cursor_impl =
807      nir_cf_node_get_function(&nir_cursor_current_block(cursor)->cf_node);
808   if (cf_list->impl != cursor_impl) {
809      foreach_list_typed(nir_cf_node, node, node, &cf_list->list)
810         relink_jump_halt_cf_node(node, cursor_impl->end_block);
811   }
812
813   split_block_cursor(cursor, &before, &after);
814
815   foreach_list_typed_safe(nir_cf_node, node, node, &cf_list->list) {
816      exec_node_remove(&node->node);
817      node->parent = before->cf_node.parent;
818      exec_node_insert_node_before(&after->cf_node.node, &node->node);
819   }
820
821   stitch_blocks(before,
822                 nir_cf_node_as_block(nir_cf_node_next(&before->cf_node)));
823   return stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)),
824                        after);
825}
826
827void
828nir_cf_delete(nir_cf_list *cf_list)
829{
830   foreach_list_typed(nir_cf_node, node, node, &cf_list->list) {
831      cleanup_cf_node(node, cf_list->impl);
832   }
833}
834