changeset 19761:37969636e6f8

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 10 Mar 2015 15:52:16 +0100
parents dde8a89e7f92 (diff) 39de568cbb02 (current diff)
children 223e1d7b15b7
files
diffstat 6 files changed, 103 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- 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");
+    }
 }
--- 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);
+    }
 }
--- 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);
     }
 
--- 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<GuardProxyNode> 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());
     }
 }
--- 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
--- 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<ValueNode> 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<ValueNode> sortNodesWithinBlockEarliest(Block b, NodeBitMap visited) {
-        List<ValueNode> 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<ValueNode> 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();
-            }
-        }
-    }
 }