Skip to content

Commit 951377b

Browse files
committed
[GR-51925] [GR-53746] LateLoweredNode for Graal.
PullRequest: graal/17937
2 parents 0ad902b + aa386ae commit 951377b

File tree

46 files changed

+1984
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1984
-212
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.core.test;
26+
27+
import org.junit.Test;
28+
29+
import jdk.graal.compiler.api.directives.GraalDirectives;
30+
import jdk.graal.compiler.core.common.type.StampFactory;
31+
import jdk.graal.compiler.graph.NodeClass;
32+
import jdk.graal.compiler.nodeinfo.NodeCycles;
33+
import jdk.graal.compiler.nodeinfo.NodeInfo;
34+
import jdk.graal.compiler.nodeinfo.NodeSize;
35+
import jdk.graal.compiler.nodes.AbstractBeginNode;
36+
import jdk.graal.compiler.nodes.BeginNode;
37+
import jdk.graal.compiler.nodes.FixedNode;
38+
import jdk.graal.compiler.nodes.IfNode;
39+
import jdk.graal.compiler.nodes.StructuredGraph;
40+
import jdk.graal.compiler.nodes.ValueNode;
41+
import jdk.graal.compiler.nodes.debug.SideEffectNode;
42+
import jdk.graal.compiler.nodes.memory.FloatingReadNode;
43+
import jdk.graal.compiler.phases.graph.ScheduledNodeIterator;
44+
45+
/**
46+
* Test to verify that the {@link ScheduledNodeIterator} can handle cases where
47+
* {@link AbstractBeginNode} have data inputs that can be lowered.
48+
*/
49+
public class ScheduledNodeIteratorBeginTest extends GraalCompilerTest {
50+
51+
static class A {
52+
int x;
53+
}
54+
55+
public static int snippet(A a, int x) {
56+
int res = a.x;
57+
if (x > 10) {
58+
GraalDirectives.sideEffect(2);
59+
} else {
60+
GraalDirectives.sideEffect(1 + res);
61+
}
62+
GraalDirectives.sideEffect(3);
63+
return x;
64+
}
65+
66+
/**
67+
* Note that we piggy back necessary graph modifications to expose the problematic pattern in
68+
* checkMidTierGraph here.
69+
*/
70+
@Override
71+
protected void checkMidTierGraph(StructuredGraph graph) {
72+
super.checkMidTierGraph(graph);
73+
assert graph.getNodes().filter(FloatingReadNode.class).count() == 1;
74+
75+
// the one with the higher node ID
76+
IfNode ifNode = null;
77+
78+
for (IfNode i : graph.getNodes(IfNode.TYPE)) {
79+
if (i.trueSuccessor().next() instanceof SideEffectNode) {
80+
assert ifNode == null : "Must not find multiple if nodes";
81+
ifNode = i;
82+
break;
83+
}
84+
}
85+
assert ifNode != null;
86+
87+
BeginNode trueSucc = (BeginNode) ifNode.trueSuccessor();
88+
89+
BeginWithReadUsage b = new BeginWithReadUsage(graph.getNodes().filter(FloatingReadNode.class).first());
90+
b = graph.add(b);
91+
92+
ifNode.setTrueSuccessor(null);
93+
94+
FixedNode oldNext = trueSucc.next();
95+
trueSucc.setNext(null);
96+
97+
b.setNext(oldNext);
98+
99+
ifNode.setTrueSuccessor(b);
100+
101+
trueSucc.safeDelete();
102+
}
103+
104+
@Test
105+
public void test() {
106+
test("snippet", new A(), 123);
107+
}
108+
109+
@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, cyclesRationale = "Test", size = NodeSize.SIZE_UNKNOWN, sizeRationale = "Test")
110+
public static class BeginWithReadUsage extends AbstractBeginNode {
111+
112+
public static final NodeClass<BeginWithReadUsage> TYPE = NodeClass.create(BeginWithReadUsage.class);
113+
@Input protected ValueNode input;
114+
115+
@SuppressWarnings("this-escape")
116+
public BeginWithReadUsage(ValueNode input) {
117+
super(TYPE, StampFactory.forVoid());
118+
this.input = input;
119+
}
120+
}
121+
122+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.core.test;
26+
27+
import java.util.function.Supplier;
28+
29+
import org.junit.AfterClass;
30+
import org.junit.BeforeClass;
31+
import org.junit.Test;
32+
33+
import jdk.graal.compiler.api.directives.GraalDirectives;
34+
import jdk.graal.compiler.core.common.type.Stamp;
35+
import jdk.graal.compiler.core.common.type.StampFactory;
36+
import jdk.graal.compiler.core.phases.HighTier;
37+
import jdk.graal.compiler.nodes.GraphState.GuardsStage;
38+
import jdk.graal.compiler.nodes.ValueNode;
39+
import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
40+
import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext;
41+
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin;
42+
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
43+
import jdk.graal.compiler.nodes.spi.LoweringTool;
44+
import jdk.graal.compiler.options.OptionValues;
45+
import jdk.graal.compiler.phases.util.Providers;
46+
import jdk.graal.compiler.replacements.SnippetTemplate;
47+
import jdk.graal.compiler.replacements.SnippetTemplate.Arguments;
48+
import jdk.graal.compiler.replacements.TestSnippets;
49+
import jdk.graal.compiler.replacements.TestSnippets.TransplantTestSnippets;
50+
import jdk.graal.compiler.replacements.nodes.LateLoweredNode;
51+
import jdk.vm.ci.code.InstalledCode;
52+
import jdk.vm.ci.code.InvalidInstalledCodeException;
53+
import jdk.vm.ci.meta.JavaKind;
54+
import jdk.vm.ci.meta.ResolvedJavaMethod;
55+
56+
public class TransplantLowLevelGraphTest extends GraalCompilerTest {
57+
58+
@BeforeClass
59+
public static void setup() {
60+
/**
61+
* Ensure snippets can be registered in a test setup running jargraal only.
62+
*/
63+
System.setProperty("GraalUnitTest", "true");
64+
}
65+
66+
@AfterClass
67+
public static void teardown() {
68+
System.clearProperty("GraalUnitTest");
69+
}
70+
71+
TestSnippets.TransplantTestSnippets.Templates transplantTestSnippets;
72+
73+
@SuppressWarnings("this-escape")
74+
public TransplantLowLevelGraphTest() {
75+
Providers p = getProviders();
76+
OptionValues opt = getInitialOptions();
77+
78+
// ensure that the snippets are registered
79+
transplantTestSnippets = new TestSnippets.TransplantTestSnippets.Templates(opt, p);
80+
}
81+
82+
@Override
83+
protected Plugins getDefaultGraphBuilderPlugins() {
84+
Plugins p = super.getDefaultGraphBuilderPlugins();
85+
Registration r = new Registration(p.getInvocationPlugins(), TransplantTestSnippets.class);
86+
87+
// register producer
88+
r.register(new InvocationPlugin("producer") {
89+
@Override
90+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
91+
JavaKind returnKind = JavaKind.Int;
92+
Stamp returnStamp = StampFactory.forKind(returnKind);
93+
ValueNode[] arguments = new ValueNode[0];
94+
LateLoweredNode lateMacroInvoke = new LateLoweredNode(b.bci(), targetMethod, returnStamp, arguments, null);
95+
lateMacroInvoke.setTemplateProducer(new Supplier<SnippetTemplate>() {
96+
@Override
97+
public SnippetTemplate get() {
98+
Arguments args = new Arguments(transplantTestSnippets.producer, GuardsStage.AFTER_FSA, LoweringTool.StandardLoweringStage.LOW_TIER);
99+
// no args
100+
SnippetTemplate template = transplantTestSnippets.template(getProviders(), lateMacroInvoke, args);
101+
return template;
102+
}
103+
});
104+
b.addPush(returnKind, lateMacroInvoke);
105+
b.setStateAfter(lateMacroInvoke);
106+
return true;
107+
}
108+
});
109+
110+
// register producerWithArgs
111+
r.register(new InvocationPlugin("producerWithArgs", int.class, int.class) {
112+
@Override
113+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg0, ValueNode arg1) {
114+
JavaKind returnKind = JavaKind.Int;
115+
Stamp returnStamp = StampFactory.forKind(returnKind);
116+
ValueNode[] arguments = new ValueNode[]{arg0, arg1};
117+
LateLoweredNode lateMacroInvoke = new LateLoweredNode(b.bci(), targetMethod, returnStamp, arguments, null);
118+
lateMacroInvoke.setTemplateProducer(new Supplier<SnippetTemplate>() {
119+
@Override
120+
public SnippetTemplate get() {
121+
Arguments args = new Arguments(transplantTestSnippets.producerWithArgs, GuardsStage.AFTER_FSA, LoweringTool.StandardLoweringStage.LOW_TIER);
122+
args.add("a", arg0);
123+
args.add("b", arg1);
124+
SnippetTemplate template = transplantTestSnippets.template(getProviders(), lateMacroInvoke, args);
125+
return template;
126+
}
127+
});
128+
b.addPush(returnKind, lateMacroInvoke);
129+
b.setStateAfter(lateMacroInvoke);
130+
return true;
131+
}
132+
});
133+
134+
// register producerWithDeopt
135+
r.register(new InvocationPlugin("producerWithDeopt", int.class, int.class) {
136+
@Override
137+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg0, ValueNode arg1) {
138+
JavaKind returnKind = JavaKind.Int;
139+
Stamp returnStamp = StampFactory.forKind(returnKind);
140+
ValueNode[] arguments = new ValueNode[]{arg0, arg1};
141+
LateLoweredNode lateMacroInvoke = new LateLoweredNode(b.bci(), targetMethod, returnStamp, arguments, null);
142+
lateMacroInvoke.setTemplateProducer(new Supplier<SnippetTemplate>() {
143+
@Override
144+
public SnippetTemplate get() {
145+
Arguments args = new Arguments(transplantTestSnippets.producerWithDeopt, GuardsStage.AFTER_FSA, LoweringTool.StandardLoweringStage.LOW_TIER);
146+
args.add("a", arg0);
147+
args.add("b", arg1);
148+
SnippetTemplate template = transplantTestSnippets.template(getProviders(), lateMacroInvoke, args);
149+
return template;
150+
}
151+
});
152+
b.addPush(returnKind, lateMacroInvoke);
153+
b.setStateAfter(lateMacroInvoke);
154+
return true;
155+
}
156+
});
157+
158+
return p;
159+
}
160+
161+
public OptionValues getOptionsWithoutInlining() {
162+
OptionValues opt = new OptionValues(getInitialOptions(), HighTier.Options.Inline, false);
163+
return opt;
164+
}
165+
166+
public int snippet01(int a) {
167+
int t = TransplantTestSnippets.producer();
168+
if (a == 12) {
169+
GraalDirectives.sideEffect();
170+
return TransplantTestSnippets.producer();
171+
} else {
172+
return t + TransplantTestSnippets.producer();
173+
}
174+
}
175+
176+
@Test
177+
public void test01() {
178+
test(getOptionsWithoutInlining(), "snippet01", 100);
179+
}
180+
181+
public int snippet02(int a, int b) {
182+
int t = TransplantTestSnippets.producerWithArgs(a, b);
183+
for (int i = 0; i < a; i++) {
184+
if (a == 12) {
185+
GraalDirectives.sideEffect();
186+
t = t * 2 + TransplantTestSnippets.producerWithArgs(a, b);
187+
} else {
188+
t = t + TransplantTestSnippets.producerWithArgs(a, b);
189+
}
190+
}
191+
return t;
192+
}
193+
194+
@Test
195+
public void test02() {
196+
test(getOptionsWithoutInlining(), "snippet02", 100, 200);
197+
}
198+
199+
public static int snippet03(int a, int b) {
200+
int t = TransplantTestSnippets.producerWithDeopt(a, b);
201+
I = t;
202+
return t;
203+
}
204+
205+
static Integer I;
206+
207+
@Test
208+
public void test03() throws InvalidInstalledCodeException {
209+
InstalledCode ic = getCode(getResolvedJavaMethod("snippet03"), getOptionsWithoutInlining());
210+
211+
ic.executeVarargs(98, 100);
212+
assert ic.isValid();
213+
214+
ic.executeVarargs(98, 100);
215+
assert ic.isValid();
216+
217+
ic.executeVarargs(98, 100);
218+
assert ic.isValid();
219+
220+
ic.executeVarargs(99, 100);
221+
assert !ic.isValid();
222+
}
223+
224+
public int snippet04(int a) {
225+
if (a == 12) {
226+
TransplantTestSnippets.producerWithArgs(a, a);
227+
} else {
228+
GraalDirectives.sideEffect(1);
229+
}
230+
GraalDirectives.sideEffect(2);
231+
GraalDirectives.controlFlowAnchor();
232+
return 0;
233+
}
234+
235+
@Test
236+
public void test04() {
237+
test(getOptionsWithoutInlining(), "snippet04", 100);
238+
}
239+
}

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifySystemPropertyUsage.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ protected void verify(StructuredGraph graph, CoreProviders context) {
8686
} else if (packageName.startsWith("ai.onnxruntime")) {
8787
// Do not verify the ONNX Java Inference Runtime.
8888
return;
89+
} else if (holderQualified.equals("jdk.graal.compiler.hotspot.HotSpotReplacementsImpl") && caller.getName().equals("registerSnippet")) {
90+
// We allow opening snippet registration in jargraal unit tests.
91+
return;
8992
}
9093
for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
9194
ResolvedJavaMethod callee = t.targetMethod();

0 commit comments

Comments
 (0)