# HG changeset patch # User Thomas Wuerthinger # Date 1425999136 -3600 # Node ID 37969636e6f8a8e206215e57151f5f2b7f31a653 # Parent dde8a89e7f9254c09937ff20b70afc7c494308ee# Parent 39de568cbb02a18049668d52859684ecea9559f9 Merge. diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Tue Mar 10 15:52:16 2015 +0100 @@ -130,4 +130,27 @@ public void test4() { test("test4Snippet", "test4Snippet"); } + + @SuppressWarnings("all") + public static int test5Snippet(int a, int b) { + if ((b & 3) == 0) { + GraalDirectives.controlFlowAnchor(); + if ((b & 7) == 0) { + GraalDirectives.controlFlowAnchor(); + return 1; + } + } else { + GraalDirectives.controlFlowAnchor(); + if ((b & 1) == 0) { + GraalDirectives.controlFlowAnchor(); + return 2; + } + } + return 0; + } + + @Test + public void test5() { + test("test5Snippet", "test5Snippet"); + } } diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Tue Mar 10 15:52:16 2015 +0100 @@ -37,6 +37,12 @@ interface B extends A { } + static final class DistinctA { + } + + static final class DistinctB { + } + @SuppressWarnings("all") public static int reference1Snippet(A a, B b) { if (a instanceof B) { @@ -60,16 +66,14 @@ test("test1Snippet", "reference1Snippet"); } - @SuppressWarnings("all") - public static int reference2Snippet(A a, B b) { + public static int reference2Snippet(A a) { if (a instanceof B) { return 1; } return 2; } - @SuppressWarnings("all") - public static int test2Snippet(A a, B b) { + public static int test2Snippet(A a) { if (a instanceof B) { B newVal = (B) a; if (newVal != null) { @@ -83,4 +87,34 @@ public void test2() { test("test2Snippet", "reference2Snippet"); } + + @SuppressWarnings("unused") + public static int reference3Snippet(Object a, Object b) { + if (a instanceof DistinctA) { + DistinctA proxyA = (DistinctA) a; + if (b instanceof DistinctB) { + return 1; + } + } + return 2; + } + + @SuppressWarnings("all") + public static int test3Snippet(Object a, Object b) { + if (a instanceof DistinctA) { + DistinctA proxyA = (DistinctA) a; + if (b instanceof DistinctB) { + if (proxyA == b) { + return 42; + } + return 1; + } + } + return 2; + } + + @Test + public void test3() { + test("test3Snippet", "reference3Snippet", true); + } } diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Tue Mar 10 15:52:16 2015 +0100 @@ -40,6 +40,10 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest { protected void test(String snippet, String referenceSnippet) { + test(snippet, referenceSnippet, false); + } + + protected void test(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); Debug.dump(graph, "Graph"); PhaseContext context = new PhaseContext(getProviders()); @@ -52,7 +56,13 @@ canonicalizer.apply(graph, context); canonicalizer.apply(graph, context); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES); - canonicalizer.apply(referenceGraph, context); + if (applyConditionalEliminationOnReference) { + new DominatorConditionalEliminationPhase(true).apply(referenceGraph, context); + canonicalizer.apply(referenceGraph, context); + canonicalizer.apply(referenceGraph, context); + } else { + canonicalizer.apply(referenceGraph, context); + } assertEquals(referenceGraph, graph); } diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Tue Mar 10 15:52:16 2015 +0100 @@ -32,7 +32,7 @@ public final class GuardProxyNode extends ProxyNode implements GuardingNode, Proxy, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(GuardProxyNode.class); - @Input(InputType.Guard) GuardingNode value; + @OptionalInput(InputType.Guard) GuardingNode value; public GuardProxyNode(GuardingNode value, AbstractBeginNode proxyPoint) { super(TYPE, StampFactory.forVoid(), proxyPoint); @@ -50,10 +50,10 @@ @Override public ValueNode value() { - return value.asNode(); + return (value == null ? null : value.asNode()); } public Node getOriginalNode() { - return value.asNode(); + return (value == null ? null : value.asNode()); } } diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Tue Mar 10 15:52:16 2015 +0100 @@ -62,12 +62,37 @@ @Override public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = this.getX().stamp(); + Stamp yStampGeneric = this.getY().stamp(); + return getSucceedingStamp(negated, xStampGeneric, yStampGeneric); + } + + private static Stamp getSucceedingStamp(boolean negated, Stamp xStampGeneric, Stamp otherStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && otherStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp otherStamp = (IntegerStamp) otherStampGeneric; + if (negated) { + if (Long.bitCount(otherStamp.upMask()) == 1) { + long newDownMask = xStamp.downMask() | otherStamp.upMask(); + if (xStamp.downMask() != newDownMask) { + return IntegerStamp.stampForMask(xStamp.getBits(), newDownMask, xStamp.upMask()).join(xStamp); + } + } + } else { + long restrictedUpMask = ((~otherStamp.downMask()) & xStamp.upMask()); + if (xStamp.upMask() != restrictedUpMask) { + return IntegerStamp.stampForMask(xStamp.getBits(), xStamp.downMask(), restrictedUpMask).join(xStamp); + } + } + } return null; } @Override public Stamp getSucceedingStampForY(boolean negated) { - return null; + Stamp xStampGeneric = this.getX().stamp(); + Stamp yStampGeneric = this.getY().stamp(); + return getSucceedingStamp(negated, yStampGeneric, xStampGeneric); } @Override diff -r 39de568cbb02 -r 37969636e6f8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 10 15:09:26 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 10 15:52:16 2015 +0100 @@ -970,17 +970,8 @@ } List sortedInstructions; - switch (strategy) { - case EARLIEST: - sortedInstructions = sortNodesWithinBlockEarliest(b, visited); - break; - case LATEST: - case LATEST_OUT_OF_LOOPS: - sortedInstructions = sortNodesWithinBlockLatest(b, visited, beforeLastLocation); - break; - default: - throw new GraalInternalError("unknown scheduling strategy"); - } + assert strategy == SchedulingStrategy.LATEST || strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS; + sortedInstructions = sortNodesWithinBlockLatest(b, visited, beforeLastLocation); assert filterSchedulableNodes(blockToNodesMap.get(b)).size() == removeProxies(sortedInstructions).size() : "sorted block does not contain the same amount of nodes: " + filterSchedulableNodes(blockToNodesMap.get(b)) + " vs. " + removeProxies(sortedInstructions); assert sameOrderForFixedNodes(blockToNodesMap.get(b), sortedInstructions) : "fixed nodes in sorted block are not in the same order"; @@ -1240,47 +1231,4 @@ } } } - - /** - * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over - * all usages. The resulting list is reversed to create an earliest-possible scheduling of - * nodes. - */ - private List sortNodesWithinBlockEarliest(Block b, NodeBitMap visited) { - List sortedInstructions = new ArrayList<>(blockToNodesMap.get(b).size() + 2); - addToEarliestSorting(b, b.getEndNode(), sortedInstructions, visited); - Collections.reverse(sortedInstructions); - return sortedInstructions; - } - - private void addToEarliestSorting(Block b, ValueNode i, List sortedInstructions, NodeBitMap visited) { - ValueNode instruction = i; - while (true) { - if (instruction == null || visited.isMarked(instruction) || cfg.getNodeToBlock().get(instruction) != b || instruction instanceof PhiNode || instruction instanceof ProxyNode) { - return; - } - - visited.mark(instruction); - for (Node usage : instruction.usages()) { - if (usage instanceof VirtualState) { - // only fixed nodes can have VirtualState -> no need to schedule them - } else { - addToEarliestSorting(b, (ValueNode) usage, sortedInstructions, visited); - } - } - - if (instruction instanceof AbstractBeginNode) { - for (ValueNode inBlock : blockToNodesMap.get(b)) { - if (!visited.isMarked(inBlock)) { - addToEarliestSorting(b, inBlock, sortedInstructions, visited); - } - } - sortedInstructions.add(instruction); - break; - } else { - sortedInstructions.add(instruction); - instruction = (ValueNode) instruction.predecessor(); - } - } - } }