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 78d5391ad7e930da74188eaa7b260e90b3ea4e9c..4f67597c6d82d1b3839dea8f66f60422249f7964 100644 |
--- a/pkg/compiler/lib/src/ssa/optimize.dart |
+++ b/pkg/compiler/lib/src/ssa/optimize.dart |
@@ -2,34 +2,24 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
-import '../common/codegen.dart' show |
- CodegenRegistry, |
- CodegenWorkItem; |
-import '../common/tasks.dart' show |
- CompilerTask; |
-import '../compiler.dart' show |
- Compiler; |
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
+import '../common/tasks.dart' show CompilerTask; |
+import '../compiler.dart' show Compiler; |
import '../constants/constant_system.dart'; |
import '../constants/values.dart'; |
-import '../core_types.dart' show |
- CoreClasses; |
+import '../core_types.dart' show CoreClasses; |
import '../dart_types.dart'; |
import '../elements/elements.dart'; |
import '../js/js.dart' as js; |
-import '../js_backend/backend_helpers.dart' show |
- BackendHelpers; |
+import '../js_backend/backend_helpers.dart' show BackendHelpers; |
import '../js_backend/js_backend.dart'; |
import '../native/native.dart' as native; |
import '../tree/tree.dart' as ast; |
import '../types/types.dart'; |
-import '../universe/selector.dart' show |
- Selector; |
-import '../universe/side_effects.dart' show |
- SideEffects; |
+import '../universe/selector.dart' show Selector; |
+import '../universe/side_effects.dart' show SideEffects; |
import '../util/util.dart'; |
-import '../world.dart' show |
- ClassWorld, |
- World; |
+import '../world.dart' show ClassWorld, World; |
import 'nodes.dart'; |
import 'types_propagation.dart'; |
@@ -64,40 +54,40 @@ class SsaOptimizerTask extends CompilerTask { |
bool trustPrimitives = compiler.options.trustPrimitives; |
measure(() { |
List<OptimizationPhase> phases = <OptimizationPhase>[ |
- // Run trivial instruction simplification first to optimize |
- // some patterns useful for type conversion. |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
- new SsaTypeConversionInserter(compiler), |
- new SsaRedundantPhiEliminator(), |
- new SsaDeadPhiEliminator(), |
- new SsaTypePropagator(compiler), |
- // After type propagation, more instructions can be |
- // simplified. |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
- new SsaCheckInserter( |
- trustPrimitives, backend, work, context.boundsChecked), |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
- new SsaCheckInserter( |
- trustPrimitives, backend, work, context.boundsChecked), |
- new SsaTypePropagator(compiler), |
- // Run a dead code eliminator before LICM because dead |
- // interceptors are often in the way of LICM'able instructions. |
- new SsaDeadCodeEliminator(compiler, this), |
- new SsaGlobalValueNumberer(compiler), |
- // After GVN, some instructions might need their type to be |
- // updated because they now have different inputs. |
- new SsaTypePropagator(compiler), |
- new SsaCodeMotion(), |
- new SsaLoadElimination(compiler), |
- new SsaRedundantPhiEliminator(), |
- new SsaDeadPhiEliminator(), |
- new SsaTypePropagator(compiler), |
- new SsaValueRangeAnalyzer(compiler, constantSystem, this, work), |
- // Previous optimizations may have generated new |
- // opportunities for instruction simplification. |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
- new SsaCheckInserter( |
- trustPrimitives, backend, work, context.boundsChecked), |
+ // Run trivial instruction simplification first to optimize |
+ // some patterns useful for type conversion. |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaTypeConversionInserter(compiler), |
+ new SsaRedundantPhiEliminator(), |
+ new SsaDeadPhiEliminator(), |
+ new SsaTypePropagator(compiler), |
+ // After type propagation, more instructions can be |
+ // simplified. |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaCheckInserter( |
+ trustPrimitives, backend, work, context.boundsChecked), |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaCheckInserter( |
+ trustPrimitives, backend, work, context.boundsChecked), |
+ new SsaTypePropagator(compiler), |
+ // Run a dead code eliminator before LICM because dead |
+ // interceptors are often in the way of LICM'able instructions. |
+ new SsaDeadCodeEliminator(compiler, this), |
+ new SsaGlobalValueNumberer(compiler), |
+ // After GVN, some instructions might need their type to be |
+ // updated because they now have different inputs. |
+ new SsaTypePropagator(compiler), |
+ new SsaCodeMotion(), |
+ new SsaLoadElimination(compiler), |
+ new SsaRedundantPhiEliminator(), |
+ new SsaDeadPhiEliminator(), |
+ new SsaTypePropagator(compiler), |
+ new SsaValueRangeAnalyzer(compiler, constantSystem, this, work), |
+ // Previous optimizations may have generated new |
+ // opportunities for instruction simplification. |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaCheckInserter( |
+ trustPrimitives, backend, work, context.boundsChecked), |
]; |
phases.forEach(runPhase); |
@@ -110,22 +100,22 @@ class SsaOptimizerTask extends CompilerTask { |
runPhase(dce); |
if (dce.eliminatedSideEffects) { |
phases = <OptimizationPhase>[ |
- new SsaTypePropagator(compiler), |
- new SsaGlobalValueNumberer(compiler), |
- new SsaCodeMotion(), |
- new SsaValueRangeAnalyzer(compiler, constantSystem, this, work), |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
- new SsaCheckInserter( |
- trustPrimitives, backend, work, context.boundsChecked), |
- new SsaSimplifyInterceptors(compiler, constantSystem, work), |
- new SsaDeadCodeEliminator(compiler, this), |
+ new SsaTypePropagator(compiler), |
+ new SsaGlobalValueNumberer(compiler), |
+ new SsaCodeMotion(), |
+ new SsaValueRangeAnalyzer(compiler, constantSystem, this, work), |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaCheckInserter( |
+ trustPrimitives, backend, work, context.boundsChecked), |
+ new SsaSimplifyInterceptors(compiler, constantSystem, work), |
+ new SsaDeadCodeEliminator(compiler, this), |
]; |
} else { |
phases = <OptimizationPhase>[ |
- new SsaTypePropagator(compiler), |
- // Run the simplifier to remove unneeded type checks inserted by |
- // type propagation. |
- new SsaInstructionSimplifier(constantSystem, backend, this, work), |
+ new SsaTypePropagator(compiler), |
+ // Run the simplifier to remove unneeded type checks inserted by |
+ // type propagation. |
+ new SsaInstructionSimplifier(constantSystem, backend, this, work), |
]; |
} |
phases.forEach(runPhase); |
@@ -160,7 +150,6 @@ bool isFixedLength(mask, Compiler compiler) { |
*/ |
class SsaInstructionSimplifier extends HBaseVisitor |
implements OptimizationPhase { |
- |
// We don't produce constant-folded strings longer than this unless they have |
// a single use. This protects against exponentially large constant folded |
// strings. |
@@ -174,10 +163,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
Compiler get compiler => backend.compiler; |
final SsaOptimizerTask optimizer; |
- SsaInstructionSimplifier(this.constantSystem, |
- this.backend, |
- this.optimizer, |
- this.work); |
+ SsaInstructionSimplifier( |
+ this.constantSystem, this.backend, this.optimizer, this.work); |
CoreClasses get coreClasses => compiler.coreClasses; |
@@ -201,12 +188,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(compiler) |
- && instruction.isNumberOrNull(compiler))) { |
+ if (!(replacement.isNumberOrNull(compiler) && |
+ instruction.isNumberOrNull(compiler))) { |
// If we can replace [instruction] with [replacement], then |
// [replacement]'s type can be narrowed. |
- TypeMask newType = replacement.instructionType.intersection( |
- instruction.instructionType, compiler.world); |
+ TypeMask newType = replacement.instructionType |
+ .intersection(instruction.instructionType, compiler.world); |
replacement.instructionType = newType; |
} |
@@ -265,8 +252,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// body. If that happens then we should not forward the constant value to |
// its uses since since the uses reachable from the assignment may have |
// values in addition to the constant passed to the function. |
- if (node.usedBy.any((user) => |
- user is HLocalSet && identical(user.local, node))) { |
+ if (node.usedBy |
+ .any((user) => user is HLocalSet && identical(user.local, node))) { |
return node; |
} |
propagateConstantValueToUses(node); |
@@ -341,14 +328,13 @@ class SsaInstructionSimplifier extends HBaseVisitor |
TypeMask resultType = backend.positiveIntType; |
// If we already have computed a more specific type, keep that type. |
if (HInstruction.isInstanceOf( |
- actualType, helpers.jsUInt31Class, classWorld)) { |
+ actualType, helpers.jsUInt31Class, classWorld)) { |
resultType = backend.uint31Type; |
} else if (HInstruction.isInstanceOf( |
- actualType, helpers.jsUInt32Class, classWorld)) { |
+ actualType, helpers.jsUInt32Class, classWorld)) { |
resultType = backend.uint32Type; |
} |
- HFieldGet result = new HFieldGet( |
- element, actualReceiver, resultType, |
+ HFieldGet result = new HFieldGet(element, actualReceiver, resultType, |
isAssignable: !isFixed); |
return result; |
} else if (actualReceiver.isConstantMap()) { |
@@ -382,7 +368,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
bool applies(Element element) { |
return selector.applies(element, world) && |
- (mask == null || mask.canHit(element, selector, world)); |
+ (mask == null || mask.canHit(element, selector, world)); |
} |
if (selector.isCall || selector.isOperator) { |
@@ -408,12 +394,10 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// 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(compiler) |
- && !input.canBeNull()) { |
+ if (argument.isString(compiler) && !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; |
} |
} |
@@ -426,9 +410,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// bounds check on removeLast). Once we start inlining, the |
// bounds check will become explicit, so we won't need this |
// optimization. |
- HInvokeDynamicMethod result = new HInvokeDynamicMethod( |
- node.selector, node.mask, |
- node.inputs.sublist(1), node.instructionType); |
+ HInvokeDynamicMethod result = new HInvokeDynamicMethod(node.selector, |
+ node.mask, node.inputs.sublist(1), node.instructionType); |
result.element = target; |
return result; |
} |
@@ -453,11 +436,12 @@ class SsaInstructionSimplifier extends HBaseVisitor |
Element element = |
compiler.world.locateSingleElement(node.selector, receiverType); |
// TODO(ngeoffray): Also fold if it's a getter or variable. |
- if (element != null |
- && element.isFunction |
+ if (element != null && |
+ element.isFunction |
// If we found out that the only target is a [:noSuchMethod:], |
// we just ignore it. |
- && element.name == node.selector.name) { |
+ && |
+ element.name == node.selector.name) { |
FunctionElement method = element; |
if (backend.isNative(method)) { |
@@ -468,8 +452,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// we should pass the default values. |
FunctionSignature parameters = method.functionSignature; |
if (parameters.optionalParameterCount == 0 || |
- parameters.parameterCount == |
- node.selector.argumentCount) { |
+ parameters.parameterCount == node.selector.argumentCount) { |
node.element = element; |
} |
} |
@@ -477,8 +460,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
return node; |
} |
- HInstruction tryInlineNativeMethod(HInvokeDynamicMethod node, |
- FunctionElement method) { |
+ HInstruction tryInlineNativeMethod( |
+ HInvokeDynamicMethod node, FunctionElement method) { |
// Enable direct calls to a native method only if we don't run in checked |
// mode, where the Dart version may have type annotations on parameters and |
// return type that it should check. |
@@ -505,7 +488,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// preserve the number of arguments, so check only the actual arguments. |
List<HInstruction> inputs = node.inputs.sublist(1); |
- int inputPosition = 1; // Skip receiver. |
+ int inputPosition = 1; // Skip receiver. |
bool canInline = true; |
signature.forEachParameter((ParameterElement element) { |
if (inputPosition++ < inputs.length && canInline) { |
@@ -551,9 +534,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
return node; |
} |
- HInstruction foldBinary(BinaryOperation operation, |
- HInstruction left, |
- HInstruction right) { |
+ HInstruction foldBinary( |
+ BinaryOperation operation, HInstruction left, HInstruction right) { |
if (left is HConstant && right is HConstant) { |
HConstant op1 = left; |
HConstant op2 = right; |
@@ -650,7 +632,6 @@ class SsaInstructionSimplifier extends HBaseVisitor |
return compareConstant(right, left); |
} |
- |
if (identical(left.nonCheck(), right.nonCheck())) { |
// Avoid constant-folding `identical(x, x)` when `x` might be double. The |
// dart2js runtime has not always been consistent with the Dart |
@@ -668,9 +649,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
return newInstruction == null ? super.visitIdentity(node) : newInstruction; |
} |
- void simplifyCondition(HBasicBlock block, |
- HInstruction condition, |
- bool value) { |
+ void simplifyCondition( |
+ HBasicBlock block, HInstruction condition, bool value) { |
condition.dominatedUsers(block.first).forEach((user) { |
HInstruction newCondition = graph.addConstantBool(value, compiler); |
user.changeUse(condition, newCondition); |
@@ -690,8 +670,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// simplify the nested use of the condition in that case, so |
// we look for all dominating negated conditions and replace |
// nested uses of them with true or false. |
- Iterable<HInstruction> dominating = condition.usedBy.where((user) => |
- user is HNot && user.dominates(node)); |
+ Iterable<HInstruction> dominating = condition.usedBy |
+ .where((user) => user is HNot && user.dominates(node)); |
dominating.forEach((hoisted) { |
simplifyCondition(node.thenBlock, hoisted, false); |
simplifyCondition(node.elseBlock, hoisted, true); |
@@ -753,13 +733,13 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// type int or double. |
} |
} else if (expression.canBePrimitiveNumber(compiler) && |
- element == coreClasses.intClass) { |
+ element == coreClasses.intClass) { |
// We let the JS semantics decide for that check. |
return node; |
- // We need the [:hasTypeArguments:] check because we don't have |
- // the notion of generics in the backend. For example, [:this:] in |
- // a class [:A<T>:], is currently always considered to have the |
- // raw type. |
+ // We need the [:hasTypeArguments:] check because we don't have |
+ // the notion of generics in the backend. For example, [:this:] in |
+ // a class [:A<T>:], is currently always considered to have the |
+ // raw type. |
} else if (!RuntimeTypes.hasTypeArguments(type)) { |
TypeMask expressionMask = expression.instructionType; |
assert(TypeMask.assertIsNormalized(expressionMask, classWorld)); |
@@ -806,8 +786,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
return inputType.isInMask(checkedType, classWorld) ? input : node; |
} |
- VariableElement findConcreteFieldForDynamicAccess(HInstruction receiver, |
- Selector selector) { |
+ VariableElement findConcreteFieldForDynamicAccess( |
+ HInstruction receiver, Selector selector) { |
TypeMask receiverType = receiver.instructionType; |
return compiler.world.locateSingleField(selector, receiverType); |
} |
@@ -882,8 +862,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
if (folded != node) return folded; |
} |
HInstruction receiver = node.getDartReceiver(compiler); |
- Element field = findConcreteFieldForDynamicAccess( |
- receiver, node.selector); |
+ Element field = findConcreteFieldForDynamicAccess(receiver, node.selector); |
if (field == null) return node; |
return directFieldGet(receiver, field); |
} |
@@ -894,14 +873,12 @@ class SsaInstructionSimplifier extends HBaseVisitor |
TypeMask type; |
if (backend.isNative(field.enclosingClass)) { |
type = TypeMaskFactory.fromNativeBehavior( |
- native.NativeBehavior.ofFieldLoad(field, compiler), |
- compiler); |
+ native.NativeBehavior.ofFieldLoad(field, compiler), compiler); |
} else { |
type = TypeMaskFactory.inferredTypeForElement(field, compiler); |
} |
- return new HFieldGet( |
- field, receiver, type, isAssignable: isAssignable); |
+ return new HFieldGet(field, receiver, type, isAssignable: isAssignable); |
} |
HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
@@ -925,10 +902,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
// inline this access. |
return node; |
} |
- HInstruction other = value.convertType( |
- compiler, |
- type, |
- HTypeConversion.CHECKED_MODE_CHECK); |
+ HInstruction other = |
+ value.convertType(compiler, type, HTypeConversion.CHECKED_MODE_CHECK); |
if (other != value) { |
node.block.addBefore(node, other); |
value = other; |
@@ -1013,8 +988,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
if (!intConstant.isUInt32()) return node; |
} |
PrimitiveConstantValue primitive = constant.constant; |
- return graph.addConstant(constantSystem.createString( |
- primitive.toDartString()), compiler); |
+ return graph.addConstant( |
+ constantSystem.createString(primitive.toDartString()), compiler); |
} |
return node; |
} |
@@ -1032,10 +1007,8 @@ class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
final String name = "SsaCheckInserter"; |
HGraph graph; |
- SsaCheckInserter(this.trustPrimitives, |
- this.backend, |
- this.work, |
- this.boundsChecked); |
+ SsaCheckInserter( |
+ this.trustPrimitives, this.backend, this.work, this.boundsChecked); |
BackendHelpers get helpers => backend.helpers; |
@@ -1059,9 +1032,8 @@ class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
} |
} |
- HBoundsCheck insertBoundsCheck(HInstruction indexNode, |
- HInstruction array, |
- HInstruction indexArgument) { |
+ HBoundsCheck insertBoundsCheck( |
+ HInstruction indexNode, HInstruction array, HInstruction indexArgument) { |
Compiler compiler = backend.compiler; |
HFieldGet length = new HFieldGet( |
helpers.jsIndexableLength, array, backend.positiveIntType, |
@@ -1071,8 +1043,7 @@ class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
TypeMask type = indexArgument.isPositiveInteger(compiler) |
? indexArgument.instructionType |
: backend.positiveIntType; |
- HBoundsCheck check = new HBoundsCheck( |
- indexArgument, length, array, type); |
+ HBoundsCheck check = new HBoundsCheck(indexArgument, length, array, type); |
indexNode.block.addBefore(indexNode, check); |
// If the index input to the bounds check was not known to be an integer |
// then we replace its uses with the bounds check, which is known to be an |
@@ -1131,10 +1102,8 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
HInstruction get zapInstruction { |
if (zapInstructionCache == null) { |
// A constant with no type does not pollute types at phi nodes. |
- ConstantValue constant = |
- new SyntheticConstantValue( |
- SyntheticConstantKind.EMPTY_VALUE, |
- const TypeMask.nonNullEmpty()); |
+ ConstantValue constant = new SyntheticConstantValue( |
+ SyntheticConstantKind.EMPTY_VALUE, const TypeMask.nonNullEmpty()); |
zapInstructionCache = analyzer.graph.addConstant(constant, compiler); |
} |
return zapInstructionCache; |
@@ -1181,8 +1150,8 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
HInstruction receiver = instruction.getDartReceiver(compiler); |
HInstruction current = instruction.next; |
do { |
- if ((current.getDartReceiver(compiler) == receiver) |
- && current.canThrow()) { |
+ if ((current.getDartReceiver(compiler) == receiver) && |
+ current.canThrow()) { |
return true; |
} |
if (current is HForeignCode && |
@@ -1232,15 +1201,15 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
} |
return false; |
} |
- return instruction.isAllocation |
- && instruction.isPure() |
- && trivialDeadStoreReceivers.putIfAbsent(instruction, |
- () => instruction.usedBy.every(isDeadUse)); |
+ return instruction.isAllocation && |
+ instruction.isPure() && |
+ trivialDeadStoreReceivers.putIfAbsent( |
+ instruction, () => instruction.usedBy.every(isDeadUse)); |
} |
bool isTrivialDeadStore(HInstruction instruction) { |
- return instruction is HFieldSet |
- && isTrivialDeadStoreReceiver(instruction.getDartReceiver(compiler)); |
+ return instruction is HFieldSet && |
+ isTrivialDeadStoreReceiver(instruction.getDartReceiver(compiler)); |
} |
bool isDeadCode(HInstruction instruction) { |
@@ -1252,9 +1221,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
hasFollowingThrowingNSM(instruction)) { |
return true; |
} |
- return !instruction.canThrow() |
- && instruction is !HParameterValue |
- && instruction is !HLocalSet; |
+ return !instruction.canThrow() && |
+ instruction is! HParameterValue && |
+ instruction is! HLocalSet; |
} |
void visitGraph(HGraph graph) { |
@@ -1272,8 +1241,8 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
while (instruction != null) { |
var previous = instruction.previous; |
if (isDeadBlock) { |
- eliminatedSideEffects = eliminatedSideEffects || |
- instruction.sideEffects.hasSideEffects(); |
+ eliminatedSideEffects = |
+ eliminatedSideEffects || instruction.sideEffects.hasSideEffects(); |
removeUsers(instruction); |
block.remove(instruction); |
} else if (isDeadCode(instruction)) { |
@@ -1306,8 +1275,8 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
// Run through the phis of the block and replace them with their input |
// that comes from the only live predecessor if that dominates the phi. |
block.forEachPhi((HPhi phi) { |
- HInstruction replacement = (indexOfLive >= 0) |
- ? phi.inputs[indexOfLive] : zapInstruction; |
+ HInstruction replacement = |
+ (indexOfLive >= 0) ? phi.inputs[indexOfLive] : zapInstruction; |
if (replacement.dominates(phi)) { |
block.rewrite(phi, replacement); |
block.removePhi(phi); |
@@ -1401,9 +1370,7 @@ class SsaLiveBlockAnalyzer extends HBaseVisitor { |
if (!input.isConstantInteger()) continue; |
IntConstantValue constant = input.constant; |
int label = constant.primitiveValue; |
- if (!liveLabels.contains(label) && |
- label <= upper && |
- label >= lower) { |
+ if (!liveLabels.contains(label) && label <= upper && label >= lower) { |
markBlockLive(node.block.successors[pos - 1]); |
liveLabels.add(label); |
} |
@@ -1431,7 +1398,7 @@ class SsaDeadPhiEliminator implements OptimizationPhase { |
for (final block in graph.blocks) { |
block.forEachPhi((HPhi phi) { |
for (final user in phi.usedBy) { |
- if (user is !HPhi) { |
+ if (user is! HPhi) { |
worklist.add(phi); |
livePhis.add(phi); |
break; |
@@ -1465,7 +1432,8 @@ class SsaDeadPhiEliminator implements OptimizationPhase { |
next = current.next; |
if (!livePhis.contains(current) |
// TODO(ahe): Not sure the following is correct. |
- && current.usedBy.isEmpty) { |
+ && |
+ current.usedBy.isEmpty) { |
block.removePhi(current); |
} |
current = next; |
@@ -1540,8 +1508,9 @@ class SsaGlobalValueNumberer implements OptimizationPhase { |
void visitGraph(HGraph graph) { |
computeChangesFlags(graph); |
moveLoopInvariantCode(graph); |
- List<GvnWorkItem> workQueue = |
- <GvnWorkItem>[new GvnWorkItem(graph.entry, new ValueSet())]; |
+ List<GvnWorkItem> workQueue = <GvnWorkItem>[ |
+ new GvnWorkItem(graph.entry, new ValueSet()) |
+ ]; |
do { |
GvnWorkItem item = workQueue.removeLast(); |
visitBasicBlock(item.block, item.valueSet, workQueue); |
@@ -1567,9 +1536,8 @@ class SsaGlobalValueNumberer implements OptimizationPhase { |
} |
} |
- void moveLoopInvariantCodeFromBlock(HBasicBlock block, |
- HBasicBlock loopHeader, |
- int changesFlags) { |
+ void moveLoopInvariantCodeFromBlock( |
+ HBasicBlock block, HBasicBlock loopHeader, int changesFlags) { |
assert(block.parentLoopHeader == loopHeader || block == loopHeader); |
HBasicBlock preheader = loopHeader.predecessors[0]; |
int dependsFlags = SideEffects.computeDependsOnFlags(changesFlags); |
@@ -1577,19 +1545,20 @@ class SsaGlobalValueNumberer implements OptimizationPhase { |
bool isLoopAlwaysTaken() { |
HInstruction instruction = loopHeader.last; |
assert(instruction is HGoto || instruction is HLoopBranch); |
- return instruction is HGoto |
- || instruction.inputs[0].isConstantTrue(); |
+ return instruction is HGoto || instruction.inputs[0].isConstantTrue(); |
} |
bool firstInstructionInLoop = block == loopHeader |
// Compensate for lack of code motion. |
- || (blockChangesFlags[loopHeader.id] == 0 |
- && isLoopAlwaysTaken() |
- && loopHeader.successors[0] == block); |
+ || |
+ (blockChangesFlags[loopHeader.id] == 0 && |
+ isLoopAlwaysTaken() && |
+ loopHeader.successors[0] == block); |
while (instruction != null) { |
HInstruction next = instruction.next; |
- if (instruction.useGvn() && instruction.isMovable |
- && (!instruction.canThrow() || firstInstructionInLoop) |
- && !instruction.sideEffects.dependsOn(dependsFlags)) { |
+ if (instruction.useGvn() && |
+ instruction.isMovable && |
+ (!instruction.canThrow() || firstInstructionInLoop) && |
+ !instruction.sideEffects.dependsOn(dependsFlags)) { |
bool loopInvariantInputs = true; |
List<HInstruction> inputs = instruction.inputs; |
for (int i = 0, length = inputs.length; i < length; i++) { |
@@ -1617,8 +1586,7 @@ class SsaGlobalValueNumberer implements OptimizationPhase { |
} |
} |
- bool isInputDefinedAfterDominator(HInstruction input, |
- HBasicBlock dominator) { |
+ bool isInputDefinedAfterDominator(HInstruction input, HBasicBlock dominator) { |
return input.block.id > dominator.id; |
} |
@@ -1707,16 +1675,14 @@ class SsaGlobalValueNumberer implements OptimizationPhase { |
// Propagate loop changes flags upwards. |
HBasicBlock parentLoopHeader = block.parentLoopHeader; |
if (parentLoopHeader != null) { |
- loopChangesFlags[parentLoopHeader.id] |= (block.isLoopHeader()) |
- ? loopChangesFlags[id] |
- : changesFlags; |
+ loopChangesFlags[parentLoopHeader.id] |= |
+ (block.isLoopHeader()) ? loopChangesFlags[id] : changesFlags; |
} |
} |
} |
int getChangesFlagsForDominatedBlock(HBasicBlock dominator, |
- HBasicBlock dominated, |
- List<HBasicBlock> workQueue) { |
+ HBasicBlock dominated, List<HBasicBlock> workQueue) { |
int changesFlags = 0; |
List<HBasicBlock> predecessors = dominated.predecessors; |
for (int i = 0, length = predecessors.length; i < length; i++) { |
@@ -1851,9 +1817,8 @@ class SsaTypeConversionInserter extends HBaseVisitor |
// to use [TypeKnown] of [input] instead. As the type information depends |
// on the control flow, we mark the inserted [HTypeKnown] nodes as |
// non-movable. |
- void insertTypePropagationForDominatedUsers(HBasicBlock dominator, |
- HInstruction input, |
- TypeMask convertedType) { |
+ void insertTypePropagationForDominatedUsers( |
+ HBasicBlock dominator, HInstruction input, TypeMask convertedType) { |
Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); |
if (dominatedUsers.isEmpty) return; |
@@ -1885,14 +1850,14 @@ class SsaTypeConversionInserter extends HBaseVisitor |
HInstruction input = instruction.expression; |
for (HIf ifUser in ifUsers) { |
- insertTypePropagationForDominatedUsers(ifUser.thenBlock, input, |
- convertedType); |
+ insertTypePropagationForDominatedUsers( |
+ ifUser.thenBlock, input, convertedType); |
// TODO(ngeoffray): Also change uses for the else block on a type |
// that knows it is not of a specific type. |
} |
for (HIf ifUser in notIfUsers) { |
- insertTypePropagationForDominatedUsers(ifUser.elseBlock, input, |
- convertedType); |
+ insertTypePropagationForDominatedUsers( |
+ ifUser.elseBlock, input, convertedType); |
// TODO(ngeoffray): Also change uses for the then block on a type |
// that knows it is not of a specific type. |
} |
@@ -1924,20 +1889,19 @@ class SsaTypeConversionInserter extends HBaseVisitor |
TypeMask nonNullType = input.instructionType.nonNullable(); |
for (HIf ifUser in ifUsers) { |
- insertTypePropagationForDominatedUsers(ifUser.elseBlock, input, |
- nonNullType); |
+ insertTypePropagationForDominatedUsers( |
+ ifUser.elseBlock, input, nonNullType); |
// Uses in thenBlock are `null`, but probably not common. |
} |
for (HIf ifUser in notIfUsers) { |
- insertTypePropagationForDominatedUsers(ifUser.thenBlock, input, |
- nonNullType); |
+ insertTypePropagationForDominatedUsers( |
+ ifUser.thenBlock, input, nonNullType); |
// Uses in elseBlock are `null`, but probably not common. |
} |
} |
- collectIfUsers(HInstruction instruction, |
- List<HInstruction> ifUsers, |
- List<HInstruction> notIfUsers) { |
+ collectIfUsers(HInstruction instruction, List<HInstruction> ifUsers, |
+ List<HInstruction> notIfUsers) { |
for (HInstruction user in instruction.usedBy) { |
if (user is HIf) { |
ifUsers.add(user); |
@@ -1982,8 +1946,8 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
if (block.predecessors.length == 0) { |
// Entry block. |
memorySet = new MemorySet(compiler); |
- } else if (block.predecessors.length == 1 |
- && block.predecessors[0].successors.length == 1) { |
+ } else if (block.predecessors.length == 1 && |
+ block.predecessors[0].successors.length == 1) { |
// No need to clone, there is no other successor for |
// `block.predecessors[0]`, and this block has only one |
// predecessor. Since we are not going to visit |
@@ -1999,7 +1963,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
memorySet = memories[block.predecessors[0].id]; |
for (int i = 1; i < block.predecessors.length; i++) { |
memorySet = memorySet.intersectionFor( |
- memories[block.predecessors[i].id], block, i); |
+ memories[block.predecessors[i].id], block, i); |
} |
} |
@@ -2015,8 +1979,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
void visitFieldGet(HFieldGet instruction) { |
if (instruction.isNullCheck) return; |
Element element = instruction.element; |
- HInstruction receiver = |
- instruction.getDartReceiver(compiler).nonCheck(); |
+ HInstruction receiver = instruction.getDartReceiver(compiler).nonCheck(); |
HInstruction existing = memorySet.lookupFieldValue(element, receiver); |
if (existing != null) { |
instruction.block.rewriteWithBetterUser(instruction, existing); |
@@ -2027,8 +1990,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
} |
void visitFieldSet(HFieldSet instruction) { |
- HInstruction receiver = |
- instruction.getDartReceiver(compiler).nonCheck(); |
+ HInstruction receiver = instruction.getDartReceiver(compiler).nonCheck(); |
memorySet.registerFieldValueUpdate( |
instruction.element, receiver, instruction.inputs.last); |
} |
@@ -2150,13 +2112,13 @@ class MemorySet { |
* Maps a field to a map of receiver to value. |
*/ |
final Map<Element, Map<HInstruction, HInstruction>> fieldValues = |
- <Element, Map<HInstruction, HInstruction>> {}; |
+ <Element, Map<HInstruction, HInstruction>>{}; |
/** |
* Maps a receiver to a map of keys to value. |
*/ |
final Map<HInstruction, Map<HInstruction, HInstruction>> keyedValues = |
- <HInstruction, Map<HInstruction, HInstruction>> {}; |
+ <HInstruction, Map<HInstruction, HInstruction>>{}; |
/** |
* Set of objects that we know don't escape the current function. |
@@ -2184,8 +2146,8 @@ class MemorySet { |
if (nonEscapingReceivers.contains(second)) return false; |
// Typed arrays of different types might have a shared buffer. |
if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true; |
- return !first.instructionType.isDisjoint( |
- second.instructionType, compiler.world); |
+ return !first.instructionType |
+ .isDisjoint(second.instructionType, compiler.world); |
} |
bool isFinal(Element element) { |
@@ -2193,9 +2155,9 @@ class MemorySet { |
} |
bool isConcrete(HInstruction instruction) { |
- return instruction is HForeignNew |
- || instruction is HConstant |
- || instruction is HLiteralList; |
+ return instruction is HForeignNew || |
+ instruction is HConstant || |
+ instruction is HLiteralList; |
} |
bool couldBeTypedArray(HInstruction receiver) { |
@@ -2218,17 +2180,16 @@ class MemorySet { |
* Sets `receiver.element` to contain [value]. Kills all potential |
* places that may be affected by this update. |
*/ |
- void registerFieldValueUpdate(Element element, |
- HInstruction receiver, |
- HInstruction value) { |
+ void registerFieldValueUpdate( |
+ Element element, HInstruction receiver, HInstruction value) { |
if (backend.isNative(element)) { |
return; // TODO(14955): Remove this restriction? |
} |
// [value] is being set in some place in memory, we remove it from |
// the non-escaping set. |
nonEscapingReceivers.remove(value); |
- Map<HInstruction, HInstruction> map = fieldValues.putIfAbsent( |
- element, () => <HInstruction, HInstruction> {}); |
+ Map<HInstruction, HInstruction> map = |
+ fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{}); |
map.forEach((key, value) { |
if (mayAlias(receiver, key)) map[key] = null; |
}); |
@@ -2238,14 +2199,13 @@ class MemorySet { |
/** |
* Registers that `receiver.element` is now [value]. |
*/ |
- void registerFieldValue(Element element, |
- HInstruction receiver, |
- HInstruction value) { |
+ void registerFieldValue( |
+ Element element, HInstruction receiver, HInstruction value) { |
if (backend.isNative(element)) { |
return; // TODO(14955): Remove this restriction? |
} |
- Map<HInstruction, HInstruction> map = fieldValues.putIfAbsent( |
- element, () => <HInstruction, HInstruction> {}); |
+ Map<HInstruction, HInstruction> map = |
+ fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{}); |
map[receiver] = value; |
} |
@@ -2273,8 +2233,8 @@ class MemorySet { |
nonEscapingReceivers.remove(input); |
}); |
- if (instruction.sideEffects.changesInstanceProperty() |
- || instruction.sideEffects.changesStaticProperty()) { |
+ if (instruction.sideEffects.changesInstanceProperty() || |
+ instruction.sideEffects.changesStaticProperty()) { |
fieldValues.forEach((element, map) { |
if (isFinal(element)) return; |
map.forEach((receiver, value) { |
@@ -2308,11 +2268,10 @@ class MemorySet { |
/** |
* Registers that `receiver[index]` is now [value]. |
*/ |
- void registerKeyedValue(HInstruction receiver, |
- HInstruction index, |
- HInstruction value) { |
- Map<HInstruction, HInstruction> map = keyedValues.putIfAbsent( |
- receiver, () => <HInstruction, HInstruction> {}); |
+ void registerKeyedValue( |
+ HInstruction receiver, HInstruction index, HInstruction value) { |
+ Map<HInstruction, HInstruction> map = |
+ keyedValues.putIfAbsent(receiver, () => <HInstruction, HInstruction>{}); |
map[index] = value; |
} |
@@ -2320,9 +2279,8 @@ class MemorySet { |
* Sets `receiver[index]` to contain [value]. Kills all potential |
* places that may be affected by this update. |
*/ |
- void registerKeyedValueUpdate(HInstruction receiver, |
- HInstruction index, |
- HInstruction value) { |
+ void registerKeyedValueUpdate( |
+ HInstruction receiver, HInstruction index, HInstruction value) { |
nonEscapingReceivers.remove(value); |
keyedValues.forEach((key, values) { |
if (mayAlias(receiver, key)) { |
@@ -2340,8 +2298,8 @@ class MemorySet { |
// Typed arrays may narrow incoming values. |
if (couldBeTypedArray(receiver)) return; |
- Map<HInstruction, HInstruction> map = keyedValues.putIfAbsent( |
- receiver, () => <HInstruction, HInstruction> {}); |
+ Map<HInstruction, HInstruction> map = |
+ keyedValues.putIfAbsent(receiver, () => <HInstruction, HInstruction>{}); |
map[index] = value; |
} |
@@ -2350,14 +2308,12 @@ class MemorySet { |
* returns [first] if [first] and [second] are equal. Otherwise |
* creates or re-uses a phi in [block] that holds [first] and [second]. |
*/ |
- HInstruction findCommonInstruction(HInstruction first, |
- HInstruction second, |
- HBasicBlock block, |
- int predecessorIndex) { |
+ HInstruction findCommonInstruction(HInstruction first, HInstruction second, |
+ HBasicBlock block, int predecessorIndex) { |
if (first == null || second == null) return null; |
if (first == second) return first; |
- TypeMask phiType = second.instructionType.union( |
- first.instructionType, compiler.world); |
+ TypeMask phiType = |
+ second.instructionType.union(first.instructionType, compiler.world); |
if (first is HPhi && first.block == block) { |
HPhi phi = first; |
phi.addInput(second); |
@@ -2379,9 +2335,8 @@ class MemorySet { |
/** |
* Returns the intersection between [this] and [other]. |
*/ |
- MemorySet intersectionFor(MemorySet other, |
- HBasicBlock block, |
- int predecessorIndex) { |
+ MemorySet intersectionFor( |
+ MemorySet other, HBasicBlock block, int predecessorIndex) { |
MemorySet result = new MemorySet(compiler); |
if (other == null) return result; |