Move all type mask code to inferrer/typemasks and use it via an AbstractValueStrategy

Change-Id: Ib6f0089b0fee05488fea9295cbb5df944bb29d49
Reviewed-on: https://dart-review.googlesource.com/56980
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Johnni Winther 2018-05-31 16:15:32 +00:00 committed by commit-bot@chromium.org
parent 7ce24328c3
commit b75da964ef
36 changed files with 103 additions and 59 deletions

View file

@ -6,6 +6,8 @@ library dart2js.compiler_base;
import 'dart:async' show Future;
import 'package:front_end/src/fasta/scanner.dart' show StringToken;
import '../compiler_new.dart' as api;
import 'backend_strategy.dart';
import 'common/names.dart' show Selectors;
@ -24,6 +26,7 @@ import 'elements/entities.dart';
import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
import 'environment.dart';
import 'frontend_strategy.dart';
import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
import 'io/source_information.dart' show SourceInformation;
import 'js_backend/backend.dart' show JavaScriptBackend;
import 'kernel/kernel_backend_strategy.dart';
@ -32,7 +35,7 @@ import 'library_loader.dart' show LibraryLoaderTask, LoadedLibraries;
import 'null_compiler_output.dart' show NullCompilerOutput, NullSink;
import 'options.dart' show CompilerOptions, DiagnosticOptions;
import 'ssa/nodes.dart' show HInstruction;
import 'package:front_end/src/fasta/scanner.dart' show StringToken;
import 'types/abstract_value_domain.dart' show AbstractValueStrategy;
import 'types/types.dart' show GlobalTypeInferenceTask;
import 'universe/selector.dart' show Selector;
import 'universe/world_builder.dart'
@ -102,6 +105,8 @@ abstract class Compiler {
JavaScriptBackend backend;
CodegenWorldBuilder _codegenWorldBuilder;
AbstractValueStrategy abstractValueStrategy = const TypeMaskStrategy();
GenericTask selfTask;
/// The constant environment for the frontend interpretation of compile-time
@ -416,7 +421,8 @@ abstract class Compiler {
ClosedWorldRefiner closeResolution(FunctionEntity mainFunction) {
phase = PHASE_DONE_RESOLVING;
ClosedWorld closedWorld = resolutionWorldBuilder.closeWorld();
ClosedWorld closedWorld =
resolutionWorldBuilder.closeWorld(abstractValueStrategy);
OutputUnitData result = deferredLoadTask.run(mainFunction, closedWorld);
ClosedWorldRefiner closedWorldRefiner =
backendStrategy.createClosedWorldRefiner(closedWorld);

View file

@ -17,7 +17,6 @@ import '../js_model/locals.dart' show JumpVisitor;
import '../kernel/element_map.dart';
import '../native/behavior.dart';
import '../options.dart';
import '../types/constants.dart';
import '../types/abstract_value_domain.dart';
import '../types/types.dart';
import '../universe/selector.dart';
@ -615,8 +614,9 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
ConstantSystem constantSystem = _closedWorld.constantSystem;
// The JavaScript backend may turn this literal into a double at
// runtime.
return _types.getConcreteTypeFor(computeTypeMask(
_closedWorld, constantSystem.createIntFromInt(node.value)));
return _types.getConcreteTypeFor(_closedWorld.abstractValueDomain
.computeAbstractValueForConstant(
constantSystem.createIntFromInt(node.value)));
}
@override
@ -624,8 +624,9 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
ConstantSystem constantSystem = _closedWorld.constantSystem;
// The JavaScript backend may turn this literal into an integer at
// runtime.
return _types.getConcreteTypeFor(
computeTypeMask(_closedWorld, constantSystem.createDouble(node.value)));
return _types.getConcreteTypeFor(_closedWorld.abstractValueDomain
.computeAbstractValueForConstant(
constantSystem.createDouble(node.value)));
}
@override

View file

@ -18,7 +18,6 @@ import '../js_emitter/sorter.dart';
import '../native/behavior.dart' as native;
import '../options.dart';
import '../types/abstract_value_domain.dart';
import '../types/constants.dart';
import '../types/types.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
@ -710,7 +709,8 @@ abstract class InferrerEngineImpl<T> extends InferrerEngine<T> {
// Although we might find a better type, we have to keep
// the old type around to ensure that we get a complete view
// of the type graph and do not drop any flow edges.
AbstractValue refinedType = computeTypeMask(closedWorld, value);
AbstractValue refinedType =
abstractValueDomain.computeAbstractValueForConstant(value);
type = new NarrowTypeInformation(
abstractValueDomain, type, refinedType);
types.allocatedTypes.add(type);

View file

@ -4,10 +4,10 @@
library types.constants;
import '../common.dart';
import '../constants/values.dart';
import '../js_backend/js_backend.dart' show SyntheticConstantKind;
import '../world.dart' show ClosedWorld;
import '../../common.dart';
import '../../constants/values.dart';
import '../../js_backend/js_backend.dart' show SyntheticConstantKind;
import '../../world.dart' show ClosedWorld;
import 'masks.dart';
/// Computes the [TypeMask] for the constant [value].

View file

@ -4,18 +4,18 @@
library masks;
import '../common.dart';
import '../common_elements.dart' show CommonElements;
import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../elements/entities.dart';
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
import '../universe/selector.dart' show Selector;
import '../universe/use.dart' show DynamicUse;
import '../universe/world_builder.dart'
import '../../common.dart';
import '../../common_elements.dart' show CommonElements;
import '../../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../../elements/entities.dart';
import '../../types/abstract_value_domain.dart';
import '../../universe/selector.dart' show Selector;
import '../../universe/use.dart' show DynamicUse;
import '../../universe/world_builder.dart'
show UniverseSelectorConstraints, SelectorConstraintsStrategy;
import '../util/util.dart';
import '../world.dart' show ClassQuery, ClosedWorld;
import 'abstract_value_domain.dart';
import '../../util/util.dart';
import '../../world.dart' show ClassQuery, ClosedWorld;
import '../type_graph_inferrer.dart' show TypeGraphInferrer;
import 'constants.dart';
part 'container_type_mask.dart';

View file

@ -59,9 +59,23 @@ class IncreasingTypeMaskSet extends UniverseSelectorConstraints {
}
}
class TypeMaskStrategy implements SelectorConstraintsStrategy {
class TypeMaskStrategy implements AbstractValueStrategy {
const TypeMaskStrategy();
@override
AbstractValueDomain createDomain(ClosedWorld closedWorld) {
return new CommonMasks(closedWorld);
}
@override
SelectorConstraintsStrategy createSelectorStrategy() {
return new TypeMaskSelectorStrategy();
}
}
class TypeMaskSelectorStrategy implements SelectorConstraintsStrategy {
const TypeMaskSelectorStrategy();
@override
UniverseSelectorConstraints createSelectorConstraints(Selector selector) {
return new IncreasingTypeMaskSet();

View file

@ -37,7 +37,6 @@ import '../library_loader.dart' show LoadedLibraries;
import '../native/native.dart' as native;
import '../ssa/ssa.dart' show SsaFunctionCompiler;
import '../tracer.dart';
import '../types/masks.dart' show TypeMaskStrategy;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/class_hierarchy_builder.dart'
show ClassHierarchyBuilder, ClassQueries;
@ -660,7 +659,9 @@ class JavaScriptBackend {
compiler.options,
const TreeShakingEnqueuerStrategy(),
compiler.backendStrategy.createCodegenWorldBuilder(
closedWorld.nativeData, closedWorld, const TypeMaskStrategy()),
closedWorld.nativeData,
closedWorld,
compiler.abstractValueStrategy.createSelectorStrategy()),
compiler.backendStrategy.createCodegenWorkItemBuilder(closedWorld),
new CodegenEnqueuerListener(
elementEnvironment,

View file

@ -39,6 +39,7 @@ import '../kernel/kelements.dart';
import '../native/behavior.dart';
import '../options.dart';
import '../ssa/ssa.dart';
import '../types/abstract_value_domain.dart';
import '../types/types.dart';
import '../universe/class_set.dart';
import '../universe/selector.dart';
@ -80,7 +81,10 @@ class JsBackendStrategy implements KernelBackendStrategy {
_closureDataLookup = new KernelClosureConversionTask(
_compiler.measurer, _elementMap, _globalLocalsMap, _compiler.options);
JsClosedWorldBuilder closedWorldBuilder = new JsClosedWorldBuilder(
_elementMap, _closureDataLookup, _compiler.options);
_elementMap,
_closureDataLookup,
_compiler.options,
_compiler.abstractValueStrategy);
return closedWorldBuilder._convertClosedWorld(
closedWorld, strategy.closureModels);
}
@ -226,9 +230,10 @@ class JsClosedWorldBuilder {
final Map<ClassEntity, ClassSet> _classSets = <ClassEntity, ClassSet>{};
final KernelClosureConversionTask _closureConversionTask;
final CompilerOptions _options;
final AbstractValueStrategy _abstractValueStrategy;
JsClosedWorldBuilder(
this._elementMap, this._closureConversionTask, this._options);
JsClosedWorldBuilder(this._elementMap, this._closureConversionTask,
this._options, this._abstractValueStrategy);
ElementEnvironment get _elementEnvironment => _elementMap.elementEnvironment;
CommonElements get _commonElements => _elementMap.commonElements;
@ -390,7 +395,8 @@ class JsClosedWorldBuilder {
assignedInstanceMembers: assignedInstanceMembers,
processedMembers: processedMembers,
mixinUses: mixinUses,
typesImplementedBySubclasses: typesImplementedBySubclasses);
typesImplementedBySubclasses: typesImplementedBySubclasses,
abstractValueStrategy: _abstractValueStrategy);
}
BackendUsage _convertBackendUsage(
@ -619,7 +625,8 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
Map<ClassEntity, Set<ClassEntity>> mixinUses,
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
Map<ClassEntity, ClassSet> classSets})
Map<ClassEntity, ClassSet> classSets,
AbstractValueStrategy abstractValueStrategy})
: super(
elementEnvironment,
dartTypes,
@ -637,7 +644,8 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
mixinUses,
typesImplementedBySubclasses,
classHierarchyNodes,
classSets);
classSets,
abstractValueStrategy);
@override
void registerClosureClass(ClassEntity cls) {

View file

@ -43,6 +43,7 @@ import '../options.dart';
import '../ordered_typeset.dart';
import '../ssa/kernel_impact.dart';
import '../ssa/type_builder.dart';
import '../types/abstract_value_domain.dart';
import '../universe/class_hierarchy_builder.dart';
import '../universe/class_set.dart';
import '../universe/selector.dart';
@ -2094,7 +2095,8 @@ class KernelClosedWorld extends ClosedWorldBase
Map<ClassEntity, Set<ClassEntity>> mixinUses,
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
Map<ClassEntity, ClassSet> classSets})
Map<ClassEntity, ClassSet> classSets,
AbstractValueStrategy abstractValueStrategy})
: super(
elementEnvironment,
dartTypes,
@ -2112,7 +2114,8 @@ class KernelClosedWorld extends ClosedWorldBase
mixinUses,
typesImplementedBySubclasses,
classHierarchyNodes,
classSets) {
classSets,
abstractValueStrategy) {
computeRtiNeed(resolutionWorldBuilder, rtiNeedBuilder, options);
}

