Skip to content

Commit 92d53c4

Browse files
committed
[dart2wasm] Add -O/--optimization-level flag to dart compile wasm
We make the meaning of -O{0,1,2,3,4} to be similar to what dart2js has. We also make the pkg/dart2wasm/tool/compile_benchmark accept the same flags. Follow-up CLs will migrate Dart CI / Golem / flutter to use -O flags. Change-Id: Id37476c596ec7483e633c7db9eec96438315e919 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/348165 Reviewed-by: Slava Egorov <[email protected]>
1 parent 7b37838 commit 92d53c4

File tree

2 files changed

+159
-61
lines changed

2 files changed

+159
-61
lines changed

pkg/dart2wasm/tool/compile_benchmark

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,46 @@
88

99
set -e
1010

11+
function follow_links() {
12+
file="$1"
13+
while [ -h "$file" ]; do
14+
# On Mac OS, readlink -f doesn't work.
15+
file="$(readlink "$file")"
16+
done
17+
echo "$file"
18+
}
19+
20+
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
21+
PROG_NAME="$(follow_links "$BASH_SOURCE")"
22+
23+
# Handle the case where dart-sdk/bin has been symlinked to.
24+
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
25+
SDK_DIR="$(cd "${PROG_DIR}/../../.." ; pwd -P)"
26+
27+
# Locate build directory, containing executables, snapshots and platform dill.
28+
if [[ `uname` == 'Darwin' ]]; then
29+
OUT_DIR="$SDK_DIR/xcodebuild"
30+
else
31+
OUT_DIR="$SDK_DIR/out"
32+
fi
33+
DART_CONFIGURATION=${DART_CONFIGURATION:-ReleaseX64}
34+
BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
35+
36+
BINARYEN="$BIN_DIR/wasm-opt"
37+
DART_AOT_RUNTIME="$BIN_DIR/dart_precompiled_runtime"
38+
SDK_ARG="--dart-sdk=$SDK_DIR"
39+
40+
function find_flags {
41+
echo -en "$(sed -n "/$1 =/,/end of $1/ p" $SDK_DIR/pkg/dartdev/lib/src/commands/compile.dart | sed '1d' | sed '$d' | tr '\n' ' ' | sed 's#\s\+# #g' | sed 's#^\s\+##' | sed 's#\s\+$##')"
42+
}
43+
# Use same flags as `dart compile exe`
44+
BINARYEN_FLAGS=($(find_flags 'binaryenFlags'))
45+
OPT_FLAGS_L0=($(find_flags 'optimizationLevel0Flags'))
46+
OPT_FLAGS_L1=($(find_flags 'optimizationLevel1Flags'))
47+
OPT_FLAGS_L2=($(find_flags 'optimizationLevel2Flags'))
48+
OPT_FLAGS_L3=($(find_flags 'optimizationLevel3Flags'))
49+
OPT_FLAGS_L4=($(find_flags 'optimizationLevel4Flags'))
50+
1151
RUN_BINARYEN=1
1252
COMPILE_BENCHMARK_BASE_NAME=""
1353
PLATFORM_FILENAME="dart2wasm_platform.dill"
@@ -38,11 +78,43 @@ while [ $# -gt 0 ]; do
3878
shift
3979
;;
4080

81+
-O0 | --optimization-level=0)
82+
DART2WASM_ARGS+=(${OPT_FLAGS_L0[@]})
83+
RUN_BINARYEN=0
84+
shift
85+
;;
86+
87+
-O1 | --optimization-level=1)
88+
DART2WASM_ARGS+=(${OPT_FLAGS_L1[@]})
89+
RUN_BINARYEN=1
90+
shift
91+
;;
92+
93+
-O2 | --optimization-level=2)
94+
DART2WASM_ARGS+=(${OPT_FLAGS_L2[@]})
95+
RUN_BINARYEN=1
96+
shift
97+
;;
98+
99+
-O3 | --optimization-level=3)
100+
DART2WASM_ARGS+=(${OPT_FLAGS_L3[@]})
101+
RUN_BINARYEN=1
102+
shift
103+
;;
104+
105+
-O4 | --optimization-level=4)
106+
DART2WASM_ARGS+=(${OPT_FLAGS_L4[@]})
107+
RUN_BINARYEN=1
108+
shift
109+
;;
110+
111+
# TODO: Remove this deprecated flag
41112
--optimize)
42113
RUN_BINARYEN=1
43114
shift
44115
;;
45116

