| 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 | 7 |
| 8 class ValueRangeInfo { | 8 class ValueRangeInfo { |
| 9 final ConstantSystem constantSystem; | 9 final ConstantSystem constantSystem; |
| 10 | 10 |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 BinaryOperation operation = relational.operation(constantSystem); | 767 BinaryOperation operation = relational.operation(constantSystem); |
| 768 Range rightRange = ranges[relational.right]; | 768 Range rightRange = ranges[relational.right]; |
| 769 Range leftRange = ranges[relational.left]; | 769 Range leftRange = ranges[relational.left]; |
| 770 | 770 |
| 771 if (relational is HIdentity) { | 771 if (relational is HIdentity) { |
| 772 handleEqualityCheck(relational); | 772 handleEqualityCheck(relational); |
| 773 } else if (operation.apply(leftRange, rightRange)) { | 773 } else if (operation.apply(leftRange, rightRange)) { |
| 774 relational.block.rewrite( | 774 relational.block.rewrite( |
| 775 relational, graph.addConstantBool(true, compiler)); | 775 relational, graph.addConstantBool(true, compiler)); |
| 776 relational.block.remove(relational); | 776 relational.block.remove(relational); |
| 777 } else if (reverseOperation(operation).apply(leftRange, rightRange)) { | 777 } else if (negateOperation(operation).apply(leftRange, rightRange)) { |
| 778 relational.block.rewrite( | 778 relational.block.rewrite( |
| 779 relational, graph.addConstantBool(false, compiler)); | 779 relational, graph.addConstantBool(false, compiler)); |
| 780 relational.block.remove(relational); | 780 relational.block.remove(relational); |
| 781 } | 781 } |
| 782 return info.newUnboundRange(); | 782 return info.newUnboundRange(); |
| 783 } | 783 } |
| 784 | 784 |
| 785 void handleEqualityCheck(HRelational node) { | 785 void handleEqualityCheck(HRelational node) { |
| 786 Range right = ranges[node.right]; | 786 Range right = ranges[node.right]; |
| 787 Range left = ranges[node.left]; | 787 Range left = ranges[node.left]; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 HRangeConversion newInstruction = | 878 HRangeConversion newInstruction = |
| 879 new HRangeConversion(instruction, backend.intType); | 879 new HRangeConversion(instruction, backend.intType); |
| 880 conversions.add(newInstruction); | 880 conversions.add(newInstruction); |
| 881 cursor.block.addBefore(cursor, newInstruction); | 881 cursor.block.addBefore(cursor, newInstruction); |
| 882 // Update the users of the instruction dominated by [cursor] to | 882 // Update the users of the instruction dominated by [cursor] to |
| 883 // use the new instruction, that has an narrower range. | 883 // use the new instruction, that has an narrower range. |
| 884 instruction.replaceAllUsersDominatedBy(cursor, newInstruction); | 884 instruction.replaceAllUsersDominatedBy(cursor, newInstruction); |
| 885 return newInstruction; | 885 return newInstruction; |
| 886 } | 886 } |
| 887 | 887 |
| 888 static BinaryOperation reverseOperation(BinaryOperation operation) { | 888 static BinaryOperation negateOperation(BinaryOperation operation) { |
| 889 if (operation == const LessOperation()) { | 889 if (operation == const LessOperation()) { |
| 890 return const GreaterEqualOperation(); | 890 return const GreaterEqualOperation(); |
| 891 } else if (operation == const LessEqualOperation()) { | 891 } else if (operation == const LessEqualOperation()) { |
| 892 return const GreaterOperation(); | 892 return const GreaterOperation(); |
| 893 } else if (operation == const GreaterOperation()) { | 893 } else if (operation == const GreaterOperation()) { |
| 894 return const LessEqualOperation(); | 894 return const LessEqualOperation(); |
| 895 } else if (operation == const GreaterEqualOperation()) { | 895 } else if (operation == const GreaterEqualOperation()) { |
| 896 return const LessOperation(); | 896 return const LessOperation(); |
| 897 } else { | 897 } else { |
| 898 return null; | 898 return null; |
| 899 } | 899 } |
| 900 } | 900 } |
| 901 | 901 |
| 902 static BinaryOperation flipOperation(BinaryOperation operation) { |
| 903 if (operation == const LessOperation()) { |
| 904 return const GreaterOperation(); |
| 905 } else if (operation == const LessEqualOperation()) { |
| 906 return const GreaterEqualOperation(); |
| 907 } else if (operation == const GreaterOperation()) { |
| 908 return const LessOperation(); |
| 909 } else if (operation == const GreaterEqualOperation()) { |
| 910 return const LessEqualOperation(); |
| 911 } else { |
| 912 return null; |
| 913 } |
| 914 } |
| 915 |
| 902 Range computeConstrainedRange(BinaryOperation operation, | 916 Range computeConstrainedRange(BinaryOperation operation, |
| 903 Range leftRange, | 917 Range leftRange, |
| 904 Range rightRange) { | 918 Range rightRange) { |
| 905 Range range; | 919 Range range; |
| 906 if (operation == const LessOperation()) { | 920 if (operation == const LessOperation()) { |
| 907 range = info.newNormalizedRange( | 921 range = info.newNormalizedRange( |
| 908 const MinIntValue(), rightRange.upper - info.intOne); | 922 const MinIntValue(), rightRange.upper - info.intOne); |
| 909 } else if (operation == const LessEqualOperation()) { | 923 } else if (operation == const LessEqualOperation()) { |
| 910 range = info.newNormalizedRange(const MinIntValue(), rightRange.upper); | 924 range = info.newNormalizedRange(const MinIntValue(), rightRange.upper); |
| 911 } else if (operation == const GreaterOperation()) { | 925 } else if (operation == const GreaterOperation()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 925 if (condition is !HRelational) return info.newUnboundRange(); | 939 if (condition is !HRelational) return info.newUnboundRange(); |
| 926 if (condition is HIdentity) return info.newUnboundRange(); | 940 if (condition is HIdentity) return info.newUnboundRange(); |
| 927 HInstruction right = condition.right; | 941 HInstruction right = condition.right; |
| 928 HInstruction left = condition.left; | 942 HInstruction left = condition.left; |
| 929 if (!left.isInteger(compiler)) return info.newUnboundRange(); | 943 if (!left.isInteger(compiler)) return info.newUnboundRange(); |
| 930 if (!right.isInteger(compiler)) return info.newUnboundRange(); | 944 if (!right.isInteger(compiler)) return info.newUnboundRange(); |
| 931 | 945 |
| 932 Range rightRange = ranges[right]; | 946 Range rightRange = ranges[right]; |
| 933 Range leftRange = ranges[left]; | 947 Range leftRange = ranges[left]; |
| 934 Operation operation = condition.operation(constantSystem); | 948 Operation operation = condition.operation(constantSystem); |
| 935 Operation reverse = reverseOperation(operation); | 949 Operation mirrorOp = flipOperation(operation); |
| 936 // Only update the true branch if this block is the only | 950 // Only update the true branch if this block is the only |
| 937 // predecessor. | 951 // predecessor. |
| 938 if (branch.trueBranch.predecessors.length == 1) { | 952 if (branch.trueBranch.predecessors.length == 1) { |
| 939 assert(branch.trueBranch.predecessors[0] == branch.block); | 953 assert(branch.trueBranch.predecessors[0] == branch.block); |
| 940 // Update the true branch to use narrower ranges for [left] and | 954 // Update the true branch to use narrower ranges for [left] and |
| 941 // [right]. | 955 // [right]. |
| 942 Range range = computeConstrainedRange(operation, leftRange, rightRange); | 956 Range range = computeConstrainedRange(operation, leftRange, rightRange); |
| 943 if (leftRange != range) { | 957 if (leftRange != range) { |
| 944 HInstruction instruction = | 958 HInstruction instruction = |
| 945 createRangeConversion(branch.trueBranch.first, left); | 959 createRangeConversion(branch.trueBranch.first, left); |
| 946 ranges[instruction] = range; | 960 ranges[instruction] = range; |
| 947 } | 961 } |
| 948 | 962 |
| 949 range = computeConstrainedRange(reverse, rightRange, leftRange); | 963 range = computeConstrainedRange(mirrorOp, rightRange, leftRange); |
| 950 if (rightRange != range) { | 964 if (rightRange != range) { |
| 951 HInstruction instruction = | 965 HInstruction instruction = |
| 952 createRangeConversion(branch.trueBranch.first, right); | 966 createRangeConversion(branch.trueBranch.first, right); |
| 953 ranges[instruction] = range; | 967 ranges[instruction] = range; |
| 954 } | 968 } |
| 955 } | 969 } |
| 956 | 970 |
| 957 // Only update the false branch if this block is the only | 971 // Only update the false branch if this block is the only |
| 958 // predecessor. | 972 // predecessor. |
| 959 if (branch.falseBranch.predecessors.length == 1) { | 973 if (branch.falseBranch.predecessors.length == 1) { |
| 960 assert(branch.falseBranch.predecessors[0] == branch.block); | 974 assert(branch.falseBranch.predecessors[0] == branch.block); |
| 975 Operation reverse = negateOperation(operation); |
| 976 Operation reversedMirror = flipOperation(reverse); |
| 961 // Update the false branch to use narrower ranges for [left] and | 977 // Update the false branch to use narrower ranges for [left] and |
| 962 // [right]. | 978 // [right]. |
| 963 Range range = computeConstrainedRange(reverse, leftRange, rightRange); | 979 Range range = computeConstrainedRange(reverse, leftRange, rightRange); |
| 964 if (leftRange != range) { | 980 if (leftRange != range) { |
| 965 HInstruction instruction = | 981 HInstruction instruction = |
| 966 createRangeConversion(branch.falseBranch.first, left); | 982 createRangeConversion(branch.falseBranch.first, left); |
| 967 ranges[instruction] = range; | 983 ranges[instruction] = range; |
| 968 } | 984 } |
| 969 | 985 |
| 970 range = computeConstrainedRange(operation, rightRange, leftRange); | 986 range = computeConstrainedRange(reversedMirror, rightRange, leftRange); |
| 971 if (rightRange != range) { | 987 if (rightRange != range) { |
| 972 HInstruction instruction = | 988 HInstruction instruction = |
| 973 createRangeConversion(branch.falseBranch.first, right); | 989 createRangeConversion(branch.falseBranch.first, right); |
| 974 ranges[instruction] = range; | 990 ranges[instruction] = range; |
| 975 } | 991 } |
| 976 } | 992 } |
| 977 | 993 |
| 978 return info.newUnboundRange(); | 994 return info.newUnboundRange(); |
| 979 } | 995 } |
| 980 | 996 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 } | 1066 } |
| 1051 | 1067 |
| 1052 Range handleBinaryOperation(HBinaryArithmetic instruction) { | 1068 Range handleBinaryOperation(HBinaryArithmetic instruction) { |
| 1053 Range leftRange = visit(instruction.left); | 1069 Range leftRange = visit(instruction.left); |
| 1054 Range rightRange = visit(instruction.right); | 1070 Range rightRange = visit(instruction.right); |
| 1055 if (leftRange == null || rightRange == null) return null; | 1071 if (leftRange == null || rightRange == null) return null; |
| 1056 BinaryOperation operation = instruction.operation(info.constantSystem); | 1072 BinaryOperation operation = instruction.operation(info.constantSystem); |
| 1057 return operation.apply(leftRange, rightRange); | 1073 return operation.apply(leftRange, rightRange); |
| 1058 } | 1074 } |
| 1059 } | 1075 } |
| OLD | NEW |