changeset 8917:de6eaeae1190

move canonicalization of BoxNode to lowering
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 08 Apr 2013 19:03:25 +0200
parents 1ee23d592f7d
children b4d42a06b3a3
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java
diffstat 2 files changed, 47 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSnippets.java	Mon Apr 08 19:01:07 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSnippets.java	Mon Apr 08 19:03:25 2013 +0200
@@ -31,6 +31,8 @@
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
@@ -170,6 +172,35 @@
         return value.shortValue();
     }
 
+    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider runtime) {
+        ValueNode value = box.getValue();
+        if (value.isConstant()) {
+            Constant sourceConstant = value.asConstant();
+            switch (box.getBoxingKind()) {
+                case Boolean:
+                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), runtime, box.graph());
+                case Byte:
+                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), runtime, box.graph());
+                case Char:
+                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), runtime, box.graph());
+                case Short:
+                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), runtime, box.graph());
+                case Int:
+                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), runtime, box.graph());
+                case Long:
+                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), runtime, box.graph());
+                case Float:
+                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), runtime, box.graph());
+                case Double:
+                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), runtime, box.graph());
+                default:
+                    assert false : "Unexpected source kind for boxing";
+                    break;
+            }
+        }
+        return null;
+    }
+
     public static class Templates extends AbstractTemplates<BoxingSnippets> {
 
         private final ResolvedJavaMethod[] valueOfMethods = new ResolvedJavaMethod[Kind.values().length];
@@ -193,12 +224,17 @@
             return unboxMethods[kind.ordinal()];
         }
 
-        public void lower(BoxNode boxingValueOf) {
-            Key key = new Key(getValueOf(boxingValueOf.getBoxingKind()));
-            Arguments arguments = new Arguments().add("value", boxingValueOf.getValue());
-            SnippetTemplate template = cache.get(key);
-            Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", boxingValueOf.graph(), boxingValueOf, template, arguments);
-            template.instantiate(runtime, boxingValueOf, DEFAULT_REPLACER, arguments);
+        public void lower(BoxNode box) {
+            FloatingNode canonical = canonicalizeBoxing(box, runtime);
+            if (canonical != null) {
+                ((StructuredGraph) box.graph()).replaceFixedWithFloating(box, canonical);
+            } else {
+                Key key = new Key(getValueOf(box.getBoxingKind()));
+                Arguments arguments = new Arguments().add("value", box.getValue());
+                SnippetTemplate template = cache.get(key);
+                Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", box.graph(), box, template, arguments);
+                template.instantiate(runtime, box, DEFAULT_REPLACER, arguments);
+            }
         }
 
         public void lower(UnboxNode unbox) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Mon Apr 08 19:01:07 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Mon Apr 08 19:03:25 2013 +0200
@@ -23,13 +23,12 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.IterableNodeType;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 
-public class BoxNode extends FixedWithNextNode implements VirtualizableAllocation, IterableNodeType, Lowerable, Canonicalizable {
+public class BoxNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Canonicalizable {
 
     @Input private ValueNode value;
     private final Kind boxingKind;
@@ -59,31 +58,10 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (value.isConstant()) {
-            Constant sourceConstant = value.asConstant();
-            switch (boxingKind) {
-                case Boolean:
-                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asBoolean()), tool.runtime(), graph());
-                case Byte:
-                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), tool.runtime(), graph());
-                case Char:
-                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), tool.runtime(), graph());
-                case Short:
-                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), tool.runtime(), graph());
-                case Int:
-                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), tool.runtime(), graph());
-                case Long:
-                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), tool.runtime(), graph());
-                case Float:
-                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), tool.runtime(), graph());
-                case Double:
-                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), tool.runtime(), graph());
-                default:
-                    assert false : "Unexpected source kind for boxing";
-                    break;
-
-            }
-        }
+        /*
+         * Constant values are not canonicalized into their constant boxing objects because this
+         * would mean that the information that they came from a valueOf is lost.
+         */
         if (usages().isEmpty()) {
             return null;
         }
@@ -102,12 +80,6 @@
         tool.replaceWithVirtual(newVirtual);
     }
 
-    /*
-     * Normally, all these variants wouldn't be needed because this can be accomplished by using a
-     * generic method with automatic unboxing. These intrinsics, however, are themselves used for
-     * recognizing boxings, which means that there would be a circularity issue.
-     */
-
     @NodeIntrinsic
     public static native Boolean box(boolean value, @ConstantNodeParameter Class<?> clazz, @ConstantNodeParameter Kind kind);