Mercurial > hg > graal-compiler
changeset 23092:407b3a638b04
Cleanup dead code in NodeIntrinsificationPhase.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Thu, 26 Nov 2015 14:44:30 +0100 |
parents | ee40de319a24 |
children | c515580658e2 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsicFactory.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationProvider.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java |
diffstat | 6 files changed, 85 insertions(+), 719 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Nov 26 14:27:42 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Nov 26 14:44:30 2015 +0100 @@ -77,7 +77,7 @@ import com.oracle.graal.nodes.util.GraphUtil; import com.oracle.graal.replacements.InlineDuringParsingPlugin; import com.oracle.graal.replacements.MethodHandlePlugin; -import com.oracle.graal.replacements.NodeIntrinsificationPhase; +import com.oracle.graal.replacements.NodeIntrinsificationProvider; import com.oracle.graal.replacements.NodeIntrinsificationPlugin; import com.oracle.graal.replacements.ReplacementsImpl; import com.oracle.graal.replacements.StandardGraphBuilderPlugins; @@ -102,7 +102,7 @@ InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess); Plugins plugins = new Plugins(invocationPlugins); - NodeIntrinsificationPhase nodeIntrinsificationPhase = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, wordTypes); + NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes); NodeIntrinsificationPlugin nodeIntrinsificationPlugin = new NodeIntrinsificationPlugin(); HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes); HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, nodeIntrinsificationPlugin); @@ -128,7 +128,7 @@ StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, invocationPlugins, true); for (NodeIntrinsicPluginFactory factory : Services.load(NodeIntrinsicPluginFactory.class)) { - factory.registerPlugin(invocationPlugins, nodeIntrinsificationPhase); + factory.registerPlugin(invocationPlugins, nodeIntrinsificationProvider); } return plugins;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsicFactory.java Thu Nov 26 14:27:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * Copyright (c) 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.replacements; - -import java.lang.reflect.Array; -import java.util.List; - -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - -import com.oracle.graal.api.replacements.SnippetReflectionProvider; -import com.oracle.graal.compiler.common.type.Stamp; -import com.oracle.graal.graph.NodeClass; -import com.oracle.graal.graph.NodeInputList; -import com.oracle.graal.nodeinfo.NodeInfo; -import com.oracle.graal.nodes.FixedWithNextNode; -import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.nodes.ValueNode; - -@NodeInfo -public final class NodeIntrinsicFactory extends FixedWithNextNode { - - public static final NodeClass<NodeIntrinsicFactory> TYPE = NodeClass.create(NodeIntrinsicFactory.class); - - public static final Object GRAPH_MARKER = new Object(); - - private final ResolvedJavaMethod constructor; - private final boolean setStampFromReturnType; - - private final Object[] injectedArguments; - - private final Class<?>[] argumentTypes; - @Input NodeInputList<ValueNode> arguments; - - private final Class<?> varargsType; - @Input NodeInputList<ValueNode> varargs; - - public NodeIntrinsicFactory(Stamp stamp, ResolvedJavaMethod constructor, boolean setStampFromReturnType, Object[] injectedArguments, Class<?>[] argumentTypes, List<ValueNode> arguments) { - this(stamp, constructor, setStampFromReturnType, injectedArguments, argumentTypes, arguments, null, null); - } - - public NodeIntrinsicFactory(Stamp stamp, ResolvedJavaMethod constructor, boolean setStampFromReturnType, Object[] injectedArguments, Class<?>[] argumentTypes, List<ValueNode> arguments, - Class<?> varargsType, List<ValueNode> varargs) { - super(TYPE, stamp); - - this.constructor = constructor; - this.setStampFromReturnType = setStampFromReturnType; - - this.injectedArguments = injectedArguments; - - this.argumentTypes = argumentTypes; - this.arguments = new NodeInputList<>(this, arguments); - - this.varargsType = varargsType; - if (varargs == null) { - this.varargs = new NodeInputList<>(this); - } else { - this.varargs = new NodeInputList<>(this, varargs); - } - } - - private static Object mkConstArgument(Class<?> argType, Constant constant, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection) { - if (argType == ResolvedJavaType.class) { - ResolvedJavaType type = constantReflection.asJavaType(constant); - assert type != null; - return type; - } else { - JavaConstant javaConstant = (JavaConstant) constant; - switch (JavaKind.fromJavaClass(argType)) { - case Boolean: - return Boolean.valueOf(javaConstant.asInt() != 0); - case Byte: - return Byte.valueOf((byte) javaConstant.asInt()); - case Short: - return Short.valueOf((short) javaConstant.asInt()); - case Char: - return Character.valueOf((char) javaConstant.asInt()); - case Object: - return snippetReflection.asObject(argType, javaConstant); - default: - return javaConstant.asBoxedPrimitive(); - } - } - } - - public ValueNode intrinsify(StructuredGraph graph, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection) { - int totalArgCount = arguments.count(); - if (injectedArguments != null) { - totalArgCount += injectedArguments.length; - } - if (varargsType != null) { - totalArgCount++; - } - - Object[] args = new Object[totalArgCount]; - int idx = 0; - - if (injectedArguments != null) { - for (int i = 0; i < injectedArguments.length; i++) { - if (injectedArguments[i] == GRAPH_MARKER) { - args[idx++] = graph; - } else { - args[idx++] = injectedArguments[i]; - } - } - } - - for (int i = 0; i < arguments.size(); i++) { - ValueNode node = arguments.get(i); - if (argumentTypes[i] == ValueNode.class) { - args[idx++] = node; - } else { - if (!node.isConstant()) { - return null; - } - - args[idx++] = mkConstArgument(argumentTypes[i], node.asConstant(), constantReflection, snippetReflection); - } - } - - if (varargsType != null) { - if (varargsType == ValueNode.class) { - args[idx++] = varargs.toArray(new ValueNode[0]); - } else { - Object array = Array.newInstance(varargsType, varargs.size()); - args[idx++] = array; - - for (int i = 0; i < varargs.size(); i++) { - ValueNode node = varargs.get(i); - if (!node.isConstant()) { - return null; - } - - Object arg = mkConstArgument(varargsType, node.asConstant(), constantReflection, snippetReflection); - if (varargsType.isPrimitive()) { - Array.set(array, i, arg); - } else { - ((Object[]) array)[i] = arg; - } - } - } - } - - assert idx == totalArgCount; - - ValueNode node = (ValueNode) snippetReflection.invoke(constructor, null, args); - if (setStampFromReturnType) { - node.setStamp(this.stamp()); - } - return node; - } -}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Thu Nov 26 14:27:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2011, 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.replacements; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.PrimitiveConstant; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; - -import com.oracle.graal.api.replacements.Fold; -import com.oracle.graal.api.replacements.SnippetReflectionProvider; -import com.oracle.graal.compiler.common.spi.ForeignCallsProvider; -import com.oracle.graal.compiler.common.type.Stamp; -import com.oracle.graal.compiler.common.type.StampFactory; -import com.oracle.graal.debug.Debug; -import com.oracle.graal.debug.internal.DebugScope; -import com.oracle.graal.graph.Node; -import com.oracle.graal.graph.Node.ConstantNodeParameter; -import com.oracle.graal.graph.Node.InjectedNodeParameter; -import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.nodes.ConstantNode; -import com.oracle.graal.nodes.FrameState; -import com.oracle.graal.nodes.LogicConstantNode; -import com.oracle.graal.nodes.PiNode; -import com.oracle.graal.nodes.ProxyNode; -import com.oracle.graal.nodes.ReturnNode; -import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.ValueProxyNode; -import com.oracle.graal.nodes.calc.FloatingNode; -import com.oracle.graal.nodes.calc.IsNullNode; -import com.oracle.graal.nodes.extended.UnboxNode; -import com.oracle.graal.nodes.extended.UnsafeStoreNode; -import com.oracle.graal.nodes.extended.ValueAnchorNode; -import com.oracle.graal.nodes.graphbuilderconf.NodeIntrinsicPluginFactory.InjectionProvider; -import com.oracle.graal.nodes.java.CheckCastNode; -import com.oracle.graal.nodes.java.LoadFieldNode; -import com.oracle.graal.nodes.java.MethodCallTargetNode; -import com.oracle.graal.nodes.spi.StampProvider; -import com.oracle.graal.nodes.util.GraphUtil; -import com.oracle.graal.phases.Phase; -import com.oracle.graal.word.WordTypes; - -/** - * Replaces calls to {@link NodeIntrinsic}s with nodes and calls to methods annotated with - * {@link Fold} with the result of invoking the annotated method via reflection. - */ -public class NodeIntrinsificationPhase extends Phase implements InjectionProvider { - - private final MetaAccessProvider metaAccess; - private final ConstantReflectionProvider constantReflection; - private final SnippetReflectionProvider snippetReflection; - private final ForeignCallsProvider foreignCalls; - private final StampProvider stampProvider; - private final WordTypes wordTypes; - - public NodeIntrinsificationPhase(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, - StampProvider stampProvider, WordTypes wordTypes) { - this.metaAccess = metaAccess; - this.constantReflection = constantReflection; - this.snippetReflection = snippetReflection; - this.foreignCalls = foreignCalls; - this.stampProvider = stampProvider; - this.wordTypes = wordTypes; - } - - @Override - public Stamp getReturnStamp(Class<?> type) { - JavaKind kind = JavaKind.fromJavaClass(type); - if (kind == JavaKind.Object) { - ResolvedJavaType returnType = metaAccess.lookupJavaType(type); - if (wordTypes.isWord(returnType)) { - return wordTypes.getWordStamp(returnType); - } else { - return StampFactory.declared(returnType); - } - } else { - return StampFactory.forKind(kind); - } - } - - @Override - public <T> T getInjectedArgument(Class<T> type) { - T injected = snippetReflection.getInjectedNodeIntrinsicParameter(type); - if (injected != null) { - return injected; - } else if (type.equals(ForeignCallsProvider.class)) { - return type.cast(foreignCalls); - } else if (type.equals(SnippetReflectionProvider.class)) { - return type.cast(snippetReflection); - } else { - throw new JVMCIError("Cannot handle injected argument of type %s.", type.getName()); - } - } - - @Override - protected void run(StructuredGraph graph) { - ArrayList<Node> cleanUpReturnList = new ArrayList<>(); - for (MethodCallTargetNode node : graph.getNodes(MethodCallTargetNode.TYPE)) { - tryIntrinsify(node, cleanUpReturnList); - } - - for (Node node : cleanUpReturnList) { - cleanUpReturnCheckCast(node); - } - } - - protected boolean tryIntrinsify(MethodCallTargetNode methodCallTargetNode, List<Node> cleanUpReturnList) { - ResolvedJavaMethod target = methodCallTargetNode.targetMethod(); - StructuredGraph graph = methodCallTargetNode.graph(); - - NodeIntrinsic intrinsic = getIntrinsic(target); - if (intrinsic != null) { - Stamp stamp = methodCallTargetNode.invoke().asNode().stamp(); - Node newInstance = createIntrinsicNode(methodCallTargetNode.arguments(), stamp, target, graph, intrinsic); - if (newInstance == null) { - return false; - } - - // Replace the invoke with the new node. - newInstance = graph.addOrUnique(newInstance); - methodCallTargetNode.invoke().intrinsify(newInstance); - - // Clean up checkcast instructions inserted by javac if the return type is generic. - cleanUpReturnList.add(newInstance); - } else if (isFoldable(target)) { - JavaConstant constant = tryFold(methodCallTargetNode.arguments(), target); - if (constant != null && constant.equals(COULD_NOT_FOLD)) { - return false; - } - - if (constant != null) { - // Replace the invoke with the result of the call - ConstantNode node = ConstantNode.forConstant(constant, metaAccess, methodCallTargetNode.graph()); - methodCallTargetNode.invoke().intrinsify(node); - - // Clean up checkcast instructions inserted by javac if the return type is generic. - cleanUpReturnList.add(node); - } else { - // Remove the invoke - methodCallTargetNode.invoke().intrinsify(null); - } - } - return true; - } - - public static final JavaConstant COULD_NOT_FOLD = new PrimitiveConstant(JavaKind.Illegal, 100) { - @Override - public boolean equals(Object o) { - return this == o; - } - }; - - public JavaConstant tryFold(List<ValueNode> args, ResolvedJavaMethod target) { - JavaConstant[] reflectArgs = prepareFoldingArguments(args); - if (reflectArgs == null) { - return COULD_NOT_FOLD; - } - JavaConstant receiver = null; - if (!target.isStatic()) { - receiver = reflectArgs[0]; - reflectArgs = Arrays.copyOfRange(reflectArgs, 1, reflectArgs.length); - } - - // Call the method - return target.invoke(receiver, reflectArgs); - } - - /** - * Select a constructor and prepare the injected arguments for intrinsification of a call to a - * {@link NodeIntrinsic} annotated method. - * - * @param arguments the arguments of the call - * @param stamp the stamp to use for the returned node - * @param method the method annotated with {@link NodeIntrinsic} - * @return an {@link NodeIntrinsicFactory} that can be used to - * {@link NodeIntrinsicFactory#intrinsify intrinsify} the call - */ - public NodeIntrinsicFactory createIntrinsicFactory(List<ValueNode> arguments, Stamp stamp, ResolvedJavaMethod method, NodeIntrinsic intrinsic) { - assert method.getAnnotation(Fold.class) == null; - assert method.isStatic() : "node intrinsic must be static: " + method; - - Class<? extends ValueNode> nodeClass = getNodeClass(method, intrinsic); - Class<?>[] parameterTypes = prepareIntrinsicArgumentTypes(method); - - return createIntrinsicFactory(nodeClass, parameterTypes, arguments, stamp, intrinsic.setStampFromReturnType()); - } - - /** - * Attempts to create a node to replace a call to a {@link NodeIntrinsic} annotated method. - * - * @param arguments the arguments of the call - * @param stamp the stamp to use for the returned node - * @param method the method annotated with {@link NodeIntrinsic} - * @param graph the graph into which the created node will be added - * @return {@code null} if intrinsification could not (yet) be performed, otherwise the node - * representing the intrinsic - */ - public ValueNode createIntrinsicNode(List<ValueNode> arguments, Stamp stamp, ResolvedJavaMethod method, StructuredGraph graph, NodeIntrinsic intrinsic) { - NodeIntrinsicFactory factory = createIntrinsicFactory(arguments, stamp, method, intrinsic); - return factory.intrinsify(graph, constantReflection, snippetReflection); - } - - /** - * Permits a subclass to override the default definition of "intrinsic". - */ - public NodeIntrinsic getIntrinsic(ResolvedJavaMethod method) { - return method.getAnnotation(Node.NodeIntrinsic.class); - } - - /** - * Permits a subclass to override the default definition of "foldable". - */ - public boolean isFoldable(ResolvedJavaMethod method) { - return method.getAnnotation(Fold.class) != null; - } - - private Class<?>[] prepareIntrinsicArgumentTypes(ResolvedJavaMethod target) { - Signature signature = target.getSignature(); - boolean hasReceiver = !target.isStatic(); - - Class<?>[] argumentTypes = new Class<?>[signature.getParameterCount(hasReceiver)]; - for (int i = 0; i < argumentTypes.length; i++) { - int parameterIndex = i; - if (hasReceiver) { - parameterIndex--; - } - if (target.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex) != null) { - ResolvedJavaType type = signature.getParameterType(parameterIndex, target.getDeclaringClass()).resolve(target.getDeclaringClass()); - Class<?> cls; - if (type.isPrimitive()) { - cls = type.getJavaKind().toJavaClass(); - } else { - cls = snippetReflection.asObject(Class.class, type.getJavaClass()); - } - /* - * If the node intrinsic method has a constant Class<?> argument, the node - * constructor wants the corresponding ResolvedJavaType. - */ - if (cls.equals(Class.class)) { - argumentTypes[i] = ResolvedJavaType.class; - } else { - argumentTypes[i] = cls; - } - } else { - argumentTypes[i] = ValueNode.class; - } - } - - return argumentTypes; - } - - /** - * Converts the arguments of an invoke node to object values suitable for use as the arguments - * to a reflective invocation of a ResolvedJavaMethod. - * - * @return the arguments for the reflective invocation or null if an argument of {@code invoke} - * is not constant - */ - private static JavaConstant[] prepareFoldingArguments(List<ValueNode> arguments) { - JavaConstant[] reflectionCallArguments = new JavaConstant[arguments.size()]; - for (int i = 0; i < reflectionCallArguments.length; ++i) { - ValueNode argument = arguments.get(i); - if (!(argument instanceof ConstantNode)) { - return null; - } - - ConstantNode constantNode = (ConstantNode) argument; - reflectionCallArguments[i] = (JavaConstant) constantNode.asConstant(); - } - return reflectionCallArguments; - } - - public Class<? extends ValueNode> getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) { - Class<?> result; - if (intrinsic.value() == NodeIntrinsic.class) { - ResolvedJavaType type = target.getDeclaringClass(); - result = snippetReflection.asObject(Class.class, type.getJavaClass()); - } else { - result = intrinsic.value(); - } - assert ValueNode.class.isAssignableFrom(result) : "Node intrinsic class " + result + " derived from @" + NodeIntrinsic.class.getSimpleName() + " annotation on " + target.format("%H.%n(%p)") + - " is not a subclass of " + ValueNode.class; - return result.asSubclass(ValueNode.class); - } - - protected NodeIntrinsicFactory createIntrinsicFactory(Class<? extends ValueNode> nodeClass, Class<?>[] parameterTypes, List<ValueNode> arguments, Stamp invokeStamp, boolean setStampFromReturnType) { - NodeIntrinsicFactory ret = null; - - for (Constructor<?> c : nodeClass.getDeclaredConstructors()) { - NodeIntrinsicFactory match = match(invokeStamp, setStampFromReturnType, c, parameterTypes, arguments); - - if (match != null) { - if (ret == null) { - ret = match; - if (!Debug.isEnabled()) { - // Don't verify there's a unique match in non-debug mode - break; - } - } else { - throw new JVMCIError("Found multiple constructors in %s compatible with signature %s", nodeClass.getName(), sigString(parameterTypes)); - } - } - } - - if (ret == null) { - throw new JVMCIError("Could not find constructor in %s compatible with signature %s", nodeClass.getName(), sigString(parameterTypes)); - } - - return ret; - } - - protected Object invokeConstructor(ResolvedJavaMethod constructor, Object[] arguments) { - return snippetReflection.invoke(constructor, null, arguments); - } - - private static String sigString(Class<?>[] types) { - StringBuilder sb = new StringBuilder("("); - for (int i = 0; i < types.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(types[i].getSimpleName()); - } - return sb.append(")").toString(); - } - - private static boolean checkNoMoreInjected(Constructor<?> c, int start) { - int count = c.getParameterCount(); - for (int i = start; i < count; i++) { - if (getParameterAnnotation(c, InjectedNodeParameter.class, i) != null) { - throw new JVMCIError("Injected parameter %d of type %s must precede all non-injected parameters of %s", i, c.getParameterTypes()[i], c.toString()); - } - } - return true; - } - - private static <T extends Annotation> T getParameterAnnotation(Executable e, Class<T> annotationClass, int parameterIndex) { - if (parameterIndex >= 0) { - Annotation[][] parameterAnnotations = e.getParameterAnnotations(); - for (Annotation a : parameterAnnotations[parameterIndex]) { - if (a.annotationType() == annotationClass) { - return annotationClass.cast(a); - } - } - } - return null; - } - - private NodeIntrinsicFactory match(Stamp invokeStamp, boolean setStampFromReturnType, Constructor<?> c, Class<?>[] parameterTypes, List<ValueNode> argumentNodes) { - Class<?>[] signature = c.getParameterTypes(); - - int injectedCount = 0; - for (int i = 0; i < signature.length; i++) { - if (getParameterAnnotation(c, InjectedNodeParameter.class, i) != null) { - injectedCount++; - } else { - assert checkNoMoreInjected(c, i); - break; - } - } - - Object[] injected = null; - if (injectedCount > 0) { - injected = new Object[injectedCount]; - for (int i = 0; i < injected.length; i++) { - assert getParameterAnnotation(c, InjectedNodeParameter.class, i) != null; - Object injectedParameter = snippetReflection.getInjectedNodeIntrinsicParameter(signature[i]); - if (injectedParameter != null) { - injected[i] = injectedParameter; - } else if (signature[i].equals(MetaAccessProvider.class)) { - injected[i] = metaAccess; - } else if (signature[i].equals(StructuredGraph.class)) { - injected[i] = NodeIntrinsicFactory.GRAPH_MARKER; - } else if (signature[i].equals(ForeignCallsProvider.class)) { - injected[i] = foreignCalls; - } else if (signature[i].equals(SnippetReflectionProvider.class)) { - injected[i] = snippetReflection; - } else if (signature[i].isAssignableFrom(Stamp.class)) { - injected[i] = invokeStamp; - } else if (signature[i].isAssignableFrom(StampProvider.class)) { - injected[i] = stampProvider; - } else { - throw new JVMCIError("Cannot handle injected argument of type %s in %s", signature[i].getName(), c.toString()); - } - } - - // Chop injected arguments from signature - signature = Arrays.copyOfRange(signature, injected.length, signature.length); - } - - if (Arrays.equals(parameterTypes, signature)) { - // Exact match - return new NodeIntrinsicFactory(invokeStamp, metaAccess.lookupJavaMethod(c), setStampFromReturnType, injected, parameterTypes, argumentNodes); - - } else if (signature.length > 0 && signature[signature.length - 1].isArray()) { - // Last constructor parameter is an array, so check if we have a vararg match - int fixedArgs = signature.length - 1; - if (parameterTypes.length < fixedArgs) { - return null; - } - for (int i = 0; i < fixedArgs; i++) { - if (!parameterTypes[i].equals(signature[i])) { - return null; - } - } - - Class<?> componentType = signature[fixedArgs].getComponentType(); - assert componentType != null; - for (int i = fixedArgs; i < argumentNodes.size(); i++) { - if (!parameterTypes[i].equals(componentType)) { - return null; - } - } - - List<ValueNode> fixed = argumentNodes.subList(0, fixedArgs); - List<ValueNode> varargs = argumentNodes.subList(fixedArgs, argumentNodes.size()); - - return new NodeIntrinsicFactory(invokeStamp, metaAccess.lookupJavaMethod(c), setStampFromReturnType, injected, parameterTypes, fixed, componentType, varargs); - - } else { - return null; - } - } - - private static String sourceLocation(Node n) { - String loc = GraphUtil.approxSourceLocation(n); - return loc == null ? "<unknown>" : loc; - } - - public void cleanUpReturnCheckCast(Node newInstance) { - if (newInstance instanceof ValueNode && (((ValueNode) newInstance).getStackKind() != JavaKind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) { - StructuredGraph graph = (StructuredGraph) newInstance.graph(); - for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) { - for (Node checkCastUsage : checkCastNode.usages().snapshot()) { - checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); - } - GraphUtil.unlinkFixedNode(checkCastNode); - GraphUtil.killCFG(checkCastNode); - } - } - } - - private static void checkCheckCastUsage(StructuredGraph graph, Node intrinsifiedNode, Node input, Node usage) { - if (usage instanceof ValueAnchorNode) { - ValueAnchorNode valueAnchorNode = (ValueAnchorNode) usage; - valueAnchorNode.removeAnchoredNode(); - Debug.log("%s: Removed a ValueAnchor input", Debug.contextSnapshot(JavaMethod.class)); - } else if (usage instanceof UnboxNode) { - UnboxNode unbox = (UnboxNode) usage; - unbox.replaceAtUsages(intrinsifiedNode); - graph.removeFixed(unbox); - Debug.log("%s: Removed an UnboxNode", Debug.contextSnapshot(JavaMethod.class)); - } else if (usage instanceof UnsafeStoreNode) { - UnsafeStoreNode store = (UnsafeStoreNode) usage; - store.replaceFirstInput(input, intrinsifiedNode); - } else if (usage instanceof LoadFieldNode) { - LoadFieldNode load = (LoadFieldNode) usage; - load.replaceAtUsages(intrinsifiedNode); - graph.removeFixed(load); - } else if (usage instanceof MethodCallTargetNode) { - MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) usage; - assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(input) + - " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod(); - usage.replaceFirstInput(input, intrinsifiedNode); - Debug.log("%s: Checkcast used in an other node intrinsic", Debug.contextSnapshot(JavaMethod.class)); - } else if (usage instanceof FrameState) { - usage.replaceFirstInput(input, null); - Debug.log("%s: Checkcast used in a FS", Debug.contextSnapshot(JavaMethod.class)); - } else if (usage instanceof ReturnNode && ((ValueNode) intrinsifiedNode).stamp() == StampFactory.forNodeIntrinsic()) { - usage.replaceFirstInput(input, intrinsifiedNode); - Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class)); - } else if (usage instanceof IsNullNode) { - if (!usage.hasNoUsages()) { - assert usage.getUsageCount() == 1 && usage.usages().first().predecessor() == input : usage + " " + input; - graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph)); - Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class)); - } else { - // Removed as usage of a GuardingPiNode - } - } else if (usage instanceof ProxyNode) { - ProxyNode proxy = (ProxyNode) usage; - assert proxy instanceof ValueProxyNode; - ProxyNode newProxy = ProxyNode.forValue((ValueNode) intrinsifiedNode, proxy.proxyPoint(), graph); - for (Node proxyUsage : usage.usages().snapshot()) { - checkCheckCastUsage(graph, newProxy, proxy, proxyUsage); - } - } else if (usage instanceof PiNode) { - for (Node piUsage : usage.usages().snapshot()) { - checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage); - } - } else { - DebugScope.forceDump(graph, "exception"); - assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast " + input + " at " + sourceLocation(input); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationProvider.java Thu Nov 26 14:44:30 2015 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, 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.replacements; + +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaType; + +import com.oracle.graal.api.replacements.SnippetReflectionProvider; +import com.oracle.graal.compiler.common.spi.ForeignCallsProvider; +import com.oracle.graal.compiler.common.type.Stamp; +import com.oracle.graal.compiler.common.type.StampFactory; +import com.oracle.graal.nodes.graphbuilderconf.NodeIntrinsicPluginFactory.InjectionProvider; +import com.oracle.graal.word.WordTypes; + +public class NodeIntrinsificationProvider implements InjectionProvider { + + private final MetaAccessProvider metaAccess; + private final SnippetReflectionProvider snippetReflection; + private final ForeignCallsProvider foreignCalls; + private final WordTypes wordTypes; + + public NodeIntrinsificationProvider(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, WordTypes wordTypes) { + this.metaAccess = metaAccess; + this.snippetReflection = snippetReflection; + this.foreignCalls = foreignCalls; + this.wordTypes = wordTypes; + } + + @Override + public Stamp getReturnStamp(Class<?> type) { + JavaKind kind = JavaKind.fromJavaClass(type); + if (kind == JavaKind.Object) { + ResolvedJavaType returnType = metaAccess.lookupJavaType(type); + if (wordTypes.isWord(returnType)) { + return wordTypes.getWordStamp(returnType); + } else { + return StampFactory.declared(returnType); + } + } else { + return StampFactory.forKind(kind); + } + } + + @Override + public <T> T getInjectedArgument(Class<T> type) { + T injected = snippetReflection.getInjectedNodeIntrinsicParameter(type); + if (injected != null) { + return injected; + } else if (type.equals(ForeignCallsProvider.class)) { + return type.cast(foreignCalls); + } else if (type.equals(SnippetReflectionProvider.class)) { + return type.cast(snippetReflection); + } else { + throw new JVMCIError("Cannot handle injected argument of type %s.", type.getName()); + } + } +}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Nov 26 14:27:42 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Nov 26 14:44:30 2015 +0100 @@ -766,12 +766,6 @@ } } while (exploded); - for (NodeIntrinsicFactory factory : snippetCopy.getNodes().filter(NodeIntrinsicFactory.class)) { - ValueNode intrinsic = factory.intrinsify(snippetCopy, providers.getConstantReflection(), snippetReflection); - assert intrinsic != null; - snippetCopy.replaceFixed(factory, intrinsic); - } - GuardsStage guardsStage = args.cacheKey.guardsStage; // Perform lowering on the snippet if (!guardsStage.allowsFloatingGuards()) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java Thu Nov 26 14:27:42 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java Thu Nov 26 14:44:30 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -36,12 +36,11 @@ import com.oracle.graal.nodes.PiNode; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.FloatingNode; -import com.oracle.graal.replacements.NodeIntrinsificationPhase; /** * A node for use in method substitutions or snippets that changes the type of its input where the - * type is not immediately available at {@link NodeIntrinsificationPhase intrinsification} time. It - * is replaced by a {@link PiNode} once the type becomes constant (which <b>must</b> happen). + * type is not immediately available at intrinsification time. It is replaced by a {@link PiNode} + * once the type becomes constant (which <b>must</b> happen). */ @NodeInfo public final class DeferredPiNode extends FloatingNode implements Canonicalizable {