Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize away trivial nested unconstrained calls #5043

Closed
fcarreiro opened this issue May 17, 2024 · 0 comments · Fixed by #5121
Closed

optimize away trivial nested unconstrained calls #5043

fcarreiro opened this issue May 17, 2024 · 0 comments · Fixed by #5121
Labels
enhancement New feature or request

Comments

@fcarreiro
Copy link

Problem

Having trivial calls to an unconstrained function that then calls another function does not get optimized away. An internal call-return is added (+ Brillig stack dumping and recovering). See AztecProtocol/aztec-packages#6449

Happy Case

It should get optimized away. This makes even more sense in aztec-public where the root function is already unconstrained.

Project Impact

Nice-to-have

Impact Context

Env getters are used particularly often and this turns what could be 1 opcode into many many (that include internal call stack allocation etc).

Workaround

None

Workaround Description

No response

Additional Context

AztecProtocol/aztec-packages#6449

Would you like to submit a PR for this Issue?

None

Support Needs

No response

@fcarreiro fcarreiro added the enhancement New feature or request label May 17, 2024
github-merge-queue bot pushed a commit that referenced this issue May 29, 2024
# Description

## Problem\*

Resolves #5043

<details>
<summary>Opcode count of Aztec public functions before => after this
change in the inlining strategy</summary>