117+
# TODO: Remove this deprecated flag
46118
--no-optimize)
47119
RUN_BINARYEN=0
48120
shift
@@ -83,40 +155,8 @@ if [ -z "$DART_FILE" -o -z "$WASM_FILE" ]; then
83155
fi
84156

85157

86-
function follow_links() {
87-
file="$1"
88-
while [ -h "$file" ]; do
89-
# On Mac OS, readlink -f doesn't work.
90-
file="$(readlink "$file")"
91-
done
92-
echo "$file"
93-
}
94-
95-
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
96-
PROG_NAME="$(follow_links "$BASH_SOURCE")"
97-
98-
# Handle the case where dart-sdk/bin has been symlinked to.
99-
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
100-
SDK_DIR="$(cd "${PROG_DIR}/../../.." ; pwd -P)"
101-
102-
# Use same binaryen flags as `dart compile exe`
103-
BINARYEN_FLAGS="$(sed -n '/binaryenFlags =/,/end of binaryenFlags/ p' $SDK_DIR/pkg/dartdev/lib/src/commands/compile.dart | sed '1d' | sed '$d' | tr '\n' ' ')"
104-
105-
# Locate build directory, containing executables, snapshots and platform dill.
106-
if [[ `uname` == 'Darwin' ]]; then
107-
OUT_DIR="$SDK_DIR/xcodebuild"
108-
else
109-
OUT_DIR="$SDK_DIR/out"
110-
fi
111-
DART_CONFIGURATION=${DART_CONFIGURATION:-ReleaseX64}
112-
BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
113-
114-
BINARYEN="$BIN_DIR/wasm-opt"
115-
DART_AOT_RUNTIME="$BIN_DIR/dart_precompiled_runtime"
116-
DART2WASM_AOT_SNAPSHOT="$BIN_DIR/$SNAPSHOT_NAME.snapshot"
117-
118158
PLATFORM_ARG="--platform=$BIN_DIR/$PLATFORM_FILENAME"
119-
SDK_ARG="--dart-sdk=$SDK_DIR"
159+
DART2WASM_AOT_SNAPSHOT="$BIN_DIR/$SNAPSHOT_NAME.snapshot"
120160

