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 |