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) { |
| 829 return node.right; |
| 830 } |
829 | 831 |
830 StringConstant rightString = getString(node.right); | 832 StringConstantValue rightString = getString(node.right); |
831 if (rightString == null) return node; | 833 if (rightString == null) return node; |
832 if (rightString.value.length == 0) return node.left; | 834 if (rightString.primitiveValue.length == 0) return node.left; |
833 | 835 |
834 HInstruction prefix = null; | 836 HInstruction prefix = null; |
835 if (leftString == null) { | 837 if (leftString == null) { |
836 if (node.left is! HStringConcat) return node; | 838 if (node.left is! HStringConcat) return node; |
837 HStringConcat leftConcat = node.left; | 839 HStringConcat leftConcat = node.left; |
838 // Don't undo CSE. | 840 // Don't undo CSE. |
839 if (leftConcat.usedBy.length != 1) return node; | 841 if (leftConcat.usedBy.length != 1) return node; |
840 prefix = leftConcat.left; | 842 prefix = leftConcat.left; |
841 leftString = getString(leftConcat.right); | 843 leftString = getString(leftConcat.right); |
842 if (leftString == null) return node; | 844 if (leftString == null) return node; |
843 } | 845 } |
844 | 846 |
845 if (leftString.value.length + rightString.value.length > | 847 if (leftString.primitiveValue.length + rightString.primitiveValue.length > |
846 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) { | 848 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) { |
847 if (node.usedBy.length > 1) return node; | 849 if (node.usedBy.length > 1) return node; |
848 } | 850 } |
849 | 851 |
850 HInstruction folded = graph.addConstant( | 852 HInstruction folded = graph.addConstant( |
851 constantSystem.createString( | 853 constantSystem.createString(new ast.DartString.concat( |
852 new ast.DartString.concat(leftString.value, rightString.value)), | 854 leftString.primitiveValue, rightString.primitiveValue)), |
853 compiler); | 855 compiler); |
854 if (prefix == null) return folded; | 856 if (prefix == null) return folded; |
855 return new HStringConcat(prefix, folded, node.node, backend.stringType); | 857 return new HStringConcat(prefix, folded, node.node, backend.stringType); |
856 } | 858 } |
857 | 859 |
858 HInstruction visitStringify(HStringify node) { | 860 HInstruction visitStringify(HStringify node) { |
859 HInstruction input = node.inputs[0]; | 861 HInstruction input = node.inputs[0]; |
860 if (input.isString(compiler)) return input; | 862 if (input.isString(compiler)) return input; |
861 if (input.isConstant()) { | 863 if (input.isConstant()) { |
862 HConstant constant = input; | 864 HConstant constant = input; |
863 if (!constant.constant.isPrimitive) return node; | 865 if (!constant.constant.isPrimitive) return node; |
864 if (constant.constant.isInt) { | 866 if (constant.constant.isInt) { |
865 // Only constant-fold int.toString() when Dart and JS results the same. | 867 // 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 | 868 // TODO(18103): We should be able to remove this work-around when issue |
867 // 18103 is resolved by providing the correct string. | 869 // 18103 is resolved by providing the correct string. |
868 IntConstant intConstant = constant.constant; | 870 IntConstantValue intConstant = constant.constant; |
869 // Very conservative range. | 871 // Very conservative range. |
870 if (!intConstant.isUInt32()) return node; | 872 if (!intConstant.isUInt32()) return node; |
871 } | 873 } |
872 PrimitiveConstant primitive = constant.constant; | 874 PrimitiveConstantValue primitive = constant.constant; |
873 return graph.addConstant(constantSystem.createString( | 875 return graph.addConstant(constantSystem.createString( |
874 primitive.toDartString()), compiler); | 876 primitive.toDartString()), compiler); |
875 } | 877 } |
876 return node; | 878 return node; |
877 } | 879 } |
878 | 880 |
879 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { | 881 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { |
880 return handleInterceptedCall(node); | 882 return handleInterceptedCall(node); |
881 } | 883 } |
882 } | 884 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 964 |
963 final Compiler compiler; | 965 final Compiler compiler; |
964 SsaLiveBlockAnalyzer analyzer; | 966 SsaLiveBlockAnalyzer analyzer; |
965 bool eliminatedSideEffects = false; | 967 bool eliminatedSideEffects = false; |
966 SsaDeadCodeEliminator(this.compiler); | 968 SsaDeadCodeEliminator(this.compiler); |
967 | 969 |
968 HInstruction zapInstructionCache; | 970 HInstruction zapInstructionCache; |
969 HInstruction get zapInstruction { | 971 HInstruction get zapInstruction { |
970 if (zapInstructionCache == null) { | 972 if (zapInstructionCache == null) { |
971 // A constant with no type does not pollute types at phi nodes. | 973 // A constant with no type does not pollute types at phi nodes. |
972 Constant constant = new DummyConstant(const TypeMask.nonNullEmpty()); | 974 ConstantValue constant = |
| 975 new DummyConstantValue(const TypeMask.nonNullEmpty()); |
973 zapInstructionCache = analyzer.graph.addConstant(constant, compiler); | 976 zapInstructionCache = analyzer.graph.addConstant(constant, compiler); |
974 } | 977 } |
975 return zapInstructionCache; | 978 return zapInstructionCache; |
976 } | 979 } |
977 | 980 |
978 /// Returns whether the next throwing instruction that may have side | 981 /// Returns whether the next throwing instruction that may have side |
979 /// effects after [instruction], throws [NoSuchMethodError] on the | 982 /// effects after [instruction], throws [NoSuchMethodError] on the |
980 /// same receiver of [instruction]. | 983 /// same receiver of [instruction]. |
981 bool hasFollowingThrowingNSM(HInstruction instruction) { | 984 bool hasFollowingThrowingNSM(HInstruction instruction) { |
982 HInstruction receiver = instruction.getDartReceiver(compiler); | 985 HInstruction receiver = instruction.getDartReceiver(compiler); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 switchRange.lower is IntValue && | 1152 switchRange.lower is IntValue && |
1150 switchRange.upper is IntValue) { | 1153 switchRange.upper is IntValue) { |
1151 IntValue lowerValue = switchRange.lower; | 1154 IntValue lowerValue = switchRange.lower; |
1152 IntValue upperValue = switchRange.upper; | 1155 IntValue upperValue = switchRange.upper; |
1153 int lower = lowerValue.value; | 1156 int lower = lowerValue.value; |
1154 int upper = upperValue.value; | 1157 int upper = upperValue.value; |
1155 Set<int> liveLabels = new Set<int>(); | 1158 Set<int> liveLabels = new Set<int>(); |
1156 for (int pos = 1; pos < node.inputs.length; pos++) { | 1159 for (int pos = 1; pos < node.inputs.length; pos++) { |
1157 HConstant input = node.inputs[pos]; | 1160 HConstant input = node.inputs[pos]; |
1158 if (!input.isConstantInteger()) continue; | 1161 if (!input.isConstantInteger()) continue; |
1159 IntConstant constant = input.constant; | 1162 IntConstantValue constant = input.constant; |
1160 int label = constant.value; | 1163 int label = constant.primitiveValue; |
1161 if (!liveLabels.contains(label) && | 1164 if (!liveLabels.contains(label) && |
1162 label <= upper && | 1165 label <= upper && |
1163 label >= lower) { | 1166 label >= lower) { |
1164 markBlockLive(node.block.successors[pos - 1]); | 1167 markBlockLive(node.block.successors[pos - 1]); |
1165 liveLabels.add(label); | 1168 liveLabels.add(label); |
1166 } | 1169 } |
1167 } | 1170 } |
1168 if (liveLabels.length != upper - lower + 1) { | 1171 if (liveLabels.length != upper - lower + 1) { |
1169 markBlockLive(node.defaultTarget); | 1172 markBlockLive(node.defaultTarget); |
1170 } | 1173 } |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2139 | 2142 |
2140 keyedValues.forEach((receiver, values) { | 2143 keyedValues.forEach((receiver, values) { |
2141 result.keyedValues[receiver] = | 2144 result.keyedValues[receiver] = |
2142 new Map<HInstruction, HInstruction>.from(values); | 2145 new Map<HInstruction, HInstruction>.from(values); |
2143 }); | 2146 }); |
2144 | 2147 |
2145 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2148 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
2146 return result; | 2149 return result; |
2147 } | 2150 } |
2148 } | 2151 } |
OLD | NEW |