changeset 7091:08fe3a509cf1

Canoncialize UnsafeLoad/Store
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 29 Nov 2012 13:31:48 +0100
parents 05ce1defa4f9
children bb6d2860e431
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java
diffstat 2 files changed, 54 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Thu Nov 29 13:24:08 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Thu Nov 29 13:31:48 2012 +0100
@@ -23,7 +23,9 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
@@ -32,7 +34,7 @@
  * Load of a value from a location specified as an offset relative to an object.
  * No null check is performed before the load.
  */
-public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable {
+public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable, Canonicalizable {
 
     public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
         this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object);
@@ -71,6 +73,30 @@
         }
     }
 
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (offset().isConstant()) {
+            long constantOffset = offset().asConstant().asLong();
+            if (constantOffset != 0) {
+                int intDisplacement = (int) (constantOffset + displacement());
+                if (constantOffset == intDisplacement) {
+                    Graph graph = this.graph();
+                    return graph.add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph.unique(ConstantNode.forInt(0, graph)), accessKind()));
+                }
+            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once UnsafeAccess only have an object base
+                ObjectStamp receiverStamp = object().objectStamp();
+                if (receiverStamp.nonNull()) {
+                    ResolvedJavaType receiverType = receiverStamp.type();
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
+                    if (field != null) {
+                        return this.graph().add(new LoadFieldNode(object(), field, StructuredGraph.INVALID_GRAPH_ID));
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
     @NodeIntrinsic
     public static native <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Nov 29 13:24:08 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Nov 29 13:31:48 2012 +0100
@@ -23,7 +23,9 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
@@ -32,7 +34,7 @@
  * Store of a value at a location specified as an offset relative to an object.
  * No null check is performed before the store.
  */
-public class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable {
+public class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, Canonicalizable {
 
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
@@ -85,6 +87,30 @@
         }
     }
 
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (offset().isConstant()) {
+            long constantOffset = offset().asConstant().asLong();
+            if (constantOffset != 0) {
+                int intDisplacement = (int) (constantOffset + displacement());
+                if (constantOffset == intDisplacement) {
+                    Graph graph = this.graph();
+                    return graph.add(new UnsafeStoreNode(this.stamp(), object(), intDisplacement, graph.unique(ConstantNode.forInt(0, graph)), value(), accessKind()));
+                }
+            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once UnsafeAccess only have an object base
+                ObjectStamp receiverStamp = object().objectStamp();
+                if (receiverStamp.nonNull()) {
+                    ResolvedJavaType receiverType = receiverStamp.type();
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
+                    if (field != null) {
+                        return this.graph().add(new StoreFieldNode(object(), field, value(), StructuredGraph.INVALID_GRAPH_ID));
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @NodeIntrinsic
     public static native void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind);