From f4422d44088a9cb171c8319797f2f27c92c8a1f1 Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Wed, 3 May 2023 02:05:17 +0530 Subject: [PATCH] Inlining heuristic: return value demotion adds arg (#4518) ## Description We currently don't support compiling functions with more than 6 args. Such functions are inlined. However, the inliner heuristic that checks this fails to say "inline" if there are 6 args, but the return type will be demoted later on, adding an additional arg. Fix that. Fixes #4477. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --- sway-ir/src/optimize/inline.rs | 14 ++++++- .../language/arg_demotion_inline/Forc.lock | 16 +++++++ .../language/arg_demotion_inline/Forc.toml | 9 ++++ .../language/arg_demotion_inline/src/main.sw | 42 +++++++++++++++++++ .../language/arg_demotion_inline/test.toml | 2 + .../stack_indexing_overflow/Forc.lock | 6 +-- .../stack_indexing_overflow/Forc.toml | 2 +- 7 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/test.toml diff --git a/sway-ir/src/optimize/inline.rs b/sway-ir/src/optimize/inline.rs index b61bc4d39c7..c7439d910a0 100644 --- a/sway-ir/src/optimize/inline.rs +++ b/sway-ir/src/optimize/inline.rs @@ -157,9 +157,21 @@ pub fn inline_in_non_predicate_module( None => {} } + let ret_type = func.get_return_type(ctx); + let num_args = { + func.args_iter(ctx).count() + + if super::target_fuel::is_demotable_type(ctx, &ret_type) { + // The return type will be demoted to memory, + // which means that there'll be an additional return arg. + 1 + } else { + 0 + } + }; + // For now, pending improvements to ASMgen for calls, we must inline any function which has // too many args. - if func.args_iter(ctx).count() as u8 > NUM_ARG_REGISTERS { + if num_args as u8 > NUM_ARG_REGISTERS { return true; } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.lock new file mode 100644 index 00000000000..14f842c35b6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.lock @@ -0,0 +1,16 @@ +[[package]] +name = 'arg_demotion_inline' +source = 'member' +dependencies = [ + 'core', + 'std', +] + +[[package]] +name = 'core' +source = 'path+from-root-603115901A793008' + +[[package]] +name = 'std' +source = 'path+from-root-603115901A793008' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.toml new file mode 100644 index 00000000000..82d1227e285 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "arg_demotion_inline" + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/src/main.sw new file mode 100644 index 00000000000..c812752935f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/src/main.sw @@ -0,0 +1,42 @@ +contract; + +abi MyContract { + fn test_function() -> bool; +} + +struct Foo { + a: u64, + b: u64, + c: u64, + d: u64, + e: u64, + f: u64, +} + +impl Foo { + fn new( + a: u64, + b: u64, + c: u64, + d: u64, + e: u64, + f: u64, + ) -> Self { + Self { + a, + b, + c, + d, + e, + f, + } + } +} + +impl MyContract for Contract { + fn test_function() -> bool { + let bar1 = Foo::new(0,0,0,0,0,0); + let bar2 = Foo::new(0,0,0,0,0,0); + true + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/test.toml new file mode 100644 index 00000000000..bd5d995dc97 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/arg_demotion_inline/test.toml @@ -0,0 +1,2 @@ +category = "compile" +expected_warnings = 8 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.lock index 3cfb201caf2..0471d8a9ba6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.lock +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.lock @@ -1,13 +1,13 @@ [[package]] name = 'core' -source = 'path+from-root-6BF9CEE717879469' +source = 'path+from-root-E733504800A298D4' [[package]] -name = 'script_multi_test' +name = 'stack_indexing_overflow' source = 'member' dependencies = ['std'] [[package]] name = 'std' -source = 'path+from-root-6BF9CEE717879469' +source = 'path+from-root-E733504800A298D4' dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.toml index 3052a70ee03..ed842ed01b8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/stack_indexing_overflow/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "script_multi_test" +name = "stack_indexing_overflow" [dependencies] std = { path = "../../../../../../../sway-lib-std" }