Skip to content

Conversation

@vaivaswatha
Copy link
Contributor

@vaivaswatha vaivaswatha commented Oct 6, 2025

Description

For the Sway code in #7344, the IR after #7381 and after this PR is shown here:

After #7381, before this PR
   fn wrapper_1(__ret_value: __ptr { b256 }) -> (), !17 {
        local { u64, ( () | { b256 } ) } __matched_value_4
        local { u64, ( () | { b256 } ) } __ret_val
        local { u64, ( () | { b256 } ) } self_

        entry(__ret_value: __ptr { b256 }):
        v0 = get_local __ptr { u64, ( () | { b256 } ) }, __ret_val
        v1 = call return_option_5(v0)
        v2 = get_local __ptr { u64, ( () | { b256 } ) }, self_, !20
        mem_copy_val v2, v0
        v3 = get_local __ptr { u64, ( () | { b256 } ) }, self_, !23
        v4 = get_local __ptr { u64, ( () | { b256 } ) }, __matched_value_4, !25
        mem_copy_val v4, v3
        v5 = get_local __ptr { u64, ( () | { b256 } ) }, self_
        v6 = const u64 0
        v7 = get_elem_ptr v5, __ptr u64, v6
        v8 = load v7, !20
        v9 = const u64 1, !22
        v10 = cmp eq v8 v9, !28
        cbr v10, unwrap_2_block0(), unwrap_2_block1(), !29

        unwrap_2_block0():
        v11 = get_local __ptr { u64, ( () | { b256 } ) }, __matched_value_4, !30
        v12 = const u64 1
        v13 = const u64 1
        v14 = get_elem_ptr v11, __ptr { b256 }, v12, v13, !20
        mem_copy_val __ret_value, v14
        v15 = const unit ()
        ret () v15

        unwrap_2_block1():
        v16 = const u64 0, !31
        revert v16, !36
    }

    fn return_option_5(__ret_value: __ptr { u64, ( () | { b256 } ) }) -> (), !39 {
        local { u64, ( () | { b256 } ) } __anon_0

        entry(__ret_value: __ptr { u64, ( () | { b256 } ) }):
        v0 = get_local __ptr { u64, ( () | { b256 } ) }, __anon_0, !40
        v1 = const u64 0
        v2 = get_elem_ptr v0, __ptr u64, v1, !40
        v3 = const u64 0, !40
        store v3 to v2, !40
        mem_copy_val __ret_value, v0
        v4 = const unit ()
        ret () v4
    }
After this PR
       fn wrapper_1(__ret_value: __ptr { b256 }) -> (), !17 {
        local { u64, ( () | { b256 } ) } __matched_value_4

        entry(__ret_value: __ptr { b256 }):
        v0 = get_local __ptr { u64, ( () | { b256 } ) }, __matched_value_4
        v1 = call return_option_5(v0)
        v2 = get_local __ptr { u64, ( () | { b256 } ) }, __matched_value_4
        v3 = const u64 0
        v4 = get_elem_ptr v2, __ptr u64, v3
        v5 = load v4, !20
        v6 = const u64 1, !22
        v7 = cmp eq v5 v6, !25
        cbr v7, unwrap_2_block0(), unwrap_2_block1(), !26

        unwrap_2_block0():
        v8 = get_local __ptr { u64, ( () | { b256 } ) }, __matched_value_4, !27
        v9 = const u64 1
        v10 = const u64 1
        v11 = get_elem_ptr v8, __ptr { b256 }, v9, v10, !20
        mem_copy_val __ret_value, v11
        v12 = const unit ()
        ret () v12

        unwrap_2_block1():
        v13 = const u64 0, !28
        revert v13, !33
    }

    fn return_option_5(__ret_value: __ptr { u64, ( () | { b256 } ) }) -> (), !36 {
        entry(__ret_value: __ptr { u64, ( () | { b256 } ) }):
        v0 = const u64 0
        v1 = get_elem_ptr __ret_value, __ptr u64, v0, !37
        v2 = const u64 0, !37
        store v2 to v1, !37
        v3 = const unit ()
        ret () v3
    }

wrapper_1, which had 3 memcpys now has 1, and return_option_5 which had one, now has none.

