changeset 23100:9f0138a3545a

Merge
author Christian Wimmer <christian.wimmer@oracle.com>
date Thu, 26 Nov 2015 22:33:42 -0800
parents 1705cb8e3dfe (diff) 624aa2dc2331 (current diff)
children e9c71863920f
files graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ForeignCallPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/IntrinsicContext.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoopExplosionPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodSubstitutionPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/NodePlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ParameterPlugin.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/JVMCIErrorTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java
diffstat 4 files changed, 157 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java	Thu Nov 26 15:58:32 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java	Thu Nov 26 22:33:42 2015 -0800
@@ -28,10 +28,15 @@
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.MetaAccessProvider;
 
+import com.oracle.graal.compiler.common.type.Stamp;
 import com.oracle.graal.graph.Graph;
 import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.NodeClass;
 import com.oracle.graal.graph.spi.Canonicalizable;
 import com.oracle.graal.graph.spi.CanonicalizerTool;
+import com.oracle.graal.nodeinfo.NodeInfo;
+import com.oracle.graal.nodes.calc.FloatingNode;
+import com.oracle.graal.nodes.extended.GuardingNode;
 import com.oracle.graal.nodes.extended.IntegerSwitchNode;
 import com.oracle.graal.nodes.spi.StampProvider;
 import com.oracle.graal.nodes.util.GraphUtil;
@@ -71,6 +76,20 @@
         }
     }
 
+    @NodeInfo
+    static class CanonicalizeToNullNode extends FloatingNode implements Canonicalizable, GuardingNode {
+        public static final NodeClass<CanonicalizeToNullNode> TYPE = NodeClass.create(CanonicalizeToNullNode.class);
+
+        protected CanonicalizeToNullNode(Stamp stamp) {
+            super(TYPE, stamp);
+        }
+
+        @Override
+        public Node canonical(CanonicalizerTool tool) {
+            return null;
+        }
+    }
+
     public SimplifyingGraphDecoder(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, StampProvider stampProvider, boolean canonicalizeReads, Architecture architecture) {
         super(architecture);
         this.metaAccess = metaAccess;
@@ -149,43 +168,73 @@
                 }
             }
 
+        } else if (node instanceof FixedGuardNode) {
+            FixedGuardNode guard = (FixedGuardNode) node;
+            if (guard.getCondition() instanceof LogicConstantNode) {
+                LogicConstantNode condition = (LogicConstantNode) guard.getCondition();
+                Node canonical;
+                if (condition.getValue() == guard.isNegated()) {
+                    DeoptimizeNode deopt = new DeoptimizeNode(guard.getAction(), guard.getReason(), guard.getSpeculation());
+                    deopt.setStateBefore(guard.stateBefore());
+                    canonical = deopt;
+                } else {
+                    /*
+                     * The guard is unnecessary, but we cannot remove the node completely yet
+                     * because there might be nodes that use it as a guard input. Therefore, we
+                     * replace it with a more lightweight node (which is floating and has no
+                     * inputs).
+                     */
+                    canonical = new CanonicalizeToNullNode(node.stamp);
+                }
+                handleCanonicaliation(methodScope, loopScope, nodeOrderId, node, canonical);
+            }
+
         } else if (node instanceof Canonicalizable) {
             Node canonical = ((Canonicalizable) node).canonical(new PECanonicalizerTool());
-            if (canonical == null) {
-                /*
-                 * This is a possible return value of canonicalization. However, we might need to
-                 * add additional usages later on for which we need a node. Therefore, we just do
-                 * nothing and leave the node in place.
-                 */
-            } else if (canonical != node) {
-                if (!canonical.isAlive()) {
-                    assert !canonical.isDeleted();
-                    canonical = methodScope.graph.addOrUniqueWithInputs(canonical);
-                    if (canonical instanceof FixedWithNextNode) {
-                        methodScope.graph.addBeforeFixed(node, (FixedWithNextNode) canonical);
-                    } else if (canonical instanceof ControlSinkNode) {
-                        FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor();
-                        predecessor.setNext((ControlSinkNode) canonical);
-                        node.safeDelete();
-                        for (Node successor : node.successors()) {
-                            successor.safeDelete();
-                        }
-
-                    } else {
-                        assert !(canonical instanceof FixedNode);
-                    }
-                }
-                if (!node.isDeleted()) {
-                    GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
-                    node.replaceAtUsages(canonical);
-                    node.safeDelete();
-                }
-                assert lookupNode(loopScope, nodeOrderId) == node;
-                registerNode(loopScope, nodeOrderId, canonical, true, false);
+            if (canonical != node) {
+                handleCanonicaliation(methodScope, loopScope, nodeOrderId, node, canonical);
             }
         }
     }
 
