Skip to content

Commit

Permalink
feat: selectively inline share_code helpers including allocation (#4212)
Browse files Browse the repository at this point in the history
To mitigate cycle perf regression of new cost model, selectively inline `share_code` helpers in the backend using an additional argument `Never | Always` (i.e. always inline vs never inline). Also, add compiler flags to explicitly opt-in or disable the inlining optimization.

NB: some recursive share_code cannot be unshared/inlined (e.g.  recursive serialization code and code that explicitly returns rather than returning control flow). 

Similar to #4207, but also inlines all heap object allocation and adds compiler flags to enable (default)/disable the optimization.
Note users may want to disable the optimization if they can't accept the increase in code size.

# Profiling data 

## new metering, sans wasm-opt
dfinity/canister-profiling#85

Overall Statistics
binary_size: 10.68% [8.58%, 12.79%]
max_mem: no change
cycles: -8.32% [-9.67%, -6.97%]

## new metering with wasm-opt 03

dfinity/canister-profiling#86

Overall Statistics
binary_size: -6.28% [-7.53%, -5.03%]
max_mem: no change
cycles: -18.21% [-20.07%, -16.36%]

## new metering, master (no-inlining) and wasm-opt 03

dfinity/canister-profiling#83

Overall Statistics
binary_size: -13.96% [-14.64%, -13.28%]
max_mem: no change
cycles: -12.46% [-13.51%, -11.41%]

(UPDATE: revised stats after @chenyan-dfinity updates to PRs)
  • Loading branch information
crusso authored Sep 19, 2023
1 parent 01e2f02 commit 698f20c
Show file tree
Hide file tree
Showing 48 changed files with 296 additions and 273 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ jobs:

artifacts:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && contains(github.event.pull_request.labels.*.name, 'build_artifacts')
needs: tests
concurrency: ci-${{ github.ref }}
strategy:
matrix:
os: [ ubuntu-latest, macos-latest ]
Expand Down
8 changes: 8 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Motoko compiler changelog

* motoko (`moc`)

* perf: inline shareble low-level functions in generated coded, trading code size for reduced cycle count. Controlled by flags:
* `-fno-shared-code` (default)
* `-f-shared-code` (legacy)
(Helps mitigate the effect of the IC's new cost model, that increases
the cost of function calls).

## 0.10.0 (2023-09-11)

* motoko (`moc`)
Expand Down
2 changes: 2 additions & 0 deletions doc/md/compiler-ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ You can use the following options with the `moc` command.
| `--copying-gc` | Use copying GC (default) |
| `--debug` | Respects debug expressions in the source (the default). |
| `--error-detail <n>` | Set level of error message detail for syntax errors, n in \[0..3\] (default 2). |
| `-fno-shared-code` | Do *not* share low-level utility code: larger code size but decreased cycle consumption (default). |
| `-fshared-code` | Do share low-level utility code: smaller code size but increased cycle consumption. |
| `--generational-gc` | Use generational GC |
| `-help`,`--help` | Displays usage information. |
| `--hide-warnings` | Hides compiler warnings. |
Expand Down
354 changes: 192 additions & 162 deletions src/codegen/compile.ml

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion src/exes/moc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,17 @@ let argspec = [

"--trap-on-call-error",
Arg.Unit (fun () -> Flags.trap_on_call_error := true),
" Trap, don't throw an `Error`, when an IC call fails due to destination queue full or freezing threshold is crossed. Emulates behaviour of moc versions < 0.8.0."
" Trap, don't throw an `Error`, when an IC call fails due to destination queue full or freezing threshold is crossed. Emulates behaviour of moc versions < 0.8.0.";

(* optimizations *)
"-fno-shared-code",
Arg.Unit (fun () -> Flags.share_code := false),
" do *not* share low-level utility code: larger code size but decreased cycle consumption (default)";

"-fshared-code",
Arg.Unit (fun () -> Flags.share_code := true),
" do share low-level utility code: smaller code size but increased cycle consumption"

]

@ Args.inclusion_args
Expand Down
1 change: 1 addition & 0 deletions src/mo_config/flags.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ let rts_stack_pages_default = 32 (* 2MB *)
let rts_stack_pages : int ref = ref rts_stack_pages_default
let trap_on_call_error = ref false
let use_stable_regions = ref false
let share_code = ref false
6 changes: 3 additions & 3 deletions test/bench/ok/alloc.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_432_930_095)
debug.print: (+268_435_456, 2_399_375_662)
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_432_749_871)
debug.print: (+268_435_456, 2_399_195_438)
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_432_749_871)
debug.print: (+268_435_456, 2_399_195_438)
ingress Completed: Reply: 0x4449444c0000
6 changes: 3 additions & 3 deletions test/bench/ok/alloc.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_500_108_610)
debug.print: (+268_435_456, 2_432_999_739)
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_499_907_906)
debug.print: (+268_435_456, 2_432_799_035)
ingress Completed: Reply: 0x4449444c0000
debug.print: (+268_435_456, 2_499_907_906)
debug.print: (+268_435_456, 2_432_799_035)
ingress Completed: Reply: 0x4449444c0000
4 changes: 2 additions & 2 deletions test/bench/ok/bignum.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {cycles = 2_389_400; size = +59_652}
debug.print: {cycles = 2_389_399; size = +59_652}
ingress Completed: Reply: 0x4449444c0000
debug.print: {cycles = 102_989_425; size = +1_817_872}
debug.print: {cycles = 102_989_422; size = +1_817_872}
ingress Completed: Reply: 0x4449444c0000
4 changes: 2 additions & 2 deletions test/bench/ok/bignum.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {cycles = 2_493_587; size = +59_652}
debug.print: {cycles = 2_493_575; size = +59_652}
ingress Completed: Reply: 0x4449444c0000
debug.print: {cycles = 103_046_373; size = +1_817_872}
debug.print: {cycles = 103_046_415; size = +1_817_872}
ingress Completed: Reply: 0x4449444c0000
4 changes: 2 additions & 2 deletions test/bench/ok/heap-32.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (50_227, +30_261_252, 620_399_314)
debug.print: (50_070, +32_992_212, 671_309_966)
debug.print: (50_227, +30_261_252, 620_249_041)
debug.print: (50_070, +32_992_212, 671_159_850)
ingress Completed: Reply: 0x4449444c0000
4 changes: 2 additions & 2 deletions test/bench/ok/heap-32.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (50_227, +30_261_252, 667_802_947)
debug.print: (50_070, +32_992_212, 720_527_336)
debug.print: (50_227, +30_261_252, 667_502_483)
debug.print: (50_070, +32_992_212, 720_277_266)
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/nat16.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (0, 18_875_143)
debug.print: (0, 18_875_142)
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/nat16.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (0, 42_992_136)
debug.print: (0, 42_992_115)
ingress Completed: Reply: 0x4449444c0000
12 changes: 6 additions & 6 deletions test/bench/ok/palindrome.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (true, +1_188, 10_852)
debug.print: (false, +1_188, 10_198)
debug.print: (false, +1_188, 10_843)
debug.print: (true, +868, 11_135)
debug.print: (false, +868, 9_989)
debug.print: (false, +868, 11_099)
debug.print: (true, +1_188, 10_601)
debug.print: (false, +1_188, 9_947)
debug.print: (false, +1_188, 10_592)
debug.print: (true, +868, 10_944)
debug.print: (false, +868, 9_878)
debug.print: (false, +868, 10_913)
ingress Completed: Reply: 0x4449444c0000
12 changes: 6 additions & 6 deletions test/bench/ok/palindrome.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: (true, +1_188, 11_854)
debug.print: (false, +1_188, 11_139)
debug.print: (false, +1_188, 11_844)
debug.print: (true, +868, 11_834)
debug.print: (false, +868, 10_653)
debug.print: (false, +868, 11_793)
debug.print: (true, +1_188, 11_633)
debug.print: (false, +1_188, 10_933)
debug.print: (false, +1_188, 11_623)
debug.print: (true, +868, 11_595)
debug.print: (false, +868, 10_493)
debug.print: (false, +868, 11_558)
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/region-mem.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 5_096_079_644}
debug.print: {heap_diff = 0; instr_diff = 5_096_079_643}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/region-mem.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 5_398_069_554}
debug.print: {heap_diff = 0; instr_diff = 5_372_903_723}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/region0-mem.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 5_221_908_764}
debug.print: {heap_diff = 0; instr_diff = 5_221_908_763}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/region0-mem.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 5_637_144_882}
debug.print: {heap_diff = 0; instr_diff = 5_624_561_963}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/stable-mem.drun-run-opt.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 2_642_411_804}
debug.print: {heap_diff = 0; instr_diff = 2_642_411_803}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/bench/ok/stable-mem.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: {heap_diff = 0; instr_diff = 3_007_316_274}
debug.print: {heap_diff = 0; instr_diff = 2_982_150_443}
ingress Completed: Reply: 0x4449444c0000
2 changes: 1 addition & 1 deletion test/run-drun/ok/perf.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: 51_218
debug.print: 50_218
ingress Completed: Reply: 0x4449444c0000
7 changes: 0 additions & 7 deletions test/run-drun/ok/perf.ic-ref-run.ok

