Type inference for polymorphic instructions. The controlling type variable can be specified explicitly as 'splat.i32x4 v5', or it can be inferred from `inst_data.typevar_operand` for some opcodes. Returns the controlling typevar for a polymorphic opcode, or `INVALID` for a non-polymorphic opcode.
(
&self,
ctx: &Context,
opcode: Opcode,
explicit_ctrl_type: Option<Type>,
inst_data: &InstructionData,
)
| 2358 | // Returns the controlling typevar for a polymorphic opcode, or `INVALID` for a non-polymorphic |
| 2359 | // opcode. |
| 2360 | fn infer_typevar( |
| 2361 | &self, |
| 2362 | ctx: &Context, |
| 2363 | opcode: Opcode, |
| 2364 | explicit_ctrl_type: Option<Type>, |
| 2365 | inst_data: &InstructionData, |
| 2366 | ) -> ParseResult<Type> { |
| 2367 | let constraints = opcode.constraints(); |
| 2368 | let ctrl_type = match explicit_ctrl_type { |
| 2369 | Some(t) => t, |
| 2370 | None => { |
| 2371 | if constraints.use_typevar_operand() { |
| 2372 | // This is an opcode that supports type inference, AND there was no |
| 2373 | // explicit type specified. Look up `ctrl_value` to see if it was defined |
| 2374 | // already. |
| 2375 | // TBD: If it is defined in another block, the type should have been |
| 2376 | // specified explicitly. It is unfortunate that the correctness of IR |
| 2377 | // depends on the layout of the blocks. |
| 2378 | let ctrl_src_value = inst_data |
| 2379 | .typevar_operand(&ctx.function.dfg.value_lists) |
| 2380 | .expect("Constraints <-> Format inconsistency"); |
| 2381 | if !ctx.map.contains_value(ctrl_src_value) { |
| 2382 | return err!( |
| 2383 | self.loc, |
| 2384 | "type variable required for polymorphic opcode, e.g. '{}.{}'; \ |
| 2385 | can't infer from {} which is not yet defined", |
| 2386 | opcode, |
| 2387 | constraints.ctrl_typeset().unwrap().example(), |
| 2388 | ctrl_src_value |
| 2389 | ); |
| 2390 | } |
| 2391 | if !ctx.function.dfg.value_is_valid_for_parser(ctrl_src_value) { |
| 2392 | return err!( |
| 2393 | self.loc, |
| 2394 | "type variable required for polymorphic opcode, e.g. '{}.{}'; \ |
| 2395 | can't infer from {} which is not yet resolved", |
| 2396 | opcode, |
| 2397 | constraints.ctrl_typeset().unwrap().example(), |
| 2398 | ctrl_src_value |
| 2399 | ); |
| 2400 | } |
| 2401 | ctx.function.dfg.value_type(ctrl_src_value) |
| 2402 | } else if constraints.is_polymorphic() { |
| 2403 | // This opcode does not support type inference, so the explicit type |
| 2404 | // variable is required. |
| 2405 | return err!( |
| 2406 | self.loc, |
| 2407 | "type variable required for polymorphic opcode, e.g. '{}.{}'", |
| 2408 | opcode, |
| 2409 | constraints.ctrl_typeset().unwrap().example() |
| 2410 | ); |
| 2411 | } else { |
| 2412 | // This is a non-polymorphic opcode. No typevar needed. |
| 2413 | INVALID |
| 2414 | } |
| 2415 | } |
| 2416 | }; |
| 2417 |
no test coverage detected