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 (at) 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 48 static inline void 49 block_add_pred(nir_block *block, nir_block *pred) 50 { 51 _mesa_set_add(block->predecessors, pred); 52 } 53 54 static inline void 55 block_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 64 static void 65 link_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 76 static void 77 unlink_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 90 static void 91 unlink_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 99 static void 100 link_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 127 static void 128 link_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 { 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 */ 163 static void 164 replace_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 185 static nir_block * 186 split_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 212 static void 213 rewrite_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 229 static void 230 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(ralloc_parent(phi), 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 = ralloc(phi, nir_phi_src); 244 src->pred = pred; 245 src->src.parent_instr = &phi->instr; 246 src->src.is_ssa = true; 247 src->src.ssa = &undef->def; 248 249 list_addtail(&src->src.use_link, &undef->def.uses); 250 251 exec_list_push_tail(&phi->srcs, &src->node); 252 } 253 } 254 255 /** 256 * Moves the successors of source to the successors of dest, leaving both 257 * successors of source NULL. 258 */ 259 260 static void 261 move_successors(nir_block *source, nir_block *dest) 262 { 263 nir_block *succ1 = source->successors[0]; 264 nir_block *succ2 = source->successors[1]; 265 266 if (succ1) { 267 unlink_blocks(source, succ1); 268 rewrite_phi_preds(succ1, source, dest); 269 } 270 271 if (succ2) { 272 unlink_blocks(source, succ2); 273 rewrite_phi_preds(succ2, source, dest); 274 } 275 276 unlink_block_successors(dest); 277 link_blocks(dest, succ1, succ2); 278 } 279 280 /* Given a basic block with no successors that has been inserted into the 281 * control flow tree, gives it the successors it would normally have assuming 282 * it doesn't end in a jump instruction. Also inserts phi sources with undefs 283 * if necessary. 284 */ 285 static void 286 block_add_normal_succs(nir_block *block) 287 { 288 if (exec_node_is_tail_sentinel(block->cf_node.node.next)) { 289 nir_cf_node *parent = block->cf_node.parent; 290 if (parent->type == nir_cf_node_if) { 291 nir_cf_node *next = nir_cf_node_next(parent); 292 nir_block *next_block = nir_cf_node_as_block(next); 293 294 link_blocks(block, next_block, NULL); 295 } else if (parent->type == nir_cf_node_loop) { 296 nir_loop *loop = nir_cf_node_as_loop(parent); 297 298 nir_block *head_block = nir_loop_first_block(loop); 299 300 link_blocks(block, head_block, NULL); 301 insert_phi_undef(head_block, block); 302 } else { 303 nir_function_impl *impl = nir_cf_node_as_function(parent); 304 link_blocks(block, impl->end_block, NULL); 305 } 306 } else { 307 nir_cf_node *next = nir_cf_node_next(&block->cf_node); 308 if (next->type == nir_cf_node_if) { 309 nir_if *next_if = nir_cf_node_as_if(next); 310 311 nir_block *first_then_block = nir_if_first_then_block(next_if); 312 nir_block *first_else_block = nir_if_first_else_block(next_if); 313 314 link_blocks(block, first_then_block, first_else_block); 315 } else { 316 nir_loop *next_loop = nir_cf_node_as_loop(next); 317 318 nir_block *first_block = nir_loop_first_block(next_loop); 319 320 link_blocks(block, first_block, NULL); 321 insert_phi_undef(first_block, block); 322 } 323 } 324 } 325 326 static nir_block * 327 split_block_end(nir_block *block) 328 { 329 nir_block *new_block = nir_block_create(ralloc_parent(block)); 330 new_block->cf_node.parent = block->cf_node.parent; 331 exec_node_insert_after(&block->cf_node.node, &new_block->cf_node.node); 332 333 if (nir_block_ends_in_jump(block)) { 334 /* Figure out what successor block would've had if it didn't have a jump 335 * instruction, and make new_block have that successor. 336 */ 337 block_add_normal_succs(new_block); 338 } else { 339 move_successors(block, new_block); 340 } 341 342 return new_block; 343 } 344 345 static nir_block * 346 split_block_before_instr(nir_instr *instr) 347 { 348 assert(instr->type != nir_instr_type_phi); 349 nir_block *new_block = split_block_beginning(instr->block); 350 351 nir_foreach_instr_safe(cur_instr, instr->block) { 352 if (cur_instr == instr) 353 break; 354 355 exec_node_remove(&cur_instr->node); 356 cur_instr->block = new_block; 357 exec_list_push_tail(&new_block->instr_list, &cur_instr->node); 358 } 359 360 return new_block; 361 } 362 363 /* Splits a basic block at the point specified by the cursor. The "before" and 364 * "after" arguments are filled out with the blocks resulting from the split 365 * if non-NULL. Note that the "beginning" of the block is actually interpreted 366 * as before the first non-phi instruction, and it's illegal to split a block 367 * before a phi instruction. 368 */ 369 370 static void 371 split_block_cursor(nir_cursor cursor, 372 nir_block **_before, nir_block **_after) 373 { 374 nir_block *before, *after; 375 switch (cursor.option) { 376 case nir_cursor_before_block: 377 after = cursor.block; 378 before = split_block_beginning(cursor.block); 379 break; 380 381 case nir_cursor_after_block: 382 before = cursor.block; 383 after = split_block_end(cursor.block); 384 break; 385 386 case nir_cursor_before_instr: 387 after = cursor.instr->block; 388 before = split_block_before_instr(cursor.instr); 389 break; 390 391 case nir_cursor_after_instr: 392 /* We lower this to split_block_before_instr() so that we can keep the 393 * after-a-jump-instr case contained to split_block_end(). 394 */ 395 if (nir_instr_is_last(cursor.instr)) { 396 before = cursor.instr->block; 397 after = split_block_end(cursor.instr->block); 398 } else { 399 after = cursor.instr->block; 400 before = split_block_before_instr(nir_instr_next(cursor.instr)); 401 } 402 break; 403 404 default: 405 unreachable("not reached"); 406 } 407 408 if (_before) 409 *_before = before; 410 if (_after) 411 *_after = after; 412 } 413 414 /** 415 * Inserts a non-basic block between two basic blocks and links them together. 416 */ 417 418 static void 419 insert_non_block(nir_block *before, nir_cf_node *node, nir_block *after) 420 { 421 node->parent = before->cf_node.parent; 422 exec_node_insert_after(&before->cf_node.node, &node->node); 423 link_block_to_non_block(before, node); 424 link_non_block_to_block(node, after); 425 } 426 427 /* walk up the control flow tree to find the innermost enclosed loop */ 428 static nir_loop * 429 nearest_loop(nir_cf_node *node) 430 { 431 while (node->type != nir_cf_node_loop) { 432 node = node->parent; 433 } 434 435 return nir_cf_node_as_loop(node); 436 } 437 438 static void 439 remove_phi_src(nir_block *block, nir_block *pred) 440 { 441 nir_foreach_instr(instr, block) { 442 if (instr->type != nir_instr_type_phi) 443 break; 444 445 nir_phi_instr *phi = nir_instr_as_phi(instr); 446 nir_foreach_phi_src_safe(src, phi) { 447 if (src->pred == pred) { 448 list_del(&src->src.use_link); 449 exec_node_remove(&src->node); 450 } 451 } 452 } 453 } 454 455 /* 456 * update the CFG after a jump instruction has been added to the end of a block 457 */ 458 459 void 460 nir_handle_add_jump(nir_block *block) 461 { 462 nir_instr *instr = nir_block_last_instr(block); 463 nir_jump_instr *jump_instr = nir_instr_as_jump(instr); 464 465 if (block->successors[0]) 466 remove_phi_src(block->successors[0], block); 467 if (block->successors[1]) 468 remove_phi_src(block->successors[1], block); 469 unlink_block_successors(block); 470 471 nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); 472 nir_metadata_preserve(impl, nir_metadata_none); 473 474 if (jump_instr->type == nir_jump_break || 475 jump_instr->type == nir_jump_continue) { 476 nir_loop *loop = nearest_loop(&block->cf_node); 477 478 if (jump_instr->type == nir_jump_continue) { 479 nir_block *first_block = nir_loop_first_block(loop); 480 link_blocks(block, first_block, NULL); 481 } else { 482 nir_cf_node *after = nir_cf_node_next(&loop->cf_node); 483 nir_block *after_block = nir_cf_node_as_block(after); 484 link_blocks(block, after_block, NULL); 485 } 486 } else { 487 assert(jump_instr->type == nir_jump_return); 488 link_blocks(block, impl->end_block, NULL); 489 } 490 } 491 492 /* Removes the successor of a block with a jump. Note that the jump to be 493 * eliminated may be free-floating. 494 */ 495 496 static void 497 unlink_jump(nir_block *block, nir_jump_type type, bool add_normal_successors) 498 { 499 if (block->successors[0]) 500 remove_phi_src(block->successors[0], block); 501 if (block->successors[1]) 502 remove_phi_src(block->successors[1], block); 503 504 unlink_block_successors(block); 505 if (add_normal_successors) 506 block_add_normal_succs(block); 507 } 508 509 void 510 nir_handle_remove_jump(nir_block *block, nir_jump_type type) 511 { 512 unlink_jump(block, type, true); 513 514 nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); 515 nir_metadata_preserve(impl, nir_metadata_none); 516 } 517 518 static void 519 update_if_uses(nir_cf_node *node) 520 { 521 if (node->type != nir_cf_node_if) 522 return; 523 524 nir_if *if_stmt = nir_cf_node_as_if(node); 525 526 if_stmt->condition.parent_if = if_stmt; 527 if (if_stmt->condition.is_ssa) { 528 list_addtail(&if_stmt->condition.use_link, 529 &if_stmt->condition.ssa->if_uses); 530 } else { 531 list_addtail(&if_stmt->condition.use_link, 532 &if_stmt->condition.reg.reg->if_uses); 533 } 534 } 535 536 /** 537 * Stitch two basic blocks together into one. The aggregate must have the same 538 * predecessors as the first and the same successors as the second. 539 */ 540 541 static void 542 stitch_blocks(nir_block *before, nir_block *after) 543 { 544 /* 545 * We move after into before, so we have to deal with up to 2 successors vs. 546 * possibly a large number of predecessors. 547 * 548 * TODO: special case when before is empty and after isn't? 549 */ 550 551 if (nir_block_ends_in_jump(before)) { 552 assert(exec_list_is_empty(&after->instr_list)); 553 if (after->successors[0]) 554 remove_phi_src(after->successors[0], after); 555 if (after->successors[1]) 556 remove_phi_src(after->successors[1], after); 557 unlink_block_successors(after); 558 exec_node_remove(&after->cf_node.node); 559 } else { 560 move_successors(after, before); 561 562 foreach_list_typed(nir_instr, instr, node, &after->instr_list) { 563 instr->block = before; 564 } 565 566 exec_list_append(&before->instr_list, &after->instr_list); 567 exec_node_remove(&after->cf_node.node); 568 } 569 } 570 571 void 572 nir_cf_node_insert(nir_cursor cursor, nir_cf_node *node) 573 { 574 nir_block *before, *after; 575 576 split_block_cursor(cursor, &before, &after); 577 578 if (node->type == nir_cf_node_block) { 579 nir_block *block = nir_cf_node_as_block(node); 580 exec_node_insert_after(&before->cf_node.node, &block->cf_node.node); 581 block->cf_node.parent = before->cf_node.parent; 582 /* stitch_blocks() assumes that any block that ends with a jump has 583 * already been setup with the correct successors, so we need to set 584 * up jumps here as the block is being inserted. 585 */ 586 if (nir_block_ends_in_jump(block)) 587 nir_handle_add_jump(block); 588 589 stitch_blocks(block, after); 590 stitch_blocks(before, block); 591 } else { 592 update_if_uses(node); 593 insert_non_block(before, node, after); 594 } 595 } 596 597 static bool 598 replace_ssa_def_uses(nir_ssa_def *def, void *void_impl) 599 { 600 nir_function_impl *impl = void_impl; 601 void *mem_ctx = ralloc_parent(impl); 602 603 nir_ssa_undef_instr *undef = 604 nir_ssa_undef_instr_create(mem_ctx, def->num_components, 605 def->bit_size); 606 nir_instr_insert_before_cf_list(&impl->body, &undef->instr); 607 nir_ssa_def_rewrite_uses(def, nir_src_for_ssa(&undef->def)); 608 return true; 609 } 610 611 static void 612 cleanup_cf_node(nir_cf_node *node, nir_function_impl *impl) 613 { 614 switch (node->type) { 615 case nir_cf_node_block: { 616 nir_block *block = nir_cf_node_as_block(node); 617 /* We need to walk the instructions and clean up defs/uses */ 618 nir_foreach_instr_safe(instr, block) { 619 if (instr->type == nir_instr_type_jump) { 620 nir_jump_type jump_type = nir_instr_as_jump(instr)->type; 621 unlink_jump(block, jump_type, false); 622 } else { 623 nir_foreach_ssa_def(instr, replace_ssa_def_uses, impl); 624 nir_instr_remove(instr); 625 } 626 } 627 break; 628 } 629 630 case nir_cf_node_if: { 631 nir_if *if_stmt = nir_cf_node_as_if(node); 632 foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list) 633 cleanup_cf_node(child, impl); 634 foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list) 635 cleanup_cf_node(child, impl); 636 637 list_del(&if_stmt->condition.use_link); 638 break; 639 } 640 641 case nir_cf_node_loop: { 642 nir_loop *loop = nir_cf_node_as_loop(node); 643 foreach_list_typed(nir_cf_node, child, node, &loop->body) 644 cleanup_cf_node(child, impl); 645 break; 646 } 647 case nir_cf_node_function: { 648 nir_function_impl *impl = nir_cf_node_as_function(node); 649 foreach_list_typed(nir_cf_node, child, node, &impl->body) 650 cleanup_cf_node(child, impl); 651 break; 652 } 653 default: 654 unreachable("Invalid CF node type"); 655 } 656 } 657 658 void 659 nir_cf_extract(nir_cf_list *extracted, nir_cursor begin, nir_cursor end) 660 { 661 nir_block *block_begin, *block_end, *block_before, *block_after; 662 663 if (nir_cursors_equal(begin, end)) { 664 exec_list_make_empty(&extracted->list); 665 extracted->impl = NULL; /* we shouldn't need this */ 666 return; 667 } 668 669 /* In the case where begin points to an instruction in some basic block and 670 * end points to the end of the same basic block, we rely on the fact that 671 * splitting on an instruction moves earlier instructions into a new basic 672 * block. If the later instructions were moved instead, then the end cursor 673 * would be pointing to the same place that begin used to point to, which 674 * is obviously not what we want. 675 */ 676 split_block_cursor(begin, &block_before, &block_begin); 677 split_block_cursor(end, &block_end, &block_after); 678 679 extracted->impl = nir_cf_node_get_function(&block_begin->cf_node); 680 exec_list_make_empty(&extracted->list); 681 682 /* Dominance and other block-related information is toast. */ 683 nir_metadata_preserve(extracted->impl, nir_metadata_none); 684 685 nir_cf_node *cf_node = &block_begin->cf_node; 686 nir_cf_node *cf_node_end = &block_end->cf_node; 687 while (true) { 688 nir_cf_node *next = nir_cf_node_next(cf_node); 689 690 exec_node_remove(&cf_node->node); 691 cf_node->parent = NULL; 692 exec_list_push_tail(&extracted->list, &cf_node->node); 693 694 if (cf_node == cf_node_end) 695 break; 696 697 cf_node = next; 698 } 699 700 stitch_blocks(block_before, block_after); 701 } 702 703 void 704 nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor) 705 { 706 nir_block *before, *after; 707 708 if (exec_list_is_empty(&cf_list->list)) 709 return; 710 711 split_block_cursor(cursor, &before, &after); 712 713 foreach_list_typed_safe(nir_cf_node, node, node, &cf_list->list) { 714 exec_node_remove(&node->node); 715 node->parent = before->cf_node.parent; 716 exec_node_insert_node_before(&after->cf_node.node, &node->node); 717 } 718 719 stitch_blocks(before, 720 nir_cf_node_as_block(nir_cf_node_next(&before->cf_node))); 721 stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)), 722 after); 723 } 724 725 void 726 nir_cf_delete(nir_cf_list *cf_list) 727 { 728 foreach_list_typed(nir_cf_node, node, node, &cf_list->list) { 729 cleanup_cf_node(node, cf_list->impl); 730 } 731 } 732