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 |