6384eceedc
Late fields start out holding a sentinel value and after they are initialized or assigned, never hold a sentinel value again.
This CL implements some removal of checks and loads based on this monotonic behaviour.
On two large Dart Angular apps, this reduces the number of late-instance-field checks by ~25%.
One app is 0.44% smaller, the other is 0.98% smaller.
The optimization_test.dart no longer forces `--disable-inlining` because that prevents the inlining that exposes the optimization opportunities.
Most tests already use `@pragma('dart2js:noInline')` to prevent inlining where relevant.
Change-Id: I2327a96e69191313ed6c07eabe94aa2962fb2648
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246881
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
72 lines
1.8 KiB
Dart
72 lines
1.8 KiB
Dart
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// @dart = 2.17
|
|
|
|
/*member: main:**/
|
|
void main() {
|
|
final x1 = XX();
|
|
x1.assignUseBar();
|
|
x1.assignUseFoo();
|
|
x1.useBar();
|
|
x1.useFoo();
|
|
}
|
|
|
|
class XX {
|
|
late int foo;
|
|
late final int bar;
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.useFoo:
|
|
SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
|
|
SsaLateFieldOptimizer.post=[HFieldGet=3,HLateReadCheck=1],
|
|
*/
|
|
void useFoo() {
|
|
use(foo, foo, effect(), foo, foo, effect(), foo, foo);
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.useBar:
|
|
SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
|
|
SsaLateFieldOptimizer.post=[HFieldGet=1,HLateReadCheck=1],
|
|
*/
|
|
void useBar() {
|
|
use(bar, bar, effect(), bar, bar, effect(), bar, bar);
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.assignUseFoo:
|
|
SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
|
|
SsaLateFieldOptimizer.post=[HFieldGet=3],
|
|
*/
|
|
void assignUseFoo() {
|
|
foo = 200;
|
|
use(effect(), foo, effect(), foo, foo, effect(), foo, foo);
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.assignUseBar:
|
|
SsaLateFieldOptimizer.pre=
|
|
[HFieldGet=4,HLateReadCheck=3,HLateWriteOnceCheck=1],
|
|
SsaLateFieldOptimizer.post=[HFieldGet=1,HLateWriteOnceCheck=1],
|
|
*/
|
|
void assignUseBar() {
|
|
bar = 100;
|
|
use(effect(), bar, effect(), bar, bar, effect(), bar, bar);
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.use:**/
|
|
void use(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
|
|
print([a1, a2, a3, a4, a5, a6, a7, a8]);
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
/*member: XX.effect:**/
|
|
int effect() {
|
|
foo++;
|
|
return 0;
|
|
}
|
|
}
|