Attention is currently required from: Sigmund Cherem.
Mayank Patke would like Sigmund Cherem to review this change.
[dart2js] Add phase 1 kernel transformer to simplify const conditionals.
Suppose we have code like
if (isDevMode) {
// do foo
} else {
// do bar
}
where isDevMode is const (or can be evaluated as const). In particular,
isDevMode can be controlled by compile-time options, like
bool.fromEnvironment.
We currently eliminate the dead branch during SSA, but that means we do
the work of compiling dead code in the previous phases. Instead, we can
recognize that the condition is const (or effectively const) and
eliminate the dead AST subtree directly.
Change-Id: Ia91da5ebc7fa496a1b963308c6e02d572cab936e
Bug: b/254543452
---
M pkg/compiler/lib/src/compiler.dart
A pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
M pkg/compiler/test/codegen/load_elimination_test.dart
M pkg/compiler/test/impact/data/statements.dart
M pkg/compiler/test/inference/data/general.dart
M pkg/compiler/test/inference/data/refine_order.dart
M pkg/compiler/test/model/native_test.dart
M tests/web/jsinterop_test.dart
M tests/web/non_jsinterop_test.dart
M tests/web_2/jsinterop_test.dart
M tests/web_2/non_jsinterop_test.dart
11 files changed, 212 insertions(+), 35 deletions(-)
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 6ccd5b0..1ab1742 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -63,6 +63,7 @@
import 'kernel/front_end_adapter.dart' show CompilerFileSystem;
import 'kernel/kernel_strategy.dart';
import 'kernel/kernel_world.dart';
+import 'kernel/transformations/const_conditional_simplifier.dart';
import 'null_compiler_output.dart' show NullCompilerOutput;
import 'options.dart' show CompilerOptions;
import 'phase/load_kernel.dart' as load_kernel;
@@ -480,6 +481,11 @@
bool shouldStopAfterLoadKernel(load_kernel.Output output) =>
output == null || compilationFailed || options.cfeOnly;
+ void simplifyConstConditionals(load_kernel.Output output) {
+ ConstConditionalSimplifier(output.component, environment, reporter, options)
+ .run();
+ }
+
Future<ModuleData> runModularAnalysis(
load_kernel.Output output, Set<Uri> moduleLibraries) async {
ir.Component component = output.component;
@@ -721,6 +727,8 @@
load_kernel.Output output = await produceKernel();
if (shouldStopAfterLoadKernel(output)) return;
+ simplifyConstConditionals(output);
+
// Run modular analysis. This may be null if modular analysis was not
// requested for this pipeline.
ModuleData moduleData;
diff --git a/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart b/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
new file mode 100644
index 0000000..06f842b
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
@@ -0,0 +1,75 @@
+// 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.
+
+import 'package:front_end/src/api_prototype/constant_evaluator.dart';
+import 'package:front_end/src/api_unstable/dart2js.dart' show LocatedMessage;
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
+
+import '../../diagnostics/diagnostic_listener.dart';
+import '../../environment.dart';
+import '../../ir/constants.dart';
+import '../../kernel/element_map.dart';
+import '../../options.dart';
+
+class ConstConditionalSimplifier extends RemovingTransformer {
+ final Component _component;
+ final Environment _environment;
+ final DiagnosticReporter _reporter;
+ final CompilerOptions _options;
+
+ late final TypeEnvironment _typeEnvironment;
+ late final Dart2jsConstantEvaluator _constantEvaluator;
+ late StaticTypeContext _staticTypeContext;
+
+ ConstConditionalSimplifier(
+ this._component, this._environment, this._reporter, this._options) {
+ final coreTypes = CoreTypes(_component);
+ final classHierarchy = ClassHierarchy(_component, coreTypes);
+ _typeEnvironment = TypeEnvironment(coreTypes, classHierarchy);
+ _constantEvaluator = Dart2jsConstantEvaluator(_component, _typeEnvironment,
+ (LocatedMessage message, List<LocatedMessage>? context) {
+ reportLocatedMessage(_reporter, message, context);
+ },
+ environment: _environment,
+ evaluationMode: _options.useLegacySubtyping
+ ? EvaluationMode.weak
+ : EvaluationMode.strong);
+ }
+
+ TreeNode run() => transform(_component);
+
+ @override
+ TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
+ _staticTypeContext = StaticTypeContext(node, _typeEnvironment);
+ return super.defaultMember(node, removalSentinel);
+ }
+
+ @override
+ TreeNode visitConditionalExpression(
+ ConditionalExpression node, TreeNode? removalSentinel) {
+ super.visitConditionalExpression(node, removalSentinel);
+ final condition = _constantEvaluator.evaluateOrNull(
+ _staticTypeContext, node.condition,
+ requireConstant: false);
+ if (condition is! BoolConstant) return node;
+ return condition.value ? node.then : node.otherwise;
+ }
+
+ @override
+ TreeNode visitIfStatement(IfStatement node, TreeNode? removalSentinel) {
+ super.visitIfStatement(node, removalSentinel);
+ final condition = _constantEvaluator.evaluateOrNull(
+ _staticTypeContext, node.condition,
+ requireConstant: false);
+ if (condition is! BoolConstant) return node;
+ if (condition.value) {
+ return node.then;
+ } else {
+ return node.otherwise ?? removalSentinel ?? EmptyStatement();
+ }
+ }
+}
diff --git a/pkg/compiler/test/codegen/load_elimination_test.dart b/pkg/compiler/test/codegen/load_elimination_test.dart
index 16305c0..0231c31 100644
--- a/pkg/compiler/test/codegen/load_elimination_test.dart
+++ b/pkg/compiler/test/codegen/load_elimination_test.dart
@@ -262,7 +262,7 @@
await test(TEST_12, 'return 6');
await test(TEST_13, 'return 6');
await test(TEST_14, 'return t1[0]');
- await test(TEST_15, 'return 42');
+ await test(TEST_15, 'return \$.a = 42');
await test(TEST_16, 'return \$.a');
await test(TEST_17,
RegExp(r'return (t1|\$\.x === 0 \? \$\.a = true : \$\.a = false);'));
diff --git a/pkg/compiler/test/impact/data/statements.dart b/pkg/compiler/test/impact/data/statements.dart
index 0685c84..6fe174c 100644
--- a/pkg/compiler/test/impact/data/statements.dart
+++ b/pkg/compiler/test/impact/data/statements.dart
@@ -33,33 +33,82 @@
testAssertWithMessage();
}
-/*member: testIfThen:type=[
+/*member: flag:
+ static=[
+ Rti._bind(1),
+ Rti._eval(1),
+ _arrayInstanceType(1),
+ _asBool(1),
+ _asBoolQ(1),
+ _asBoolS(1),
+ _asDouble(1),
+ _asDoubleQ(1),
+ _asDoubleS(1),
+ _asInt(1),
+ _asIntQ(1),
+ _asIntS(1),
+ _asNum(1),
+ _asNumQ(1),
+ _asNumS(1),
+ _asObject(1),
+ _asString(1),
+ _asStringQ(1),
+ _asStringS(1),
+ _asTop(1),
+ _generalAsCheckImplementation(1),
+ _generalIsTestImplementation(1),
+ _generalNullableAsCheckImplementation(1),
+ _generalNullableIsTestImplementation(1),
+ _installSpecializedAsCheck(1),
+ _installSpecializedIsTest(1),
+ _instanceType(1),
+ _isBool(1),
+ _isInt(1),
+ _isNum(1),
+ _isObject(1),
+ _isString(1),
+ _isTop(1),
+ findType(1),
+ instanceType(1)],
+ type=[
+ inst:Closure,
+ inst:JSBool,
+ inst:JSNull,
+ param:bool*]
+*/
+bool flag; // late
+
+/*member: testIfThen:
+ static=[set:flag],
+ type=[
inst:JSBool,
inst:JSInt,
inst:JSNumNotInt,
inst:JSNumber,
inst:JSPositiveInt,
inst:JSUInt31,
- inst:JSUInt32]*/
+ inst:JSUInt32]
+*/
testIfThen() {
- // ignore: DEAD_CODE
- if (false) return 42;
+ if (flag = false) return 42;
return 1;
}
-/*member: testIfThenElse:type=[
+/*member: testIfThenElse:
+ static=[set:flag],
+ type=[
inst:JSBool,
inst:JSInt,
inst:JSNumNotInt,
inst:JSNumber,
inst:JSPositiveInt,
inst:JSUInt31,
- inst:JSUInt32]*/
+ inst:JSUInt32]
+*/
testIfThenElse() {
- if (true)
+ if (flag = true)
return 42;
else
- // ignore: DEAD_CODE
return 1;
}
diff --git a/pkg/compiler/test/inference/data/general.dart b/pkg/compiler/test/inference/data/general.dart
index db114da..730d848 100644
--- a/pkg/compiler/test/inference/data/general.dart
+++ b/pkg/compiler/test/inference/data/general.dart
@@ -560,12 +560,15 @@
return a;
}
+/*member: flag:Value([null|exact=JSBool], value: true)*/
+bool flag; // late
+
/*member: testDoWhile3:Value([exact=JSBool], value: false)*/
testDoWhile3() {
dynamic a = 42;
do {
a = 'foo';
- if (true) continue;
+ if (flag = true) continue;
return false;
} while (true);
// ignore: dead_code
@@ -577,7 +580,7 @@
dynamic a = 'foo';
do {
a = 54;
- if (true) break;
+ if (flag = true) break;
return 3.5;
} while (true);
return a;
@@ -686,11 +689,12 @@
set myField(/*[subclass=JSUInt32]*/ a) {}
/*member: A.returnInt1:[subclass=JSUInt32]*/
- returnInt1() => /*invoke: [exact=JSUInt31]*/ ++ /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
+ returnInt1() => /*invoke: [exact=JSUInt31]*/
+ ++ /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
/*member: A.returnInt2:[subclass=JSUInt32]*/
- returnInt2() => /*invoke: [exact=JSUInt31]*/ ++this
- . /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
+ returnInt2() => /*invoke: [exact=JSUInt31]*/
+ ++this. /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
/*member: A.returnInt3:[subclass=JSUInt32]*/
returnInt3() =>
@@ -698,8 +702,8 @@
42;
/*member: A.returnInt4:[subclass=JSUInt32]*/
- returnInt4() => /*[subclass=A]*/ /*update: [subclass=A]*/ myField /*invoke: [exact=JSUInt31]*/ +=
- 42;
+ returnInt4() => /*[subclass=A]*/ /*update: [subclass=A]*/
+ myField /*invoke: [exact=JSUInt31]*/ += 42;
/*member: A.[]:[exact=JSUInt31]*/
operator [](/*[exact=JSUInt31]*/ index) => 42;
@@ -708,8 +712,8 @@
operator []=(/*[exact=JSUInt31]*/ index, /*[subclass=JSUInt32]*/ value) {}
/*member: A.returnInt5:[subclass=JSUInt32]*/
- returnInt5() => /*invoke: [exact=JSUInt31]*/ ++this /*[subclass=A]*/ /*update: [subclass=A]*/ [
- 0];
+ returnInt5() => /*invoke: [exact=JSUInt31]*/
+ ++this /*[subclass=A]*/ /*update: [subclass=A]*/ [0];
/*member: A.returnInt6:[subclass=JSUInt32]*/
returnInt6() => this /*[subclass=A]*/ /*update: [subclass=A]*/ [
@@ -724,16 +728,16 @@
B() : super.generative();
/*member: B.returnInt1:[subclass=JSUInt32]*/
- returnInt1() => /*invoke: [exact=JSUInt31]*/ ++new A()
- . /*[exact=A]*/ /*update: [exact=A]*/ myField;
+ returnInt1() => /*invoke: [exact=JSUInt31]*/
+ ++new A(). /*[exact=A]*/ /*update: [exact=A]*/ myField;
/*member: B.returnInt2:[subclass=JSUInt32]*/
returnInt2() => new A()
. /*[exact=A]*/ /*update: [exact=A]*/ myField /*invoke: [exact=JSUInt31]*/ += 4;
/*member: B.returnInt3:[subclass=JSUInt32]*/
- returnInt3() => /*invoke: [exact=JSUInt31]*/ ++new A() /*[exact=A]*/ /*update: [exact=A]*/ [
- 0];
+ returnInt3() => /*invoke: [exact=JSUInt31]*/
+ ++new A() /*[exact=A]*/ /*update: [exact=A]*/ [0];
/*member: B.returnInt4:[subclass=JSUInt32]*/
returnInt4() => new A() /*[exact=A]*/ /*update: [exact=A]*/ [
@@ -763,11 +767,12 @@
C();
/*member: C.returnInt1:[subclass=JSPositiveInt]*/
- returnInt1() => /*invoke: [subclass=JSPositiveInt]*/ ++ /*update: [exact=C]*/ /*[exact=C]*/ myField;
+ returnInt1() => /*invoke: [subclass=JSPositiveInt]*/
+ ++ /*update: [exact=C]*/ /*[exact=C]*/ myField;
/*member: C.returnInt2:[subclass=JSPositiveInt]*/
- returnInt2() => /*invoke: [subclass=JSPositiveInt]*/ ++this
- . /*[exact=C]*/ /*update: [exact=C]*/ myField;
+ returnInt2() => /*invoke: [subclass=JSPositiveInt]*/
+ ++this. /*[exact=C]*/ /*update: [exact=C]*/ myField;
/*member: C.returnInt3:[subclass=JSPositiveInt]*/
returnInt3() =>
@@ -775,8 +780,8 @@
42;
/*member: C.returnInt4:[subclass=JSPositiveInt]*/
- returnInt4() => /*[exact=C]*/ /*update: [exact=C]*/ myField /*invoke: [subclass=JSPositiveInt]*/ +=
- 42;
+ returnInt4() => /*[exact=C]*/ /*update: [exact=C]*/
+ myField /*invoke: [subclass=JSPositiveInt]*/ += 42;
/*member: C.[]:[subclass=JSPositiveInt]*/
operator [](/*[exact=JSUInt31]*/ index) => /*[exact=C]*/ myField;
@@ -786,8 +791,8 @@
/*[exact=JSUInt31]*/ index, /*[subclass=JSPositiveInt]*/ value) {}
/*member: C.returnInt5:[subclass=JSPositiveInt]*/
- returnInt5() => /*invoke: [subclass=JSPositiveInt]*/ ++this /*[exact=C]*/ /*update: [exact=C]*/ [
- 0];
+ returnInt5() => /*invoke: [subclass=JSPositiveInt]*/
+ ++this /*[exact=C]*/ /*update: [exact=C]*/ [0];
/*member: C.returnInt6:[subclass=JSPositiveInt]*/
returnInt6() => this /*[exact=C]*/ /*update: [exact=C]*/ [
diff --git a/pkg/compiler/test/inference/data/refine_order.dart b/pkg/compiler/test/inference/data/refine_order.dart
index cef03af..73d124b 100644
--- a/pkg/compiler/test/inference/data/refine_order.dart
+++ b/pkg/compiler/test/inference/data/refine_order.dart
@@ -136,11 +136,14 @@
// Access both branches of a conditional expression.
////////////////////////////////////////////////////////////////////////////////
+/*member: flag:Value([null|exact=JSBool], value: true)*/
+bool flag; // late
+
/*member: conditionalBothBranches:[null]*/
@pragma('dart2js:assumeDynamic')
conditionalBothBranches(/*[null|subclass=Object]*/ o) {
// ignore: DEAD_CODE
- true ? o.field : o.field;
+ (flag = true) ? o.field : o.field;
o. /*[subclass=Object]*/ field;
}
@@ -152,7 +155,7 @@
@pragma('dart2js:assumeDynamic')
conditionalOneBranchOnly(/*[null|subclass=Object]*/ o) {
// ignore: DEAD_CODE
- true ? o.field : null;
+ (flag = true) ? o.field : null;
o.field;
o. /*[subclass=Object]*/ field;
}
diff --git a/pkg/compiler/test/model/native_test.dart b/pkg/compiler/test/model/native_test.dart
index cfc954a..6d6fa48 100644
--- a/pkg/compiler/test/model/native_test.dart
+++ b/pkg/compiler/test/model/native_test.dart
@@ -23,6 +23,7 @@
await runTest('tests/web_2/jsinterop_test.dart', '', {
'Class': Kind.regular,
'JsInteropClass': Kind.jsInterop,
+ 'flag': Kind.regular,
'topLevelField': Kind.regular,
'topLevelGetter': Kind.regular,
'topLevelSetter': Kind.regular,
@@ -83,6 +84,7 @@
await runTest('tests/web_2/non_jsinterop_test.dart', '', {
'Class': Kind.regular,
'JsInteropClass': Kind.jsInterop,
+ 'flag': Kind.regular,
'topLevelField': Kind.regular,
'topLevelGetter': Kind.regular,
'topLevelSetter': Kind.regular,
diff --git a/tests/web/jsinterop_test.dart b/tests/web/jsinterop_test.dart
index 994f1f1..9647186 100644
--- a/tests/web/jsinterop_test.dart
+++ b/tests/web/jsinterop_test.dart
@@ -239,8 +239,10 @@
external static externalStaticJsInteropMethod();
}
+late bool flag;
+
main() {
- if (false) {
+ if (flag = false) {
topLevelSetter = topLevelField = topLevelGetter;
topLevelFunction();
externalTopLevelSetter = externalTopLevelGetter;
diff --git a/tests/web/non_jsinterop_test.dart b/tests/web/non_jsinterop_test.dart
index 550ea27..6173cd9 100644
--- a/tests/web/non_jsinterop_test.dart
+++ b/tests/web/non_jsinterop_test.dart
@@ -238,8 +238,10 @@
external static externalStaticJsInteropMethod();
}
+late bool flag;
+
main() {
- if (false) {
+ if (flag = false) {
topLevelSetter = topLevelField = topLevelGetter;
topLevelFunction();
externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
diff --git a/tests/web_2/jsinterop_test.dart b/tests/web_2/jsinterop_test.dart
index 5ee057c..bf3766c 100644
--- a/tests/web_2/jsinterop_test.dart
+++ b/tests/web_2/jsinterop_test.dart
@@ -241,8 +241,10 @@
external static externalStaticJsInteropMethod();
}
+bool flag;
+
main() {
- if (false) {
+ if (flag = false) {
topLevelSetter = topLevelField = topLevelGetter;
topLevelFunction();
externalTopLevelSetter = externalTopLevelGetter;
diff --git a/tests/web_2/non_jsinterop_test.dart b/tests/web_2/non_jsinterop_test.dart
index 5406438..1e63305 100644
--- a/tests/web_2/non_jsinterop_test.dart
+++ b/tests/web_2/non_jsinterop_test.dart
@@ -240,8 +240,10 @@
external static externalStaticJsInteropMethod();
}
+bool flag;
+
main() {
- if (false) {
+ if (flag = false) {
topLevelSetter = topLevelField = topLevelGetter;
topLevelFunction();
externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
To view, visit change 270281. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Sigmund Cherem.
Attention is currently required from: Mayank Patke.
Patch set 5:Code-Review +1
1 comment:
Patchset:
Awesome, thanks Mayank!
To view, visit change 270281. To unsubscribe, or for help writing mail filters, visit settings.
Commit Queue submitted this change.
5 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:
```
The name of the file: pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
Insertions: 1, Deletions: 1.
The diff is too large to show. Please review the diff.
```
```
The name of the file: pkg/compiler/lib/src/compiler.dart
Insertions: 12, Deletions: 4.
The diff is too large to show. Please review the diff.
```
[dart2js] Add phase 1 kernel transformer to simplify const conditionals.
Suppose we have code like
if (isDevMode) {
// do foo
} else {
// do bar
}
where isDevMode is const (or can be evaluated as const). In particular,
isDevMode can be controlled by compile-time options, like
bool.fromEnvironment.
We currently eliminate the dead branch during SSA, but that means we do
the work of compiling dead code in the previous phases. Instead, we can
recognize that the condition is const (or effectively const) and
eliminate the dead AST subtree directly.
Change-Id: Ia91da5ebc7fa496a1b963308c6e02d572cab936e
Bug: b/254543452
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/270281
Reviewed-by: Sigmund Cherem <sig...@google.com>
---
M pkg/compiler/lib/src/compiler.dart
A pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
M pkg/compiler/test/codegen/load_elimination_test.dart
M pkg/compiler/test/impact/data/statements.dart
M pkg/compiler/test/inference/data/general.dart
M pkg/compiler/test/inference/data/refine_order.dart
M pkg/compiler/test/model/native_test.dart
M tests/web/jsinterop_test.dart
M tests/web/non_jsinterop_test.dart
M tests/web_2/jsinterop_test.dart
M tests/web_2/non_jsinterop_test.dart
11 files changed, 224 insertions(+), 37 deletions(-)
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 56716a9..0d3d0ac 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -52,6 +52,7 @@
import 'kernel/front_end_adapter.dart' show CompilerFileSystem;
import 'kernel/kernel_strategy.dart';
import 'kernel/kernel_world.dart';
+import 'kernel/transformations/const_conditional_simplifier.dart';
import 'null_compiler_output.dart' show NullCompilerOutput;
import 'options.dart' show CompilerOptions;
import 'phase/load_kernel.dart' as load_kernel;
@@ -442,6 +443,19 @@
bool shouldStopAfterLoadKernel(load_kernel.Output? output) =>
output == null || compilationFailed || options.cfeOnly;
+ void simplifyConstConditionals(load_kernel.Output output) {
+ if (options.readClosedWorldUri == null) {
+ // No existing closed world means we're in phase 1, so run the
+ // transformer.
+ ConstConditionalSimplifier(
+ output.component, environment, reporter, options)
+ .run();
+ }
+
+ // If the closed world is deserialized instead, then the input .dill should
+ // already have the modified AST.
+ }
+
Future<ModuleData> runModularAnalysis(
load_kernel.Output output, Set<Uri> moduleLibraries) async {
ir.Component component = output.component;
@@ -685,17 +699,19 @@
final output = await produceKernel();
if (shouldStopAfterLoadKernel(output)) return;
+ simplifyConstConditionals(output!);
+
// Run modular analysis. This may be null if modular analysis was not
// requested for this pipeline.
ModuleData? moduleData;
if (options.modularMode || options.hasModularAnalysisInputs) {
- moduleData = await produceModuleData(output!);
+ moduleData = await produceModuleData(output);
}
if (shouldStopAfterModularAnalysis) return;
// Compute closed world.
DataAndIndices<JClosedWorld>? closedWorldAndIndices =
- await produceClosedWorld(output!, moduleData);
+ await produceClosedWorld(output, moduleData);
if (shouldStopAfterClosedWorld(closedWorldAndIndices)) return;
// Run global analysis.
diff --git a/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart b/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
new file mode 100644
index 0000000..28556b8
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/transformations/const_conditional_simplifier.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
index 822a582..2dc3129 100644
--- a/pkg/compiler/test/codegen/load_elimination_test.dart
+++ b/pkg/compiler/test/codegen/load_elimination_test.dart
@@ -260,7 +260,7 @@
index 1693141..32cc9b1 100644
index 09ee5ed..34660a1 100644
--- a/pkg/compiler/test/model/native_test.dart
+++ b/pkg/compiler/test/model/native_test.dart
@@ -21,6 +21,7 @@
await runTest('tests/web_2/jsinterop_test.dart', '', {
'Class': Kind.regular,
'JsInteropClass': Kind.jsInterop,
+ 'flag': Kind.regular,
'topLevelField': Kind.regular,
'topLevelGetter': Kind.regular,
'topLevelSetter': Kind.regular,
@@ -81,6 +82,7 @@
To view, visit change 270281. To unsubscribe, or for help writing mail filters, visit settings.
go/dart-cbuild result: SUCCESS
Details: https://goto.google.com/dart-cbuild/find/397ed8673c8dfc702f136a79bcbccac40efa3369