[dart2js] Remove HInstruction.isControlFlow
Change-Id: I5c0b5a8cf0b5c499d854fd8ce62e3c9c85b7ad5b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403388
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/js/js_debug.dart b/pkg/compiler/lib/src/js/js_debug.dart
index 0a78a27..b45179c 100644
--- a/pkg/compiler/lib/src/js/js_debug.dart
+++ b/pkg/compiler/lib/src/js/js_debug.dart
@@ -67,4 +67,7 @@
void error(String message) {
buffer.write('>>$message<<');
}
+
+ @override
+ bool get isDebugContext => true;
}
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 6ea5f66..0929e05 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -774,7 +774,7 @@
}
if (needsAssignment &&
- !instruction.isControlFlow() &&
+ !instruction.isJsStatement() &&
variableNames.hasName(instruction)) {
visitExpression(instruction);
assignVariable(
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 9795ed9..a4968e5 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -1085,7 +1085,7 @@
}
void tryGenerateAtUseSite(HInstruction instruction) {
- if (instruction.isControlFlow()) return;
+ if (instruction.isJsStatement()) return;
markAsGenerateAtUseSite(instruction);
}
@@ -1289,12 +1289,14 @@
bool isSafeToGenerateAtUseSite(HInstruction user, HInstruction input) {
// HCreate evaluates arguments in order and passes them to a constructor.
if (user is HCreate) return true;
+
// A [HForeign] instruction uses operators and if we generate [input] at use
// site, the precedence or evaluation order might be wrong.
if (user is HForeign) return false;
- // A [HCheck] instruction with control flow uses its input
+
+ // A [HCheck] instruction that is a statement sometimes uses its input
// multiple times, so we avoid generating it at use site.
- if (user is HCheck && user.isControlFlow()) return false;
+ if (user is HCheck && user.isJsStatement()) return false;
// A read-modify-write like `o.field += value` reads the field before
// evaluating the value, so if we generate [input] at the value, the order
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 0620aac..ec18e7f 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1235,9 +1235,6 @@
/// Can this node throw an exception?
bool canThrow(AbstractValueDomain domain) => false;
- /// Does this node potentially affect control flow.
- bool isControlFlow() => false;
-
bool isValue(AbstractValueDomain domain) =>
domain.isPrimitiveValue(instructionType);
@@ -1477,6 +1474,12 @@
bool isCodeMotionInvariant() => false;
+ /// Returns `true` when this HInstruction might be compiled to a JavaScript
+ /// statement, `false` when always compiled to a JavaScript expression.
+ ///
+ /// Some checks are marked as statements even though the generated code is an
+ /// expression. This is done when the value of the generated expression does
+ /// not correspond to the value of the check (usually one of its inputs).
bool isJsStatement() => false;
bool dominates(HInstruction other) {
@@ -1782,8 +1785,6 @@
// There can be an additional fourth input which is the index to report to
// [ioore]. This is used by the expansion of [JSArray.removeLast].
HInstruction get reportedIndex => inputs.length > 3 ? inputs[3] : index;
- @override
- bool isControlFlow() => true;
@override
R accept<R>(HVisitor<R> visitor) => visitor.visitBoundsCheck(this);
@@ -1806,8 +1807,7 @@
abstract class HControlFlow extends HInstruction {
HControlFlow() : super._noType();
- @override
- bool isControlFlow() => true;
+
@override
bool isJsStatement() => true;
@@ -2357,10 +2357,6 @@
@override
R accept<R>(HVisitor<R> visitor) => visitor.visitFieldSet(this);
- // HFieldSet is an expression if it has a user.
- @override
- bool isJsStatement() => usedBy.isEmpty;
-
@override
String toString() => "FieldSet(element=$element,type=$instructionType)";
}
@@ -2490,8 +2486,6 @@
R accept<R>(HVisitor<R> visitor) => visitor.visitReadModifyWrite(this);
@override
- bool isJsStatement() => isAssignOp;
- @override
String toString() => "ReadModifyWrite $jsOp $opKind $element";
}
@@ -2538,8 +2532,6 @@
HLocalValue get local => inputs[0] as HLocalValue;
HInstruction get value => inputs[1];
- @override
- bool isJsStatement() => true;
}
/// Invocation of a native or JS-interop method.
@@ -2699,6 +2691,7 @@
@override
bool isJsStatement() => isStatement;
+
@override
bool canThrow(AbstractValueDomain domain) {
if (inputs.isNotEmpty) {
@@ -3648,8 +3641,6 @@
bool typeEquals(other) => other is HStaticStore;
@override
bool dataEquals(HStaticStore other) => element == other.element;
- @override
- bool isJsStatement() => usedBy.isEmpty;
}
class HLiteralList extends HInstruction {
@@ -3833,8 +3824,6 @@
@override
bool isJsStatement() => true;
- @override
- bool isControlFlow() => true;
@override
_GvnType get _gvnType => _GvnType.primitiveCheck;
@@ -3920,8 +3909,6 @@
: super._oneInput();
@override
- bool isControlFlow() => true;
- @override
bool isJsStatement() => true;
@override
@@ -3974,9 +3961,6 @@
}
@override
- bool isControlFlow() => true;
-
- @override
bool isCodeMotionInvariant() => false;
}
@@ -4111,8 +4095,7 @@
@override
bool isJsStatement() => false;
- @override
- bool isControlFlow() => false;
+
@override
bool canThrow(AbstractValueDomain domain) => false;
@@ -5017,7 +5000,7 @@
AbstractValue inputType,
AbstractValueDomain domain,
) {
- // TODO(sra): Depening on the checked flags, the output is fixed-length or
+ // TODO(sra): Depending on the checked flags, the output is fixed-length or
// unmodifiable. Refine the type to the degree an AbstractValue can express
// that.
return inputType;
@@ -5037,8 +5020,6 @@
R accept<R>(HVisitor<R> visitor) => visitor.visitArrayFlagsCheck(this);
@override
- bool isControlFlow() => true;
- @override
bool isJsStatement() => true;
@override