Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Unified Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 2777163002: Make codegen and optimizations depend more directly on data objects. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/ssa/optimize.dart
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 1810ecb442964c292cc8a8bed9091429c2761a68..eca5c22108adaf21d691c0ec86b4d8150e3d3e0a 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -16,7 +16,10 @@ import '../elements/resolution_types.dart';
import '../js/js.dart' as js;
import '../js_backend/backend_helpers.dart' show BackendHelpers;
import '../js_backend/js_backend.dart';
+import '../js_backend/interceptor_data.dart' show InterceptorData;
+import '../js_backend/native_data.dart' show NativeData;
import '../native/native.dart' as native;
+import '../options.dart';
import '../tree/dartstring.dart' as ast;
import '../types/types.dart';
import '../universe/selector.dart' show Selector;
@@ -36,26 +39,34 @@ abstract class OptimizationPhase {
}
class SsaOptimizerTask extends CompilerTask {
- final JavaScriptBackend backend;
+ final JavaScriptBackend _backend;
Map<HInstruction, Range> ranges = <HInstruction, Range>{};
- SsaOptimizerTask(JavaScriptBackend backend)
- : this.backend = backend,
- super(backend.compiler.measurer);
+ SsaOptimizerTask(this._backend) : super(_backend.compiler.measurer);
String get name => 'SSA optimizer';
- Compiler get compiler => backend.compiler;
+ Compiler get _compiler => _backend.compiler;
+
+ GlobalTypeInferenceResults get _results => _compiler.globalInference.results;
+
+ BackendHelpers get _helpers => _backend.helpers;
+
+ CompilerOptions get _options => _compiler.options;
+
+ RuntimeTypesSubstitutions get _rtiSubstitutions => _backend.rtiSubstitutions;
+
+ InterceptorData get _interceptorData => _backend.interceptorData;
void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
void runPhase(OptimizationPhase phase) {
measureSubtask(phase.name, () => phase.visitGraph(graph));
- backend.tracer.traceGraph(phase.name, graph);
+ _backend.tracer.traceGraph(phase.name, graph);
assert(graph.isValid());
}
- bool trustPrimitives = compiler.options.trustPrimitives;
+ bool trustPrimitives = _options.trustPrimitives;
CodegenRegistry registry = work.registry;
Set<HInstruction> boundsChecked = new Set<HInstruction>();
SsaCodeMotion codeMotion;
@@ -64,51 +75,55 @@ class SsaOptimizerTask extends CompilerTask {
List<OptimizationPhase> phases = <OptimizationPhase>[
// Run trivial instruction simplification first to optimize
// some patterns useful for type conversion.
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
new SsaTypeConversionInserter(closedWorld),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
- new SsaTypePropagator(compiler, closedWorld),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
// After type propagation, more instructions can be
// simplified.
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
new SsaCheckInserter(
- trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ trustPrimitives, _helpers, closedWorld, boundsChecked),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
new SsaCheckInserter(
- trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaTypePropagator(compiler, closedWorld),
+ trustPrimitives, _helpers, closedWorld, boundsChecked),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
// Run a dead code eliminator before LICM because dead
// interceptors are often in the way of LICM'able instructions.
new SsaDeadCodeEliminator(closedWorld, this),
new SsaGlobalValueNumberer(),
// After GVN, some instructions might need their type to be
// updated because they now have different inputs.
- new SsaTypePropagator(compiler, closedWorld),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
codeMotion = new SsaCodeMotion(),
loadElimination =
- new SsaLoadElimination(backend, compiler, closedWorld),
+ new SsaLoadElimination(_helpers, _compiler, closedWorld),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
// After GVN and load elimination the same value may be used in code
// controlled by a test on the value, so redo 'conversion insertion' to
// learn from the refined type.
new SsaTypeConversionInserter(closedWorld),
- new SsaTypePropagator(compiler, closedWorld),
- new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
+ new SsaValueRangeAnalyzer(_helpers, closedWorld, this),
// Previous optimizations may have generated new
// opportunities for instruction simplification.
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
new SsaCheckInserter(
- trustPrimitives, backend, closedWorld, boundsChecked),
+ trustPrimitives, _helpers, closedWorld, boundsChecked),
];
phases.forEach(runPhase);
// Simplifying interceptors is not strictly just an optimization, it is
// required for implementation correctness because the code generator
// assumes it is always performed.
- runPhase(new SsaSimplifyInterceptors(
- compiler, closedWorld, work.element.enclosingClass));
+ runPhase(new SsaSimplifyInterceptors(closedWorld, _helpers,
+ _interceptorData, work.element.enclosingClass));
SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
runPhase(dce);
@@ -116,23 +131,25 @@ class SsaOptimizerTask extends CompilerTask {
dce.eliminatedSideEffects ||
loadElimination.newGvnCandidates) {
phases = <OptimizationPhase>[
- new SsaTypePropagator(compiler, closedWorld),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
new SsaGlobalValueNumberer(),
new SsaCodeMotion(),
- new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ new SsaValueRangeAnalyzer(_helpers, closedWorld, this),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
new SsaCheckInserter(
- trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaSimplifyInterceptors(
- compiler, closedWorld, work.element.enclosingClass),
+ trustPrimitives, _helpers, closedWorld, boundsChecked),
+ new SsaSimplifyInterceptors(closedWorld, _helpers, _interceptorData,
+ work.element.enclosingClass),
new SsaDeadCodeEliminator(closedWorld, this),
];
} else {
phases = <OptimizationPhase>[
- new SsaTypePropagator(compiler, closedWorld),
+ new SsaTypePropagator(_results, _options, _helpers, closedWorld),
// Run the simplifier to remove unneeded type checks inserted by
// type propagation.
- new SsaInstructionSimplifier(backend, closedWorld, this, registry),
+ new SsaInstructionSimplifier(_results, _options, _helpers,
+ _rtiSubstitutions, closedWorld, registry),
];
}
phases.forEach(runPhase);
@@ -171,27 +188,25 @@ class SsaInstructionSimplifier extends HBaseVisitor
static const MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH = 512;
final String name = "SsaInstructionSimplifier";
- final JavaScriptBackend backend;
- final ClosedWorld closedWorld;
- final CodegenRegistry registry;
- HGraph graph;
- Compiler get compiler => backend.compiler;
- final SsaOptimizerTask optimizer;
+ final GlobalTypeInferenceResults _globalInferenceResults;
+ final CompilerOptions _options;
+ final BackendHelpers _helpers;
+ final RuntimeTypesSubstitutions _rtiSubstitutions;
+ final ClosedWorld _closedWorld;
+ final CodegenRegistry _registry;
+ HGraph _graph;
- SsaInstructionSimplifier(
- this.backend, this.closedWorld, this.optimizer, this.registry);
+ SsaInstructionSimplifier(this._globalInferenceResults, this._options,
+ this._helpers, this._rtiSubstitutions, this._closedWorld, this._registry);
- CommonElements get commonElements => closedWorld.commonElements;
+ CommonElements get commonElements => _closedWorld.commonElements;
- BackendHelpers get helpers => backend.helpers;
+ ConstantSystem get constantSystem => _closedWorld.constantSystem;
- ConstantSystem get constantSystem => closedWorld.constantSystem;
-
- GlobalTypeInferenceResults get globalInferenceResults =>
- compiler.globalInference.results;
+ NativeData get _nativeData => _closedWorld.nativeData;
void visitGraph(HGraph visitee) {
- graph = visitee;
+ _graph = visitee;
visitDominatorTree(visitee);
}
@@ -208,12 +223,12 @@ class SsaInstructionSimplifier extends HBaseVisitor
// might be that an operation thought to return double, can be
// simplified to an int. For example:
// `2.5 * 10`.
- if (!(replacement.isNumberOrNull(closedWorld) &&
- instruction.isNumberOrNull(closedWorld))) {
+ if (!(replacement.isNumberOrNull(_closedWorld) &&
+ instruction.isNumberOrNull(_closedWorld))) {
// If we can replace [instruction] with [replacement], then
// [replacement]'s type can be narrowed.
TypeMask newType = replacement.instructionType
- .intersection(instruction.instructionType, closedWorld);
+ .intersection(instruction.instructionType, _closedWorld);
replacement.instructionType = newType;
}
@@ -260,7 +275,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (node.usedBy.isEmpty) return;
ConstantValue value = getConstantFromType(node);
if (value != null) {
- HConstant constant = graph.addConstant(value, closedWorld);
+ HConstant constant = _graph.addConstant(value, _closedWorld);
for (HInstruction user in node.usedBy.toList()) {
user.changeUse(node, constant);
}
@@ -296,7 +311,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
List<HInstruction> inputs = node.inputs;
assert(inputs.length == 1);
HInstruction input = inputs[0];
- if (input.isBoolean(closedWorld)) return input;
+ if (input.isBoolean(_closedWorld)) return input;
// If the code is unreachable, remove the HBoolify. This can happen when
// there is a throw expression in a short-circuit conditional. Removing the
@@ -306,8 +321,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
// All values that cannot be 'true' are boolified to false.
TypeMask mask = input.instructionType;
- if (!mask.contains(helpers.jsBoolClass, closedWorld)) {
- return graph.addConstantBool(false, closedWorld);
+ if (!mask.contains(_helpers.jsBoolClass, _closedWorld)) {
+ return _graph.addConstantBool(false, _closedWorld);
}
return node;
}
@@ -319,7 +334,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (input is HConstant) {
HConstant constant = input;
bool isTrue = constant.constant.isTrue;
- return graph.addConstantBool(!isTrue, closedWorld);
+ return _graph.addConstantBool(!isTrue, _closedWorld);
} else if (input is HNot) {
return input.inputs[0];
}
@@ -336,33 +351,34 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (operand is HConstant) {
HConstant receiver = operand;
ConstantValue folded = operation.fold(receiver.constant);
- if (folded != null) return graph.addConstant(folded, closedWorld);
+ if (folded != null) return _graph.addConstant(folded, _closedWorld);
}
return null;
}
HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) {
HInstruction actualReceiver = node.inputs[1];
- if (actualReceiver.isIndexablePrimitive(closedWorld)) {
+ if (actualReceiver.isIndexablePrimitive(_closedWorld)) {
if (actualReceiver.isConstantString()) {
HConstant constantInput = actualReceiver;
StringConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, closedWorld);
+ return _graph.addConstantInt(constant.length, _closedWorld);
} else if (actualReceiver.isConstantList()) {
HConstant constantInput = actualReceiver;
ListConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, closedWorld);
+ return _graph.addConstantInt(constant.length, _closedWorld);
}
- bool isFixed = isFixedLength(actualReceiver.instructionType, closedWorld);
+ bool isFixed =
+ isFixedLength(actualReceiver.instructionType, _closedWorld);
TypeMask actualType = node.instructionType;
- TypeMask resultType = closedWorld.commonMasks.positiveIntType;
+ TypeMask resultType = _closedWorld.commonMasks.positiveIntType;
// If we already have computed a more specific type, keep that type.
if (HInstruction.isInstanceOf(
- actualType, helpers.jsUInt31Class, closedWorld)) {
- resultType = closedWorld.commonMasks.uint31Type;
+ actualType, _helpers.jsUInt31Class, _closedWorld)) {
+ resultType = _closedWorld.commonMasks.uint31Type;
} else if (HInstruction.isInstanceOf(
- actualType, helpers.jsUInt32Class, closedWorld)) {
- resultType = closedWorld.commonMasks.uint32Type;
+ actualType, _helpers.jsUInt32Class, _closedWorld)) {
+ resultType = _closedWorld.commonMasks.uint32Type;
}
HGetLength result =
new HGetLength(actualReceiver, resultType, isAssignable: !isFixed);
@@ -370,7 +386,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
} else if (actualReceiver.isConstantMap()) {
HConstant constantInput = actualReceiver;
MapConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, closedWorld);
+ return _graph.addConstantInt(constant.length, _closedWorld);
}
return null;
}
@@ -386,8 +402,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
// Try converting the instruction to a builtin instruction.
- HInstruction instruction =
- node.specializer.tryConvertToBuiltin(node, compiler, closedWorld);
+ HInstruction instruction = node.specializer.tryConvertToBuiltin(
+ node, _globalInferenceResults, _options, _helpers, _closedWorld);
if (instruction != null) return instruction;
Selector selector = node.selector;
@@ -396,36 +412,36 @@ class SsaInstructionSimplifier extends HBaseVisitor
bool applies(MemberEntity element) {
return selector.applies(element) &&
- (mask == null || mask.canHit(element, selector, closedWorld));
+ (mask == null || mask.canHit(element, selector, _closedWorld));
}
if (selector.isCall || selector.isOperator) {
FunctionEntity target;
- if (input.isExtendableArray(closedWorld)) {
- if (applies(helpers.jsArrayRemoveLast)) {
- target = helpers.jsArrayRemoveLast;
- } else if (applies(helpers.jsArrayAdd)) {
+ if (input.isExtendableArray(_closedWorld)) {
+ if (applies(_helpers.jsArrayRemoveLast)) {
+ target = _helpers.jsArrayRemoveLast;
+ } else if (applies(_helpers.jsArrayAdd)) {
// The codegen special cases array calls, but does not
// inline argument type checks.
- if (!compiler.options.enableTypeAssertions) {
- target = helpers.jsArrayAdd;
+ if (!_options.enableTypeAssertions) {
+ target = _helpers.jsArrayAdd;
}
}
- } else if (input.isStringOrNull(closedWorld)) {
- if (applies(helpers.jsStringSplit)) {
+ } else if (input.isStringOrNull(_closedWorld)) {
+ if (applies(_helpers.jsStringSplit)) {
HInstruction argument = node.inputs[2];
- if (argument.isString(closedWorld)) {
- target = helpers.jsStringSplit;
+ if (argument.isString(_closedWorld)) {
+ target = _helpers.jsStringSplit;
}
- } else if (applies(helpers.jsStringOperatorAdd)) {
+ } else if (applies(_helpers.jsStringOperatorAdd)) {
// `operator+` is turned into a JavaScript '+' so we need to
// make sure the receiver and the argument are not null.
// TODO(sra): Do this via [node.specializer].
HInstruction argument = node.inputs[2];
- if (argument.isString(closedWorld) && !input.canBeNull()) {
+ if (argument.isString(_closedWorld) && !input.canBeNull()) {
return new HStringConcat(input, argument, node.instructionType);
}
- } else if (applies(helpers.jsStringToString) && !input.canBeNull()) {
+ } else if (applies(_helpers.jsStringToString) && !input.canBeNull()) {
return input;
}
}
@@ -444,7 +460,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return result;
}
} else if (selector.isGetter) {
- if (selector.applies(helpers.jsIndexableLength)) {
+ if (selector.applies(_helpers.jsIndexableLength)) {
HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
if (optimized != null) return optimized;
}
@@ -460,9 +476,9 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (folded != node) return folded;
}
- TypeMask receiverType = node.getDartReceiver(closedWorld).instructionType;
+ TypeMask receiverType = node.getDartReceiver(_closedWorld).instructionType;
MemberEntity element =
- closedWorld.locateSingleElement(node.selector, receiverType);
+ _closedWorld.locateSingleElement(node.selector, receiverType);
// TODO(ngeoffray): Also fold if it's a getter or variable.
if (element != null &&
element.isFunction
@@ -472,7 +488,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
node.selector.applies(element)) {
MethodElement method = element;
- if (backend.nativeData.isNativeMember(method)) {
+ if (_nativeData.isNativeMember(method)) {
HInstruction folded = tryInlineNativeMethod(node, method);
if (folded != null) return folded;
} else {
@@ -498,11 +514,11 @@ class SsaInstructionSimplifier extends HBaseVisitor
element.isField &&
element.name == node.selector.name) {
FieldEntity field = element;
- if (!backend.nativeData.isNativeMember(field) &&
- !node.isCallOnInterceptor(closedWorld)) {
- HInstruction receiver = node.getDartReceiver(closedWorld);
+ if (!_nativeData.isNativeMember(field) &&
+ !node.isCallOnInterceptor(_closedWorld)) {
+ HInstruction receiver = node.getDartReceiver(_closedWorld);
TypeMask type = TypeMaskFactory.inferredTypeForElement(
- field as Entity, globalInferenceResults);
+ field as Entity, _globalInferenceResults);
HInstruction load = new HFieldGet(field, receiver, type);
node.block.addBefore(node, load);
Selector callSelector = new Selector.callClosureFrom(node.selector);
@@ -548,7 +564,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
List<HInstruction> inputs = node.inputs.sublist(1);
bool canInline = true;
- if (compiler.options.enableTypeAssertions && inputs.length > 1) {
+ if (_options.enableTypeAssertions && inputs.length > 1) {
// TODO(sra): Check if [input] is guaranteed to pass the parameter
// type check. Consider using a strengthened type check to avoid
// passing `null` to primitive types since the native methods usually
@@ -574,9 +590,9 @@ class SsaInstructionSimplifier extends HBaseVisitor
// Strengthen instruction type from annotations to help optimize
// dependent instructions.
native.NativeBehavior nativeBehavior =
- backend.nativeData.getNativeMethodBehavior(method);
+ _nativeData.getNativeMethodBehavior(method);
TypeMask returnType =
- TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
+ TypeMaskFactory.fromNativeBehavior(nativeBehavior, _closedWorld);
HInvokeDynamicMethod result =
new HInvokeDynamicMethod(node.selector, node.mask, inputs, returnType);
result.element = method;
@@ -585,7 +601,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction visitBoundsCheck(HBoundsCheck node) {
HInstruction index = node.index;
- if (index.isInteger(closedWorld)) return node;
+ if (index.isInteger(_closedWorld)) return node;
if (index.isConstant()) {
HConstant constantInstruction = index;
assert(!constantInstruction.constant.isInt);
@@ -603,7 +619,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HConstant op1 = left;
HConstant op2 = right;
ConstantValue folded = operation.fold(op1.constant, op2.constant);
- if (folded != null) return graph.addConstant(folded, closedWorld);
+ if (folded != null) return _graph.addConstant(folded, _closedWorld);
}
return null;
}
@@ -613,7 +629,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction right = node.right;
// We can only perform this rewriting on Integer, as it is not
// valid for -0.0.
- if (left.isInteger(closedWorld) && right.isInteger(closedWorld)) {
+ if (left.isInteger(_closedWorld) && right.isInteger(_closedWorld)) {
if (left is HConstant && left.constant.isZero) return right;
if (right is HConstant && right.constant.isZero) return left;
}
@@ -623,7 +639,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction visitMultiply(HMultiply node) {
HInstruction left = node.left;
HInstruction right = node.right;
- if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) {
+ if (left.isNumber(_closedWorld) && right.isNumber(_closedWorld)) {
if (left is HConstant && left.constant.isOne) return right;
if (right is HConstant && right.constant.isOne) return left;
}
@@ -664,14 +680,14 @@ class SsaInstructionSimplifier extends HBaseVisitor
TypeMask leftType = left.instructionType;
TypeMask rightType = right.instructionType;
- HInstruction makeTrue() => graph.addConstantBool(true, closedWorld);
- HInstruction makeFalse() => graph.addConstantBool(false, closedWorld);
+ HInstruction makeTrue() => _graph.addConstantBool(true, _closedWorld);
+ HInstruction makeFalse() => _graph.addConstantBool(false, _closedWorld);
// Intersection of int and double return conflicting, so
// we don't optimize on numbers to preserve the runtime semantics.
- if (!(left.isNumberOrNull(closedWorld) &&
- right.isNumberOrNull(closedWorld))) {
- if (leftType.isDisjoint(rightType, closedWorld)) {
+ if (!(left.isNumberOrNull(_closedWorld) &&
+ right.isNumberOrNull(_closedWorld))) {
+ if (leftType.isDisjoint(rightType, _closedWorld)) {
return makeFalse();
}
}
@@ -684,15 +700,15 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (constant.constant.isTrue) {
return input;
} else {
- return new HNot(input, closedWorld.commonMasks.boolType);
+ return new HNot(input, _closedWorld.commonMasks.boolType);
}
}
- if (left.isConstantBoolean() && right.isBoolean(closedWorld)) {
+ if (left.isConstantBoolean() && right.isBoolean(_closedWorld)) {
return compareConstant(left, right);
}
- if (right.isConstantBoolean() && left.isBoolean(closedWorld)) {
+ if (right.isConstantBoolean() && left.isBoolean(_closedWorld)) {
return compareConstant(right, left);
}
@@ -701,8 +717,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
// dart2js runtime has not always been consistent with the Dart
// specification (section 16.0.1), which makes distinctions on NaNs and
// -0.0 that are hard to implement efficiently.
- if (left.isIntegerOrNull(closedWorld)) return makeTrue();
- if (!left.canBePrimitiveNumber(closedWorld)) return makeTrue();
+ if (left.isIntegerOrNull(_closedWorld)) return makeTrue();
+ if (!left.canBePrimitiveNumber(_closedWorld)) return makeTrue();
}
return null;
@@ -716,7 +732,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
void simplifyCondition(
HBasicBlock block, HInstruction condition, bool value) {
condition.dominatedUsers(block.first).forEach((user) {
- HInstruction newCondition = graph.addConstantBool(value, closedWorld);
+ HInstruction newCondition = _graph.addConstantBool(value, _closedWorld);
user.changeUse(condition, newCondition);
});
}
@@ -758,44 +774,44 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
if (type.isObject || type.treatAsDynamic) {
- return graph.addConstantBool(true, closedWorld);
+ return _graph.addConstantBool(true, _closedWorld);
}
ResolutionInterfaceType interfaceType = type;
ClassEntity element = interfaceType.element;
HInstruction expression = node.expression;
- if (expression.isInteger(closedWorld)) {
+ if (expression.isInteger(_closedWorld)) {
if (element == commonElements.intClass ||
element == commonElements.numClass ||
commonElements.isNumberOrStringSupertype(element)) {
- return graph.addConstantBool(true, closedWorld);
+ return _graph.addConstantBool(true, _closedWorld);
} else if (element == commonElements.doubleClass) {
// We let the JS semantics decide for that check. Currently
// the code we emit will always return true.
return node;
} else {
- return graph.addConstantBool(false, closedWorld);
+ return _graph.addConstantBool(false, _closedWorld);
}
- } else if (expression.isDouble(closedWorld)) {
+ } else if (expression.isDouble(_closedWorld)) {
if (element == commonElements.doubleClass ||
element == commonElements.numClass ||
commonElements.isNumberOrStringSupertype(element)) {
- return graph.addConstantBool(true, closedWorld);
+ return _graph.addConstantBool(true, _closedWorld);
} else if (element == commonElements.intClass) {
// We let the JS semantics decide for that check. Currently
// the code we emit will return true for a double that can be
// represented as a 31-bit integer and for -0.0.
return node;
} else {
- return graph.addConstantBool(false, closedWorld);
+ return _graph.addConstantBool(false, _closedWorld);
}
- } else if (expression.isNumber(closedWorld)) {
+ } else if (expression.isNumber(_closedWorld)) {
if (element == commonElements.numClass) {
- return graph.addConstantBool(true, closedWorld);
+ return _graph.addConstantBool(true, _closedWorld);
} else {
// We cannot just return false, because the expression may be of
// type int or double.
}
- } else if (expression.canBePrimitiveNumber(closedWorld) &&
+ } else if (expression.canBePrimitiveNumber(_closedWorld) &&
element == commonElements.intClass) {
// We let the JS semantics decide for that check.
return node;
@@ -805,14 +821,14 @@ class SsaInstructionSimplifier extends HBaseVisitor
// raw type.
} else if (!RuntimeTypesSubstitutions.hasTypeArguments(type)) {
TypeMask expressionMask = expression.instructionType;
- assert(TypeMask.assertIsNormalized(expressionMask, closedWorld));
+ assert(TypeMask.assertIsNormalized(expressionMask, _closedWorld));
TypeMask typeMask = (element == commonElements.nullClass)
- ? new TypeMask.subtype(element, closedWorld)
- : new TypeMask.nonNullSubtype(element, closedWorld);
- if (expressionMask.union(typeMask, closedWorld) == typeMask) {
- return graph.addConstantBool(true, closedWorld);
- } else if (expressionMask.isDisjoint(typeMask, closedWorld)) {
- return graph.addConstantBool(false, closedWorld);
+ ? new TypeMask.subtype(element, _closedWorld)
+ : new TypeMask.nonNullSubtype(element, _closedWorld);
+ if (expressionMask.union(typeMask, _closedWorld) == typeMask) {
+ return _graph.addConstantBool(true, _closedWorld);
+ } else if (expressionMask.isDisjoint(typeMask, _closedWorld)) {
+ return _graph.addConstantBool(false, _closedWorld);
}
}
return node;
@@ -856,10 +872,10 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
HInstruction removeIfCheckAlwaysSucceeds(HCheck node, TypeMask checkedType) {
- if (checkedType.containsAll(closedWorld)) return node;
+ if (checkedType.containsAll(_closedWorld)) return node;
HInstruction input = node.checkedInput;
TypeMask inputType = input.instructionType;
- return inputType.isInMask(checkedType, closedWorld) ? input : node;
+ return inputType.isInMask(checkedType, _closedWorld) ? input : node;
}
HInstruction removeCheck(HCheck node) => node.checkedInput;
@@ -867,7 +883,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
FieldEntity findConcreteFieldForDynamicAccess(
HInstruction receiver, Selector selector) {
TypeMask receiverType = receiver.instructionType;
- return closedWorld.locateSingleField(selector, receiverType);
+ return _closedWorld.locateSingleField(selector, receiverType);
}
HInstruction visitFieldGet(HFieldGet node) {
@@ -883,7 +899,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
Map<FieldEntity, ConstantValue> fields = constructedConstant.fields;
ConstantValue value = fields[node.element];
if (value != null) {
- return graph.addConstant(value, closedWorld);
+ return _graph.addConstant(value, _closedWorld);
}
}
}
@@ -893,20 +909,21 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction visitGetLength(HGetLength node) {
var receiver = node.receiver;
- if (graph.allocatedFixedLists.contains(receiver)) {
+ if (_graph.allocatedFixedLists.contains(receiver)) {
// TODO(ngeoffray): checking if the second input is an integer
// should not be necessary but it currently makes it easier for
// other optimizations to reason about a fixed length constructor
// that we know takes an int.
- if (receiver.inputs[0].isInteger(closedWorld)) {
+ if (receiver.inputs[0].isInteger(_closedWorld)) {
return receiver.inputs[0];
}
} else if (receiver.isConstantList() || receiver.isConstantString()) {
- return graph.addConstantInt(receiver.constant.length, closedWorld);
+ return _graph.addConstantInt(receiver.constant.length, _closedWorld);
} else {
var type = receiver.instructionType;
if (type.isContainer && type.length != null) {
- HInstruction constant = graph.addConstantInt(type.length, closedWorld);
+ HInstruction constant =
+ _graph.addConstantInt(type.length, _closedWorld);
if (type.isNullable) {
// If the container can be null, we update all uses of the length
// access to use the constant instead, but keep the length access in
@@ -920,7 +937,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
if (node.isAssignable &&
- isFixedLength(receiver.instructionType, closedWorld)) {
+ isFixedLength(receiver.instructionType, _closedWorld)) {
// The input type has changed to fixed-length so change to an unassignable
// HGetLength to allow more GVN optimizations.
return new HGetLength(receiver, node.instructionType,
@@ -936,7 +953,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
instruction = node.index;
int index = instruction.constant.primitiveValue;
if (index >= 0 && index < entries.length) {
- return graph.addConstant(entries[index], closedWorld);
+ return _graph.addConstant(entries[index], _closedWorld);
}
}
return node;
@@ -948,13 +965,13 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction folded = handleInterceptedCall(node);
if (folded != node) return folded;
}
- HInstruction receiver = node.getDartReceiver(closedWorld);
+ HInstruction receiver = node.getDartReceiver(_closedWorld);
FieldEntity field =
findConcreteFieldForDynamicAccess(receiver, node.selector);
if (field != null) return directFieldGet(receiver, field);
if (node.element == null) {
- MemberEntity element = closedWorld.locateSingleElement(
+ MemberEntity element = _closedWorld.locateSingleElement(
node.selector, receiver.instructionType);
if (element != null && element.name == node.selector.name) {
node.element = element;
@@ -970,15 +987,15 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
HInstruction directFieldGet(HInstruction receiver, FieldEntity field) {
- bool isAssignable = !closedWorld.fieldNeverChanges(field);
+ bool isAssignable = !_closedWorld.fieldNeverChanges(field);
TypeMask type;
- if (backend.nativeData.isNativeClass(field.enclosingClass)) {
+ if (_nativeData.isNativeClass(field.enclosingClass)) {
type = TypeMaskFactory.fromNativeBehavior(
- backend.nativeData.getNativeFieldLoadBehavior(field), closedWorld);
+ _nativeData.getNativeFieldLoadBehavior(field), _closedWorld);
} else {
type = TypeMaskFactory.inferredTypeForElement(
- field as Entity, globalInferenceResults);
+ field as Entity, _globalInferenceResults);
}
return new HFieldGet(field, receiver, type, isAssignable: isAssignable);
@@ -990,14 +1007,14 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (folded != node) return folded;
}
- HInstruction receiver = node.getDartReceiver(closedWorld);
+ HInstruction receiver = node.getDartReceiver(_closedWorld);
FieldElement field =
findConcreteFieldForDynamicAccess(receiver, node.selector);
if (field == null || !field.isAssignable) return node;
// Use `node.inputs.last` in case the call follows the interceptor calling
// convention, but is not a call on an interceptor.
HInstruction value = node.inputs.last;
- if (compiler.options.enableTypeAssertions) {
+ if (_options.enableTypeAssertions) {
ResolutionDartType type = field.type;
if (!type.treatAsRaw ||
type.isTypeVariable ||
@@ -1009,7 +1026,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return node;
}
HInstruction other = value.convertType(
- closedWorld, type, HTypeConversion.CHECKED_MODE_CHECK);
+ _closedWorld, type, HTypeConversion.CHECKED_MODE_CHECK);
if (other != value) {
node.block.addBefore(node, other);
value = other;
@@ -1022,13 +1039,13 @@ class SsaInstructionSimplifier extends HBaseVisitor
propagateConstantValueToUses(node);
MemberEntity element = node.element;
- if (element == compiler.commonElements.identicalFunction) {
+ if (element == commonElements.identicalFunction) {
if (node.inputs.length == 2) {
return new HIdentity(node.inputs[0], node.inputs[1], null,
- closedWorld.commonMasks.boolType)
+ _closedWorld.commonMasks.boolType)
..sourceInformation = node.sourceInformation;
}
- } else if (element == backend.helpers.checkConcurrentModificationError) {
+ } else if (element == _helpers.checkConcurrentModificationError) {
if (node.inputs.length == 2) {
HInstruction firstArgument = node.inputs[0];
if (firstArgument is HConstant) {
@@ -1036,20 +1053,20 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (constant.constant.isTrue) return constant;
}
}
- } else if (element == backend.helpers.checkInt) {
+ } else if (element == _helpers.checkInt) {
if (node.inputs.length == 1) {
HInstruction argument = node.inputs[0];
- if (argument.isInteger(closedWorld)) return argument;
+ if (argument.isInteger(_closedWorld)) return argument;
}
- } else if (element == backend.helpers.checkNum) {
+ } else if (element == _helpers.checkNum) {
if (node.inputs.length == 1) {
HInstruction argument = node.inputs[0];
- if (argument.isNumber(closedWorld)) return argument;
+ if (argument.isNumber(_closedWorld)) return argument;
}
- } else if (element == backend.helpers.checkString) {
+ } else if (element == _helpers.checkString) {
if (node.inputs.length == 1) {
HInstruction argument = node.inputs[0];
- if (argument.isString(closedWorld)) return argument;
+ if (argument.isString(_closedWorld)) return argument;
}
}
return node;
@@ -1094,18 +1111,18 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (node.usedBy.length > 1) return node;
}
- HInstruction folded = graph.addConstant(
+ HInstruction folded = _graph.addConstant(
constantSystem.createString(new ast.DartString.concat(
leftString.primitiveValue, rightString.primitiveValue)),
- closedWorld);
+ _closedWorld);
if (prefix == null) return folded;
return new HStringConcat(
- prefix, folded, closedWorld.commonMasks.stringType);
+ prefix, folded, _closedWorld.commonMasks.stringType);
}
HInstruction visitStringify(HStringify node) {
HInstruction input = node.inputs[0];
- if (input.isString(closedWorld)) return input;
+ if (input.isString(_closedWorld)) return input;
HInstruction tryConstant() {
if (!input.isConstant()) return null;
@@ -1120,8 +1137,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (!intConstant.isUInt32()) return null;
}
PrimitiveConstantValue primitive = constant.constant;
- return graph.addConstant(
- constantSystem.createString(primitive.toDartString()), closedWorld);
+ return _graph.addConstant(
+ constantSystem.createString(primitive.toDartString()), _closedWorld);
}
HInstruction tryToString() {
@@ -1129,16 +1146,17 @@ class SsaInstructionSimplifier extends HBaseVisitor
// it directly. Keep the stringifier for primitives (since they have fast
// path code in the stringifier) and for classes requiring interceptors
// (since SsaInstructionSimplifier runs after SsaSimplifyInterceptors).
- if (input.canBePrimitive(closedWorld)) return null;
+ if (input.canBePrimitive(_closedWorld)) return null;
if (input.canBeNull()) return null;
Selector selector = Selectors.toString_;
TypeMask toStringType = TypeMaskFactory.inferredTypeForSelector(
- selector, input.instructionType, globalInferenceResults);
- if (!toStringType.containsOnlyString(closedWorld)) return null;
+ selector, input.instructionType, _globalInferenceResults);
+ if (!toStringType.containsOnlyString(_closedWorld)) return null;
// All intercepted classes extend `Interceptor`, so if the receiver can't
// be a class extending `Interceptor` then it can be called directly.
- if (new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, closedWorld)
- .isDisjoint(input.instructionType, closedWorld)) {
+ if (new TypeMask.nonNullSubclass(
+ _helpers.jsInterceptorClass, _closedWorld)
+ .isDisjoint(input.instructionType, _closedWorld)) {
var inputs = <HInstruction>[input, input]; // [interceptor, receiver].
HInstruction result = new HInvokeDynamicMethod(
selector,
@@ -1158,10 +1176,10 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
bool needsSubstitutionForTypeVariableAccess(ClassEntity cls) {
- if (closedWorld.isUsedAsMixin(cls)) return true;
+ if (_closedWorld.isUsedAsMixin(cls)) return true;
- return closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) {
- return !backend.rtiSubstitutions.isTrivialSubstitution(subclass, cls);
+ return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) {
+ return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
});
}
@@ -1210,7 +1228,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
if (source == null) return null;
- return new HTypeInfoReadRaw(source, closedWorld.commonMasks.dynamicType);
+ return new HTypeInfoReadRaw(source, _closedWorld.commonMasks.dynamicType);
}
// TODO(sra): Consider fusing type expression trees with no type variables,
@@ -1233,7 +1251,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
TypeInfoExpressionKind.COMPLETE,
typeArgument,
const <HInstruction>[],
- closedWorld.commonMasks.dynamicType);
+ _closedWorld.commonMasks.dynamicType);
return replacement;
}
return node;
@@ -1263,7 +1281,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
TypeInfoExpressionKind.COMPLETE,
type,
arguments,
- closedWorld.commonMasks.dynamicType);
+ _closedWorld.commonMasks.dynamicType);
return replacement;
}
@@ -1296,7 +1314,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
// become dead. This breaks the algorithm for generating the per-type
// runtime type information, so we instantiate them here in case the
// HCreate becomes dead.
- object.instantiatedTypes?.forEach(registry.registerInstantiation);
+ object.instantiatedTypes?.forEach(_registry.registerInstantiation);
}
if (object.hasRtiInput) {
@@ -1314,7 +1332,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return finishSubstituted(
object.element,
// If there are type arguments, all type arguments are 'dynamic'.
- (int i) => graph.addConstantNull(closedWorld));
+ (int i) => _graph.addConstantNull(_closedWorld));
}
}
@@ -1329,15 +1347,13 @@ class SsaInstructionSimplifier extends HBaseVisitor
class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
final Set<HInstruction> boundsChecked;
final bool trustPrimitives;
- final JavaScriptBackend backend;
+ final BackendHelpers _helpers;
final ClosedWorld closedWorld;
final String name = "SsaCheckInserter";
HGraph graph;
- SsaCheckInserter(
- this.trustPrimitives, this.backend, this.closedWorld, this.boundsChecked);
-
- BackendHelpers get helpers => backend.helpers;
+ SsaCheckInserter(this.trustPrimitives, this._helpers, this.closedWorld,
+ this.boundsChecked);
void visitGraph(HGraph graph) {
this.graph = graph;
@@ -1400,7 +1416,7 @@ class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
MemberEntity element = node.element;
if (node.isInterceptedCall) return;
- if (element != helpers.jsArrayRemoveLast) return;
+ if (element != _helpers.jsArrayRemoveLast) return;
if (boundsChecked.contains(node)) return;
// `0` is the index we want to check, but we want to report `-1`, as if we
// executed `a[a.length-1]`
@@ -2258,7 +2274,7 @@ class SsaTypeConversionInserter extends HBaseVisitor
* location.
*/
class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
- final JavaScriptBackend backend;
+ final BackendHelpers _helpers;
final Compiler compiler;
final ClosedWorld closedWorld;
final String name = "SsaLoadElimination";
@@ -2266,7 +2282,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
List<MemorySet> memories;
bool newGvnCandidates = false;
- SsaLoadElimination(this.backend, this.compiler, this.closedWorld);
+ SsaLoadElimination(this._helpers, this.compiler, this.closedWorld);
void visitGraph(HGraph graph) {
memories = new List<MemorySet>(graph.blocks.length);
@@ -2335,8 +2351,8 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
}
void visitGetLength(HGetLength instruction) {
- _visitFieldGet(backend.helpers.jsIndexableLength,
- instruction.receiver.nonCheck(), instruction);
+ _visitFieldGet(_helpers.jsIndexableLength, instruction.receiver.nonCheck(),
+ instruction);
}
void _visitFieldGet(
« no previous file with comments | « pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart ('k') | pkg/compiler/lib/src/ssa/types_propagation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698