Closes #7344.


Note

Introduces a reverse memcpy copy-propagation pass, hooks it into the Opt1 Fuel pipeline, and adds small IR utilities; updates snapshots and IDs accordingly.

  • IR Optimizations:
    • New Pass: memcpyprop_reverse (copy-propagation replacing memcpy sources with destinations) in sway-ir/src/optimize/memcpyopt.rs with supporting logic (is_clobbered, deconstruct_memcpy).
    • Registration: Registered in pass_manager.rs and added to Fuel Opt1 pipeline (sway-core/src/lib.rs) before SROA/MEM2REG.
  • IR Utilities/Analysis:
    • DomTree::dominates_instr(...) added to analysis/dominator.rs.
    • BlockArgument::as_value(...) in block.rs.
    • Function::remove_instructions(...) in function.rs.
    • Refactors deconstruct_memcpy to return Option and adjusts callers.
  • Pass Manager:
    • Registers create_memcpyprop_reverse_pass() alongside existing passes.
  • Tests/Snapshots:
    • Update golden outputs (IR/ASM sizes, configurables offsets, gas counts).
    • Refresh contract IDs/predicate addresses in several e2e tests.

Written by Cursor Bugbot for commit 816fd00. This will update automatically on new commits. Configure here.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 6, 2025

CodSpeed Performance Report

Merging #7443 will improve performances by 23.58%

Comparing vaivaswatha/memcpy_prop_new (816fd00) with master (be2d6ae)

Summary

⚡ 1 improvement
✅ 24 untouched

Benchmarks breakdown

Benchmark BASE HEAD Change
format 474.5 ms 383.9 ms +23.58%

@vaivaswatha
Copy link
Contributor Author

vaivaswatha commented Oct 8, 2025

