This implementation is richer than `InsertBuilder` because we use the data of the instruction being inserted to add related info to the DFG and the SSA building system, and perform debug sanity checks.
(self, data: InstructionData, ctrl_typevar: Type)
| 109 | // instruction being inserted to add related info to the DFG and the SSA building system, |
| 110 | // and perform debug sanity checks. |
| 111 | fn build(self, data: InstructionData, ctrl_typevar: Type) -> (Inst, &'short mut DataFlowGraph) { |
| 112 | // We only insert the Block in the layout when an instruction is added to it |
| 113 | self.builder.ensure_inserted_block(); |
| 114 | |
| 115 | let inst = self.builder.func.dfg.make_inst(data); |
| 116 | self.builder.func.dfg.make_inst_results(inst, ctrl_typevar); |
| 117 | self.builder.func.layout.append_inst(inst, self.block); |
| 118 | if !self.builder.srcloc.is_default() { |
| 119 | self.builder.func.set_srcloc(inst, self.builder.srcloc); |
| 120 | } |
| 121 | |
| 122 | match &self.builder.func.dfg.insts[inst] { |
| 123 | ir::InstructionData::Jump { |
| 124 | destination: dest, .. |
| 125 | } => { |
| 126 | // If the user has supplied jump arguments we must adapt the arguments of |
| 127 | // the destination block |
| 128 | let block = dest.block(&self.builder.func.dfg.value_lists); |
| 129 | self.builder.declare_successor(block, inst); |
| 130 | } |
| 131 | |
| 132 | ir::InstructionData::Brif { |
| 133 | blocks: [branch_then, branch_else], |
| 134 | .. |
| 135 | } => { |
| 136 | let block_then = branch_then.block(&self.builder.func.dfg.value_lists); |
| 137 | let block_else = branch_else.block(&self.builder.func.dfg.value_lists); |
| 138 | |
| 139 | self.builder.declare_successor(block_then, inst); |
| 140 | if block_then != block_else { |
| 141 | self.builder.declare_successor(block_else, inst); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | ir::InstructionData::BranchTable { table, .. } => { |
| 146 | let pool = &self.builder.func.dfg.value_lists; |
| 147 | |
| 148 | // Unlike most other jumps/branches and like try_call, |
| 149 | // jump tables are capable of having the same successor appear |
| 150 | // multiple times, so we must deduplicate. |
| 151 | let mut unique = EntitySet::<Block>::new(); |
| 152 | for dest_block in self |
| 153 | .builder |
| 154 | .func |
| 155 | .stencil |
| 156 | .dfg |
| 157 | .jump_tables |
| 158 | .get(*table) |
| 159 | .expect("you are referencing an undeclared jump table") |
| 160 | .all_branches() |
| 161 | { |
| 162 | let block = dest_block.block(pool); |
| 163 | if !unique.insert(block) { |
| 164 | continue; |
| 165 | } |
| 166 | |
| 167 | // Call `declare_block_predecessor` instead of `declare_successor` for |
| 168 | // avoiding the borrow checker. |
no test coverage detected