Skip to content

Commit 8f1be54

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] New RTI: Improve normalization of is-tests.
Change-Id: I48e5a19af931dd2f76cceea6b5a9abb513d5fd39 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124463 Commit-Queue: Mayank Patke <fishythefish@google.com> Reviewed-by: Stephen Adams <sra@google.com>
1 parent 1b344fc commit 8f1be54

File tree

2 files changed

+93
-28
lines changed

2 files changed

+93
-28
lines changed

pkg/compiler/lib/src/ssa/nodes.dart

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:front_end/src/api_unstable/dart2js.dart' show Link;
66

77
import '../closure.dart';
88
import '../common.dart';
9+
import '../common_elements.dart';
910
import '../constants/constant_system.dart' as constant_system;
1011
import '../constants/values.dart';
1112
import '../elements/entities.dart';
@@ -4367,6 +4368,9 @@ class HIsTest extends HInstruction {
43674368
HInstruction get typeInput => inputs[0];
43684369
HInstruction get checkedInput => inputs[1];
43694370

4371+
AbstractBool evaluate(JClosedWorld closedWorld) =>
4372+
_isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld);
4373+
43704374
@override
43714375
accept(HVisitor visitor) => visitor.visitIsTest(this);
43724376

@@ -4398,6 +4402,9 @@ class HIsTestSimple extends HInstruction {
43984402

43994403
HInstruction get checkedInput => inputs[0];
44004404

4405+
AbstractBool evaluate(JClosedWorld closedWorld) =>
4406+
_isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld);
4407+
44014408
@override
44024409
accept(HVisitor visitor) => visitor.visitIsTestSimple(this);
44034410

@@ -4414,6 +4421,75 @@ class HIsTestSimple extends HInstruction {
44144421
String toString() => 'HIsTestSimple()';
44154422
}
44164423