Impact on `should_pass` tests
testing should_pass/language/ before after
Testing should_pass/language/abi_cast_nested_method 2.304 KB 2.304 KB
Testing should_pass/language/abort_control_flow_good 328 B 328 B
Testing should_pass/language/addrof_intrinsic 3.144 KB 3.112 KB
Testing should_pass/language/aliased_imports 344 B 344 B
Testing should_pass/language/arg_demotion_inline 1.064 KB 1.064 KB
Testing should_pass/language/args_on_stack 18.248 KB 18.2 KB
Testing should_pass/language/array/array_basics 648 B 648 B
Testing should_pass/language/array/array_generics 344 B 344 B
Testing should_pass/language/asm/instructions/bldd 32 B 32 B
Testing should_pass/language/asm/instructions/ecall 32 B 32 B
Testing should_pass/language/asm/instructions/ldc 88 B 88 B
Testing should_pass/language/asm/instructions/wqxx 2.184 KB 2.184 KB
Testing should_pass/language/asm_empty_block 32 B 32 B
Testing should_pass/language/asm_expr_basic 456 B 456 B
Testing should_pass/language/asm_uninitialized_register_shadows_item 368 B 360 B
Testing should_pass/language/asm_without_return 32 B 32 B
Testing should_pass/language/associated_const_abi 4.8 KB 4.8 KB
Testing should_pass/language/associated_const_abi_multiple 3.2 KB 3.2 KB
Testing should_pass/language/associated_const_impl 344 B 344 B
Testing should_pass/language/associated_const_impl_local_same_name 344 B 344 B
Testing should_pass/language/associated_const_impl_multiple 104 B 104 B
Testing should_pass/language/associated_const_impl_self 472 B 472 B
Testing should_pass/language/associated_const_in_decls_of_other_constants 2.368 KB 2.36 KB
Testing should_pass/language/associated_const_trait 40 B 40 B
Testing should_pass/language/associated_const_trait_default 104 B 104 B
Testing should_pass/language/associated_const_trait_impl_method 344 B 344 B
Testing should_pass/language/associated_const_trait_method 344 B 344 B
Testing should_pass/language/associated_const_visibility 32 B 32 B
Testing should_pass/language/associated_type_and_associated_const 344 B 344 B
Testing should_pass/language/associated_type_ascription 344 B 344 B
Testing should_pass/language/associated_type_container 1.488 KB 1.48 KB
Testing should_pass/language/associated_type_container_in_library 1.488 KB 1.48 KB
Testing should_pass/language/associated_type_fully_qualified 504 B 504 B
Testing should_pass/language/associated_type_iterator 1.536 KB 1.52 KB
Testing should_pass/language/associated_type_method 344 B 344 B
Testing should_pass/language/associated_type_parameter 344 B 344 B
Testing should_pass/language/attributes_abi_name 1.416 KB 1.416 KB
Testing should_pass/language/attributes_all_in_one 896 B 888 B
Testing should_pass/language/attributes_test_attribute 32 B 32 B
Testing should_pass/language/b256_bad_jumps 328 B 328 B
Testing should_pass/language/b256_bitwise_ops 6.528 KB 6.216 KB
Testing should_pass/language/b256_ops 2.456 KB 2.432 KB
Testing should_pass/language/basic_func_decl 320 B 320 B
Testing should_pass/language/basic_predicate 64 B 64 B
Testing should_pass/language/binary_and_hex_literals 320 B 320 B
Testing should_pass/language/binop_intrinsics 336 B 336 B
Testing should_pass/language/bitwise_not 320 B 320 B
Testing should_pass/language/blanket_trait 320 B 320 B
Testing should_pass/language/bool_and_or 336 B 336 B
Testing should_pass/language/break_and_continue 808 B 808 B
Testing should_pass/language/break_and_continue_block_ret 32 B 32 B
Testing should_pass/language/builtin_type_method_call 336 B 336 B
Testing should_pass/language/callpath_local_shadowing 96 B 96 B
Testing should_pass/language/chained_if_let 464 B 432 B
Testing should_pass/language/complex_ir_cfg 824 B 824 B
Testing should_pass/language/configurable_consts 5.112 KB 5.016 KB
Testing should_pass/language/configurable_tests 8.192 KB 8.096 KB
Testing should_pass/language/const_decl_and_use_in_library 336 B 336 B
Testing should_pass/language/const_decl_in_library 360 B 360 B
Testing should_pass/language/const_generics 896 B 872 B
Testing should_pass/language/const_indexing_aggregates_asmgen 568 B 568 B
Testing should_pass/language/const_inits 2.104 KB 2.104 KB
Testing should_pass/language/contract_caller_as_ret 888 B 888 B
Testing should_pass/language/contract_caller_dynamic_address 1.728 KB 1.728 KB
Testing should_pass/language/contract_calls_unwrapped_contract_id 1.792 KB 1.792 KB
Testing should_pass/language/contract_ret_intrinsic 3.168 KB 3.168 KB
Testing should_pass/language/dereferenced_projection_reassignment 1.616 KB 1.616 KB
Testing should_pass/language/diverging_exprs 824 B 824 B
Testing should_pass/language/doc_comments 928 B 928 B
Testing should_pass/language/dummy_method_issue 280 B 280 B
Testing should_pass/language/duplicated_storage_keys 240 B 240 B
Testing should_pass/language/empty_method_initializer 744 B 728 B
Testing should_pass/language/enum_destructuring 400 B 392 B
Testing should_pass/language/enum_if_let 728 B 680 B
Testing should_pass/language/enum_if_let_large_type 648 B 624 B
Testing should_pass/language/enum_in_fn_decl 416 B 392 B
Testing should_pass/language/enum_init_fn_call 584 B 552 B
Testing should_pass/language/enum_instantiation 3.376 KB 3.048 KB
Testing should_pass/language/enum_padding 1.624 KB 1.616 KB
Testing should_pass/language/enum_type_inference 336 B 336 B
Testing should_pass/language/enum_variant_imports 456 B 448 B
Testing should_pass/language/eq_and_neq 1.408 KB 1.392 KB
Testing should_pass/language/eq_intrinsic 336 B 336 B
Testing should_pass/language/fallback_only 1.904 KB 1.904 KB
Testing should_pass/language/far_jumps/many_blobs 7.44048 MB 7.44048 MB
Testing should_pass/language/far_jumps/single_blob 336 B 336 B
Testing should_pass/language/for_loops 3.056 KB 3.048 KB
Testing should_pass/language/fqp_in_lib 96 B 96 B
Testing should_pass/language/funcs_with_generic_types 320 B 320 B
Testing should_pass/language/function_return_type_unification 352 B 352 B
Testing should_pass/language/generic_functions 320 B 320 B
Testing should_pass/language/generic_impl_self 3.168 KB 2.784 KB
Testing should_pass/language/generic_impl_self_where 1.712 KB 1.696 KB
Testing should_pass/language/generic_inside_generic 432 B 416 B
Testing should_pass/language/generic_result_method 616 B 616 B
Testing should_pass/language/generic_struct 320 B 320 B
Testing should_pass/language/generic_struct_instantiation 328 B 328 B
Testing should_pass/language/generic_structs 320 B 320 B
Testing should_pass/language/generic_trait_constraints 800 B 800 B
Testing should_pass/language/generic_traits 1.232 KB 1.232 KB
Testing should_pass/language/generic_transpose 856 B 824 B
Testing should_pass/language/generic_tuple_trait 504 B 504 B
Testing should_pass/language/generic_type_inference 2.472 KB 2.464 KB
Testing should_pass/language/generic_where_in_impl_self 456 B 456 B
Testing should_pass/language/generic_where_in_impl_self2 456 B 456 B
Testing should_pass/language/generics_in_contract 2.336 KB 2.336 KB
Testing should_pass/language/gtf_intrinsic 752 B 752 B
Testing should_pass/language/if_elseif_enum 680 B 688 B
Testing should_pass/language/if_implicit_unit 96 B 96 B
Testing should_pass/language/if_let_no_side_effects 440 B 440 B
Testing should_pass/language/impl_self_method 352 B 352 B
Testing should_pass/language/impl_self_method_order 352 B 352 B
Testing should_pass/language/implicit_casting 336 B 336 B
Testing should_pass/language/implicit_return 336 B 336 B
Testing should_pass/language/import_from_private_ancestor 32 B 32 B
Testing should_pass/language/import_method_from_other_file 416 B 416 B
Testing should_pass/language/import_star_name_clash 1.712 KB 1.664 KB
Testing should_pass/language/import_trailing_comma 344 B 344 B
Testing should_pass/language/import_with_different_callpaths 1.496 KB 1.392 KB
Testing should_pass/language/impure_ifs 944 B 944 B
Testing should_pass/language/inline_if_expr_const 96 B 96 B
Testing should_pass/language/insert_element_reg_reuse 1.936 KB 1.808 KB
Testing should_pass/language/integer_type_inference 936 B 872 B
Testing should_pass/language/intrinsics/dbg 2.48 KB 2.472 KB
Testing should_pass/language/intrinsics/dbg_release 5.64 KB 5.712 KB
Testing should_pass/language/intrinsics/transmute 1.608 KB 1.584 KB
Testing should_pass/language/is_prime 904 B 904 B
Testing should_pass/language/is_reference_type 320 B 320 B
Testing should_pass/language/largeint_sroa 536 B 504 B
Testing should_pass/language/left_to_right_func_args_evaluation 368 B 368 B
Testing should_pass/language/local_impl_for_ord 320 B 320 B
Testing should_pass/language/logging 2.928 KB 2.912 KB
Testing should_pass/language/main_args/main_args_empty 336 B 336 B
Testing should_pass/language/main_args/main_args_empty 48 B 48 B
Testing should_pass/language/main_args/main_args_generics 1.304 KB 1.304 KB
Testing should_pass/language/main_args/main_args_one_u64 408 B 408 B
Testing should_pass/language/main_args/main_args_ref 424 B 424 B
Testing should_pass/language/main_args/main_args_ref_copy 464 B 464 B
Testing should_pass/language/main_args/main_args_ref_ref 536 B 528 B
Testing should_pass/language/main_args/main_args_two_u64 440 B 440 B
Testing should_pass/language/main_args/main_args_various_types 2.272 KB 2.192 KB
Testing should_pass/language/main_returns_unit 96 B 96 B
Testing should_pass/language/many_stack_variables 376 B 376 B
Testing should_pass/language/marker_traits/marker_trait_enum_implemented_for_all_enums 32 B 32 B
Testing should_pass/language/marker_traits/marker_trait_error_implemented_for_error_types 32 B 32 B
Testing should_pass/language/match_expressions_all 1.6 KB 1.584 KB
Testing should_pass/language/match_expressions_constants 3.016 KB 3.016 KB
Testing should_pass/language/match_expressions_empty_enums 336 B 336 B
Testing should_pass/language/match_expressions_enums 2.696 KB 2.696 KB
Testing should_pass/language/match_expressions_explicit_rets 320 B 320 B
Testing should_pass/language/match_expressions_inside_generic_functions 488 B 488 B
Testing should_pass/language/match_expressions_mismatched 392 B 384 B
Testing should_pass/language/match_expressions_nested 1.608 KB 1.584 KB
Testing should_pass/language/match_expressions_rest 1.504 KB 1.496 KB
Testing should_pass/language/match_expressions_simple 400 B 400 B
Testing should_pass/language/match_expressions_structs 392 B 392 B
Testing should_pass/language/match_expressions_unreachable_catch_all_last_arm 1.08 KB 968 B
Testing should_pass/language/match_expressions_unreachable_catch_all_middle_arm 896 B 800 B
Testing should_pass/language/match_expressions_unreachable_last_arm 2.248 KB 2.16 KB
Testing should_pass/language/match_expressions_unreachable_middle_arm 2.592 KB 2.512 KB
Testing should_pass/language/match_expressions_with_self 480 B 480 B
Testing should_pass/language/mega_example 8.384 KB 8.352 KB
Testing should_pass/language/memcpy 672 B 672 B
Testing should_pass/language/method_indirect_inference 640 B 640 B
Testing should_pass/language/method_nested_type_args 96 B 96 B
Testing should_pass/language/method_on_empty_struct 328 B 328 B
Testing should_pass/language/method_on_primitives 240 B 240 B
Testing should_pass/language/method_unambiguous 584 B 584 B
Testing should_pass/language/module_dep 32 B 32 B
Testing should_pass/language/module_dep_multiple 32 B 32 B
Testing should_pass/language/module_dep_self 32 B 32 B
Testing should_pass/language/modulo_uint_test 320 B 320 B
Testing should_pass/language/multi_impl_self 336 B 336 B
Testing should_pass/language/multi_item_import 320 B 320 B
Testing should_pass/language/mutable_and_initd 448 B 448 B
Testing should_pass/language/mutable_arrays 336 B 336 B
Testing should_pass/language/mutable_arrays_enum 400 B 392 B
Testing should_pass/language/mutable_arrays_multiple_nested 328 B 328 B
Testing should_pass/language/mutable_arrays_nested 328 B 328 B
Testing should_pass/language/mutable_arrays_struct 336 B 336 B
Testing should_pass/language/mutable_arrays_swap 336 B 336 B
Testing should_pass/language/name_resolution_after_monomorphization 368 B 368 B
Testing should_pass/language/nested_generics 320 B 320 B
Testing should_pass/language/nested_struct_destructuring 328 B 328 B
Testing should_pass/language/nested_structs 1.112 KB 1.112 KB
Testing should_pass/language/nested_while_and_if 432 B 432 B
Testing should_pass/language/new_allocator_test 408 B 408 B
Testing should_pass/language/non_literal_const_decl 336 B 336 B
Testing should_pass/language/numeric_constants 424 B 424 B
Testing should_pass/language/numeric_type_propagation 424 B 424 B
Testing should_pass/language/op_precedence 320 B 320 B
Testing should_pass/language/ops 416 B 416 B
Testing should_pass/language/out_of_order_decl 320 B 320 B
Testing should_pass/language/overlapped_trait_impls 672 B 640 B
Testing should_pass/language/panic_expression/panic_keyword_behind_feature_flag_on 32 B 32 B
Testing should_pass/language/panic_expression/panic_string_slices 176 B 176 B
Testing should_pass/language/panic_expression/panicking_predicate 72 B 72 B
Testing should_pass/language/predicate_while 112 B 112 B
Testing should_pass/language/predicate_while_dep 112 B 112 B
Testing should_pass/language/prelude_access 96 B 96 B
Testing should_pass/language/prelude_access2 96 B 96 B
Testing should_pass/language/primitive_type_argument 336 B 336 B
Testing should_pass/language/pusha_popa_multiple_defreg 2.032 KB 2.032 KB
Testing should_pass/language/raw_identifiers 3.504 KB 3.504 KB
Testing should_pass/language/raw_identifiers 3.504 KB 3.504 KB
Testing should_pass/language/raw_ptr/vec_ret 896 B 888 B
Testing should_pass/language/reassignment_operators 328 B 328 B
Testing should_pass/language/reassignment_rhs_lhs_evaluation_order 840 B 840 B
Testing should_pass/language/redundant_return 328 B 328 B
Testing should_pass/language/reexport/aliases 1.104 KB 1.056 KB
Testing should_pass/language/reexport/multiple_imports_of_same_reexport 1.528 KB 1.432 KB
Testing should_pass/language/reexport/reexport_paths 992 B 832 B
Testing should_pass/language/reexport/reexport_paths_external_lib 2.184 KB 2.064 KB
Testing should_pass/language/reexport/shadowing_in_reexporting_module 1.536 KB 1.456 KB
Testing should_pass/language/reexport/simple_glob_import 904 B 864 B
Testing should_pass/language/reexport/simple_item_import 904 B 864 B
Testing should_pass/language/reexport/visibility 904 B 864 B
Testing should_pass/language/ref_mutable_arrays 336 B 336 B
Testing should_pass/language/ref_mutable_arrays_inline 336 B 336 B
Testing should_pass/language/ref_mutable_fn_args_bool 320 B 320 B
Testing should_pass/language/ref_mutable_fn_args_call 336 B 336 B
Testing should_pass/language/ref_mutable_fn_args_struct 336 B 336 B
Testing should_pass/language/ref_mutable_fn_args_struct_assign 336 B 336 B
Testing should_pass/language/ref_mutable_fn_args_u32 352 B 352 B
Testing should_pass/language/references/dereferencing_control_flow_expressions 744 B 744 B
Testing should_pass/language/references/impl_reference_types 13.568 KB 13.568 KB
Testing should_pass/language/references/mutability_of_references 896 B 896 B
Testing should_pass/language/references/mutability_of_references_memcpy_bug 2.952 KB 2.952 KB
Testing should_pass/language/references/reassigning_via_references_in_aggregates 4.544 KB 4.464 KB
Testing should_pass/language/references/references_and_type_aliases 648 B 648 B
Testing should_pass/language/references/references_in_aggregates 3.784 KB 3.744 KB
Testing should_pass/language/references/references_in_asm_blocks 1.872 KB 1.872 KB
Testing should_pass/language/references/referencing_control_flow_expressions 504 B 504 B
Testing should_pass/language/references/referencing_function_parameters 3.648 KB 3.632 KB
Testing should_pass/language/references/referencing_function_parameters_simple 1.576 KB 1.504 KB
Testing should_pass/language/references/referencing_global_constants 1.216 KB 1.216 KB
Testing should_pass/language/references/referencing_parts_of_aggregates 4.208 KB 4.208 KB
Testing should_pass/language/references/referencing_references 1.024 KB 1.024 KB
Testing should_pass/language/references/type_unification_of_references 3.056 KB 2.848 KB
Testing should_pass/language/ret_small_string 416 B 416 B
Testing should_pass/language/ret_string_in_struct 472 B 456 B
Testing should_pass/language/retd_b256 456 B 456 B
Testing should_pass/language/retd_small_array 480 B 480 B
Testing should_pass/language/retd_struct 904 B 896 B
Testing should_pass/language/retd_zero_len_array 208 B 208 B
Testing should_pass/language/revert_in_first_if_branch 104 B 104 B
Testing should_pass/language/same_const_name 96 B 96 B
Testing should_pass/language/same_const_name_lib 32 B 32 B
Testing should_pass/language/self_impl_reassignment 888 B 856 B
Testing should_pass/language/shadowing/bug_fix_associated_const_shadowing_itself 40 B 40 B
Testing should_pass/language/shadowing/shadowed_glob_imports 472 B 464 B
Testing should_pass/language/shadowing/shadowed_prelude_imports 352 B 352 B
Testing should_pass/language/size_of 328 B 328 B
Testing should_pass/language/slice/slice_contract 2.696 KB 2.696 KB
Testing should_pass/language/slice/slice_intrinsics 7.152 KB 7.152 KB
Testing should_pass/language/slice/slice_script 568 B 568 B
Testing should_pass/language/smo 1.88 KB 1.88 KB
Testing should_pass/language/smo_opcode 376 B 376 B
Testing should_pass/language/string_slice/string_slice_contract 2.664 KB 2.664 KB
Testing should_pass/language/string_slice/string_slice_features 408 B 408 B
Testing should_pass/language/string_slice/string_slice_script 640 B 640 B
Testing should_pass/language/struct_destructuring 336 B 336 B
Testing should_pass/language/struct_field_access 336 B 336 B
Testing should_pass/language/struct_field_reassignment 328 B 328 B
Testing should_pass/language/struct_init_reorder 176 B 176 B
Testing should_pass/language/struct_instantiation 1.92 KB 1.904 KB
Testing should_pass/language/submodule_visibility 32 B 32 B
Testing should_pass/language/supertraits 4.008 KB 4.008 KB
Testing should_pass/language/supertraits_with_trait_methods 384 B 384 B
Testing should_pass/language/totalord 2.328 KB 2.28 KB
Testing should_pass/language/trait_constraint_param_order 320 B 320 B
Testing should_pass/language/trait_generic_override 320 B 320 B
Testing should_pass/language/trait_import_with_star 96 B 96 B
Testing should_pass/language/trait_inference 752 B 752 B
Testing should_pass/language/trait_method_ascription_disambiguate 320 B 320 B
Testing should_pass/language/trait_method_generic_qualified 320 B 320 B
Testing should_pass/language/trait_method_qualified 320 B 320 B
Testing should_pass/language/trait_nested 824 B 824 B
Testing should_pass/language/tuple_access 448 B 448 B
Testing should_pass/language/tuple_desugaring 384 B 384 B
Testing should_pass/language/tuple_field_reassignment 440 B 440 B
Testing should_pass/language/tuple_in_struct 664 B 664 B
Testing should_pass/language/tuple_indexing 344 B 344 B
Testing should_pass/language/tuple_single_element 384 B 384 B
Testing should_pass/language/tuple_trait 392 B 392 B
Testing should_pass/language/tuple_types 352 B 352 B
Testing should_pass/language/type_alias 2.48 KB 2.312 KB
Testing should_pass/language/type_alias_from_dependency 32 B 32 B
Testing should_pass/language/type_inference_propagation_of_type_constraints 736 B 736 B
Testing should_pass/language/typeinfo_custom_callpath 160 B 160 B
Testing should_pass/language/typeinfo_custom_callpath2 160 B 160 B
Testing should_pass/language/typeinfo_custom_callpath_with_import 168 B 168 B
Testing should_pass/language/u256/u256_abi 728 B 728 B
Testing should_pass/language/u256/u256_operators 3.912 KB 3.816 KB
Testing should_pass/language/unary_not_basic 320 B 320 B
Testing should_pass/language/unary_not_basic_2 320 B 320 B
Testing should_pass/language/unify_never 336 B 336 B
Testing should_pass/language/unit_ret_use 152 B 152 B
Testing should_pass/language/unit_type_variants 656 B 656 B
Testing should_pass/language/use_absolute_path 328 B 328 B
Testing should_pass/language/use_full_path_names 344 B 344 B
Testing should_pass/language/valid_impurity 888 B 888 B
Testing should_pass/language/where_clause_enums 768 B 736 B
Testing should_pass/language/where_clause_functions 1.848 KB 1.808 KB
Testing should_pass/language/where_clause_generic_traits 96 B 96 B
Testing should_pass/language/where_clause_generic_tuple 336 B 336 B
Testing should_pass/language/where_clause_impls 424 B 424 B
Testing should_pass/language/where_clause_methods 1.832 KB 1.832 KB
Testing should_pass/language/where_clause_structs 616 B 616 B
Testing should_pass/language/where_clause_traits 320 B 320 B
Testing should_pass/language/while_loops 592 B 592 B
Testing should_pass/language/zero_field_types 336 B 336 B
Testing should_pass/language/zk_opcodes 456 B 432 B

