changeset 11306:2a26b86d7724

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 14 Aug 2013 14:27:52 +0200
parents edf7e09ad382 (diff) fcb4cf14a3c3 (current diff)
children da412706d0fd
files
diffstat 3 files changed, 77 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Aug 14 11:24:11 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Aug 14 14:27:52 2013 +0200
@@ -488,16 +488,36 @@
                 ResolvedJavaType type = state.getNodeType(object);
                 if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) {
                     boolean nonNull = state.isNonNull(object);
-                    ValueAnchorNode anchor = graph.add(new ValueAnchorNode());
+                    GuardingNode replacementAnchor = null;
+                    if (nonNull) {
+                        // Search for valid instanceof anchor.
+                        for (InstanceOfNode instanceOfNode : object.usages().filter(InstanceOfNode.class)) {
+                            if (instanceOfNode.type() == checkCast.type() && state.trueConditions.containsKey(instanceOfNode)) {
+                                ValueNode v = state.trueConditions.get(instanceOfNode);
+                                if (v instanceof GuardingNode) {
+                                    replacementAnchor = (GuardingNode) v;
+                                }
+                            }
+                        }
+                    }
+                    ValueAnchorNode anchor = null;
+                    if (replacementAnchor == null) {
+                        anchor = graph.add(new ValueAnchorNode());
+                        replacementAnchor = anchor;
+                    }
                     PiNode piNode;
                     if (isNull) {
                         ConstantNode nullObject = ConstantNode.forObject(null, metaAccessProvider, graph);
-                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), anchor));
+                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), replacementAnchor));
                     } else {
-                        piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), anchor));
+                        piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor));
                     }
                     checkCast.replaceAtUsages(piNode);
-                    graph.replaceFixedWithFixed(checkCast, anchor);
+                    if (anchor != null) {
+                        graph.replaceFixedWithFixed(checkCast, anchor);
+                    } else {
+                        graph.removeFixed(checkCast);
+                    }
                     metricCheckCastRemoved.increment();
                 }
             } else if (node instanceof IfNode) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Wed Aug 14 11:24:11 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Wed Aug 14 14:27:52 2013 +0200
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.Graph.NodeChangedListener;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -34,11 +35,14 @@
 
 public class IterativeConditionalEliminationPhase extends BasePhase<PhaseContext> {
 
+    private static final int MAX_ITERATIONS = 256;
+
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
         Set<Node> canonicalizationRoots = new HashSet<>();
         ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getRuntime());
         Listener listener = new Listener(canonicalizationRoots);
+        int count = 0;
         while (true) {
             graph.trackInputChange(listener);
             eliminate.apply(graph);
@@ -48,6 +52,9 @@
             }
             new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), canonicalizationRoots, null).apply(graph);
             canonicalizationRoots.clear();
+            if (++count > MAX_ITERATIONS) {
+                throw new BailoutException("Number of iterations in conditional elimination phase exceeds " + MAX_ITERATIONS);
+            }
         }
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Aug 14 11:24:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Aug 14 14:27:52 2013 +0200
@@ -152,6 +152,52 @@
     }
 
     /**
+     * Associates the given type token with the given value for the case that condition is true.
+     * 
+     * @param condition the custom type check
+     * @param value the value that is of the given custom type after the check
+     * @param customType the custom type that should be associated with the value
+     * @return the type check condition
+     */
+    public static boolean customTypeCheck(boolean condition, Object value, Object customType) {
+        return condition;
+    }
+
+    /**
+     * Treats the given value as a value of the given class. The class must evaluate to a constant.
+     * If the compiler can prove that the given value is of the given custom type, the cast is safe.
+     * 
+     * @param value the value that is known to have the specified type
+     * @param clazz the specified type of the value
+     * @param customType the custom type that if present on a value makes this unsafe cast safe
+     * @return the value
+     */
+    @SuppressWarnings("unchecked")
+    @Unsafe
+    public static <T> T unsafeCast(Object value, Class<T> clazz, Object customType) {
+        return (T) value;
+    }
+
+    /**
+     * Proxies a sun.misc.Unsafe instance into an instance that adds a custom location identity on
+     * its accesses. This means that the accesses on these kind of location identities can only
+     * alias among themselves. It also allows to specify a custom type for the receiver values of
+     * follow-up unsafe accesses. Both the custom type and the location identity must evaluate to a
+     * constant. Furthermore, you should use the new sun.misc.Unsafe instance immediately for one
+     * read or write access via a sun.misc.Unsafe method and not store it anywhere.
+     * 
+     * @param unsafe the instance of sun.misc.Unsafe
+     * @param customType the expected type of the receiver object of follow-up unsafe accesses
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    @Unsafe
+    public static sun.misc.Unsafe unsafeCustomization(sun.misc.Unsafe unsafe, Object customType, Object locationIdentity) {
+        return unsafe;
+    }
+
+    /**
      * Marks methods that are considered slowpath and should therefore not be inlined by default.
      */
     @Retention(RetentionPolicy.RUNTIME)