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

Method expand_module

crates/rustc_codegen_spirv/src/linker/specializer.rs:2300–2497  ·  view source on GitHub ↗

Expand every "generic" global/function, and `OpName`/decorations applied to them, to their respective full set of instances, treating the original "generic" definition and its inferred `Replacements` as a template.

(mut self)

Source from the content-addressed store, hash-verified

2298 /// to them, to their respective full set of instances, treating the original
2299 /// "generic" definition and its inferred `Replacements` as a template.
2300 fn expand_module(mut self) -> Module {
2301 // From here on out we assume all instances are known, so ensure there
2302 // aren't any left unpropagated.
2303 self.propagate_instances();
2304
2305 // HACK(eddyb) steal `Vec`s so that we can still call methods on `self` below.
2306 let module = self.builder.module_mut();
2307 let mut entry_points = mem::take(&mut module.entry_points);
2308 let debug_names = mem::take(&mut module.debug_names);
2309 let annotations = mem::take(&mut module.annotations);
2310 let types_global_values = mem::take(&mut module.types_global_values);
2311 let functions = mem::take(&mut module.functions);
2312
2313 // Adjust `OpEntryPoint ...` in-place to use the new IDs for *Interface*
2314 // module-scoped `OpVariable`s (which should each have one instance).
2315 for inst in &mut entry_points {
2316 let func_id = inst.operands[1].unwrap_id_ref();
2317 assert!(
2318 !self.specializer.generics.contains_key(&func_id),
2319 "entry-point %{func_id} shouldn't be \"generic\""
2320 );
2321
2322 for interface_operand in &mut inst.operands[3..] {
2323 let interface_id = interface_operand.unwrap_id_ref();
2324 let mut instances = self.all_instances_of(interface_id);
2325 match (instances.next(), instances.next()) {
2326 (None, _) => unreachable!(
2327 "entry-point %{} has overly-\"generic\" \
2328 interface variable %{}, with no instances",
2329 func_id, interface_id
2330 ),
2331 (Some(_), Some(_)) => unreachable!(
2332 "entry-point %{} has overly-\"generic\" \
2333 interface variable %{}, with too many instances: {:?}",
2334 func_id,
2335 interface_id,
2336 FmtBy(|f| f
2337 .debug_list()
2338 .entries(self.all_instances_of(interface_id).map(
2339 |(instance, _)| FmtBy(move |f| write!(
2340 f,
2341 "{}",
2342 instance.display(|generic_args| generic_args.iter().copied())
2343 ))
2344 ))
2345 .finish())
2346 ),
2347 (Some((_, &instance_id)), None) => {
2348 *interface_operand = Operand::IdRef(instance_id);
2349 }
2350 }
2351 }
2352 }
2353
2354 // FIXME(eddyb) bucket `instances` into global vs function, and count
2355 // annotations separately, so that we can know exact capacities below.
2356
2357 // Expand `Op* %target ...` when `target` is "generic".

Callers 1

specializeFunction · 0.80

Calls 9

apply_rewrite_rulesFunction · 0.85
propagate_instancesMethod · 0.80
all_instances_ofMethod · 0.80
to_concreteMethod · 0.80
index_setMethod · 0.80
idMethod · 0.80
iterMethod · 0.80
nextMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected