Skip to content

Commit 6e4d191

Browse files
committed
linker/inline: code review
#811 (review)
1 parent b473f2a commit 6e4d191

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
@@ -24,14 +24,15 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
2424
.iter()
2525
.map(|f| should_inline(&disallowed_argument_types, &disallowed_return_types, f))
2626
.collect();
27-
// This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion
28-
let postorder = compute_function_postorder(sess, module, &to_delete)?;
29-
let functions = module
27+
// This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion,
28+
// so we exit with an error if [`compute_function_postorder`] finds it.
29+
let function_to_index = module
3030
.functions
3131
.iter()
3232
.enumerate()
3333
.map(|(idx, f)| (f.def_id().unwrap(), idx))
3434
.collect();
35+
let postorder = compute_function_postorder(sess, module, &function_to_index, &to_delete)?;
3536
let void = module
3637
.types_global_values
3738
.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 {
@@ -284,7 +283,7 @@ struct Inliner<'m, 'map> {
284283
types_global_values: &'m mut Vec<Instruction>,
285284
void: Word,
286285
ptr_map: FxHashMap<Word, Word>,
287-
functions: &'map FunctionMap,
286+
function_to_index: &'map FunctionMap,
288287
needs_inline: &'map [bool],
289288
invalid_args: FxHashSet<Word>,
290289
}
@@ -328,14 +327,9 @@ impl Inliner<'_, '_> {
328327
functions[index] = function;
329328
}
330329

331-
/// Inlines one block and returns whether inlining actually occurred.
330+
/// Inlines one block.
332331
/// After calling this, `blocks[block_idx]` is finished processing.
333-
fn inline_block(
334-
&mut self,
335-
caller: &mut Function,
336-
functions: &[Function],
337-
block_idx: usize,
338-
) -> bool {
332+
fn inline_block(&mut self, caller: &mut Function, functions: &[Function], block_idx: usize) {
339333
// Find the first inlined OpFunctionCall
340334
let call = caller.blocks[block_idx]
341335
.instructions
@@ -346,14 +340,14 @@ impl Inliner<'_, '_> {
346340
(
347341
index,
348342
inst,
349-
self.functions[&inst.operands[0].id_ref_any().unwrap()],
343+
self.function_to_index[&inst.operands[0].id_ref_any().unwrap()],
350344
)
351345
})
352346
.find(|(_, inst, func_idx)| {
353347
self.needs_inline[*func_idx] || args_invalid(&self.invalid_args, inst)
354348
});
355349
let (call_index, call_inst, callee_idx) = match call {
356-
None => return false,
350+
None => return,
357351
Some(call) => call,
358352
};
359353
let callee = &functions[callee_idx];
@@ -422,7 +416,8 @@ impl Inliner<'_, '_> {
422416
let mut callee_header = take(&mut inlined_blocks[0]).instructions;
423417
// TODO: OpLine handling
424418
let num_variables = callee_header.partition_point(|inst| inst.class.opcode == Op::Variable);
425-
// Rather than fuse blocks, generate a new jump here. Branch fusing will take care of
419+
// Rather than fuse the first block of the inline function to the current block,
420+
// generate a new jump here. Branch fusing will take care of
426421
// it, and we maintain the invariant that current block has finished processing.
427422
let jump_to = self.id();
428423
inlined_blocks[0] = Block {
@@ -463,8 +458,6 @@ impl Inliner<'_, '_> {
463458
caller
464459
.blocks
465460
.splice((block_idx + 1)..(block_idx + 1), inlined_blocks);
466-
467-
true
468461
}
469462

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

0 commit comments

Comments
 (0)