Skip to content

Conversation

xunilrj
Copy link
Contributor

@xunilrj xunilrj commented Aug 22, 2025

Description

Continuation of #6860.

This PR implements multiple small features focusing on improving AbiDecode for arrays.

1 - Before this PR, the implementation of AbiDecode for arrays was decoding the first element and creating a "repeat array" with it. Depending on the array length, the initialisation would be five stores or a loop copying the first item over all slots.

Now we create a "repeat array" of zeros of the required size. This will be initialised with just one MCLI/MCL. And then we transmute this into the desired array type.

The final ASM is still far from ideal. But will improve with future optimizations.

pshl i15                      ; save registers 16..40
pshh i524288                  ; save registers 40..64
move $$locbase $sp            ; save locals base register for function transmute_by_reference_7
cfei i144                     ; allocate 144 bytes for locals and 0 slots for call arguments
move $r0 $$arg0               ; save argument 0 (__ret_value)
move $r1 $$reta               ; save return address
mcli $$locbase i64            ; clear memory [u8; 64], 64 bytes
addi $r2 $$locbase i72        ; get offset to local __ptr [u8; 64]
mcpi $r2 $$locbase i64        ; copy memory
addi $r2 $$locbase i72        ; get offset to local __ptr [u8; 64]
addi $r3 $$locbase i64        ; get offset to local __ptr __ptr [u8; 64]
sw   $$locbase $r2 i8         ; store word
addi $r2 $$locbase i136       ; get offset to local __ptr __ptr u256
mcpi $r2 $r3 i8               ; copy memory
lw   $r2 $$locbase i17        ; load word
mcpi $r0 $r2 i32              ; copy memory
move $$retv $r0               ; set return value
cfsi i144                     ; free 144 bytes for locals and 0 slots for extra call arguments
move $$reta $r1               ; restore return address
poph i524288                  ; restore registers 40..64
popl i15                      ; restore registers 16..40
jal  $zero $$reta i0          ; return from call

2 - Array lengths can now be specified using const variables.

One limitation is that these lengths must be limited to simple const variables, local or global, but associated consts are still not working.
Another limitation is that we can't unify arrays lengths that use variables and literals. For example: let _: [u64; 1] = [0u64; A];

const GLOBAL_A: u64 = 1;
#[inline(never)]
fn arrays_with_const_length() {
    const A = 1;
    const B = A + 1;

    let _ = [0u64; A];
    let _: [u64; A] = [0u64];
    let _ = [0u64; GLOBAL_A];

    let _ = [0u64; B];
    let _: [u64; B] = [0u64, 1u64];
}

3 - const declarations can now use const generics in their expressions.

#[inline(never)]
fn const_with_const_generics<const B: u64>() {
    const A: u64 = B + 1;
    __dbg(A);
}

4 - __transmute can now transmute references.

fn transmute_by_reference() -> u256 {
    let mut bytes = [0u8; 32];
    let v: &mut u256 = __transmute::<&mut [u8; 32], &mut u256>(&mut bytes);
    *v
}

5 - Snapshot tests now support a "filter-fn" command, which will parse the compiler output and focus on the specified fns. This will help by eliminating clutter from the snapshots.

Its first argument is the project that we want to filter, and the second is a comma-separated list of all function names we want.

In the example below, {name} is the name of the project where the snapshot.toml lives.

cmds = [
    "forc build --path {root} --ir final --asm final | filter-fn {name} transmute_by_reference_7",
]

convert_resolved_type_info

One of the biggest changes was that convert_resolved_type_info needs access to the "context" that is being compiled, as types can include expressions. At the moment, only const variables and const generics variables. But soon enough, we will be able to write more complex expressions, and we will need full access to available symbols.

Checklist

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@xunilrj xunilrj self-assigned this Aug 22, 2025
Copy link

codspeed-hq bot commented Aug 22, 2025

CodSpeed Performance Report

Merging #7342 will not alter performance

Comparing xunilrj/improve-array-decode (c654509) with master (c2696d6)

Summary

✅ 25 untouched benchmarks

@xunilrj xunilrj force-pushed the xunilrj/improve-array-decode branch from ee3de5a to 1c69c63 Compare August 26, 2025 12:33
@xunilrj xunilrj force-pushed the xunilrj/improve-array-decode branch from 66a53f2 to ae74d8e Compare August 26, 2025 17:48
@xunilrj xunilrj marked this pull request as ready for review August 26, 2025 21:25
@xunilrj xunilrj requested review from a team as code owners August 26, 2025 21:25
@xunilrj xunilrj enabled auto-merge (squash) August 27, 2025 10:44
@xunilrj xunilrj force-pushed the xunilrj/improve-array-decode branch from 44a6090 to 9acff6e Compare August 28, 2025 11:01
@xunilrj xunilrj force-pushed the xunilrj/improve-array-decode branch from 7c46cf4 to d317025 Compare August 28, 2025 18:21
tritao
tritao previously approved these changes Sep 1, 2025
@xunilrj xunilrj merged commit 65d6520 into master Sep 8, 2025
41 checks passed
@xunilrj xunilrj deleted the xunilrj/improve-array-decode branch September 8, 2025 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants