# HG changeset patch # User Andreas Woess # Date 1373894941 -7200 # Node ID f4f46b734a4c73f0bb95bcc06344cabe96b50929 # Parent 9f5a4074e36b282a98c16a1d5962f86f0da173dd# Parent 7f6580db1e889403398bea2188830af505647598 Merge diff -r 7f6580db1e88 -r f4f46b734a4c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 14:49:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 15:29:01 2013 +0200 @@ -22,8 +22,13 @@ */ package com.oracle.graal.compiler.test; +import static org.junit.Assert.*; + import org.junit.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; /** @@ -89,4 +94,82 @@ test("search", e2, "e3", new Entry("e4")); } + + @SuppressWarnings("unused") + public static int testNullnessSnippet(Object a, Object b) { + if (a == null) { + if (a == b) { + if (b == null) { + return 1; + } else { + return -2; + } + } else { + if (b == null) { + return 3; + } else { + return 4; + } + } + } else { + if (a == b) { + if (b == null) { + return -5; + } else { + return 6; + } + } else { + if (b == null) { + return 7; + } else { + return 8; + } + } + } + } + + @Test + public void testNullness() { + test("testNullnessSnippet", null, null); + test("testNullnessSnippet", null, new Object()); + test("testNullnessSnippet", new Object(), null); + test("testNullnessSnippet", new Object(), new Object()); + + StructuredGraph graph = parse("testNullnessSnippet"); + new ConditionalEliminationPhase(runtime()).apply(graph); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { + assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); + } + } + + @SuppressWarnings("unused") + public static int testDisjunctionSnippet(Object a) { + if (a instanceof Integer) { + if (a == null) { + return -1; + } else { + return 2; + } + } else { + return 3; + } + } + + @Test + public void testDisjunction() { + StructuredGraph graph = parse("testDisjunctionSnippet"); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + IfNode ifNode = (IfNode) graph.start().next(); + InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition(); + LogicDisjunctionNode disjunction = graph.unique(new LogicDisjunctionNode(graph.unique(new IsNullNode(graph.getLocal(0))), instanceOf)); + ifNode.setCondition(disjunction); + ifNode.negate(disjunction); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new ConditionalEliminationPhase(runtime()).apply(graph); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { + assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); + } + } } diff -r 7f6580db1e88 -r f4f46b734a4c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 14:49:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 15:29:01 2013 +0200 @@ -315,42 +315,48 @@ } private void registerCondition(boolean isTrue, LogicNode condition, ValueNode anchor) { - state.addCondition(isTrue, condition, anchor); + if (!isTrue && condition instanceof LogicDisjunctionNode) { + LogicDisjunctionNode disjunction = (LogicDisjunctionNode) condition; + registerCondition(disjunction.isXNegated(), disjunction.getX(), anchor); + registerCondition(disjunction.isYNegated(), disjunction.getY(), anchor); + } else { + state.addCondition(isTrue, condition, anchor); - if (isTrue && condition instanceof InstanceOfNode) { - InstanceOfNode instanceOf = (InstanceOfNode) condition; - ValueNode object = instanceOf.object(); - state.addNullness(false, object); - state.addType(instanceOf.type(), object); - } else if (condition instanceof IsNullNode) { - IsNullNode nullCheck = (IsNullNode) condition; - state.addNullness(isTrue, nullCheck.object()); - } else if (condition instanceof ObjectEqualsNode) { - ObjectEqualsNode equals = (ObjectEqualsNode) condition; - ValueNode x = equals.x(); - ValueNode y = equals.y(); - if (isTrue) { - if (state.isNull(x) && !state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, y); - } else if (!state.isNull(x) && state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, x); - } - if (state.isNonNull(x) && !state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, y); - } else if (!state.isNonNull(x) && state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, x); - } - } else { - if (state.isNull(x) && !state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, y); - } else if (!state.isNonNull(x) && state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, x); + if (isTrue && condition instanceof InstanceOfNode) { + InstanceOfNode instanceOf = (InstanceOfNode) condition; + ValueNode object = instanceOf.object(); + state.addNullness(false, object); + state.addType(instanceOf.type(), object); + } else if (condition instanceof IsNullNode) { + IsNullNode nullCheck = (IsNullNode) condition; + state.addNullness(isTrue, nullCheck.object()); + } else if (condition instanceof ObjectEqualsNode) { + ObjectEqualsNode equals = (ObjectEqualsNode) condition; + ValueNode x = equals.x(); + ValueNode y = equals.y(); + if (isTrue) { + if (state.isNull(x) && !state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(true, y); + } else if (!state.isNull(x) && state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(true, x); + } + if (state.isNonNull(x) && !state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, y); + } else if (!state.isNonNull(x) && state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, x); + } + } else { + if (state.isNull(x) && !state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, y); + } else if (!state.isNonNull(x) && state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, x); + } } } }