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

Function split_copy_memory

crates/rustc_codegen_spirv/src/linker/mem2reg.rs:308–357  ·  view source on GitHub ↗

Splits an OpCopyMemory into an OpLoad followed by an OpStore. This is because we want to be able to mem2reg variables used in OpCopyMemory, but analysis becomes very difficult: we only analyze one variable at a time, but OpCopyMemory can copy between two local variables (both of which are getting mem2reg'd), requiring cross-analysis shenanigans. So, if we know at least one side of the OpCopyMemory

(
    header: &mut ModuleHeader,
    blocks: &mut [Block],
    var_map: &FxHashMap<Word, VarInfo>,
)

Source from the content-addressed store, hash-verified

306// Finally, an edge case to keep in mind is that an OpCopyMemory can happen between two vars in the
307// same var map (e.g. `s.x = s.y;`).
308fn split_copy_memory(
309 header: &mut ModuleHeader,
310 blocks: &mut [Block],
311 var_map: &FxHashMap<Word, VarInfo>,
312) {
313 for block in blocks {
314 let mut inst_index = 0;
315 while inst_index < block.instructions.len() {
316 let inst = &block.instructions[inst_index];
317 if inst.class.opcode == Op::CopyMemory {
318 let target = inst.operands[0].id_ref_any().unwrap();
319 let source = inst.operands[1].id_ref_any().unwrap();
320 if inst.operands.len() > 2 {
321 // TODO: Copy the memory operands to the load/store
322 bug!("mem2reg OpCopyMemory doesn't support memory operands yet");
323 }
324 let ty = match (var_map.get(&target), var_map.get(&source)) {
325 (None, None) => {
326 inst_index += 1;
327 continue;
328 }
329 (Some(target), None) => target.ty,
330 (None, Some(source)) => source.ty,
331 (Some(target), Some(source)) => {
332 assert_eq!(target.ty, source.ty);
333 target.ty
334 }
335 };
336 let temp_id = id(header);
337 block.instructions[inst_index] = Instruction::new(
338 Op::Load,
339 Some(ty),
340 Some(temp_id),
341 vec![Operand::IdRef(source)],
342 );
343 inst_index += 1;
344 block.instructions.insert(
345 inst_index,
346 Instruction::new(
347 Op::Store,
348 None,
349 None,
350 vec![Operand::IdRef(target), Operand::IdRef(temp_id)],
351 ),
352 );
353 }
354 inst_index += 1;
355 }
356 }
357}
358
359fn has_store(block: &Block, var_map: &FxHashMap<Word, VarInfo>) -> bool {
360 block.instructions.iter().any(|inst| {

Callers 1

insert_phis_allFunction · 0.85

Calls 3

idFunction · 0.85
insertMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected