Mercurial > hg > graal-compiler
changeset 22262:71a696ca2862
Support optimization of reads from special memory locations
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Mon, 20 Jul 2015 11:19:52 -0700 |
parents | 11f9d9c2c1bf |
children | 7abe84b97eaa |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CanonicalizableLocation.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java |
diffstat | 6 files changed, 188 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Jul 20 11:19:37 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Jul 20 11:19:52 2015 -0700 @@ -69,6 +69,10 @@ return input.graph().unique(new CompressionNode(CompressionOp.Compress, input, encoding)); } + public static CompressionNode compressNoUnique(ValueNode input, CompressEncoding encoding) { + return new CompressionNode(CompressionOp.Compress, input, encoding); + } + public static CompressionNode uncompress(ValueNode input, CompressEncoding encoding) { return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding)); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Jul 20 11:19:37 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Jul 20 11:19:52 2015 -0700 @@ -22,22 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.hotspot.*; -import jdk.internal.jvmci.meta.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static jdk.internal.jvmci.common.UnsafeAccess.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.common.*; +import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.meta.Assumptions.AssumptionResult; +import jdk.internal.jvmci.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.word.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -49,6 +56,60 @@ */ public class HotSpotReplacementsUtil { + abstract static class HotSpotOptimizingLocationIdentity extends NamedLocationIdentity implements CanonicalizableLocation { + + HotSpotOptimizingLocationIdentity(String name) { + super(name, true); + } + + @Override + public abstract ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool); + + protected ValueNode findReadHub(ValueNode object) { + ValueNode base = object; + if (base instanceof CompressionNode) { + base = ((CompressionNode) base).getValue(); + } + if (base instanceof Access) { + Access access = (Access) base; + if (access.getLocationIdentity().equals(HUB_LOCATION)) { + AddressNode address = access.getAddress(); + if (address instanceof OffsetAddressNode) { + OffsetAddressNode offset = (OffsetAddressNode) address; + return offset.getBase(); + } + } + } else if (base instanceof LoadHubNode) { + LoadHubNode loadhub = (LoadHubNode) base; + return loadhub.getValue(); + } + return null; + } + + /** + * Fold reads that convert from Class -> Hub -> Class or vice versa. + * + * @param read + * @param object + * @param otherLocation + * @return an earlier read or the original {@code read} + */ + protected static ValueNode foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation) { + if (object instanceof Access) { + Access access = (Access) object; + if (access.getLocationIdentity().equals(otherLocation)) { + AddressNode address = access.getAddress(); + if (address instanceof OffsetAddressNode) { + OffsetAddressNode offset = (OffsetAddressNode) address; + assert offset.getBase().stamp().isCompatible(read.stamp()); + return offset.getBase(); + } + } + } + return read; + } + } + @Fold public static HotSpotVMConfig config() { return runtime().getConfig(); @@ -296,7 +357,23 @@ return config().jvmAccWrittenFlags; } - public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = NamedLocationIdentity.immutable("Klass::_layout_helper"); + public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = new HotSpotOptimizingLocationIdentity("Klass::_layout_helper") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ValueNode javaObject = findReadHub(object); + if (javaObject != null) { + if (javaObject.stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) javaObject.stamp(); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess()); + if (type.isArray() && !type.getComponentType().isPrimitive()) { + int layout = ((HotSpotResolvedObjectTypeImpl) type).layoutHelper(); + return ConstantNode.forInt(layout); + } + } + } + return read; + } + }; @Fold public static int klassLayoutHelperOffset() { @@ -356,7 +433,20 @@ public static final LocationIdentity HUB_WRITE_LOCATION = NamedLocationIdentity.mutable("Hub:write"); - public static final LocationIdentity HUB_LOCATION = NamedLocationIdentity.immutable("Hub"); + public static final LocationIdentity HUB_LOCATION = new HotSpotOptimizingLocationIdentity("Hub") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ResolvedJavaType constantType = LoadHubNode.findSynonymType(read.graph(), tool.getMetaAccess(), object); + if (constantType != null) { + if (config().useCompressedClassPointers) { + return ConstantNode.forConstant(read.stamp(), ((HotSpotMetaspaceConstant) constantType.getObjectHub()).compress(config().getKlassEncoding()), tool.getMetaAccess()); + } else { + return ConstantNode.forConstant(read.stamp(), constantType.getObjectHub(), tool.getMetaAccess()); + } + } + return read; + } + }; @Fold private static int hubOffset() { @@ -655,14 +745,24 @@ return config().klassModifierFlagsOffset; } - public static final LocationIdentity CLASS_KLASS_LOCATION = NamedLocationIdentity.immutable("Class._klass"); + public static final LocationIdentity CLASS_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + return foldIndirection(read, object, CLASS_MIRROR_LOCATION); + } + }; @Fold public static int klassOffset() { return config().klassOffset; } - public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = NamedLocationIdentity.mutable("Class._array_klass"); + public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._array_klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + return foldIndirection(read, object, ARRAY_KLASS_COMPONENT_MIRROR); + } + }; @Fold public static int arrayKlassOffset() { @@ -854,7 +954,26 @@ } } - public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = NamedLocationIdentity.immutable("ObjArrayKlass::_element_klass"); + public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("ObjArrayKlass::_element_klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ValueNode javaObject = findReadHub(object); + if (javaObject != null) { + ResolvedJavaType type = StampTool.typeOrNull(javaObject); + if (type != null && type.isArray()) { + ResolvedJavaType element = type.getComponentType(); + if (element != null && !element.isPrimitive() && !element.getElementalType().isInterface()) { + AssumptionResult<ResolvedJavaType> leafType = element.findLeafConcreteSubtype(); + if (leafType != null) { + object.graph().getAssumptions().record(leafType); + return ConstantNode.forConstant(read.stamp(), leafType.getResult().getObjectHub(), tool.getMetaAccess()); + } + } + } + } + return read; + } + }; @Fold public static int arrayClassElementOffset() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CanonicalizableLocation.java Mon Jul 20 11:19:52 2015 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.memory.address.*; + +public interface CanonicalizableLocation { + ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool); +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Mon Jul 20 11:19:37 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Mon Jul 20 11:19:52 2015 -0700 @@ -89,10 +89,18 @@ return this; } - private static ValueNode findSynonym(ValueNode curValue, Stamp stamp, StructuredGraph graph, MetaAccessProvider metaAccess) { + public static ValueNode findSynonym(ValueNode curValue, Stamp stamp, StructuredGraph graph, MetaAccessProvider metaAccess) { + ResolvedJavaType exactType = findSynonymType(graph, metaAccess, curValue); + if (exactType != null) { + return ConstantNode.forConstant(stamp, exactType.getObjectHub(), metaAccess); + } + return null; + } + + public static ResolvedJavaType findSynonymType(StructuredGraph graph, MetaAccessProvider metaAccess, ValueNode curValue) { + ResolvedJavaType exactType = null; if (metaAccess != null && curValue.stamp() instanceof ObjectStamp) { ObjectStamp objectStamp = (ObjectStamp) curValue.stamp(); - ResolvedJavaType exactType = null; if (objectStamp.isExactType()) { exactType = objectStamp.type(); } else if (objectStamp.type() != null && graph != null && graph.getAssumptions() != null) { @@ -102,12 +110,8 @@ graph.getAssumptions().record(leafConcreteSubtype); } } - - if (exactType != null) { - return ConstantNode.forConstant(stamp, exactType.getObjectHub(), metaAccess); - } } - return null; + return exactType; } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jul 20 11:19:37 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jul 20 11:19:52 2015 -0700 @@ -133,6 +133,13 @@ return length; } } + if (locationIdentity instanceof CanonicalizableLocation) { + CanonicalizableLocation canonicalize = (CanonicalizableLocation) locationIdentity; + ValueNode result = canonicalize.canonicalizeRead(read, address, object, tool); + assert result != null && result.stamp().isCompatible(read.stamp()); + return result; + } + } return read; }
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java Mon Jul 20 11:19:37 2015 -0700 +++ b/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java Mon Jul 20 11:19:52 2015 -0700 @@ -29,18 +29,17 @@ /** * A {@link LocationIdentity} with a name. */ -public final class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { +public class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { /** * Map for asserting all {@link NamedLocationIdentity} instances have a unique name. */ static class DB { - private static final HashMap<String, NamedLocationIdentity> map = new HashMap<>(); + private static final HashSet<String> map = new HashSet<>(); - static boolean checkUnique(NamedLocationIdentity identity) { - NamedLocationIdentity oldValue = map.put(identity.name, identity); - if (oldValue != null) { - throw new AssertionError("identity " + identity + " already exists"); + static boolean checkUnique(String name) { + if (!map.add(name)) { + throw new AssertionError("identity " + name + " already exists"); } return true; } @@ -49,9 +48,10 @@ private final String name; private final boolean immutable; - private NamedLocationIdentity(String name, boolean immutable) { + protected NamedLocationIdentity(String name, boolean immutable) { this.name = name; this.immutable = immutable; + assert DB.checkUnique(name); } /** @@ -82,9 +82,7 @@ * @param immutable true if the location is immutable */ private static NamedLocationIdentity create(String name, boolean immutable) { - NamedLocationIdentity id = new NamedLocationIdentity(name, immutable); - assert DB.checkUnique(id); - return id; + return new NamedLocationIdentity(name, immutable); } @Override