Split the block containing `before` in two. Insert `new_block` after the old block and move `before` and the following instructions to `new_block`: ```text old_block: i1 i2 i3 << before i4 ``` becomes: ```text old_block: i1 i2 new_block: i3 << before i4 ```
(&mut self, new_block: Block, before: Inst)
| 554 | /// i4 |
| 555 | /// ``` |
| 556 | pub fn split_block(&mut self, new_block: Block, before: Inst) { |
| 557 | let old_block = self |
| 558 | .inst_block(before) |
| 559 | .expect("The `before` instruction must be in the layout"); |
| 560 | debug_assert!(!self.is_block_inserted(new_block)); |
| 561 | |
| 562 | // Insert new_block after old_block. |
| 563 | let next_block = self.blocks[old_block].next; |
| 564 | let last_inst = self.blocks[old_block].last_inst; |
| 565 | { |
| 566 | let node = &mut self.blocks[new_block]; |
| 567 | node.prev = old_block.into(); |
| 568 | node.next = next_block; |
| 569 | node.first_inst = before.into(); |
| 570 | node.last_inst = last_inst; |
| 571 | } |
| 572 | self.blocks[old_block].next = new_block.into(); |
| 573 | |
| 574 | // Fix backwards link. |
| 575 | if Some(old_block) == self.last_block { |
| 576 | self.last_block = Some(new_block); |
| 577 | } else { |
| 578 | self.blocks[next_block.unwrap()].prev = new_block.into(); |
| 579 | } |
| 580 | |
| 581 | // Disconnect the instruction links. |
| 582 | let prev_inst = self.insts[before].prev; |
| 583 | self.insts[before].prev = None.into(); |
| 584 | self.blocks[old_block].last_inst = prev_inst; |
| 585 | match prev_inst.expand() { |
| 586 | None => self.blocks[old_block].first_inst = None.into(), |
| 587 | Some(pi) => self.insts[pi].next = None.into(), |
| 588 | } |
| 589 | |
| 590 | // Fix the instruction -> block pointers. |
| 591 | let mut opt_i = Some(before); |
| 592 | while let Some(i) = opt_i { |
| 593 | debug_assert_eq!(self.insts[i].block.expand(), Some(old_block)); |
| 594 | self.insts[i].block = new_block.into(); |
| 595 | opt_i = self.insts[i].next.into(); |
| 596 | } |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | #[derive(Clone, Debug, Default)] |