On the blackjack Sway contract, the code size goes down from 21.144 KB to 21.048 KB

@vaivaswatha vaivaswatha marked this pull request as ready for review October 8, 2025 15:33
@vaivaswatha vaivaswatha requested a review from a team as a code owner October 8, 2025 15:33
cursor[bot]

This comment was marked as outdated.

xunilrj
xunilrj previously approved these changes Oct 13, 2025
@vaivaswatha vaivaswatha requested a review from a team October 21, 2025 16:42
@vaivaswatha vaivaswatha enabled auto-merge (squash) October 22, 2025 00:00
xunilrj
xunilrj previously approved these changes Oct 23, 2025
@vaivaswatha vaivaswatha requested a review from a team October 23, 2025 14:51
@cursor
Copy link

cursor bot commented Oct 23, 2025

Bug: Transitive Closure Algorithm Inefficiency

The transitive closure algorithm unconditionally sets changed = true whenever insert() is called, even if the key-value pair already exists in the map. This causes unnecessary iterations since HashMap::insert() returns the old value when the key already exists, but the algorithm doesn't check if the insertion actually changed anything. While this doesn't affect correctness (the algorithm will still terminate and produce the correct result), it leads to inefficient execution with more iterations than needed.

Fix in Cursor Fix in Web

cursor[bot]

