Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
| 8 String get name; | 8 String get name; |
| 9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
| 10 } | 10 } |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 | 209 |
| 210 HInstruction visitInvokeUnary(HInvokeUnary node) { | 210 HInstruction visitInvokeUnary(HInvokeUnary node) { |
| 211 HInstruction folded = | 211 HInstruction folded = |
| 212 foldUnary(node.operation(constantSystem), node.operand); | 212 foldUnary(node.operation(constantSystem), node.operand); |
| 213 return folded != null ? folded : node; | 213 return folded != null ? folded : node; |
| 214 } | 214 } |
| 215 | 215 |
| 216 HInstruction foldUnary(UnaryOperation operation, HInstruction operand) { | 216 HInstruction foldUnary(UnaryOperation operation, HInstruction operand) { |
| 217 if (operand is HConstant) { | 217 if (operand is HConstant) { |
| 218 HConstant receiver = operand; | 218 HConstant receiver = operand; |
| 219 Constant folded = operation.fold(receiver.constant); | 219 ConstantValue folded = operation.fold(receiver.constant); |
| 220 if (folded != null) return graph.addConstant(folded, compiler); | 220 if (folded != null) return graph.addConstant(folded, compiler); |
| 221 } | 221 } |
| 222 return null; | 222 return null; |
| 223 } | 223 } |
| 224 | 224 |
| 225 HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) { | 225 HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) { |
| 226 HInstruction actualReceiver = node.inputs[1]; | 226 HInstruction actualReceiver = node.inputs[1]; |
| 227 if (actualReceiver.isIndexablePrimitive(compiler)) { | 227 if (actualReceiver.isIndexablePrimitive(compiler)) { |
| 228 if (actualReceiver.isConstantString()) { | 228 if (actualReceiver.isConstantString()) { |
| 229 HConstant constantInput = actualReceiver; | 229 HConstant constantInput = actualReceiver; |
| 230 StringConstant constant = constantInput.constant; | 230 StringConstantValue constant = constantInput.constant; |
| 231 return graph.addConstantInt(constant.length, compiler); | 231 return graph.addConstantInt(constant.length, compiler); |
| 232 } else if (actualReceiver.isConstantList()) { | 232 } else if (actualReceiver.isConstantList()) { |
| 233 HConstant constantInput = actualReceiver; | 233 HConstant constantInput = actualReceiver; |
| 234 ListConstant constant = constantInput.constant; | 234 ListConstantValue constant = constantInput.constant; |
| 235 return graph.addConstantInt(constant.length, compiler); | 235 return graph.addConstantInt(constant.length, compiler); |
| 236 } | 236 } |
| 237 Element element = backend.jsIndexableLength; | 237 Element element = backend.jsIndexableLength; |
| 238 bool isFixed = isFixedLength(actualReceiver.instructionType, compiler); | 238 bool isFixed = isFixedLength(actualReceiver.instructionType, compiler); |
| 239 HFieldGet result = new HFieldGet( | 239 HFieldGet result = new HFieldGet( |
| 240 element, actualReceiver, backend.positiveIntType, | 240 element, actualReceiver, backend.positiveIntType, |
| 241 isAssignable: !isFixed); | 241 isAssignable: !isFixed); |
| 242 return result; | 242 return result; |
| 243 } else if (actualReceiver.isConstantMap()) { | 243 } else if (actualReceiver.isConstantMap()) { |
| 244 HConstant constantInput = actualReceiver; | 244 HConstant constantInput = actualReceiver; |
| 245 MapConstant constant = constantInput.constant; | 245 MapConstantValue constant = constantInput.constant; |
| 246 return graph.addConstantInt(constant.length, compiler); | 246 return graph.addConstantInt(constant.length, compiler); |
| 247 } | 247 } |
| 248 return null; | 248 return null; |
| 249 } | 249 } |
| 250 | 250 |
| 251 HInstruction handleInterceptedCall(HInvokeDynamic node) { | 251 HInstruction handleInterceptedCall(HInvokeDynamic node) { |
| 252 // Try constant folding the instruction. | 252 // Try constant folding the instruction. |
| 253 Operation operation = node.specializer.operation(constantSystem); | 253 Operation operation = node.specializer.operation(constantSystem); |
| 254 if (operation != null) { | 254 if (operation != null) { |
| 255 HInstruction instruction = node.inputs.length == 2 | 255 HInstruction instruction = node.inputs.length == 2 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 } | 432 } |
| 433 return node; | 433 return node; |
| 434 } | 434 } |
| 435 | 435 |
| 436 HInstruction foldBinary(BinaryOperation operation, | 436 HInstruction foldBinary(BinaryOperation operation, |
| 437 HInstruction left, | 437 HInstruction left, |
| 438 HInstruction right) { | 438 HInstruction right) { |
| 439 if (left is HConstant && right is HConstant) { | 439 if (left is HConstant && right is HConstant) { |
| 440 HConstant op1 = left; | 440 HConstant op1 = left; |
| 441 HConstant op2 = right; | 441 HConstant op2 = right; |
| 442 Constant folded = operation.fold(op1.constant, op2.constant); | 442 ConstantValue folded = operation.fold(op1.constant, op2.constant); |
| 443 if (folded != null) return graph.addConstant(folded, compiler); | 443 if (folded != null) return graph.addConstant(folded, compiler); |
| 444 } | 444 } |
| 445 return null; | 445 return null; |
| 446 } | 446 } |
| 447 | 447 |
| 448 HInstruction visitAdd(HAdd node) { | 448 HInstruction visitAdd(HAdd node) { |
| 449 HInstruction left = node.left; | 449 HInstruction left = node.left; |
| 450 HInstruction right = node.right; | 450 HInstruction right = node.right; |
| 451 // We can only perform this rewriting on Integer, as it is not | 451 // We can only perform this rewriting on Integer, as it is not |
| 452 // valid for -0.0. | 452 // valid for -0.0. |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 } else { | 716 } else { |
| 717 return constant; | 717 return constant; |
| 718 } | 718 } |
| 719 } | 719 } |
| 720 } | 720 } |
| 721 } | 721 } |
| 722 | 722 |
| 723 // HFieldGet of a constructed constant can be replaced with the constant's | 723 // HFieldGet of a constructed constant can be replaced with the constant's |
| 724 // field. | 724 // field. |
| 725 if (receiver is HConstant) { | 725 if (receiver is HConstant) { |
| 726 Constant constant = receiver.constant; | 726 ConstantValue constant = receiver.constant; |
| 727 if (constant.isConstructedObject) { | 727 if (constant.isConstructedObject) { |
| 728 ConstructedConstant constructedConstant = constant; | 728 ConstructedConstantValue constructedConstant = constant; |
| 729 Map<Element, Constant> fields = constructedConstant.fieldElements; | 729 Map<Element, ConstantValue> fields = constructedConstant.fieldElements; |
| 730 Constant value = fields[node.element]; | 730 ConstantValue value = fields[node.element]; |
| 731 if (value != null) { | 731 if (value != null) { |
| 732 return graph.addConstant(value, compiler); | 732 return graph.addConstant(value, compiler); |
| 733 } | 733 } |
| 734 } | 734 } |
| 735 } | 735 } |
| 736 | 736 |
| 737 return node; | 737 return node; |
| 738 } | 738 } |
| 739 | 739 |
| 740 HInstruction visitIndex(HIndex node) { | 740 HInstruction visitIndex(HIndex node) { |
| 741 if (node.receiver.isConstantList() && node.index.isConstantInteger()) { | 741 if (node.receiver.isConstantList() && node.index.isConstantInteger()) { |
| 742 var instruction = node.receiver; | 742 var instruction = node.receiver; |
| 743 List<Constant> entries = instruction.constant.entries; | 743 List<ConstantValue> entries = instruction.constant.entries; |
| 744 instruction = node.index; | 744 instruction = node.index; |
| 745 int index = instruction.constant.value; | 745 int index = instruction.constant.primitiveValue; |
| 746 if (index >= 0 && index < entries.length) { | 746 if (index >= 0 && index < entries.length) { |
| 747 return graph.addConstant(entries[index], compiler); | 747 return graph.addConstant(entries[index], compiler); |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 return node; | 750 return node; |
| 751 } | 751 } |
| 752 | 752 |
| 753 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 753 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 754 if (node.isInterceptedCall) { | 754 if (node.isInterceptedCall) { |
| 755 HInstruction folded = handleInterceptedCall(node); | 755 HInstruction folded = handleInterceptedCall(node); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 } | 811 } |
| 812 | 812 |
| 813 HInstruction visitStringConcat(HStringConcat node) { | 813 HInstruction visitStringConcat(HStringConcat node) { |
| 814 // Simplify string concat: | 814 // Simplify string concat: |
| 815 // | 815 // |
| 816 // "" + R -> R | 816 // "" + R -> R |
| 817 // L + "" -> L | 817 // L + "" -> L |
| 818 // "L" + "R" -> "LR" | 818 // "L" + "R" -> "LR" |
| 819 // (prefix + "L") + "R" -> prefix + "LR" | 819 // (prefix + "L") + "R" -> prefix + "LR" |
| 820 // | 820 // |
| 821 StringConstant getString(HInstruction instruction) { | 821 StringConstantValue getString(HInstruction instruction) { |
| 822 if (!instruction.isConstantString()) return null; | 822 if (!instruction.isConstantString()) return null; |
| 823 HConstant constant = instruction; | 823 HConstant constant = instruction; |
| 824 return constant.constant; | 824 return constant.constant; |
| 825 } | 825 } |
| 826 | 826 |
| 827 StringConstant leftString = getString(node.left); | 827 StringConstantValue leftString = getString(node.left); |
| 828 if (leftString != null && leftString.value.length == 0) return node.right; | 828 if (leftString != null && leftString.primitiveValue.length == 0) return node .right; |
|
sigurdm
2014/10/01 07:46:48
Long line
Johnni Winther
2014/10/01 08:21:24
Done.
| |
| 829 | 829 |
| 830 StringConstant rightString = getString(node.right); | 830 StringConstantValue rightString = getString(node.right); |
| 831 if (rightString == null) return node; | 831 if (rightString == null) return node; |
| 832 if (rightString.value.length == 0) return node.left; | 832 if (rightString.primitiveValue.length == 0) return node.left; |
| 833 | 833 |
| 834 HInstruction prefix = null; | 834 HInstruction prefix = null; |
| 835 if (leftString == null) { | 835 if (leftString == null) { |
| 836 if (node.left is! HStringConcat) return node; | 836 if (node.left is! HStringConcat) return node; |
| 837 HStringConcat leftConcat = node.left; | 837 HStringConcat leftConcat = node.left; |
| 838 // Don't undo CSE. | 838 // Don't undo CSE. |
| 839 if (leftConcat.usedBy.length != 1) return node; | 839 if (leftConcat.usedBy.length != 1) return node; |
| 840 prefix = leftConcat.left; | 840 prefix = leftConcat.left; |
| 841 leftString = getString(leftConcat.right); | 841 leftString = getString(leftConcat.right); |
| 842 if (leftString == null) return node; | 842 if (leftString == null) return node; |
| 843 } | 843 } |
| 844 | 844 |
| 845 if (leftString.value.length + rightString.value.length > | 845 if (leftString.primitiveValue.length + rightString.primitiveValue.length > |
| 846 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) { | 846 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) { |
| 847 if (node.usedBy.length > 1) return node; | 847 if (node.usedBy.length > 1) return node; |
| 848 } | 848 } |
| 849 | 849 |
| 850 HInstruction folded = graph.addConstant( | 850 HInstruction folded = graph.addConstant( |
| 851 constantSystem.createString( | 851 constantSystem.createString( |
| 852 new ast.DartString.concat(leftString.value, rightString.value)), | 852 new ast.DartString.concat(leftString.primitiveValue, rightString.pri mitiveValue)), |
| 853 compiler); | 853 compiler); |
| 854 if (prefix == null) return folded; | 854 if (prefix == null) return folded; |
| 855 return new HStringConcat(prefix, folded, node.node, backend.stringType); | 855 return new HStringConcat(prefix, folded, node.node, backend.stringType); |
| 856 } | 856 } |
| 857 | 857 |
| 858 HInstruction visitStringify(HStringify node) { | 858 HInstruction visitStringify(HStringify node) { |
| 859 HInstruction input = node.inputs[0]; | 859 HInstruction input = node.inputs[0]; |
| 860 if (input.isString(compiler)) return input; | 860 if (input.isString(compiler)) return input; |
| 861 if (input.isConstant()) { | 861 if (input.isConstant()) { |
| 862 HConstant constant = input; | 862 HConstant constant = input; |
| 863 if (!constant.constant.isPrimitive) return node; | 863 if (!constant.constant.isPrimitive) return node; |
| 864 if (constant.constant.isInt) { | 864 if (constant.constant.isInt) { |
| 865 // Only constant-fold int.toString() when Dart and JS results the same. | 865 // Only constant-fold int.toString() when Dart and JS results the same. |
| 866 // TODO(18103): We should be able to remove this work-around when issue | 866 // TODO(18103): We should be able to remove this work-around when issue |
| 867 // 18103 is resolved by providing the correct string. | 867 // 18103 is resolved by providing the correct string. |
| 868 IntConstant intConstant = constant.constant; | 868 IntConstantValue intConstant = constant.constant; |
| 869 // Very conservative range. | 869 // Very conservative range. |
| 870 if (!intConstant.isUInt32()) return node; | 870 if (!intConstant.isUInt32()) return node; |
| 871 } | 871 } |
| 872 PrimitiveConstant primitive = constant.constant; | 872 PrimitiveConstantValue primitive = constant.constant; |
| 873 return graph.addConstant(constantSystem.createString( | 873 return graph.addConstant(constantSystem.createString( |
| 874 primitive.toDartString()), compiler); | 874 primitive.toDartString()), compiler); |
| 875 } | 875 } |
| 876 return node; | 876 return node; |
| 877 } | 877 } |
| 878 | 878 |
| 879 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { | 879 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { |
| 880 return handleInterceptedCall(node); | 880 return handleInterceptedCall(node); |
| 881 } | 881 } |
| 882 } | 882 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 962 | 962 |
| 963 final Compiler compiler; | 963 final Compiler compiler; |
| 964 SsaLiveBlockAnalyzer analyzer; | 964 SsaLiveBlockAnalyzer analyzer; |
| 965 bool eliminatedSideEffects = false; | 965 bool eliminatedSideEffects = false; |
| 966 SsaDeadCodeEliminator(this.compiler); | 966 SsaDeadCodeEliminator(this.compiler); |
| 967 | 967 |
| 968 HInstruction zapInstructionCache; | 968 HInstruction zapInstructionCache; |
| 969 HInstruction get zapInstruction { | 969 HInstruction get zapInstruction { |
| 970 if (zapInstructionCache == null) { | 970 if (zapInstructionCache == null) { |
| 971 // A constant with no type does not pollute types at phi nodes. | 971 // A constant with no type does not pollute types at phi nodes. |
| 972 Constant constant = new DummyConstant(const TypeMask.nonNullEmpty()); | 972 ConstantValue constant = new DummyConstantValue(const TypeMask.nonNullEmpt y()); |
|
sigurdm
2014/10/01 07:46:48
Long line
Johnni Winther
2014/10/01 08:21:24
Done.
| |
| 973 zapInstructionCache = analyzer.graph.addConstant(constant, compiler); | 973 zapInstructionCache = analyzer.graph.addConstant(constant, compiler); |
| 974 } | 974 } |
| 975 return zapInstructionCache; | 975 return zapInstructionCache; |
| 976 } | 976 } |
| 977 | 977 |
| 978 /// Returns whether the next throwing instruction that may have side | 978 /// Returns whether the next throwing instruction that may have side |
| 979 /// effects after [instruction], throws [NoSuchMethodError] on the | 979 /// effects after [instruction], throws [NoSuchMethodError] on the |
| 980 /// same receiver of [instruction]. | 980 /// same receiver of [instruction]. |
| 981 bool hasFollowingThrowingNSM(HInstruction instruction) { | 981 bool hasFollowingThrowingNSM(HInstruction instruction) { |
| 982 HInstruction receiver = instruction.getDartReceiver(compiler); | 982 HInstruction receiver = instruction.getDartReceiver(compiler); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 switchRange.lower is IntValue && | 1149 switchRange.lower is IntValue && |
| 1150 switchRange.upper is IntValue) { | 1150 switchRange.upper is IntValue) { |
| 1151 IntValue lowerValue = switchRange.lower; | 1151 IntValue lowerValue = switchRange.lower; |
| 1152 IntValue upperValue = switchRange.upper; | 1152 IntValue upperValue = switchRange.upper; |
| 1153 int lower = lowerValue.value; | 1153 int lower = lowerValue.value; |
| 1154 int upper = upperValue.value; | 1154 int upper = upperValue.value; |
| 1155 Set<int> liveLabels = new Set<int>(); | 1155 Set<int> liveLabels = new Set<int>(); |
| 1156 for (int pos = 1; pos < node.inputs.length; pos++) { | 1156 for (int pos = 1; pos < node.inputs.length; pos++) { |
| 1157 HConstant input = node.inputs[pos]; | 1157 HConstant input = node.inputs[pos]; |
| 1158 if (!input.isConstantInteger()) continue; | 1158 if (!input.isConstantInteger()) continue; |
| 1159 IntConstant constant = input.constant; | 1159 IntConstantValue constant = input.constant; |
| 1160 int label = constant.value; | 1160 int label = constant.primitiveValue; |
| 1161 if (!liveLabels.contains(label) && | 1161 if (!liveLabels.contains(label) && |
| 1162 label <= upper && | 1162 label <= upper && |
| 1163 label >= lower) { | 1163 label >= lower) { |
| 1164 markBlockLive(node.block.successors[pos - 1]); | 1164 markBlockLive(node.block.successors[pos - 1]); |
| 1165 liveLabels.add(label); | 1165 liveLabels.add(label); |
| 1166 } | 1166 } |
| 1167 } | 1167 } |
| 1168 if (liveLabels.length != upper - lower + 1) { | 1168 if (liveLabels.length != upper - lower + 1) { |
| 1169 markBlockLive(node.defaultTarget); | 1169 markBlockLive(node.defaultTarget); |
| 1170 } | 1170 } |
| (...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2139 | 2139 |
| 2140 keyedValues.forEach((receiver, values) { | 2140 keyedValues.forEach((receiver, values) { |
| 2141 result.keyedValues[receiver] = | 2141 result.keyedValues[receiver] = |
| 2142 new Map<HInstruction, HInstruction>.from(values); | 2142 new Map<HInstruction, HInstruction>.from(values); |
| 2143 }); | 2143 }); |
| 2144 | 2144 |
| 2145 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2145 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2146 return result; | 2146 return result; |
| 2147 } | 2147 } |
| 2148 } | 2148 } |
| OLD | NEW |