24
25 package org.graalvm.compiler.replacements.nodes;
26
27 import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
28 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
29 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
30 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
31
32 import org.graalvm.compiler.api.replacements.MethodSubstitution;
33 import org.graalvm.compiler.api.replacements.Snippet;
34 import org.graalvm.compiler.core.common.type.StampPair;
35 import org.graalvm.compiler.debug.DebugCloseable;
36 import org.graalvm.compiler.debug.DebugContext;
37 import org.graalvm.compiler.debug.GraalError;
38 import org.graalvm.compiler.graph.Node;
39 import org.graalvm.compiler.graph.NodeClass;
40 import org.graalvm.compiler.graph.NodeInputList;
41 import org.graalvm.compiler.nodeinfo.NodeInfo;
42 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
43 import org.graalvm.compiler.nodes.FixedNode;
44 import org.graalvm.compiler.nodes.Invokable;
45 import org.graalvm.compiler.nodes.FixedWithNextNode;
46 import org.graalvm.compiler.nodes.FrameState;
47 import org.graalvm.compiler.nodes.InvokeNode;
48 import org.graalvm.compiler.nodes.StructuredGraph;
49 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
50 import org.graalvm.compiler.nodes.ValueNode;
51 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
52 import org.graalvm.compiler.nodes.spi.Lowerable;
53 import org.graalvm.compiler.nodes.spi.LoweringTool;
54 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
55 import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
56 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
57 import org.graalvm.compiler.phases.common.LoweringPhase;
58 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
59 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
60 import org.graalvm.compiler.phases.tiers.PhaseContext;
61
62 import jdk.vm.ci.meta.JavaKind;
63 import jdk.vm.ci.meta.ResolvedJavaMethod;
64 import jdk.internal.vm.compiler.word.LocationIdentity;
65
66 /**
67 * Macro nodes can be used to temporarily replace an invoke. They can, for example, be used to
68 * implement constant folding for known JDK functions like {@link Class#isInterface()}.<br/>
69 * <br/>
70 * During lowering, multiple sources are queried in order to look for a replacement:
71 * <ul>
72 * <li>If {@link #getLoweredSnippetGraph(LoweringTool)} returns a non-null result, this graph is
73 * used as a replacement.</li>
74 * <li>If a {@link MethodSubstitution} for the target method is found, this substitution is used as
75 * a replacement.</li>
76 * <li>Otherwise, the macro node is replaced with an {@link InvokeNode}. Note that this is only
77 * possible if the macro node is a {@link MacroStateSplitNode}.</li>
78 * </ul>
79 */
80 //@formatter:off
81 @NodeInfo(cycles = CYCLES_UNKNOWN,
82 cyclesRationale = "If this node is not optimized away it will be lowered to a call, which we cannot estimate",
83 size = SIZE_UNKNOWN,
84 sizeRationale = "If this node is not optimized away it will be lowered to a call, which we cannot estimate")
143 public FixedNode asFixedNode() {
144 return this;
145 }
146
147 /**
148 * Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must
149 * have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}.
150 */
151 @SuppressWarnings("unused")
152 protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
153 return null;
154 }
155
156 /**
157 * Applies {@linkplain LoweringPhase lowering} to a replacement graph.
158 *
159 * @param replacementGraph a replacement (i.e., snippet or method substitution) graph
160 */
161 @SuppressWarnings("try")
162 protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
163 final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getConstantFieldProvider(), tool.getLowerer(), tool.getReplacements(),
164 tool.getStampProvider(), null);
165 if (!graph().hasValueProxies()) {
166 new RemoveValueProxyPhase().apply(replacementGraph);
167 }
168 GuardsStage guardsStage = graph().getGuardsStage();
169 if (!guardsStage.allowsFloatingGuards()) {
170 new GuardLoweringPhase().apply(replacementGraph, null);
171 if (guardsStage.areFrameStatesAtDeopts()) {
172 new FrameStateAssignmentPhase().apply(replacementGraph);
173 }
174 }
175 DebugContext debug = replacementGraph.getDebug();
176 try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", replacementGraph)) {
177 new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c);
178 } catch (Throwable e) {
179 throw debug.handle(e);
180 }
181 return replacementGraph;
182 }
183
184 @Override
|
24
25 package org.graalvm.compiler.replacements.nodes;
26
27 import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
28 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
29 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
30 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
31
32 import org.graalvm.compiler.api.replacements.MethodSubstitution;
33 import org.graalvm.compiler.api.replacements.Snippet;
34 import org.graalvm.compiler.core.common.type.StampPair;
35 import org.graalvm.compiler.debug.DebugCloseable;
36 import org.graalvm.compiler.debug.DebugContext;
37 import org.graalvm.compiler.debug.GraalError;
38 import org.graalvm.compiler.graph.Node;
39 import org.graalvm.compiler.graph.NodeClass;
40 import org.graalvm.compiler.graph.NodeInputList;
41 import org.graalvm.compiler.nodeinfo.NodeInfo;
42 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
43 import org.graalvm.compiler.nodes.FixedNode;
44 import org.graalvm.compiler.nodes.FixedWithNextNode;
45 import org.graalvm.compiler.nodes.FrameState;
46 import org.graalvm.compiler.nodes.Invokable;
47 import org.graalvm.compiler.nodes.InvokeNode;
48 import org.graalvm.compiler.nodes.StructuredGraph;
49 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
50 import org.graalvm.compiler.nodes.ValueNode;
51 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
52 import org.graalvm.compiler.nodes.spi.Lowerable;
53 import org.graalvm.compiler.nodes.spi.LoweringTool;
54 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
55 import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
56 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
57 import org.graalvm.compiler.phases.common.LoweringPhase;
58 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
59 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
60 import org.graalvm.compiler.phases.tiers.PhaseContext;
61 import jdk.internal.vm.compiler.word.LocationIdentity;
62
63 import jdk.vm.ci.meta.JavaKind;
64 import jdk.vm.ci.meta.ResolvedJavaMethod;
65
66 /**
67 * Macro nodes can be used to temporarily replace an invoke. They can, for example, be used to
68 * implement constant folding for known JDK functions like {@link Class#isInterface()}.<br/>
69 * <br/>
70 * During lowering, multiple sources are queried in order to look for a replacement:
71 * <ul>
72 * <li>If {@link #getLoweredSnippetGraph(LoweringTool)} returns a non-null result, this graph is
73 * used as a replacement.</li>
74 * <li>If a {@link MethodSubstitution} for the target method is found, this substitution is used as
75 * a replacement.</li>
76 * <li>Otherwise, the macro node is replaced with an {@link InvokeNode}. Note that this is only
77 * possible if the macro node is a {@link MacroStateSplitNode}.</li>
78 * </ul>
79 */
80 //@formatter:off
81 @NodeInfo(cycles = CYCLES_UNKNOWN,
82 cyclesRationale = "If this node is not optimized away it will be lowered to a call, which we cannot estimate",
83 size = SIZE_UNKNOWN,
84 sizeRationale = "If this node is not optimized away it will be lowered to a call, which we cannot estimate")
143 public FixedNode asFixedNode() {
144 return this;
145 }
146
147 /**
148 * Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must
149 * have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}.
150 */
151 @SuppressWarnings("unused")
152 protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
153 return null;
154 }
155
156 /**
157 * Applies {@linkplain LoweringPhase lowering} to a replacement graph.
158 *
159 * @param replacementGraph a replacement (i.e., snippet or method substitution) graph
160 */
161 @SuppressWarnings("try")
162 protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
163 final PhaseContext c = new PhaseContext(tool.getProviders());
164 if (!graph().hasValueProxies()) {
165 new RemoveValueProxyPhase().apply(replacementGraph);
166 }
167 GuardsStage guardsStage = graph().getGuardsStage();
168 if (!guardsStage.allowsFloatingGuards()) {
169 new GuardLoweringPhase().apply(replacementGraph, null);
170 if (guardsStage.areFrameStatesAtDeopts()) {
171 new FrameStateAssignmentPhase().apply(replacementGraph);
172 }
173 }
174 DebugContext debug = replacementGraph.getDebug();
175 try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", replacementGraph)) {
176 new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c);
177 } catch (Throwable e) {
178 throw debug.handle(e);
179 }
180 return replacementGraph;
181 }
182
183 @Override
|