This comment was marked as outdated.

@ironcev ironcev added compiler General compiler. Should eventually become more specific as the issue is triaged compiler: ir IRgen and sway-ir including optimization passes labels Nov 7, 2025
self.0[&node].children.get(i).cloned()
}

/// Does `dominator` `dominate` `dominatee`?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Does `dominator` `dominate` `dominatee`?
/// Does `dominator` dominate `dominatee`?

None
}

/// Get that Value that this argument represents.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Get that Value that this argument represents.
/// Get the [Value] that this argument represents.

Comment on lines +829 to +831
/// Starting backwards from end_inst, till we reach start_inst or the entry block,
/// is scrutiny_ptr (or an alias of it) stored to (i.e., clobbered)?/
/// Also checks that there is no overlap (common symbols) b/w no_overlap_ptr and scrutiny_ptr.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Starting backwards from end_inst, till we reach start_inst or the entry block,
/// is scrutiny_ptr (or an alias of it) stored to (i.e., clobbered)?/
/// Also checks that there is no overlap (common symbols) b/w no_overlap_ptr and scrutiny_ptr.
/// Starting backwards from `end_inst`, till we reach `start_inst` or the entry block,
/// is `scrutiny_ptr` (or an alias of it) stored to (i.e., clobbered)?
/// Also checks that there is no overlap (common symbols) between `no_overlap_ptr` and `scrutiny_ptr`.

) -> bool {
let store_block = store_val.get_instruction(context).unwrap().parent;
let end_block = end_inst.get_instruction(context).unwrap().parent;
let function = end_block.get_function(context);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function is used only to get_entry_block, which is additionally called in a loop. We can instead of the function have entry_block defined here and use it in the loop.

Suggested change
let function = end_block.get_function(context);
let entry_block = end_block.get_function(context).get_entry_block(context);

pub fn create_memcpyprop_reverse_pass() -> Pass {
Pass {
name: MEMCPYPROP_REVERSE_NAME,
descr: "Memcpyprop Reverse: Copy propagation of memcpy instructions",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it consistent with other descriptions.

Suggested change
descr: "Memcpyprop Reverse: Copy propagation of memcpy instructions",
descr: "Copy propagation of MemCopy instructions",

Ok(true)
}

pub const MEMCPYPROP_REVERSE_NAME: &str = "memcpyprop_reverse";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add this constant to PassManager::OPTIMIZATION_PASSES, otherwise it will not be available in the CLI.

Copy link
Member

@ironcev ironcev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the high importance of this pass, we should have dedicated ir_generation test(s) for it. And also add the pass to the pass_group in ir_generation. For tests, we can perhaps take the two examples from the original issue and ensure there are no additional memcpys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler: ir IRgen and sway-ir including optimization passes compiler General compiler. Should eventually become more specific as the issue is triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Eliminate mem_copy_vals when returning aggregates

4 participants