Mercurial > hg > truffle
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);