# HG changeset patch # User Lukas Stadler # Date 1365440605 -7200 # Node ID de6eaeae1190107befb2d0651acd03e73ca1c70d # Parent 1ee23d592f7de086302b51631bea815381f39351 move canonicalization of BoxNode to lowering diff -r 1ee23d592f7d -r de6eaeae1190 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSnippets.java --- 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 { 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) { diff -r 1ee23d592f7d -r de6eaeae1190 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- 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);