@@ -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<()> {
8791fn 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