Skip to content

Commit 973e617

Browse files
committed
inlining: correctly rewire non-value usages
1 parent ab75b44 commit 973e617

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright (c) 2025, 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.inlining;
26+
27+
import java.io.Serial;
28+
29+
import org.junit.Test;
30+
31+
import jdk.graal.compiler.api.directives.GraalDirectives;
32+
import jdk.graal.compiler.core.test.GraalCompilerTest;
33+
import jdk.graal.compiler.nodes.StructuredGraph;
34+
import jdk.graal.compiler.phases.common.CanonicalizerPhase;
35+
import jdk.graal.compiler.phases.common.ConditionalEliminationPhase;
36+
import jdk.graal.compiler.phases.common.inlining.InliningPhase;
37+
import jdk.graal.compiler.phases.common.inlining.policy.GreedyInliningPolicy;
38+
39+
/**
40+
* Penetrates the correct rewiring of non-value edges attached to an
41+
* {@link jdk.graal.compiler.nodes.java.ExceptionObjectNode} during inlining.
42+
*/
43+
public class InliningExceptionEdgeTest extends GraalCompilerTest {
44+
45+
public static class SpecialException extends RuntimeException {
46+
@Serial private static final long serialVersionUID = 1L;
47+
}
48+
49+
public static class SpecialException1 extends SpecialException {
50+
@Serial private static final long serialVersionUID = 1L;
51+
}
52+
53+
private static final RuntimeException SpecialException = new SpecialException();
54+
private static final RuntimeException SpecialException1 = new SpecialException1();
55+
private static final RuntimeException B3Exception = new RuntimeException("B3");
56+
57+
static boolean B1;
58+
static boolean B2;
59+
static boolean B3;
60+
61+
public abstract static class Base {
62+
abstract int foo();
63+
}
64+
65+
public static class A extends Base {
66+
@Override
67+
int foo() {
68+
if (B1) {
69+
throw SpecialException;
70+
}
71+
return 1;
72+
}
73+
}
74+
75+
public static class B extends Base {
76+
@Override
77+
int foo() {
78+
if (B2) {
79+
throw SpecialException1;
80+
}
81+
return 2;
82+
}
83+
}
84+
85+
public static class C extends Base {
86+
@Override
87+
int foo() {
88+
if (B3) {
89+
throw B3Exception;
90+
}
91+
return 3;
92+
}
93+
}
94+
95+
public static int snippet(int limit, Base b) {
96+
Base bNonNull = GraalDirectives.guardingNonNull(b);
97+
int ret = 0;
98+
for (int i = 0; i < limit; i++) {
99+
try {
100+
ret += bNonNull.foo();
101+
} catch (Throwable t) {
102+
if (t instanceof SpecialException) {
103+
ret--;
104+
}
105+
}
106+
}
107+
return ret;
108+
}
109+
110+
@Test
111+
public void testExceptionEdgeReplace() {
112+
A a = new A();
113+
B b = new B();
114+
C c = new C();
115+
116+
// we want a profile for the instanceof
117+
for (int i = 0; i < 10000; i++) {
118+
try {
119+
B1 = true;
120+
B2 = false;
121+
B3 = false;
122+
snippet(10, a);
123+
snippet(10, b);
124+
snippet(10, c);
125+
} catch (Throwable t) {
126+
// swallow, we want profiles
127+
}
128+
}
129+
StructuredGraph g = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
130+
CanonicalizerPhase canonicalizer = CanonicalizerPhase.create();
131+
canonicalizer.apply(g, getDefaultHighTierContext());
132+
new ConditionalEliminationPhase(canonicalizer, false).apply(g, getDefaultHighTierContext());
133+
new InliningPhase(new GreedyInliningPolicy(null), canonicalizer).apply(g, getDefaultHighTierContext());
134+
}
135+
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import jdk.graal.compiler.core.common.type.StampFactory;
3535
import jdk.graal.compiler.debug.Assertions;
3636
import jdk.graal.compiler.graph.Node;
37+
import jdk.graal.compiler.nodeinfo.InputType;
3738
import jdk.graal.compiler.nodes.AbstractBeginNode;
3839
import jdk.graal.compiler.nodes.AbstractMergeNode;
3940
import jdk.graal.compiler.nodes.BeginNode;
@@ -244,6 +245,7 @@ private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, CoreProvi
244245
if (invoke instanceof InvokeWithExceptionNode) {
245246
InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
246247
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
248+
exceptionEdge.replaceAtUsages(exceptionMerge, InputType.Guard, InputType.Anchor);
247249
exceptionEdge.replaceAtUsages(exceptionObjectPhi);
248250
exceptionEdge.setNext(null);
249251
GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());

0 commit comments

Comments
 (0)