| 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 import '../compiler.dart' show Compiler; | |
| 6 import '../constant_system_dart.dart'; | 5 import '../constant_system_dart.dart'; |
| 7 import '../constants/constant_system.dart'; | 6 import '../constants/constant_system.dart'; |
| 8 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
| 9 import '../js_backend/js_backend.dart'; | 8 import '../js_backend/js_backend.dart'; |
| 9 import '../js_backend/backend_helpers.dart'; |
| 10 import '../world.dart' show ClosedWorld; | 10 import '../world.dart' show ClosedWorld; |
| 11 import 'nodes.dart'; | 11 import 'nodes.dart'; |
| 12 import 'optimize.dart'; | 12 import 'optimize.dart'; |
| 13 | 13 |
| 14 class ValueRangeInfo { | 14 class ValueRangeInfo { |
| 15 final ConstantSystem constantSystem; | 15 final ConstantSystem constantSystem; |
| 16 | 16 |
| 17 IntValue intZero; | 17 IntValue intZero; |
| 18 IntValue intOne; | 18 IntValue intOne; |
| 19 | 19 |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 * save them here in order to remove them once the phase is done. | 594 * save them here in order to remove them once the phase is done. |
| 595 */ | 595 */ |
| 596 final List<HRangeConversion> conversions = <HRangeConversion>[]; | 596 final List<HRangeConversion> conversions = <HRangeConversion>[]; |
| 597 | 597 |
| 598 /** | 598 /** |
| 599 * Value ranges for integer instructions. This map gets populated by | 599 * Value ranges for integer instructions. This map gets populated by |
| 600 * the dominator tree visit. | 600 * the dominator tree visit. |
| 601 */ | 601 */ |
| 602 final Map<HInstruction, Range> ranges = new Map<HInstruction, Range>(); | 602 final Map<HInstruction, Range> ranges = new Map<HInstruction, Range>(); |
| 603 | 603 |
| 604 final Compiler compiler; | 604 final BackendHelpers backendHelpers; |
| 605 final ClosedWorld closedWorld; | 605 final ClosedWorld closedWorld; |
| 606 final ConstantSystem constantSystem; | |
| 607 final ValueRangeInfo info; | 606 final ValueRangeInfo info; |
| 608 final SsaOptimizerTask optimizer; | 607 final SsaOptimizerTask optimizer; |
| 609 | 608 |
| 610 HGraph graph; | 609 HGraph graph; |
| 611 | 610 |
| 612 SsaValueRangeAnalyzer( | 611 SsaValueRangeAnalyzer( |
| 613 this.compiler, this.closedWorld, constantSystem, this.optimizer) | 612 this.backendHelpers, ClosedWorld closedWorld, this.optimizer) |
| 614 : info = new ValueRangeInfo(constantSystem), | 613 : info = new ValueRangeInfo(closedWorld.constantSystem), |
| 615 this.constantSystem = constantSystem; | 614 this.closedWorld = closedWorld; |
| 615 |
| 616 ConstantSystem get constantSystem => closedWorld.constantSystem; |
| 616 | 617 |
| 617 void visitGraph(HGraph graph) { | 618 void visitGraph(HGraph graph) { |
| 618 this.graph = graph; | 619 this.graph = graph; |
| 619 visitDominatorTree(graph); | 620 visitDominatorTree(graph); |
| 620 // We remove the range conversions after visiting the graph so | 621 // We remove the range conversions after visiting the graph so |
| 621 // that the graph does not get polluted with these instructions | 622 // that the graph does not get polluted with these instructions |
| 622 // only necessary for this phase. | 623 // only necessary for this phase. |
| 623 removeRangeConversion(); | 624 removeRangeConversion(); |
| 624 // TODO(herhut): Find a cleaner way to pass around ranges. | 625 // TODO(herhut): Find a cleaner way to pass around ranges. |
| 625 optimizer.ranges = ranges; | 626 optimizer.ranges = ranges; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 if (constantNum.isMinusZero) constantNum = new IntConstantValue(0); | 696 if (constantNum.isMinusZero) constantNum = new IntConstantValue(0); |
| 696 Value value = info.newIntValue(constantNum.primitiveValue); | 697 Value value = info.newIntValue(constantNum.primitiveValue); |
| 697 return info.newNormalizedRange(value, value); | 698 return info.newNormalizedRange(value, value); |
| 698 } | 699 } |
| 699 | 700 |
| 700 Range visitFieldGet(HFieldGet fieldGet) { | 701 Range visitFieldGet(HFieldGet fieldGet) { |
| 701 if (!fieldGet.isInteger(closedWorld)) return info.newUnboundRange(); | 702 if (!fieldGet.isInteger(closedWorld)) return info.newUnboundRange(); |
| 702 if (!fieldGet.receiver.isIndexablePrimitive(closedWorld)) { | 703 if (!fieldGet.receiver.isIndexablePrimitive(closedWorld)) { |
| 703 return visitInstruction(fieldGet); | 704 return visitInstruction(fieldGet); |
| 704 } | 705 } |
| 705 JavaScriptBackend backend = compiler.backend; | 706 assert(fieldGet.element == backendHelpers.jsIndexableLength); |
| 706 assert(fieldGet.element == backend.helpers.jsIndexableLength); | |
| 707 PositiveValue value = info.newPositiveValue(fieldGet); | 707 PositiveValue value = info.newPositiveValue(fieldGet); |
| 708 // We know this range is above zero. To simplify the analysis, we | 708 // We know this range is above zero. To simplify the analysis, we |
| 709 // put the zero value as the lower bound of this range. This | 709 // put the zero value as the lower bound of this range. This |
| 710 // allows to easily remove the second bound check in the following | 710 // allows to easily remove the second bound check in the following |
| 711 // expression: a[1] + a[0]. | 711 // expression: a[1] + a[0]. |
| 712 return info.newNormalizedRange(info.intZero, value); | 712 return info.newNormalizedRange(info.intZero, value); |
| 713 } | 713 } |
| 714 | 714 |
| 715 Range visitBoundsCheck(HBoundsCheck check) { | 715 Range visitBoundsCheck(HBoundsCheck check) { |
| 716 // Save the next instruction, in case the check gets removed. | 716 // Save the next instruction, in case the check gets removed. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 if (!left.isInteger(closedWorld)) return info.newUnboundRange(); | 783 if (!left.isInteger(closedWorld)) return info.newUnboundRange(); |
| 784 if (!right.isInteger(closedWorld)) return info.newUnboundRange(); | 784 if (!right.isInteger(closedWorld)) return info.newUnboundRange(); |
| 785 BinaryOperation operation = relational.operation(constantSystem); | 785 BinaryOperation operation = relational.operation(constantSystem); |
| 786 Range rightRange = ranges[relational.right]; | 786 Range rightRange = ranges[relational.right]; |
| 787 Range leftRange = ranges[relational.left]; | 787 Range leftRange = ranges[relational.left]; |
| 788 | 788 |
| 789 if (relational is HIdentity) { | 789 if (relational is HIdentity) { |
| 790 handleEqualityCheck(relational); | 790 handleEqualityCheck(relational); |
| 791 } else if (operation.apply(leftRange, rightRange)) { | 791 } else if (operation.apply(leftRange, rightRange)) { |
| 792 relational.block | 792 relational.block |
| 793 .rewrite(relational, graph.addConstantBool(true, compiler)); | 793 .rewrite(relational, graph.addConstantBool(true, closedWorld)); |
| 794 relational.block.remove(relational); | 794 relational.block.remove(relational); |
| 795 } else if (negateOperation(operation).apply(leftRange, rightRange)) { | 795 } else if (negateOperation(operation).apply(leftRange, rightRange)) { |
| 796 relational.block | 796 relational.block |
| 797 .rewrite(relational, graph.addConstantBool(false, compiler)); | 797 .rewrite(relational, graph.addConstantBool(false, closedWorld)); |
| 798 relational.block.remove(relational); | 798 relational.block.remove(relational); |
| 799 } | 799 } |
| 800 return info.newUnboundRange(); | 800 return info.newUnboundRange(); |
| 801 } | 801 } |
| 802 | 802 |
| 803 void handleEqualityCheck(HRelational node) { | 803 void handleEqualityCheck(HRelational node) { |
| 804 Range right = ranges[node.right]; | 804 Range right = ranges[node.right]; |
| 805 Range left = ranges[node.left]; | 805 Range left = ranges[node.left]; |
| 806 if (left.isSingleValue && right.isSingleValue && left == right) { | 806 if (left.isSingleValue && right.isSingleValue && left == right) { |
| 807 node.block.rewrite(node, graph.addConstantBool(true, compiler)); | 807 node.block.rewrite(node, graph.addConstantBool(true, closedWorld)); |
| 808 node.block.remove(node); | 808 node.block.remove(node); |
| 809 } | 809 } |
| 810 } | 810 } |
| 811 | 811 |
| 812 Range handleInvokeModulo(HInvokeDynamicMethod invoke) { | 812 Range handleInvokeModulo(HInvokeDynamicMethod invoke) { |
| 813 HInstruction left = invoke.inputs[1]; | 813 HInstruction left = invoke.inputs[1]; |
| 814 HInstruction right = invoke.inputs[2]; | 814 HInstruction right = invoke.inputs[2]; |
| 815 Range divisor = ranges[right]; | 815 Range divisor = ranges[right]; |
| 816 if (divisor != null) { | 816 if (divisor != null) { |
| 817 // For Integer values we can be precise in the upper bound, | 817 // For Integer values we can be precise in the upper bound, |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 Range handleBinaryOperation(HBinaryArithmetic instruction) { | 1084 Range handleBinaryOperation(HBinaryArithmetic instruction) { |
| 1085 Range leftRange = visit(instruction.left); | 1085 Range leftRange = visit(instruction.left); |
| 1086 Range rightRange = visit(instruction.right); | 1086 Range rightRange = visit(instruction.right); |
| 1087 if (leftRange == null || rightRange == null) return null; | 1087 if (leftRange == null || rightRange == null) return null; |
| 1088 BinaryOperation operation = instruction.operation(info.constantSystem); | 1088 BinaryOperation operation = instruction.operation(info.constantSystem); |
| 1089 return operation.apply(leftRange, rightRange); | 1089 return operation.apply(leftRange, rightRange); |
| 1090 } | 1090 } |
| 1091 } | 1091 } |
| OLD | NEW |