MCPcopy Create free account
hub / github.com/Rust-GPU/rust-gpu / collect_generics

Method collect_generics

crates/rustc_codegen_spirv/src/linker/specializer.rs:567–647  ·  view source on GitHub ↗
(&mut self, module: &Module)

Source from the content-addressed store, hash-verified

565 }
566
567 fn collect_generics(&mut self, module: &Module) {
568 // Process all defining instructions for globals (types, constants,
569 // and module-scoped variables), and functions' `OpFunction` instructions,
570 // but note that for `OpFunction`s only the signature is considered,
571 // actual inference based on bodies happens later, in `infer_function`.
572 let types_global_values_and_functions = module
573 .types_global_values
574 .iter()
575 .chain(module.functions.iter().filter_map(|f| f.def.as_ref()));
576
577 let mut forward_declared_pointers = FxHashSet::default();
578 for inst in types_global_values_and_functions {
579 let result_id = if inst.class.opcode == Op::TypeForwardPointer {
580 forward_declared_pointers.insert(inst.operands[0].unwrap_id_ref());
581 inst.operands[0].unwrap_id_ref()
582 } else {
583 let result_id = inst.result_id.unwrap_or_else(|| {
584 unreachable!(
585 "Op{:?} is in `types_global_values` but not have a result ID",
586 inst.class.opcode
587 );
588 });
589 if forward_declared_pointers.remove(&result_id) {
590 // HACK(eddyb) this is a forward-declared pointer, pretend
591 // it's not "generic" at all to avoid breaking the rest of
592 // the logic - see module-level docs for how this should be
593 // handled in the future to support recursive data types.
594 assert_eq!(inst.class.opcode, Op::TypePointer);
595 continue;
596 }
597 result_id
598 };
599
600 // Record all integer `OpConstant`s (used for `IndexComposite`).
601 if inst.class.opcode == Op::Constant {
602 if let Operand::LiteralInt32(x) = inst.operands[0] {
603 self.int_consts.insert(result_id, x);
604 }
605 }
606
607 // Instantiate `inst` in a fresh inference context, to determine
608 // how many parameters it needs, and how they might be constrained.
609 let (param_count, param_values, replacements) = {
610 let mut infer_cx = InferCx::new(self);
611 infer_cx.instantiate_instruction(inst, InstructionLocation::Module);
612
613 let param_count = infer_cx.infer_var_values.len() as u32;
614
615 // FIXME(eddyb) dedup this with `infer_function`.
616 let param_values = infer_cx
617 .infer_var_values
618 .iter()
619 .map(|v| v.map_var(|InferVar(i)| Param(i)));
620 // Only allocate `param_values` if they constrain parameters.
621 let param_values = if param_values.clone().any(|v| v != Value::Unknown) {
622 Some(param_values.collect())
623 } else {
624 None

Callers 1

specializeFunction · 0.80

Calls 8

ParamClass · 0.85
iterMethod · 0.80
insertMethod · 0.80
map_varMethod · 0.80
into_replacementsMethod · 0.80
as_refMethod · 0.45
collectMethod · 0.45

Tested by

no test coverage detected