Skip to content

Commit fa653c1

Browse files
committed
linker/inline: code review
EmbarkStudios#811 (review)
1 parent 910a149 commit fa653c1

File tree

1 file changed

+16
-23
lines changed
  • crates/rustc_codegen_spirv/src/linker

1 file changed

+16
-23
lines changed

crates/rustc_codegen_spirv/src/linker/inline.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
2323
.iter()
2424
.map(|f| should_inline(&disallowed_argument_types, &disallowed_return_types, f))
2525
.collect();
26-
// This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion
27-
let postorder = compute_function_postorder(sess, module, &to_delete)?;
28-
let functions = module
26+
// This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion,
27+
// so we exit with an error if [`compute_function_postorder`] finds it.
28+
let function_to_index = module
2929
.functions
3030
.iter()
3131
.enumerate()
3232
.map(|(idx, f)| (f.def_id().unwrap(), idx))
3333
.collect();
34+
let postorder = compute_function_postorder(sess, module, &function_to_index, &to_delete)?;
3435
let void = module
3536
.types_global_values
3637
.iter()
@@ -56,10 +57,13 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
5657
types_global_values: &mut module.types_global_values,
5758
void,
5859
ptr_map,
59-
functions: &functions,
60+
function_to_index: &function_to_index,
6061
needs_inline: &to_delete,
6162
invalid_args,
6263
};
64+
// Processing functions in post-order of call tree we ensure that
65+
// inlined functions already have all of the inner functions inlined, so we don't do
66+
// the same work multiple times.
6367
for index in postorder {
6468
inliner.inline_fn(&mut module.functions, index);
6569
fuse_trivial_branches(&mut module.functions[index]);
@@ -87,14 +91,9 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
8791
fn compute_function_postorder(
8892
sess: &Session,
8993
module: &Module,
94+
func_to_index: &FxHashMap<Word, usize>,
9095
to_delete: &[bool],
9196
) -> super::Result<Vec<usize>> {
92-
let func_to_index: FxHashMap<Word, usize> = module
93-
.functions
94-
.iter()
95-
.enumerate()
96-
.map(|(index, func)| (func.def_id().unwrap(), index))
97-
.collect();
9897
/// Possible node states for cycle-discovering DFS.
9998
#[derive(Clone, PartialEq)]
10099
enum NodeState {
@@ -286,7 +285,7 @@ struct Inliner<'m, 'map> {
286285
types_global_values: &'m mut Vec<Instruction>,
287286
void: Word,
288287
ptr_map: FxHashMap<Word, Word>,
289-
functions: &'map FunctionMap,
288+
function_to_index: &'map FunctionMap,
290289
needs_inline: &'map [bool],
291290
invalid_args: FxHashSet<Word>,
292291
}
@@ -330,14 +329,9 @@ impl Inliner<'_, '_> {
330329
functions[index] = function;
331330
}
332331

333-
/// Inlines one block and returns whether inlining actually occurred.
332+
/// Inlines one block.
334333
/// After calling this, `blocks[block_idx]` is finished processing.
335-
fn inline_block(
336-
&mut self,
337-
caller: &mut Function,
338-
functions: &[Function],
339-
block_idx: usize,
340-
) -> bool {
334+
fn inline_block(&mut self, caller: &mut Function, functions: &[Function], block_idx: usize) {
341335
// Find the first inlined OpFunctionCall
342336
let call = caller.blocks[block_idx]
343337
.instructions
@@ -348,14 +342,14 @@ impl Inliner<'_, '_> {
348342
(
349343
index,
350344
inst,
351-
self.functions[&inst.operands[0].id_ref_any().unwrap()],
345+
self.function_to_index[&inst.operands[0].id_ref_any().unwrap()],
352346
)
353347
})
354348
.find(|(_, inst, func_idx)| {
355349
self.needs_inline[*func_idx] || args_invalid(&self.invalid_args, inst)
356350
});
357351
let (call_index, call_inst, callee_idx) = match call {
358-
None => return false,
352+
None => return,
359353
Some(call) => call,
360354
};
361355
let callee = &functions[callee_idx];
@@ -424,7 +418,8 @@ impl Inliner<'_, '_> {
424418
let mut callee_header = take(&mut inlined_blocks[0]).instructions;
425419
// TODO: OpLine handling
426420
let num_variables = callee_header.partition_point(|inst| inst.class.opcode == Op::Variable);
427-
// Rather than fuse blocks, generate a new jump here. Branch fusing will take care of
421+
// Rather than fuse the first block of the inline function to the current block,
422+
// generate a new jump here. Branch fusing will take care of
428423
// it, and we maintain the invariant that current block has finished processing.
429424
let jump_to = self.id();
430425
inlined_blocks[0] = Block {
@@ -465,8 +460,6 @@ impl Inliner<'_, '_> {
465460
caller
466461
.blocks
467462
.splice((block_idx + 1)..(block_idx + 1), inlined_blocks);
468-
469-
true
470463
}
471464

472465
fn add_clone_id_rules(&mut self, rewrite_rules: &mut FxHashMap<Word, Word>, blocks: &[Block]) {

0 commit comments

Comments
 (0)