888 } else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) {
889 conditional = (ConditionalNode) falseValue;
890 constant = trueValue;
891 negateCondition = false;
892 } else {
893 return null;
894 }
895 boolean negateConditionalCondition = false;
896 ValueNode otherValue = null;
897 if (constant == conditional.trueValue()) {
898 otherValue = conditional.falseValue();
899 negateConditionalCondition = false;
900 } else if (constant == conditional.falseValue()) {
901 otherValue = conditional.trueValue();
902 negateConditionalCondition = true;
903 }
904 if (otherValue != null && otherValue.isConstant()) {
905 double shortCutProbability = probability(trueSuccessor());
906 LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability);
907 return graph().unique(new ConditionalNode(newCondition, constant, otherValue));
908 } else if (!negateCondition && constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant()) {
909 IntegerLessThanNode lessThan = null;
910 IntegerEqualsNode equals = null;
911 if (condition() instanceof IntegerLessThanNode && conditional.condition() instanceof IntegerEqualsNode && constant.asJavaConstant().asLong() == -1 &&
912 conditional.trueValue().asJavaConstant().asLong() == 0 && conditional.falseValue().asJavaConstant().asLong() == 1) {
913 lessThan = (IntegerLessThanNode) condition();
914 equals = (IntegerEqualsNode) conditional.condition();
915 } else if (condition() instanceof IntegerEqualsNode && conditional.condition() instanceof IntegerLessThanNode && constant.asJavaConstant().asLong() == 0 &&
916 conditional.trueValue().asJavaConstant().asLong() == -1 && conditional.falseValue().asJavaConstant().asLong() == 1) {
917 lessThan = (IntegerLessThanNode) conditional.condition();
918 equals = (IntegerEqualsNode) condition();
919 }
920 if (lessThan != null) {
921 assert equals != null;
922 NodeView view = NodeView.from(tool);
923 if ((lessThan.getX() == equals.getX() && lessThan.getY() == equals.getY()) || (lessThan.getX() == equals.getY() && lessThan.getY() == equals.getX())) {
924 return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp(view).getStackKind(), false));
925 }
926 }
927 }
928 }
929 return null;
930 }
931
932 /**
933 * Take an if that is immediately dominated by a merge with a single phi and split off any paths
934 * where the test would be statically decidable creating a new merge below the approriate side
935 * of the IfNode. Any undecidable tests will continue to use the original IfNode.
936 *
937 * @param tool
938 */
939 @SuppressWarnings("try")
940 private boolean splitIfAtPhi(SimplifierTool tool) {
941 if (graph().getGuardsStage().areFrameStatesAtSideEffects()) {
942 // Disabled until we make sure we have no FrameState-less merges at this stage
943 return false;
944 }
|
888 } else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) {
889 conditional = (ConditionalNode) falseValue;
890 constant = trueValue;
891 negateCondition = false;
892 } else {
893 return null;
894 }
895 boolean negateConditionalCondition = false;
896 ValueNode otherValue = null;
897 if (constant == conditional.trueValue()) {
898 otherValue = conditional.falseValue();
899 negateConditionalCondition = false;
900 } else if (constant == conditional.falseValue()) {
901 otherValue = conditional.trueValue();
902 negateConditionalCondition = true;
903 }
904 if (otherValue != null && otherValue.isConstant()) {
905 double shortCutProbability = probability(trueSuccessor());
906 LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability);
907 return graph().unique(new ConditionalNode(newCondition, constant, otherValue));
908 } else if (constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant() && condition() instanceof CompareNode &&
909 conditional.condition() instanceof CompareNode) {
910 Condition cond1 = ((CompareNode) condition()).condition().asCondition();
911 if (negateCondition) {
912 cond1 = cond1.negate();
913 }
914 // cond1 is EQ, NE, LT, or GE
915 Condition cond2 = ((CompareNode) conditional.condition()).condition().asCondition();
916 ValueNode x = ((CompareNode) condition()).getX();
917 ValueNode y = ((CompareNode) condition()).getY();
918 ValueNode x2 = ((CompareNode) conditional.condition()).getX();
919 ValueNode y2 = ((CompareNode) conditional.condition()).getY();
920 // `x cond1 y ? c1 : (x2 cond2 y2 ? c2 : c3)`
921 boolean sameVars = x == x2 && y == y2;
922 if (!sameVars && x == y2 && y == x2) {
923 sameVars = true;
924 cond2 = cond2.mirror();
925 }
926 // cond2 is EQ, LT, or GT
927 if (sameVars) {
928 JavaKind stackKind = conditional.trueValue().stamp(NodeView.from(tool)).getStackKind();
929 assert !stackKind.isNumericFloat();
930 long c1 = constant.asJavaConstant().asLong();
931 long c2 = conditional.trueValue().asJavaConstant().asLong();
932 long c3 = conditional.falseValue().asJavaConstant().asLong();
933 // `x cond1 y ? c1 : (x cond2 y ? c2 : c3)`
934 if (cond1 == Condition.GE && cond2 == Condition.LT) {
935 // x >= y ? v1 : (x < y ? v2 : v3) => x >= y ? v1 : v2
936 return graph().unique(new ConditionalNode(condition(), conditional.trueValue(), constant));
937 } else if (cond1 == Condition.GE && cond2 == Condition.GT) {
938 // x >= y ? v1 : (x > y ? v2 : v3) => x >= y ? v1 : v3
939 return graph().unique(new ConditionalNode(condition(), conditional.falseValue(), constant));
940 } else if (cond1 == Condition.EQ && cond2 == Condition.EQ) {
941 // x == y ? v1 : (x == y ? v2 : v3) => x == y ? v1 : v3
942 return graph().unique(new ConditionalNode(condition(), conditional.falseValue(), constant));
943 } else if (cond1 == Condition.NE && cond2 == Condition.LT) {
944 // x != y ? v1 : (x < y ? v2 : v3) => x != y ? v1 : v3
945 return graph().unique(new ConditionalNode(condition(), conditional.falseValue(), constant));
946 } else if (cond1 == Condition.LT && cond2 == Condition.EQ && c1 == -1 && c2 == 0 && c3 == 1) {
947 // x < y ? -1 : (x == y ? 0 : 1) => x cmp y
948 return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
949 } else if (cond1 == Condition.LT && cond2 == Condition.EQ && c1 == 1 && c2 == 0 && c3 == -1) {
950 // x < y ? 1 : (x == y ? 0 : -1) => y cmp x
951 return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
952 } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == -1 && c3 == 1) {
953 // x == y ? 0 : (x < y ? -1 : 1) => x cmp y
954 return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
955 } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == 1 && c3 == -1) {
956 // x == y ? 0 : (x < y ? 1 : -1) => y cmp x
957 return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
958 } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == -1 && c3 == 1) {
959 // x == y ? 0 : (x > y ? -1 : 1) => y cmp x
960 return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
961 } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == 1 && c3 == -1) {
962 // x == y ? 0 : (x > y ? 1 : -1) => x cmp y
963 return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
964 } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == 1 && c2 == -1 && c3 == 0) {
965 // x < y ? 1 : (x > y ? -1 : 0) => y cmp x
966 return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
967 } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == -1 && c2 == 1 && c3 == 0) {
968 // x < y ? -1 : (x > y ? 1 : 0) => x cmp y
969 return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
970 }
971 }
972 }
973 }
974 return null;
975 }
976
977 /**
978 * Take an if that is immediately dominated by a merge with a single phi and split off any paths
979 * where the test would be statically decidable creating a new merge below the approriate side
980 * of the IfNode. Any undecidable tests will continue to use the original IfNode.
981 *
982 * @param tool
983 */
984 @SuppressWarnings("try")
985 private boolean splitIfAtPhi(SimplifierTool tool) {
986 if (graph().getGuardsStage().areFrameStatesAtSideEffects()) {
987 // Disabled until we make sure we have no FrameState-less merges at this stage
988 return false;
989 }
|