+    private void handleCanonicaliation(MethodScope methodScope, LoopScope loopScope, int nodeOrderId, FixedNode node, Node c) {
+        Node canonical = c;
+
+        if (canonical == null) {
+            /*
+             * This is a possible return value of canonicalization. However, we might need to add
+             * additional usages later on for which we need a node. Therefore, we just do nothing
+             * and leave the node in place.
+             */
+            return;
+        }
+
+        if (!canonical.isAlive()) {
+            assert !canonical.isDeleted();
+            canonical = methodScope.graph.addOrUniqueWithInputs(canonical);
+            if (canonical instanceof FixedWithNextNode) {
+                methodScope.graph.addBeforeFixed(node, (FixedWithNextNode) canonical);
+            } else if (canonical instanceof ControlSinkNode) {
+                FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor();
+                predecessor.setNext((ControlSinkNode) canonical);
+                node.safeDelete();
+                for (Node successor : node.successors()) {
+                    successor.safeDelete();
+                }
+
+            } else {
+                assert !(canonical instanceof FixedNode);
+            }
+        }
+        if (!node.isDeleted()) {
+            GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
+            node.replaceAtUsages(canonical);
+            node.safeDelete();
+        }
+        assert lookupNode(loopScope, nodeOrderId) == node;
+        registerNode(loopScope, nodeOrderId, canonical, true, false);
+    }
+
     @Override
     protected Node handleFloatingNodeBeforeAdd(MethodScope methodScope, LoopScope loopScope, Node node) {
         if (node instanceof Canonicalizable) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Thu Nov 26 15:58:32 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Thu Nov 26 22:33:42 2015 -0800
@@ -92,8 +92,8 @@
     @Override
     public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, OBJECT_TAG);
-        return getObjectUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, OBJECT_TAG);
+        return getObjectUnsafe(slotIndex, slot, condition);
     }
 
     private Object[] getLocals() {
@@ -108,8 +108,7 @@
         return unsafeCast(tags, byte[].class, true, true);
     }
 
-    private Object getObjectUnsafe(int slotIndex, FrameSlot slot) {
-        boolean condition = this.getTags()[slotIndex] == OBJECT_TAG;
+    private Object getObjectUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         return unsafeGetObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, condition, slot);
     }
 
@@ -127,13 +126,12 @@
     @Override
     public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, BYTE_TAG);
-        return getByteUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, BYTE_TAG);
+        return getByteUnsafe(slotIndex, slot, condition);
     }
 
-    private byte getByteUnsafe(int slotIndex, FrameSlot slot) {
+    private byte getByteUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slotIndex] == BYTE_TAG;
         return (byte) unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
     }
 
@@ -152,13 +150,12 @@
     @Override
     public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, BOOLEAN_TAG);
-        return getBooleanUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, BOOLEAN_TAG);
+        return getBooleanUnsafe(slotIndex, slot, condition);
     }
 
-    private boolean getBooleanUnsafe(int slotIndex, FrameSlot slot) {
+    private boolean getBooleanUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slotIndex] == BOOLEAN_TAG;
         return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot) != 0;
     }
 
@@ -177,13 +174,12 @@
     @Override
     public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, FLOAT_TAG);
-        return getFloatUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, FLOAT_TAG);
+        return getFloatUnsafe(slotIndex, slot, condition);
     }
 
-    private float getFloatUnsafe(int slotIndex, FrameSlot slot) {
+    private float getFloatUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slotIndex] == FLOAT_TAG;
         return unsafeGetFloat(getPrimitiveLocals(), offset, condition, slot);
     }
 
@@ -202,13 +198,12 @@
     @Override
     public long getLong(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, LONG_TAG);
-        return getLongUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, LONG_TAG);
+        return getLongUnsafe(slotIndex, slot, condition);
     }
 
-    private long getLongUnsafe(int slotIndex, FrameSlot slot) {
+    private long getLongUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slotIndex] == LONG_TAG;
         return unsafeGetLong(getPrimitiveLocals(), offset, condition, slot);
     }
 
@@ -227,13 +222,12 @@
     @Override
     public int getInt(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, INT_TAG);
-        return getIntUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, INT_TAG);
+        return getIntUnsafe(slotIndex, slot, condition);
     }
 
-    private int getIntUnsafe(int slotIndex, FrameSlot slot) {
+    private int getIntUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slot.getIndex()] == INT_TAG;
         return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
     }
 
@@ -252,13 +246,12 @@
     @Override
     public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
-        verifyGet(slotIndex, DOUBLE_TAG);
-        return getDoubleUnsafe(slotIndex, slot);
+        boolean condition = verifyGet(slotIndex, DOUBLE_TAG);
+        return getDoubleUnsafe(slotIndex, slot, condition);
     }
 
-    private double getDoubleUnsafe(int slotIndex, FrameSlot slot) {
+    private double getDoubleUnsafe(int slotIndex, FrameSlot slot, boolean condition) {
         long offset = getPrimitiveOffset(slotIndex);
-        boolean condition = this.getTags()[slotIndex] == DOUBLE_TAG;
         return unsafeGetDouble(getPrimitiveLocals(), offset, condition, slot);
     }
 
@@ -284,12 +277,14 @@
         getTags()[slotIndex] = tag;
     }
 