View file

@ -1010,9 +1010,6 @@ abstract class HInstruction implements Spannable {
/// Does this node potentially affect control flow.
bool isControlFlow() => false;
bool isExact(AbstractValueDomain domain) =>
domain.isExactOrNull(instructionType);
bool isValue(AbstractValueDomain domain) =>
domain.isPrimitiveValue(instructionType);

View file

@ -7,9 +7,21 @@ library dart2js.abstract_value_domain;
import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../elements/entities.dart';
import '../universe/selector.dart';
import '../universe/world_builder.dart';
import '../world.dart';
enum AbstractBool { True, False, Maybe }
/// Strategy for the abstraction of runtime values used by the global type
/// inference.
abstract class AbstractValueStrategy {
/// Creates the abstract value domain for [closedWorld].
AbstractValueDomain createDomain(ClosedWorld closedWorld);
/// Creates the [SelectorConstraintsStrategy] used by the backend enqueuer.
SelectorConstraintsStrategy createSelectorStrategy();
}
/// A value in an abstraction of runtime values.
abstract class AbstractValue {}

View file

@ -1025,7 +1025,7 @@ abstract class KernelResolutionWorldBuilderBase
classQueries);
@override
ClosedWorld closeWorld() {
ClosedWorld closeWorld(AbstractValueStrategy abstractValueStrategy) {
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
populateHierarchyNodes();
@ -1061,6 +1061,7 @@ abstract class KernelResolutionWorldBuilderBase
mixinUses: classHierarchyBuilder.mixinUses,
typesImplementedBySubclasses: typesImplementedBySubclasses,
classHierarchyNodes: classHierarchyBuilder.classHierarchyNodes,
classSets: classHierarchyBuilder.classSets);
classSets: classHierarchyBuilder.classSets,
abstractValueStrategy: abstractValueStrategy);
}
}

