Replace the caller's call instruction with a jump to the caller's inlined copy of the callee's entry block. Also associates the callee's parameters with the caller's arguments in our value map. Returns the caller's stack map entries, if any.
(
allocs: &mut InliningAllocs,
func: &mut ir::Function,
call_inst: ir::Inst,
callee: &ir::Function,
entity_map: &EntityMap,
)
| 1215 | /// |
| 1216 | /// Returns the caller's stack map entries, if any. |
| 1217 | fn replace_call_with_jump( |
| 1218 | allocs: &mut InliningAllocs, |
| 1219 | func: &mut ir::Function, |
| 1220 | call_inst: ir::Inst, |
| 1221 | callee: &ir::Function, |
| 1222 | entity_map: &EntityMap, |
| 1223 | ) -> Option<ir::UserStackMapEntryVec> { |
| 1224 | trace!("Replacing `call` with `jump`"); |
| 1225 | trace!( |
| 1226 | " --> call instruction: {call_inst:?}: {}", |
| 1227 | func.dfg.display_inst(call_inst) |
| 1228 | ); |
| 1229 | |
| 1230 | let callee_entry_block = callee |
| 1231 | .layout |
| 1232 | .entry_block() |
| 1233 | .expect("callee function should have an entry block"); |
| 1234 | let callee_param_values = callee.dfg.block_params(callee_entry_block); |
| 1235 | let caller_arg_values = SmallValueVec::from_iter(func.dfg.inst_args(call_inst).iter().copied()); |
| 1236 | debug_assert_eq!(callee_param_values.len(), caller_arg_values.len()); |
| 1237 | debug_assert_eq!(callee_param_values.len(), callee.signature.params.len()); |
| 1238 | for (abi, (callee_param_value, caller_arg_value)) in callee |
| 1239 | .signature |
| 1240 | .params |
| 1241 | .iter() |
| 1242 | .zip(callee_param_values.into_iter().zip(caller_arg_values)) |
| 1243 | { |
| 1244 | debug_assert_eq!(abi.value_type, callee.dfg.value_type(*callee_param_value)); |
| 1245 | debug_assert_eq!(abi.value_type, func.dfg.value_type(caller_arg_value)); |
| 1246 | allocs.set_inlined_value(callee, *callee_param_value, caller_arg_value); |
| 1247 | } |
| 1248 | |
| 1249 | // Replace the caller's call instruction with a jump to the caller's inlined |
| 1250 | // copy of the callee's entry block. |
| 1251 | // |
| 1252 | // Note that the call block dominates the inlined entry block (and also all |
| 1253 | // other inlined blocks) so we can reference the arguments directly, and do |
| 1254 | // not need to add block parameters to the inlined entry block. |
| 1255 | let inlined_entry_block = entity_map.inlined_block(callee_entry_block); |
| 1256 | func.replace(call_inst).jump(inlined_entry_block, &[]); |
| 1257 | trace!( |
| 1258 | " --> replaced with jump instruction: {call_inst:?}: {}", |
| 1259 | func.dfg.display_inst(call_inst) |
| 1260 | ); |
| 1261 | |
| 1262 | let stack_map_entries = func.dfg.take_user_stack_map_entries(call_inst); |
| 1263 | stack_map_entries |
| 1264 | } |
| 1265 | |
| 1266 | /// Keeps track of mapping callee entities to their associated inlined caller |
| 1267 | /// entities. |
no test coverage detected