```
_approve_bridge_and_exit_input_asset_to_L1 on contract Uniswap with size 3788 => 3166
_assert_token_is_same on contract TokenBridge with size 916 => 640
_assert_token_is_same on contract Uniswap with size 1845 => 1546
_borrow on contract Lending with size 10988 => 10152
_call_mint_on_token on contract TokenBridge with size 1427 => 1125
_check_deadline on contract Crowdfunding with size 1015 => 752
_deposit on contract Lending with size 1699 => 1220
_increase_public_balance on contract GasToken with size 1325 => 1103
_increase_public_balance on contract Token with size 1577 => 1201
_increase_public_balance on contract TokenBlacklist with size 1577 => 1201
_reduce_total_supply on contract Token with size 945 => 626
_reduce_total_supply on contract TokenBlacklist with size 945 => 626
_repay on contract Lending with size 6775 => 6284
_withdraw on contract Lending with size 10715 => 9850
add_args_return on contract AvmNestedCallsTest with size 15 => 15
add_args_return on contract AvmTest with size 15 => 15
add_storage_map on contract AvmTest with size 797 => 664
add_to_tally_public on contract EasyPrivateVoting with size 1496 => 1112
add_u128 on contract AvmTest with size 187 => 187
admin on contract Token with size 495 => 348
approve_public_authwit on contract EcdsaAccount with size 977 => 718
approve_public_authwit on contract SchnorrAccount with size 743 => 621
approve_public_authwit on contract SchnorrHardcodedAccount with size 742 => 620
approve_public_authwit on contract SchnorrSingleKeyAccount with size 742 => 620
assert_block_number on contract AppSubscription with size 920 => 669
assert_minter_and_mint on contract Token with size 1434 => 1035
assert_not_expired on contract AppSubscription with size 910 => 658
assert_nullifier_exists on contract AvmTest with size 242 => 156
assert_public_global_vars on contract Test with size 1054 => 679
assert_same on contract AvmNestedCallsTest with size 138 => 138
assert_unsiloed_nullifier_acvm on contract AvmAcvmInteropTest with size 102 => 16
assertion_failure on contract AvmTest with size 166 => 166
avm_to_acvm_call on contract AvmAcvmInteropTest with size 287 => 169
balance_of_public on contract GasToken with size 651 => 612
balance_of_public on contract Token with size 880 => 710
balance_of_public on contract TokenBlacklist with size 880 => 710
borrow_public on contract Lending with size 1193 => 939
broadcast on contract Benchmarking with size 419 => 337
burn_public on contract Token with size 2426 => 1962
burn_public on contract TokenBlacklist with size 3148 => 2468
call_acvm_from_avm on contract AvmAcvmInteropTest with size 574 => 503
call_avm_from_acvm on contract AvmAcvmInteropTest with size 578 => 507
check_balance on contract GasToken with size 856 => 768
check_selector on contract AvmTest with size 463 => 463
claim_public on contract GasToken with size 3963 => 3416
claim_public on contract TokenBridge with size 4176 => 3457
constant_field_acvm on contract AvmAcvmInteropTest with size 13 => 13
constant_field_avm on contract AvmAcvmInteropTest with size 13 => 13
constructor on contract AppSubscription with size 3376 => 1983
constructor on contract Auth with size 1414 => 994
constructor on contract AvmInitializerTest with size 1290 => 908
constructor on contract Claim with size 1700 => 1123
constructor on contract EasyPrivateVoting with size 1454 => 941
constructor on contract FPC with size 1700 => 1123
constructor on contract InclusionProofs with size 1021 => 704
constructor on contract Token with size 2737 => 1961
constructor on contract TokenBlacklist with size 1925 => 1285
constructor on contract TokenBridge with size 1400 => 924
constructor on contract Uniswap with size 1326 => 909
consume_message_from_arbitrary_sender_public on contract Test with size 2203 => 1893
consume_mint_public_message on contract Test with size 2910 => 2600
create_different_nullifier_in_nested_call on contract AvmNestedCallsTest with size 743 => 639
create_l2_to_l1_message_arbitrary_recipient_public on contract Test with size 56 => 12
create_l2_to_l1_message_public on contract Test with size 73 => 29
create_same_nullifier_in_nested_call on contract AvmNestedCallsTest with size 741 => 637
debug_logging on contract AvmTest with size 725 => 402
deposit_public on contract Lending with size 2286 => 1846
dummy_public_call on contract Test with size 354 => 284
emit_nullifier_and_check on contract AvmTest with size 436 => 314
emit_nullifier_public on contract Test with size 47 => 11
emit_unencrypted on contract Test with size 54 => 16
emit_unencrypted_log on contract AvmTest with size 757 => 685
end_vote on contract EasyPrivateVoting with size 514 => 279
exit_to_l1_public on contract TokenBridge with size 2154 => 1773
get_address on contract AvmTest with size 45 => 13
get_args_hash on contract AvmTest with size 18 => 18
get_asset on contract Lending with size 888 => 718
get_assets on contract Lending with size 587 => 411
get_authorized on contract Auth with size 597 => 443
get_authorized_delay on contract Auth with size 702 => 517
get_block_number on contract AvmTest with size 45 => 13
get_chain_id on contract AvmTest with size 45 => 13
get_fee_per_da_gas on contract AvmTest with size 45 => 13
get_fee_per_l2_gas on contract AvmTest with size 45 => 13
get_portal_address_public on contract TokenBridge with size 297 => 145
get_position on contract Lending with size 3908 => 3623
get_price on contract PriceFeed with size 617 => 579
get_public_value on contract StatefulTest with size 636 => 598
get_roles on contract TokenBlacklist with size 989 => 749
get_scheduled_authorized on contract Auth with size 595 => 443
get_sender on contract AvmTest with size 45 => 13
get_shared_immutable_constrained_public on contract DocsExample with size 438 => 406
get_shared_immutable_constrained_public_indirect on contract DocsExample with size 701 => 607
get_shared_immutable_constrained_public_multiple on contract DocsExample with size 136 => 98
get_storage_address on contract AvmTest with size 45 => 13
get_timestamp on contract AvmTest with size 45 => 13
get_token on contract TokenBridge with size 513 => 366
get_transaction_fee on contract AvmTest with size 45 => 13
get_version on contract AvmTest with size 45 => 13
increment_balance on contract Benchmarking with size 1472 => 1264
increment_public_value on contract StatefulTest with size 695 => 449
increment_public_value_no_init_check on contract StatefulTest with size 447 => 351
init on contract Crowdfunding with size 2100 => 1341
init on contract Lending with size 958 => 598
initialize_public_immutable on contract DocsExample with size 433 => 252
initialize_shared_immutable on contract DocsExample with size 433 => 252
is_minter on contract Token with size 838 => 668
is_time_equal on contract Test with size 56 => 18
keccak_hash on contract AvmTest with size 49 => 49
l1_to_l2_msg_exists on contract AvmTest with size 65 => 17
mint_private on contract Token with size 1247 => 790
mint_private on contract TokenBlacklist with size 1495 => 906
mint_public on contract GasToken with size 946 => 813
mint_public on contract Token with size 2048 => 1520
mint_public on contract TokenBlacklist with size 2821 => 2137
modulo2 on contract AvmTest with size 16 => 16
nested_call_to_add on contract AvmNestedCallsTest with size 862 => 756
nested_call_to_add_with_gas on contract AvmNestedCallsTest with size 929 => 799
nested_static_call_to_add on contract AvmNestedCallsTest with size 890 => 784
nested_static_call_to_set_storage on contract AvmNestedCallsTest with size 759 => 665
new_note_hash on contract AvmTest with size 47 => 11
new_nullifier on contract AvmAcvmInteropTest with size 47 => 11
new_nullifier on contract AvmNestedCallsTest with size 47 => 11
new_nullifier on contract AvmTest with size 47 => 11
new_nullifier_acvm on contract AvmAcvmInteropTest with size 47 => 11
note_hash_exists on contract AvmTest with size 65 => 17
nullifier_collision on contract AvmTest with size 82 => 12
nullifier_exists on contract AvmTest with size 103 => 17
on_card_played on contract CardGame with size 2386 => 2151
on_cards_claimed on contract CardGame with size 2176 => 1927
on_game_joined on contract CardGame with size 1972 => 1733
pay_refund on contract FPC with size 2052 => 1685
pay_refund_with_shielded_rebate on contract FPC with size 2138 => 1771
pedersen_hash on contract AvmTest with size 19 => 19
pedersen_hash_with_index on contract AvmTest with size 19 => 19
poseidon2_hash on contract AvmTest with size 1370 => 1370
prepare_fee on contract FPC with size 1643 => 1280
pub_call_public_fn on contract ImportTest with size 710 => 636
pub_entry_point on contract Parent with size 263 => 189
pub_entry_point_twice on contract Parent with size 497 => 339
pub_get_value on contract Child with size 174 => 22
pub_get_value on contract StaticChild with size 409 => 281
pub_illegal_inc_value on contract StaticChild with size 448 => 336
pub_inc_value on contract Child with size 175 => 45
pub_inc_value on contract StaticChild with size 175 => 45
pub_inc_value_internal on contract Child with size 552 => 340
pub_set_value on contract Child with size 108 => 30
pub_set_value on contract StaticChild with size 108 => 30
public_call on contract StaticParent with size 263 => 189
public_constructor on contract StatefulTest with size 1808 => 1399
public_delegate_set_value on contract Delegator with size 724 => 724
public_get_decimals on contract Token with size 557 => 411
public_get_name on contract Token with size 538 => 392
public_get_symbol on contract Token with size 546 => 400
public_get_value_from_child on contract StaticParent with size 759 => 685
public_nested_static_call on contract Parent with size 674 => 561
public_nested_static_call on contract StaticParent with size 1012 => 894
public_set_value on contract DelegatedOn with size 68 => 28
public_static_call on contract Parent with size 328 => 236
public_static_call on contract StaticParent with size 328 => 236
push_nullifier_public on contract InclusionProofs with size 285 => 117
read_storage_immutable on contract AvmInitializerTest with size 286 => 133
read_storage_list on contract AvmTest with size 101 => 62
read_storage_map on contract AvmTest with size 385 => 341
read_storage_single on contract AvmTest with size 66 => 27
register on contract KeyRegistry with size 6385 => 5041
repay_public on contract Lending with size 2141 => 1747
rotate_npk_m on contract KeyRegistry with size 2592 => 1843
send_l2_to_l1_msg on contract AvmTest with size 56 => 12
set_admin on contract Token with size 528 => 257
set_authorized on contract Auth with size 925 => 474
set_authorized_delay on contract Auth with size 679 => 400
set_minter on contract Token with size 865 => 559
set_opcode_big_field on contract AvmTest with size 19 => 19
set_opcode_small_field on contract AvmTest with size 13 => 13
set_opcode_u32 on contract AvmTest with size 13 => 13
set_opcode_u64 on contract AvmTest with size 13 => 13
set_opcode_u8 on contract AvmTest with size 13 => 13
set_portal on contract GasToken with size 434 => 272
set_price on contract PriceFeed with size 401 => 349
set_read_storage_single on contract AvmTest with size 122 => 42
set_storage_list on contract AvmTest with size 76 => 30
set_storage_map on contract AvmTest with size 409 => 355
set_storage_single on contract AvmNestedCallsTest with size 65 => 25
set_storage_single on contract AvmTest with size 65 => 25
set_value_twice_with_nested_first on contract Child with size 803 => 654
set_value_twice_with_nested_last on contract Child with size 791 => 654
set_value_with_two_nested_calls on contract Child with size 1308 => 1063
sha256_hash on contract AvmTest with size 47 => 47
shield on contract Token with size 2368 => 1809
shield on contract TokenBlacklist with size 3102 => 2315
spend_public_authwit on contract DocsExample with size 14 => 14
spend_public_authwit on contract EcdsaAccount with size 1008 => 637
spend_public_authwit on contract SchnorrAccount with size 770 => 541
spend_public_authwit on contract SchnorrHardcodedAccount with size 770 => 540
spend_public_authwit on contract SchnorrSingleKeyAccount with size 770 => 540
spend_public_authwit on contract Uniswap with size 749 => 486
start_game on contract CardGame with size 2518 => 2175
swap_public on contract Uniswap with size 7983 => 6584
test_authwit_send_money on contract AvmAcvmInteropTest with size 803 => 709
test_get_contract_instance on contract AvmTest with size 522 => 410
test_get_contract_instance_raw on contract AvmTest with size 159 => 83
test_nullifier_inclusion_from_public on contract InclusionProofs with size 332 => 121
to_radix_le on contract AvmTest with size 187 => 187
total_supply on contract Token with size 536 => 390
total_supply on contract TokenBlacklist with size 536 => 390
transfer_public on contract Token with size 3071 => 2512
transfer_public on contract TokenBlacklist with size 4491 => 3533
u128_addition_overflow on contract AvmTest with size 772 => 668
u128_from_integer_overflow on contract AvmTest with size 357 => 357
update_accumulator on contract Lending with size 8695 => 8358
update_leader on contract DocsExample with size 430 => 290
update_roles on contract TokenBlacklist with size 2058 => 1252
withdraw_public on contract Lending with size 1190 => 93
```

</details>


## Summary\*

This PR:
- Creates a separate pass for "runtime separation" where we convert any
Acir function called from brillig to a brillig function. After that
pass, all functions have correct runtime, meaning they'll be converted
to the runtime they hold.
- Updates the inliner to only consider entry points all brillig
functions called from ACIR and all brillig recursive functions, instead
of all brillig functions
 
With this change the inliner can correctly detect which brillig
functions **must not** be inlined. This opens the door to allowing
annotating brillig functions with inlining suggestions in the future.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

1 participant