View file

@ -23,6 +23,7 @@ import '../js_model/elements.dart' show JSignatureMethod;
import '../kernel/element_map_impl.dart';
import '../native/enqueue.dart' show NativeResolutionEnqueuer;
import '../options.dart';
import '../types/abstract_value_domain.dart';
import '../universe/class_set.dart';
import '../util/enumset.dart';
import '../util/util.dart';

View file

@ -23,7 +23,6 @@ import 'js_backend/runtime_types.dart'
import 'ordered_typeset.dart';
import 'options.dart';
import 'types/abstract_value_domain.dart';
import 'types/masks.dart' show CommonMasks;
import 'universe/class_set.dart';
import 'universe/function_set.dart' show FunctionSet;
import 'universe/selector.dart' show Selector;
@ -389,7 +388,7 @@ abstract class ClosedWorldRefiner {
abstract class OpenWorld implements World {
void registerUsedElement(MemberEntity element);
ClosedWorld closeWorld();
ClosedWorld closeWorld(AbstractValueStrategy abstractValueStrategy);
/// Returns an iterable over all mixin applications that mixin [cls].
Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls);
@ -496,11 +495,12 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
this.mixinUses,
this.typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
Map<ClassEntity, ClassSet> classSets)
Map<ClassEntity, ClassSet> classSets,
AbstractValueStrategy abstractValueStrategy)
: this._implementedClasses = implementedClasses,
this._classHierarchyNodes = classHierarchyNodes,
this._classSets = classSets {
_abstractValueDomain = new CommonMasks(this);
_abstractValueDomain = abstractValueStrategy.createDomain(this);
}
@override

