# HG changeset patch # User Lukas Stadler # Date 1404121134 -7200 # Node ID e6622e77e8c7d21fd019b84ac9e2a84232c49275 # Parent b2b362cc1a9fbbbcfdc7e97a3e53d5096dcfd4bc split MacroNode into MacroNode and MacroStateSplitNode diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -34,7 +34,7 @@ * * @see ClassSubstitutions#cast(Class, Object) */ -public class ClassCastNode extends MacroNode implements Canonicalizable.Binary { +public class ClassCastNode extends MacroStateSplitNode implements Canonicalizable.Binary { public ClassCastNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Mon Jun 30 11:38:54 2014 +0200 @@ -35,7 +35,7 @@ * @see ClassSubstitutions#getClassLoader0(Class) */ @SuppressWarnings("javadoc") -public class ClassGetClassLoader0Node extends MacroNode implements Canonicalizable { +public class ClassGetClassLoader0Node extends MacroStateSplitNode implements Canonicalizable { public ClassGetClassLoader0Node(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -38,7 +38,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; -public class ArrayCopyNode extends MacroNode implements Virtualizable, Lowerable { +public class ArrayCopyNode extends MacroStateSplitNode implements Virtualizable, Lowerable { public ArrayCopyNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class CallSiteTargetNode extends MacroNode implements Canonicalizable, Lowerable { +public class CallSiteTargetNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { public CallSiteTargetNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -44,7 +44,7 @@ /** * Node for invocation methods defined on the class {@link MethodHandle}. */ -public class MethodHandleNode extends MacroNode implements Simplifiable { +public class MethodHandleNode extends MacroStateSplitNode implements Simplifiable { /** The method that this node is representing. */ private final IntrinsicMethod intrinsicMethod; diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -39,7 +39,7 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.replacements.nodes.*; -public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider { +public class ObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { public ObjectCloneNode(Invoke invoke) { super(invoke); @@ -107,7 +107,7 @@ /* * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an * exact type) and if it is a cloneable type. - * + * * If yes, then the exact type is returned, otherwise it returns null. */ private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable { +public class ReflectionGetCallerClassNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { public ReflectionGetCallerClassNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -24,13 +24,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -39,7 +39,22 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.*; -public class MacroNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { +/** + * Macro nodes can be used to temporarily replace an invoke (usually by using the + * {@link MacroSubstitution} annotation). They can, for example, be used to implement constant + * folding for known JDK functions like {@link Class#isInterface()}.
+ *
+ * During lowering, multiple sources are queried in order to look for a replacement: + *
    + *
  • If {@link #getLoweredSnippetGraph(LoweringTool)} returns a non-null result, this graph is + * used as a replacement.
  • + *
  • If a {@link MethodSubstitution} for the target method is found, this substitution is used as + * a replacement.
  • + *
  • Otherwise, the macro node is replaced with an {@link InvokeNode}. Note that this is only + * possible if the macro node is a {@link MacroStateSplitNode}.
  • + *
+ */ +public class MacroNode extends FixedWithNextNode implements Lowerable { @Input protected final NodeInputList arguments; @@ -49,7 +64,7 @@ private final InvokeKind invokeKind; protected MacroNode(Invoke invoke) { - super(invoke.asNode().stamp(), invoke.stateAfter()); + super(StampFactory.forKind(((MethodCallTargetNode) invoke.callTarget()).targetMethod().getSignature().getReturnKind())); MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget(); this.arguments = new NodeInputList<>(this, methodCallTarget.arguments()); this.bci = invoke.bci(); @@ -70,6 +85,10 @@ return returnType; } + protected FrameState stateAfter() { + return null; + } + /** * Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must * have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}. @@ -145,6 +164,7 @@ InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(graph(), "After inlining replacement %s", replacementGraph); } else { + assert stateAfter() != null : "cannot lower to invoke without state: " + this; invoke.lower(tool); } } @@ -166,23 +186,4 @@ } return invoke; } - - protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { - for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { - Invoke invoke = call.invoke(); - if (!call.targetMethod().equals(getTargetMethod())) { - throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName()); - } - assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI; - // Here we need to fix the bci of the invoke - InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci())); - newInvoke.setStateAfter(invoke.stateAfter()); - snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke); - } - } - - @Override - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; - } } diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, 2014, 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.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; + +/** + * This is an extension of {@link MacroNode} that is a {@link StateSplit} and a + * {@link MemoryCheckpoint}. + */ +public class MacroStateSplitNode extends MacroNode implements StateSplit, MemoryCheckpoint.Single { + + @Input(InputType.State) private FrameState stateAfter; + + protected MacroStateSplitNode(Invoke invoke) { + super(invoke); + this.stateAfter = invoke.stateAfter(); + } + + @Override + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } + + public LocationIdentity getLocationIdentity() { + return LocationIdentity.ANY_LOCATION; + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } + + protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { + for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { + Invoke invoke = call.invoke(); + if (!call.targetMethod().equals(getTargetMethod())) { + throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName()); + } + assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI; + // Here we need to fix the bci of the invoke + InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci())); + newInvoke.setStateAfter(invoke.stateAfter()); + snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke); + } + } +} diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -31,7 +31,7 @@ * This node class can be used to create {@link MacroNode}s for simple pure functions like * {@link System#identityHashCode(Object)}. */ -public abstract class PureFunctionMacroNode extends MacroNode implements Canonicalizable { +public abstract class PureFunctionMacroNode extends MacroStateSplitNode implements Canonicalizable { public PureFunctionMacroNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -25,8 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.*; @@ -50,6 +53,11 @@ } @Override + public void lower(LoweringTool tool) { + throw new GraalInternalError(GraphUtil.approxSourceException(this, new RuntimeException("assumption could not be evaluated to a constant"))); + } + + @Override public void simplify(SimplifierTool tool) { ValueNode assumption = getAssumption(); if (tool.assumptions() != null && assumption.isConstant()) { diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; public class BailoutNode extends MacroNode implements Canonicalizable { @@ -35,13 +36,20 @@ assert arguments.size() == 1; } + public ValueNode getMessage() { + return arguments.get(0); + } + + @Override + public void lower(LoweringTool tool) { + throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)"); + } + @Override public Node canonical(CanonicalizerTool tool) { - ValueNode arg = arguments.get(0); - String message = ""; - if (arg.isConstant()) { - message = arg.asConstant().toValueString(); + if (getMessage().isConstant()) { + throw new BailoutException(getMessage().asConstant().toValueString()); } - throw new BailoutException(message); + return this; } } diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { +public class NeverInlineMacroNode extends MacroStateSplitNode implements com.oracle.graal.graph.IterableNodeType { public NeverInlineMacroNode(Invoke invoke) { super(invoke); diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -22,10 +22,11 @@ */ package com.oracle.graal.truffle.nodes.asserts; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; -public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { +public class NeverPartOfCompilationNode extends MacroNode implements IterableNodeType { private final String message; diff -r b2b362cc1a9f -r e6622e77e8c7 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Thu Jun 26 13:26:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Jun 30 11:38:54 2014 +0200 @@ -34,7 +34,9 @@ /** * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. */ -public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { +public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable, StateSplit { + + @Input(InputType.State) private FrameState stateAfter; private static final int ARGUMENT_COUNT = 4; private static final int OBJECT_ARGUMENT_INDEX = 0; @@ -45,6 +47,7 @@ public CustomizedUnsafeStoreMacroNode(Invoke invoke) { super(invoke, "The location argument could not be resolved to a constant."); assert arguments.size() == ARGUMENT_COUNT; + this.stateAfter = invoke.stateAfter(); } @Override @@ -61,8 +64,21 @@ locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant()); } - return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter()); + return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter); } return this; } + + @Override + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + this.stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } }