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

Function inline

crates/rustc_codegen_spirv/src/linker/inline.rs:30–195  ·  view source on GitHub ↗
(sess: &Session, module: &mut Module)

Source from the content-addressed store, hash-verified

28}
29
30pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
31 // This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion
32 deny_recursion_in_module(sess, module)?;
33
34 let custom_ext_inst_set_import = module
35 .ext_inst_imports
36 .iter()
37 .find(|inst| {
38 assert_eq!(inst.class.opcode, Op::ExtInstImport);
39 inst.operands[0].unwrap_literal_string() == &custom_insts::CUSTOM_EXT_INST_SET[..]
40 })
41 .map(|inst| inst.result_id.unwrap());
42
43 // HACK(eddyb) compute the set of functions that may `Abort` *transitively*,
44 // which is only needed because of how we inline (sometimes it's outside-in,
45 // aka top-down, instead of always being inside-out, aka bottom-up).
46 //
47 // (inlining is needed in the first place because our custom `Abort`
48 // instructions get lowered to a simple `OpReturn` in entry-points, but
49 // that requires that they get inlined all the way up to the entry-points)
50 let functions_that_may_abort = custom_ext_inst_set_import
51 .map(|custom_ext_inst_set_import| {
52 let mut may_abort_by_id = FxHashSet::default();
53
54 // FIXME(eddyb) use this `CallGraph` abstraction more during inlining.
55 let call_graph = CallGraph::collect(module);
56 for func_idx in call_graph.post_order() {
57 let func_id = module.functions[func_idx].def_id().unwrap();
58
59 let any_callee_may_abort = call_graph.callees[func_idx].iter().any(|&callee_idx| {
60 may_abort_by_id.contains(&module.functions[callee_idx].def_id().unwrap())
61 });
62 if any_callee_may_abort {
63 may_abort_by_id.insert(func_id);
64 continue;
65 }
66
67 let may_abort_directly = module.functions[func_idx].blocks.iter().any(|block| {
68 match &block.instructions[..] {
69 [.., last_normal_inst, terminator_inst]
70 if last_normal_inst.class.opcode == Op::ExtInst
71 && last_normal_inst.operands[0].unwrap_id_ref()
72 == custom_ext_inst_set_import
73 && CustomOp::decode_from_ext_inst(last_normal_inst)
74 == CustomOp::Abort =>
75 {
76 assert_eq!(terminator_inst.class.opcode, Op::Unreachable);
77 true
78 }
79
80 _ => false,
81 }
82 });
83 if may_abort_directly {
84 may_abort_by_id.insert(func_id);
85 }
86 }
87

Callers 1

linkFunction · 0.85

Calls 11

deny_recursion_in_moduleFunction · 0.85
should_inlineFunction · 0.85
has_dont_inlineFunction · 0.85
get_namesFunction · 0.85
next_idFunction · 0.85
fuse_trivial_branchesFunction · 0.85
iterMethod · 0.80
post_orderMethod · 0.80
insertMethod · 0.80
inline_fnMethod · 0.80
collectMethod · 0.45

Tested by

no test coverage detected