121161
function measure() {
122162
set +e

pkg/dartdev/lib/src/commands/compile.dart

Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,6 @@ import '../native_assets.dart';
1919
import '../sdk.dart';
2020
import '../utils.dart';
2121

22-
// The unique place where we store dart2wasm binaryen flags.
23-
//
24-
// Other uses (e.g. in shell scripts) will grep in this file for the flags. So
25-
// please keep it as a simple multi-line string of flags.
26-
final List<String> binaryenFlags = '''
27-
--all-features
28-
--closed-world
29-
--traps-never-happen
30-
--type-unfinalizing
31-
-O3
32-
--type-ssa
33-
--gufa
34-
-O3
35-
--type-merging
36-
-O1
37-
--type-finalizing
38-
''' // end of binaryenFlags
39-
.split('\n')
40-
.map((line) => line.trim())
41-
.where((line) => line.isNotEmpty)
42-
.toList();
43-
4422
const int compileErrorExitCode = 64;
4523

4624
class Option {
@@ -435,6 +413,57 @@ class CompileWasmCommand extends CompileSubcommandCommand {
435413
static const String help =
436414
'Compile Dart to a WebAssembly/WasmGC module (EXPERIMENTAL).';
437415

416+
// The unique place where we store various flags for dart2wasm & binaryen.
417+
//
418+
// Other uses (e.g. pkg/dart2wasm/tool/compile_benchmark) will grep in this
419+
// file for the flags. So please keep the formatting.
420+
421+
final List<String> binaryenFlags = _flagList('''
422+
--all-features
423+
--closed-world
424+
--traps-never-happen
425+
--type-unfinalizing
426+
-O3
427+
--type-ssa
428+
--gufa
429+
-O3
430+
--type-merging
431+
-O1
432+
--type-finalizing
433+
'''); // end of binaryenFlags
434+
435+
final List<String> optimizationLevel0Flags = _flagList('''
436+
--no-inlining
437+
'''); // end of optimizationLevel0Flags
438+
439+
final List<String> optimizationLevel1Flags = _flagList('''
440+
--inlining
441+
'''); // end of optimizationLevel1Flags
442+
443+
final List<String> optimizationLevel2Flags = _flagList('''
444+
--inlining
445+
--minify
446+
'''); // end of optimizationLevel2Flags
447+
448+
final List<String> optimizationLevel3Flags = _flagList('''
449+
--inlining
450+
--minify
451+
--omit-implicit-checks
452+
'''); // end of optimizationLevel3Flags
453+
454+
final List<String> optimizationLevel4Flags = _flagList('''
455+
--inlining
456+
--minify
457+
--omit-implicit-checks
458+
--omit-explicit-checks
459+
'''); // end of optimizationLevel4Flags
460+
461+
static List<String> _flagList(String lines) => lines
462+
.split('\n')
463+
.map((line) => line.trim())
464+
.where((line) => line.isNotEmpty)
465+
.toList();
466+
438467
CompileWasmCommand({bool verbose = false})
439468
: super(commandName, help, verbose, hidden: !verbose) {
440469
argParser
@@ -450,6 +479,7 @@ class CompileWasmCommand extends CompileSubcommandCommand {
450479
help: 'Generate minified output.',
451480
hide: !verbose,
452481
)
482+
// TODO: Deprecate this flag.
453483
..addFlag(
454484
'optimize',
455485
defaultsTo: true,
@@ -500,6 +530,16 @@ class CompileWasmCommand extends CompileSubcommandCommand {
500530
valueHelp: 'page count',
501531
hide: !verbose,
502532
)
533+
..addOption(
534+
'optimization-level',
535+
abbr: 'O',
536+
help: 'Controls optimizations that can help reduce code-size and '
537+
'improve performance of the generated code.',
538+
allowed: ['0', '1', '2', '3', '4'],
539+
defaultsTo: null, // TODO: Set this to '1'
540+
valueHelp: 'level',
541+
hide: !verbose,
542+
)
503543
..addOption(
504544
packagesOption.flag,
505545
abbr: packagesOption.abbr,
@@ -575,24 +615,42 @@ class CompileWasmCommand extends CompileSubcommandCommand {
575615
}
576616
}
577617

618+
final defaultOptimizationLevel = args['optimize'] ? '1' : '0';
619+
final optimizationLevel =
620+
int.parse(args['optimization-level'] ?? defaultOptimizationLevel);
621+
final runWasmOpt = optimizationLevel >= 1;
622+
578623
final dart2wasmCommand = [
579624
sdk.dartAotRuntime,
580625
sdk.dart2wasmSnapshot,
626+
581627
'--libraries-spec=${sdk.librariesJson}',
582628
'--dart-sdk=$sdkPath',
583629
if (verbose) '--verbose',
584630
if (packages != null) '--packages=$packages',
585-
if (args['enable-asserts']) '--enable-asserts',
586631
if (args['print-wasm']) '--print-wasm',
587632
if (args['print-kernel']) '--print-kernel',
588-
if (args['omit-type-checks']) '--omit-type-checks',
589-
if (args['name-section']) '--name-section',
590-
if (args['minify']) '--minify',
633+
if (args['enable-asserts']) '--enable-asserts',
634+
for (final define in defines) '-D$define',
591635
if (maxPages != null) ...[
592636
'--import-shared-memory',
593637
'--shared-memory-max-pages=$maxPages',
594638
],
595-
for (final define in defines) '-D$define',
639+
640+
// First we pass flags based on the optimization level.
641+
...switch (optimizationLevel) {
642+
0 => optimizationLevel0Flags,
643+
1 => optimizationLevel1Flags,
644+
2 => optimizationLevel2Flags,
645+
3 => optimizationLevel3Flags,
646+
4 => optimizationLevel4Flags,
647+
_ => throw 'unreachable',
648+
},
649+
// Then we pass flags that were opted into explicitly.
650+
if (args['omit-type-checks']) '--omit-type-checks',
651+
if (args['name-section']) '--name-section',
652+
if (args['minify']) '--minify',
653+
596654
path.absolute(sourcePath),
597655
outputFile,
598656
];
@@ -608,7 +666,7 @@ class CompileWasmCommand extends CompileSubcommandCommand {
608666
return compileErrorExitCode;
609667
}
610668

611-
if (args['optimize']) {
669+
if (runWasmOpt) {
612670
final unoptFile = '$outputFileBasename.unopt.wasm';
613671
File(outputFile).renameSync(unoptFile);
614672

0 commit comments

Comments
 (0)