Generates instructions containing the remaining defs in a block after other instructions have been emitted.
(&mut self, block: Block)
| 695 | /// Generates instructions containing the remaining defs in a block after |
| 696 | /// other instructions have been emitted. |
| 697 | fn gen_block_start_defs(&mut self, block: Block) -> Result<()> { |
| 698 | // We may need to emit multiple instructions due to MAX_INST_OPERANDS. |
| 699 | while !self.defs_by_blocks[block].is_empty() { |
| 700 | self.early_fixed.clear(); |
| 701 | self.late_fixed.clear(); |
| 702 | self.reuse_operands.clear(); |
| 703 | |
| 704 | let mut inst = InstData { |
| 705 | operands: vec![], |
| 706 | clobbers: vec![], |
| 707 | block, |
| 708 | terminator_kind: None, |
| 709 | is_pure: self.u.arbitrary()?, |
| 710 | }; |
| 711 | |
| 712 | let mut defined_values = vec![]; |
| 713 | while inst.operands.len() < MAX_INST_OPERANDS { |
| 714 | let Some(value) = self.defs_by_blocks[block].pop() else { |
| 715 | break; |
| 716 | }; |
| 717 | let op = self.gen_def( |
| 718 | block, |
| 719 | value, |
| 720 | false, |
| 721 | inst.operands.len(), |
| 722 | &mut defined_values, |
| 723 | )?; |
| 724 | inst.operands.push(op); |
| 725 | } |
| 726 | |
| 727 | if self.domtree.immediate_dominator(block).is_some() { |
| 728 | for value in defined_values { |
| 729 | if !self.u.arbitrary()? { |
| 730 | self.add_indirect_remat(value, block, true)?; |
| 731 | } |
| 732 | } |
| 733 | } |
| 734 | |
| 735 | self.block_insts[block].push(inst); |
| 736 | } |
| 737 | |
| 738 | Ok(()) |
| 739 | } |
| 740 | |
| 741 | /// Generates a single instruction in the given block. |
| 742 | fn gen_inst(&mut self, block: Block, is_first_inst: bool, is_ret: bool) -> Result<InstData> { |
no test coverage detected