(&mut self, elab_values: &mut Vec<Value>, idom: Option<Block>, block: Block)
| 747 | } |
| 748 | |
| 749 | fn elaborate_block(&mut self, elab_values: &mut Vec<Value>, idom: Option<Block>, block: Block) { |
| 750 | trace!("elaborate_block: block {}", block); |
| 751 | self.start_block(idom, block); |
| 752 | |
| 753 | // Iterate over the side-effecting skeleton using the linked |
| 754 | // list in Layout. We will insert instructions that are |
| 755 | // elaborated *before* `inst`, so we can always use its |
| 756 | // next-link to continue the iteration. |
| 757 | let mut next_inst = self.func.layout.first_inst(block); |
| 758 | let mut first_branch = None; |
| 759 | while let Some(inst) = next_inst { |
| 760 | trace!( |
| 761 | "elaborating inst {} with results {:?}", |
| 762 | inst, |
| 763 | self.func.dfg.inst_results(inst) |
| 764 | ); |
| 765 | // Record the first branch we see in the block; all |
| 766 | // elaboration for args of *any* branch must be inserted |
| 767 | // before the *first* branch, because the branch group |
| 768 | // must remain contiguous at the end of the block. |
| 769 | if self.func.dfg.insts[inst].opcode().is_branch() && first_branch == None { |
| 770 | first_branch = Some(inst); |
| 771 | } |
| 772 | |
| 773 | // Determine where elaboration inserts insts. |
| 774 | let before = first_branch.unwrap_or(inst); |
| 775 | trace!(" -> inserting before {}", before); |
| 776 | |
| 777 | elab_values.extend(self.func.dfg.inst_values(inst)); |
| 778 | for arg in elab_values.iter_mut() { |
| 779 | trace!(" -> arg {}", *arg); |
| 780 | // Elaborate the arg, placing any newly-inserted insts |
| 781 | // before `before`. Get the updated value, which may |
| 782 | // be different than the original. |
| 783 | let mut new_arg = self.elaborate_eclass_use(*arg, before); |
| 784 | Self::maybe_remat_arg( |
| 785 | &self.remat_values, |
| 786 | &mut self.func, |
| 787 | &mut self.remat_copies, |
| 788 | block, |
| 789 | inst, |
| 790 | &mut new_arg, |
| 791 | &mut self.stats, |
| 792 | ); |
| 793 | trace!(" -> rewrote arg to {:?}", new_arg); |
| 794 | *arg = new_arg.value; |
| 795 | } |
| 796 | self.func |
| 797 | .dfg |
| 798 | .overwrite_inst_values(inst, elab_values.drain(..)); |
| 799 | |
| 800 | // We need to put the results of this instruction in the |
| 801 | // map now. |
| 802 | for &result in self.func.dfg.inst_results(inst) { |
| 803 | trace!(" -> result {}", result); |
| 804 | let best_result = self.value_to_best_value[result]; |
| 805 | self.value_to_elaborated_value.insert_if_absent( |
| 806 | &NullCtx, |
no test coverage detected