[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