[dart2js] Specialize strong 'is Object'
- o is Object --> o != null. - Avoid specializing 'is Object' to instanceof. Change-Id: Id882666d547ee2e06c6b92dec5a8070302dd9415 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147686 Reviewed-by: Joshua Litt <joshualitt@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
83a2b2e51d
commit
03e504e5fa
@@ -12,7 +12,8 @@ import '../universe/class_hierarchy.dart' show ClassHierarchy;
|
||||
import '../world.dart' show JClosedWorld;
|
||||
|
||||
enum IsTestSpecialization {
|
||||
null_,
|
||||
isNull,
|
||||
notNull,
|
||||
string,
|
||||
bool,
|
||||
num,
|
||||
@@ -27,8 +28,7 @@ class SpecializedChecks {
|
||||
if (dartType is LegacyType) {
|
||||
DartType base = dartType.baseType;
|
||||
// `Never*` accepts only `null`.
|
||||
if (base is NeverType) return IsTestSpecialization.null_;
|
||||
// TODO(sra): Handle strong checking 'x is Object' --> `x != null`.
|
||||
if (base is NeverType) return IsTestSpecialization.isNull;
|
||||
// `Object*` is top and should be handled by constant folding.
|
||||
if (base.isObject) return null;
|
||||
return _findIsTestSpecialization(base, graph, closedWorld);
|
||||
@@ -44,7 +44,7 @@ class SpecializedChecks {
|
||||
|
||||
if (element == commonElements.nullClass ||
|
||||
element == commonElements.jsNullClass) {
|
||||
return IsTestSpecialization.null_;
|
||||
return IsTestSpecialization.isNull;
|
||||
}
|
||||
|
||||
if (element == commonElements.jsStringClass ||
|
||||
@@ -73,6 +73,9 @@ class SpecializedChecks {
|
||||
}
|
||||
|
||||
DartTypes dartTypes = closedWorld.dartTypes;
|
||||
// Top types (here it could be Object in non-NNBD mode) should be constant
|
||||
// folded outside the specializer. This test protects logic below.
|
||||
if (dartTypes.isTopType(dartType)) return null;
|
||||
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
|
||||
if (!dartTypes.isSubtype(
|
||||
elementEnvironment.getClassInstantiationToBounds(element),
|
||||
@@ -84,6 +87,11 @@ class SpecializedChecks {
|
||||
return IsTestSpecialization.arrayTop;
|
||||
}
|
||||
|
||||
if (dartType.isObject) {
|
||||
assert(!dartTypes.isTopType(dartType)); // Checked above.
|
||||
return IsTestSpecialization.notNull;
|
||||
}
|
||||
|
||||
ClassHierarchy classHierarchy = closedWorld.classHierarchy;
|
||||
InterceptorData interceptorData = closedWorld.interceptorData;
|
||||
OutputUnitData outputUnitData = closedWorld.outputUnitData;
|
||||
@@ -92,6 +100,7 @@ class SpecializedChecks {
|
||||
!interceptorData.isInterceptedClass(element) &&
|
||||
outputUnitData.hasOnlyNonDeferredImportPathsToClass(
|
||||
graph.element, element)) {
|
||||
assert(!dartType.isObject); // Checked above.
|
||||
return IsTestSpecialization.instanceof;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3492,9 +3492,10 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
||||
|
||||
js.Expression test;
|
||||
switch (node.specialization) {
|
||||
case IsTestSpecialization.null_:
|
||||
// This case should be lowered to [HIdentity] during optimization.
|
||||
test = js.Binary(relation, value, js.LiteralNull());
|
||||
case IsTestSpecialization.isNull:
|
||||
case IsTestSpecialization.notNull:
|
||||
// These cases should be lowered using [HIdentity] during optimization.
|
||||
failedAt(node, 'Missing lowering');
|
||||
break;
|
||||
|
||||
case IsTestSpecialization.string:
|
||||
|
||||
@@ -2176,12 +2176,17 @@ class SsaInstructionSimplifier extends HBaseVisitor
|
||||
SpecializedChecks.findIsTestSpecialization(
|
||||
dartType, _graph, _closedWorld);
|
||||
|
||||
if (specialization == IsTestSpecialization.null_) {
|
||||
return HIdentity(
|
||||
if (specialization == IsTestSpecialization.isNull ||
|
||||
specialization == IsTestSpecialization.notNull) {
|
||||
HInstruction nullTest = HIdentity(
|
||||
node.checkedInput,
|
||||
_graph.addConstantNull(_closedWorld),
|
||||
null,
|
||||
_abstractValueDomain.boolType);
|
||||
if (specialization == IsTestSpecialization.isNull) return nullTest;
|
||||
nullTest.sourceInformation = node.sourceInformation;
|
||||
node.block.addBefore(node, nullTest);
|
||||
return HNot(nullTest, _abstractValueDomain.boolType);
|
||||
}
|
||||
|
||||
if (specialization != null) {
|
||||
|
||||
Reference in New Issue
Block a user