Skip to content

Commit

Permalink
Merge pull request #13 from fitzgen/fix-recursion-guard
Browse files Browse the repository at this point in the history
Use defined function index when guarding against recursive inlining
  • Loading branch information
fitzgen committed Oct 18, 2023
2 parents a74ae23 + 22dc70e commit a6b733a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
12 changes: 5 additions & 7 deletions src/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,24 +786,22 @@ impl Optimizer {

// ... and if that function index is not already on our winlining stack
// (i.e. we aren't in a recursive inlining chain)...
if on_stack.contains(&callee_func_index) {
let defined_func_index = callee_func_index
.checked_sub(context.num_imported_funcs)
.unwrap();
if on_stack.contains(&defined_func_index) {
return Ok(None);
}

// ... and if that function has the correct type (if this is not true
// then either the profile is bogus/mismatched or every time the call
// site was executed it trapped)...
if context.funcs[usize::try_from(callee_func_index - context.num_imported_funcs).unwrap()]
!= type_index
{
if context.funcs[usize::try_from(defined_func_index).unwrap()] != type_index {
return Ok(None);
}

// ... then we can winline this callee and push it onto our stack!

let defined_func_index = callee_func_index
.checked_sub(context.num_imported_funcs)
.unwrap();
let locals_delta = *num_locals;
let func_body = context.func_bodies[usize::try_from(defined_func_index).unwrap()].clone();
let ops = func_body
Expand Down
38 changes: 38 additions & 0 deletions tests/all/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,44 @@ fn dont_inline_direct_recursion() -> Result<()> {
)
}

#[test]
fn dont_inline_direct_recursion_with_imports() -> Result<()> {
assert_optimize(
Optimizer::new().min_total_calls(100),
&[&[(1, 100)]],
r#"
(module
(type (func (param i32) (result i32)))
(import "foo" "bar" (func (type 0)))
(func (type 0)
local.get 0
local.get 0
call_indirect (type 0)
)
(table 100 100 funcref)
(elem (i32.const 0) funcref (ref.func 1))
)
"#,
r#"
(module
(type (;0;) (func (param i32) (result i32)))
(import "foo" "bar" (func (;0;) (type 0)))
(func (;1;) (type 0) (param i32) (result i32)
(local i32)
local.get 0
local.get 0
call_indirect (type 0)
)
(table (;0;) 100 100 funcref)
(elem (;0;) (i32.const 0) funcref (ref.func 1))
)
"#,
)
}

#[test]
fn multiple_funcref_tables() -> Result<()> {
assert_optimize(
Expand Down

0 comments on commit a6b733a

Please sign in to comment.