View file

@ -6,8 +6,8 @@ import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints;
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/types/types.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
import '../inference/type_mask_test_helper.dart';

View file

@ -6,7 +6,7 @@ import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import '../memory_compiler.dart';
const String TEST = """

View file

@ -7,7 +7,7 @@
import "package:async_helper/async_helper.dart";
import "package:compiler/src/commandline_options.dart";
import "package:compiler/src/constants/values.dart";
import "package:compiler/src/types/masks.dart";
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import "package:expect/expect.dart";
import '../memory_compiler.dart';

View file

@ -9,7 +9,7 @@ import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/types/types.dart';
import 'package:compiler/src/js_model/locals.dart';
import 'package:compiler/src/kernel/element_map.dart';

View file

@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/types/masks.dart' show ContainerTypeMask, TypeMask;
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:expect/expect.dart';
import 'type_mask_test_helper.dart';

View file

@ -8,10 +8,10 @@ import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/types/abstract_value_domain.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;

View file

@ -6,8 +6,8 @@ import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/types/abstract_value_domain.dart';
import 'package:compiler/src/types/masks.dart' show MapTypeMask, TypeMask;
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';

View file

@ -7,7 +7,7 @@ import 'package:expect/expect.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/world.dart';
import 'type_mask_test_helper.dart';
import '../memory_compiler.dart';

View file

@ -8,7 +8,7 @@ import 'dart:async';
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
import '../type_test_helper.dart';

View file

@ -7,7 +7,7 @@ import 'package:expect/expect.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/world.dart';
import '../memory_compiler.dart';

View file

@ -4,7 +4,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';

View file

@ -4,7 +4,7 @@
library type_mask_test_helper;
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
export 'package:compiler/src/types/types.dart';

View file

@ -4,7 +4,7 @@
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
import "package:compiler/src/types/masks.dart";
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import "package:compiler/src/world.dart";
import '../type_test_helper.dart';

View file

@ -13,7 +13,7 @@ import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/enqueue.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:compiler/src/universe/world_impact.dart';

View file

@ -5,7 +5,7 @@
import 'dart:async';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/inferrer/typemasks/masks.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';