4424+
AbstractBool _isTestResult(HInstruction expression, DartType dartType,
4425+
AbstractValueWithPrecision checkedAbstractValue, JClosedWorld closedWorld) {
4426+
AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
4427+
AbstractValue subsetType = expression.instructionType;
4428+
AbstractValue supersetType = checkedAbstractValue.abstractValue;
4429+
if (checkedAbstractValue.isPrecise &&
4430+
abstractValueDomain.isIn(subsetType, supersetType).isDefinitelyTrue) {
4431+
return AbstractBool.True;
4432+
}
4433+
4434+
// TODO(39287): Let the abstract value domain fully handle this.
4435+
// Currently, the abstract value domain cannot (soundly) state that an is-test
4436+
// is definitely false, so we reuse some of the case-by-case logic from the
4437+
// old [HIs] optimization.
4438+
if (dartType.isTop) return AbstractBool.True;
4439+
if (dartType is! InterfaceType) return AbstractBool.Maybe;
4440+
InterfaceType type = dartType;
4441+
ClassEntity element = type.element;
4442+
if (type.typeArguments.isNotEmpty) return AbstractBool.Maybe;
4443+
JCommonElements commonElements = closedWorld.commonElements;
4444+
if (expression.isInteger(abstractValueDomain).isDefinitelyTrue) {
4445+
if (element == commonElements.intClass ||
4446+
element == commonElements.numClass ||
4447+
commonElements.isNumberOrStringSupertype(element)) {
4448+
return AbstractBool.True;
4449+
}
4450+
if (element == commonElements.doubleClass) {
4451+
// We let the JS semantics decide for that check. Currently the code we
4452+
// emit will always return true.
4453+
return AbstractBool.Maybe;
4454+
}
4455+
return AbstractBool.False;
4456+
}
4457+
if (expression.isDouble(abstractValueDomain).isDefinitelyTrue) {
4458+
if (element == commonElements.doubleClass ||
4459+
element == commonElements.numClass ||
4460+
commonElements.isNumberOrStringSupertype(element)) {
4461+
return AbstractBool.True;
4462+
}
4463+
if (element == commonElements.intClass) {
4464+
// We let the JS semantics decide for that check. Currently the code we
4465+
// emit will return true for a double that can be represented as a 31-bit
4466+
// integer and for -0.0.
4467+
return AbstractBool.Maybe;
4468+
}
4469+
return AbstractBool.False;
4470+
}
4471+
if (expression.isNumber(abstractValueDomain).isDefinitelyTrue) {
4472+
if (element == commonElements.numClass) {
4473+
return AbstractBool.True;
4474+
}
4475+
// We cannot just return false, because the expression may be of type int or
4476+
// double.
4477+
return AbstractBool.Maybe;
4478+
}
4479+
if (expression.isPrimitiveNumber(abstractValueDomain).isPotentiallyTrue &&
4480+
element == commonElements.intClass) {
4481+
// We let the JS semantics decide for that check.
4482+
return AbstractBool.Maybe;
4483+
}
4484+
// We need the raw check because we don't have the notion of generics in the
4485+
// backend. For example, `this` in a class `A<T>` is currently always
4486+
// considered to have the raw type.
4487+
if (type.treatAsRaw) {
4488+
return abstractValueDomain.isInstanceOf(subsetType, element);
4489+
}
4490+
return AbstractBool.Maybe;
4491+
}
4492+
44174493
/// Type cast or type check using Rti form of type expression.
44184494
class HAsCheck extends HCheck {
44194495
final AbstractValueWithPrecision checkedType;

pkg/compiler/lib/src/ssa/optimize.dart

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,18 +2042,11 @@ class SsaInstructionSimplifier extends HBaseVisitor
20422042

20432043
@override
20442044
HInstruction visitIsTest(HIsTest node) {
2045-
AbstractValueWithPrecision checkedAbstractValue = node.checkedAbstractValue;
2046-
HInstruction checkedInput = node.checkedInput;
2047-
AbstractValue inputType = checkedInput.instructionType;
2048-
2049-
AbstractBool isIn = _abstractValueDomain.isIn(
2050-
inputType, checkedAbstractValue.abstractValue);
2051-
2052-
if (isIn.isDefinitelyFalse) {
2045+
AbstractBool result = node.evaluate(_closedWorld);
2046+
if (result.isDefinitelyFalse) {
20532047
return _graph.addConstantBool(false, _closedWorld);
20542048
}
2055-
2056-
if (checkedAbstractValue.isPrecise && isIn.isDefinitelyTrue) {
2049+
if (result.isDefinitelyTrue) {
20572050
return _graph.addConstantBool(true, _closedWorld);
20582051
}
20592052

@@ -2070,15 +2063,21 @@ class SsaInstructionSimplifier extends HBaseVisitor
20702063
dartType, _graph, _closedWorld);
20712064

20722065
if (specialization == IsTestSpecialization.null_) {
2073-
return HIdentity(checkedInput, _graph.addConstantNull(_closedWorld),
2074-
null, _abstractValueDomain.boolType);
2066+
return HIdentity(
2067+
node.checkedInput,
2068+
_graph.addConstantNull(_closedWorld),
2069+
null,
2070+
_abstractValueDomain.boolType);
20752071
}
20762072

20772073
if (specialization != null) {
2078-
AbstractValueWithPrecision checkedType = _abstractValueDomain
2079-
.createFromStaticType(dartType, nullable: false);
2074+
AbstractValueWithPrecision checkedType =
2075+
_abstractValueDomain.createFromStaticType(dartType,
2076+
nullable: _abstractValueDomain
2077+
.isNull(node.checkedAbstractValue.abstractValue)
2078+
.isPotentiallyTrue);
20802079
return HIsTestSimple(dartType, checkedType, specialization,
2081-
checkedInput, _abstractValueDomain.boolType);
2080+
node.checkedInput, _abstractValueDomain.boolType);
20822081
}
20832082
}
20842083

@@ -2089,23 +2088,13 @@ class SsaInstructionSimplifier extends HBaseVisitor
20892088

20902089
@override
20912090
HInstruction visitIsTestSimple(HIsTestSimple node) {
2092-
AbstractValueWithPrecision checkedAbstractValue = node.checkedAbstractValue;
2093-
HInstruction checkedInput = node.checkedInput;
2094-
AbstractValue inputType = checkedInput.instructionType;
2095-
2096-
AbstractBool isIn = _abstractValueDomain.isIn(
2097-
inputType, checkedAbstractValue.abstractValue);
2098-
2099-
if (isIn.isDefinitelyFalse) {
2091+
AbstractBool result = node.evaluate(_closedWorld);
2092+
if (result.isDefinitelyFalse) {
21002093
return _graph.addConstantBool(false, _closedWorld);
21012094
}
2102-
2103-
if (!checkedAbstractValue.isPrecise) return node;
2104-
2105-
if (isIn.isDefinitelyTrue) {
2095+
if (result.isDefinitelyTrue) {
21062096
return _graph.addConstantBool(true, _closedWorld);
21072097
}
2108-
21092098
return node;
21102099
}
21112100

0 commit comments

Comments
 (0)