sway icon indicating copy to clipboard operation
sway copied to clipboard

Trivial fns allowing control if a type is trivially encoded/decoded

Open xunilrj opened this issue 1 month ago • 4 comments

Description

Continuation of https://github.com/FuelLabs/sway/pull/7488.

This PR introduces the option for each type to control its own is_trivial.

Primitive data types have direct implementation (only decoding bool is false, as we need to guarantee its value is zero or one).

Structs, tuples, arrays etc... are trivial if their runtime representation and "inner types" allow for trivial encoding or decoding.

Enums are more complicated as we need to control that the enum tag is valid; they are not trivial.

String arrays are not trivially encoded/decoded for backwards compatibility with "encoding v0" that needs padding in some cases.

Some tests are showing a small regression (6 gas), which comes from the introduced "if" not being optimised away. I want to solve this in another PR, where the "if" condition will come from a const, and IR generation will guarantee that only one branch will ever be emitted.

Snapshot "echo"

Small QOL of snapshot was introduced with the "echo" command. It just prints the message directly, wrapping on 80 chars. The idea is to explain what the snapshot is trying to test.

Checklist

  • [x] I have linked to any relevant issues.
  • [x] 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).
  • [x] 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.
  • [x] 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.

[!NOTE] Add per-type trivial encode/decode flags and use raw_ptr fast paths in ABI (encode/decode) with supporting changes to codec, String/Vec, and tests.

  • std/codec:
    • Introduce AbiEncode::is_encode_trivial and AbiDecode::is_decode_trivial; add helpers is_encode_trivial/is_decode_trivial.
    • Switch encode/abi_decode to branch on triviality; add decode_from_raw_ptr and raw-ptr-based decode_* helpers.
    • Make BufferReader parameter accessors return raw_ptr; minor refactors to use raw ptr copies.
    • Implement triviality for primitives, arrays/tuples (conditional), str[strN] non-trivial, enums non-trivial.
  • std/string & std/vec: implement trivial encode/decode markers (non-trivial) and adapt codec impls.
  • Tests/fixtures:
    • Update snapshots (IR/ASM/bytecode/gas), JSON ABI offsets, contract/predicate IDs, and logging expectations to match new encoding paths.

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

xunilrj avatar Nov 20 '25 12:11 xunilrj

CodSpeed Performance Report

Merging #7501 will degrade performances by 12.57%

Comparing xunilrj/trivial-fns-codec-traits (9f6ed6e) with master (b4fa78d)

Summary

❌ 1 regression
✅ 24 untouched

:warning: Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
compile 4.7 s 5.3 s -12.57%

codspeed-hq[bot] avatar Nov 20 '25 12:11 codspeed-hq[bot]

-13.24% compile time regression is a bit unfortunate. Any way we can get this number down a bit?

JoshuaBatty avatar Nov 24 '25 02:11 JoshuaBatty

Bytecode e2e

Improvements Regressions
Count 106 37
Average 18.99% -23.49%
Median 13.27% -6.36%
Max 47.47% -525.00%
Min 0.61% -0.52%

Gas Usage e2e

Improvements Regressions
Count 40 19
Average 8.10% -18.67%
Median 5.77% -2.89%
Max 36.80% -262.26%
Min 0.04% -0.21%

Gas Usage In Langauge Tests

Improvements Regressions
Count 6 19
Average 1.41% -1.94%
Median 0.65% -0.12%
Max 3.64% -13.59%
Min 0.03% -0.01%

xunilrj avatar Dec 04 '25 16:12 xunilrj

PR Summary

Introduce per-type trivial encode/decode flags in ABI, update implementations and snapshots (including new snapshot echo), and refresh contract IDs/tooling.

  • ABI/Encoding:
    • Add per-type AbiEncode/AbiDecode hooks: is_encode_trivial() and is_decode_trivial(); wire into primitives and composites (structs/tuples/arrays use inner/truntime checks; enums non-trivial; strings/Vecs non-trivial for v0 compat).
    • Implement non-trivial encode for String, Vec<T>, and several test newtypes (raw ptr, custom error).
  • Tests/Snapshots:
    • Update IR/ASM, gas counts, and ABI JSON (offsets/log metadata) to reflect triviality and logging changes.
    • Add unit-type enum logging; adjust various snapshots (array/tuple/const_generics/panic/logging/etc.).
    • Add echo command to snapshot harness (80-char wrapped) for inline test descriptions.
  • Tooling/Misc:
    • Update contract IDs across require-deployment tests; fix update-contract-ids.sh to pass path to forc contract-id.

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

cursor[bot] avatar Dec 04 '25 16:12 cursor[bot]

:+1:

ironcev avatar Dec 14 '25 14:12 ironcev

gas usage e2e

Improvements Regressions
Count
Average
Median
Max
Min

gas usage in lang

Improvements Regressions
Count 17 34
Average 0.62% -3.09%
Median 0.03% -1.82%
Max 3.64% -18.32%
Min 0.01% -0.01%

Worst offender now are string arrays. Which are not trivially encoded/decoded anymore, because that layout issue that we have.

xunilrj avatar Dec 15 '25 20:12 xunilrj