-    private void verifyGet(int slotIndex, byte tag) throws FrameSlotTypeException {
+    private boolean verifyGet(int slotIndex, byte tag) throws FrameSlotTypeException {
         checkSlotIndex(slotIndex);
-        if (getTags()[slotIndex] != tag) {
+        boolean condition = getTags()[slotIndex] == tag;
+        if (!condition) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             throw new FrameSlotTypeException();
         }
+        return condition;
     }
 
     private void checkSlotIndex(int slotIndex) {
@@ -312,22 +307,34 @@
             resize();
         }
         byte tag = getTags()[slotIndex];
-        if (tag == BOOLEAN_TAG) {
-            return getBooleanUnsafe(slotIndex, slot);
-        } else if (tag == BYTE_TAG) {
-            return getByteUnsafe(slotIndex, slot);
-        } else if (tag == INT_TAG) {
-            return getIntUnsafe(slotIndex, slot);
-        } else if (tag == DOUBLE_TAG) {
-            return getDoubleUnsafe(slotIndex, slot);
-        } else if (tag == LONG_TAG) {
-            return getLongUnsafe(slotIndex, slot);
-        } else if (tag == FLOAT_TAG) {
-            return getFloatUnsafe(slotIndex, slot);
-        } else {
-            assert tag == OBJECT_TAG;
-            return getObjectUnsafe(slotIndex, slot);
+        boolean condition = (tag == BOOLEAN_TAG);
+        if (condition) {
+            return getBooleanUnsafe(slotIndex, slot, condition);
+        }
+        condition = (tag == BYTE_TAG);
+        if (condition) {
+            return getByteUnsafe(slotIndex, slot, condition);
+        }
+        condition = (tag == INT_TAG);
+        if (condition) {
+            return getIntUnsafe(slotIndex, slot, condition);
         }
+        condition = (tag == DOUBLE_TAG);
+        if (condition) {
+            return getDoubleUnsafe(slotIndex, slot, condition);
+        }
+        condition = (tag == LONG_TAG);
+        if (condition) {
+            return getLongUnsafe(slotIndex, slot, condition);
+        }
+        condition = (tag == FLOAT_TAG);
+        if (condition) {
+            return getFloatUnsafe(slotIndex, slot, condition);
+        }
+        condition = tag == OBJECT_TAG;
+        assert condition;
+        return getObjectUnsafe(slotIndex, slot, condition);
+
     }
 
     private boolean resize() {
@@ -345,10 +352,13 @@
 
     private byte getTag(FrameSlot slot) {
         int slotIndex = slot.getIndex();
-        if (slotIndex >= getTags().length) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            resize();
+        byte[] cachedTags = getTags();
+        if (slotIndex < cachedTags.length) {
+            return cachedTags[slotIndex];
         }
+
+        CompilerDirectives.transferToInterpreterAndInvalidate();
+        resize();
         return getTags()[slotIndex];
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Nov 26 15:58:32 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Nov 26 22:33:42 2015 -0800
@@ -340,8 +340,23 @@
         getCompilationNotify().notifyShutdown(this);
     }
 
+    protected void doCompile(OptimizedCallTarget optimizedCallTarget) {
+        int repeats = TruffleCompilerOptions.TruffleCompilationRepeats.getValue();
+        if (repeats <= 1) {
+            /* Normal compilation. */
+            doCompile0(optimizedCallTarget);
+
+        } else {
+            /* Repeated compilation for compilation time benchmarking. */
+            for (int i = 0; i < repeats; i++) {
+                doCompile0(optimizedCallTarget);
+            }
+            System.exit(0);
+        }
+    }
+
     @SuppressWarnings("try")
-    protected void doCompile(OptimizedCallTarget optimizedCallTarget) {
+    private void doCompile0(OptimizedCallTarget optimizedCallTarget) {
         boolean success = true;
         try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) {
             getTruffleCompiler().compileMethod(optimizedCallTarget);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Nov 26 15:58:32 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Nov 26 22:33:42 2015 -0800
@@ -126,6 +126,9 @@
     @Option(help = "Print information for compilation results", type = OptionType.Debug)
     public static final OptionValue<Boolean> TraceTruffleCompilation = new OptionValue<>(false);
 
+    @Option(help = "Compile time benchmarking: repeat Truffle compilation n times and then exit the VM", type = OptionType.Debug)
+    public static final OptionValue<Integer> TruffleCompilationRepeats = new OptionValue<>(0);
+
     @Option(help = "Print information for compilation queuing", type = OptionType.Debug)
     public static final OptionValue<Boolean> TraceTruffleCompilationDetails = new OptionValue<>(false);