This file was deleted.

6 changes: 2 additions & 4 deletions test/run/ok/array-bounds.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Error: failed to run main module `_out/array-bounds.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Array.idx
1: Array.idx_bigint
2: init
3: _start
0: init
1: _start
2: wasm trap: unreachable
1 change: 1 addition & 0 deletions test/run/optimise-for-array.mo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//MOC-FLAG -fshared-code
import Prim "mo:⛔";

// Differences between incremental and non-incremental compilation (additional forwarding header field).
Expand Down
1 change: 1 addition & 0 deletions test/run/unboxed-let.mo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//MOC-FLAG -fshared-code
func goNat32() {
let x : Nat32 = 1 +% 1;
var y : Nat32 = 1; y *%= 2;
Expand Down
1 change: 1 addition & 0 deletions test/run/words.mo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//MOC-FLAG -fshared-code
import Prim "mo:⛔";

// CHECK: func $init
Expand Down
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int16-int8-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int16-int8-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int16-lower.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int16-lower.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int16>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int16-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int16-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int16-upper.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int16-upper.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int16>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int32-int16-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int32-int16-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int32-lower.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int32-lower.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int32>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int32-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int32-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int32-upper.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int32-upper.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int32>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int64-int32-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int64-int32-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int64-lower.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int64-lower.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int->Int64
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int64-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int64-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int64-upper.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int64-upper.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int->Int64
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int8-lower.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int8-lower.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int8>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int8-negation.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int8-negation.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: neg32_trap
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-int8-upper.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-int8-upper.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Int-><Int8>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
5 changes: 2 additions & 3 deletions test/trap/ok/outrange-nat16.wasm-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Error: failed to run main module `_out/outrange-nat16.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: Nat-><Nat16>
1: init
2: _start
0: init
1: _start
2: wasm trap: unreachable
Loading

0 comments on commit 698f20c

Please sign in to comment.