Skip to content

Commit 524cc5f

Browse files
committed
[GR-32192] Exclude inlining option.
PullRequest: graal/9349
2 parents 1477a82 + 0ee082a commit 524cc5f

File tree

6 files changed

+258
-1
lines changed

6 files changed

+258
-1
lines changed

compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/DefaultInliningPolicy.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,14 @@ public Object newCallNodeData(CallNode callNode) {
110110
}
111111

112112
private void inline(CallTree tree) {
113+
String inlineOnly = options.get(PolyglotCompilerOptions.InlineOnly);
113114
final int inliningBudget = options.get(PolyglotCompilerOptions.InliningInliningBudget);
114115
final PriorityQueue<CallNode> inlineQueue = getQueue(tree, CallNode.State.Expanded);
115116
CallNode candidate;
116117
while ((candidate = inlineQueue.poll()) != null) {
118+
if (!InliningPolicy.acceptForInline(candidate, inlineOnly)) {
119+
continue;
120+
}
117121
if (candidate.isTrivial()) {
118122
candidate.inline();
119123
continue;

compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/InliningPolicy.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
*/
2525
package org.graalvm.compiler.truffle.compiler.phases.inlining;
2626

27+
import org.graalvm.collections.Pair;
28+
import org.graalvm.compiler.truffle.options.PolyglotCompilerOptions;
29+
30+
import java.util.ArrayList;
31+
import java.util.List;
2732
import java.util.Map;
2833

2934
@SuppressWarnings("unused")
@@ -47,4 +52,58 @@ default void afterExpand(CallNode callNode) {
4752

4853
default void run(CallTree tree) {
4954
}
55+
56+
/**
57+
* Checks if the {@link CallNode} should be compiled. The
58+
* {@link PolyglotCompilerOptions#InlineOnly InlineOnly} options are used to determine if the
59+
* root node should be compiled.
60+
*/
61+
static boolean acceptForInline(CallNode rootNode, String inlineOnly) {
62+
if (inlineOnly == null) {
63+
return true;
64+
}
65+
Pair<List<String>, List<String>> value = getInlineOnly(inlineOnly);
66+
if (value != null) {
67+
String name = rootNode.getName();
68+
List<String> includes = value.getLeft();
69+
boolean included = includes.isEmpty();
70+
if (name != null) {
71+
for (int i = 0; !included && i < includes.size(); i++) {
72+
if (name.contains(includes.get(i))) {
73+
included = true;
74+
}
75+
}
76+
}
77+
if (!included) {
78+
return false;
79+
}
80+
if (name != null) {
81+
for (String exclude : value.getRight()) {
82+
if (name.contains(exclude)) {
83+
return false;
84+
}
85+
}
86+
}
87+
}
88+
return true;
89+
}
90+
91+
/**
92+
* Returns the include and exclude sets for the {@link PolyglotCompilerOptions#InlineOnly}
93+
* option. The {@link Pair#getLeft() left} value is the include set and the
94+
* {@link Pair#getRight() right} value is the exclude set.
95+
*/
96+
static Pair<List<String>, List<String>> getInlineOnly(String inlineOnly) {
97+
List<String> includesList = new ArrayList<>();
98+
List<String> excludesList = new ArrayList<>();
99+
String[] items = inlineOnly.split(",");
100+
for (String item : items) {
101+
if (item.startsWith("~")) {
102+
excludesList.add(item.substring(1));
103+
} else {
104+
includesList.add(item);
105+
}
106+
}
107+
return Pair.create(includesList, excludesList);
108+
}
50109
}

compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/TrivialOnlyInliningPolicy.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,23 @@
2424
*/
2525
package org.graalvm.compiler.truffle.compiler.phases.inlining;
2626

27+
import org.graalvm.compiler.truffle.options.PolyglotCompilerOptions;
28+
import org.graalvm.options.OptionValues;
29+
2730
final class TrivialOnlyInliningPolicy implements InliningPolicy {
31+
private final OptionValues options;
32+
33+
TrivialOnlyInliningPolicy(OptionValues options) {
34+
this.options = options;
35+
}
36+
2837
@Override
2938
public void run(CallTree tree) {
39+
String inlineOnly = options.get(PolyglotCompilerOptions.InlineOnly);
3040
for (CallNode child : tree.getRoot().getChildren()) {
41+
if (!InliningPolicy.acceptForInline(child, inlineOnly)) {
42+
continue;
43+
}
3144
if (child.isTrivial()) {
3245
child.expand();
3346
child.inline();

compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/TrivialOnlyPolicyProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ public TrivialOnlyPolicyProvider() {
4040

4141
@Override
4242
public InliningPolicy get(OptionValues options, CoreProviders providers) {
43-
return new TrivialOnlyInliningPolicy();
43+
return new TrivialOnlyInliningPolicy(options);
4444
}
4545
}

compiler/src/org.graalvm.compiler.truffle.options/src/org/graalvm/compiler/truffle/options/PolyglotCompilerOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ private String indent(int nameLength) {
388388

389389
// Inlining
390390

391+
@Option(help = "Restrict inlined methods to ','-separated list of includes (or excludes prefixed with '~').", category = OptionCategory.INTERNAL)
392+
public static final OptionKey<String> InlineOnly = new OptionKey<>(null, OptionType.defaultType(String.class));
393+
391394
@Option(help = "Enable automatic inlining of guest language call targets.", category = OptionCategory.EXPERT)
392395
public static final OptionKey<Boolean> Inlining = new OptionKey<>(true);
393396

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright (c) 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+
26+
package org.graalvm.compiler.truffle.test.inlining;
27+
28+
import org.graalvm.polyglot.Context;
29+
import org.junit.Assert;
30+
import org.junit.Test;
31+
32+
import com.oracle.truffle.api.CallTarget;
33+
import com.oracle.truffle.api.CompilerDirectives;
34+
import com.oracle.truffle.api.RootCallTarget;
35+
import com.oracle.truffle.api.Truffle;
36+
import com.oracle.truffle.api.TruffleLanguage;
37+
import com.oracle.truffle.api.TruffleRuntime;
38+
import com.oracle.truffle.api.frame.VirtualFrame;
39+
import com.oracle.truffle.api.nodes.DirectCallNode;
40+
import com.oracle.truffle.api.nodes.RootNode;
41+
import com.oracle.truffle.api.test.polyglot.ProxyLanguage;
42+
43+
public class InlineOnlyTest {
44+
private static final String COMPILATION_ROOT_NAME = "main";
45+
private static final String METHOD_EXCLUDED_FROM_INLINING = "~should-not-be-inlined";
46+
private static final String METHOD_INLINED = "should-be-inlined,another-inlined-method";
47+
48+
@Test
49+
public void testNoInliningForMethodsWithPattern() throws Exception {
50+
try (Context c = Context.newBuilder().allowExperimentalOptions(true).//
51+
option("engine.CompilationFailureAction", "Throw").//
52+
option("engine.CompileImmediately", "true").//
53+
option("engine.BackgroundCompilation", "false").//
54+
option("engine.CompileOnly", COMPILATION_ROOT_NAME).//
55+
option("engine.InlineOnly", METHOD_EXCLUDED_FROM_INLINING).//
56+
build()) {
57+
c.eval(InlineOnlyTest.ExcludePatternTestLanguage.ID, "");
58+
c.eval(InlineOnlyTest.ExcludePatternTestLanguage.ID, "");
59+
}
60+
}
61+
62+
@Test
63+
public void testInlinedMethods() throws Exception {
64+
try (Context c = Context.newBuilder().allowExperimentalOptions(true).//
65+
option("engine.CompilationFailureAction", "Throw").//
66+
option("engine.CompileImmediately", "true").//
67+
option("engine.BackgroundCompilation", "false").//
68+
option("engine.CompileOnly", COMPILATION_ROOT_NAME).//
69+
option("engine.InlineOnly", METHOD_INLINED).//
70+
build()) {
71+
c.eval(InlineOnlyTest.InlineSelectedMethodsTestLanguage.ID, "");
72+
c.eval(InlineOnlyTest.InlineSelectedMethodsTestLanguage.ID, "");
73+
}
74+
}
75+
76+
@TruffleLanguage.Registration(id = InlineOnlyTest.ExcludePatternTestLanguage.ID, name = "InlineOnlyTest: With Exclude Pattern Test Language", version = "1.0")
77+
public static class ExcludePatternTestLanguage extends ProxyLanguage {
78+
79+
public static final String ID = "truffle-exclude-pattern-test-language";
80+
81+
@Override
82+
protected CallTarget parse(ParsingRequest request) throws Exception {
83+
final TruffleRuntime runtime = Truffle.getRuntime();
84+
final RootCallTarget rootCallTarget = runtime.createCallTarget(new RootNode(this) {
85+
86+
@Override
87+
public String toString() {
88+
return getName();
89+
}
90+
91+
@Override
92+
public Object execute(VirtualFrame frame) {
93+
CompilerDirectives.bailout("This node should not be inlined");
94+
return 99;
95+
}
96+
97+
@Override
98+
public String getName() {
99+
return METHOD_EXCLUDED_FROM_INLINING;
100+
}
101+
});
102+
return runtime.createCallTarget(new RootNode(this) {
103+
104+
@Child DirectCallNode callNode = runtime.createDirectCallNode(rootCallTarget);
105+
106+
@Override
107+
public String toString() {
108+
return getName();
109+
}
110+
111+
@Override
112+
public String getName() {
113+
return COMPILATION_ROOT_NAME;
114+
}
115+
116+
@Override
117+
public Object execute(VirtualFrame frame) {
118+
return callNode.call();
119+
}
120+
});
121+
}
122+
}
123+
124+
@TruffleLanguage.Registration(id = InlineOnlyTest.InlineSelectedMethodsTestLanguage.ID, name = "InlineOnlyTest: Inline Methods", version = "1.0")
125+
public static class InlineSelectedMethodsTestLanguage extends ProxyLanguage {
126+
127+
public static final String ID = "truffle-inline-selected-methods-test-language";
128+
129+
@Override
130+
protected CallTarget parse(ParsingRequest request) throws Exception {
131+
final TruffleRuntime runtime = Truffle.getRuntime();
132+
final RootCallTarget rootCallTarget = runtime.createCallTarget(new RootNode(this) {
133+
134+
@Override
135+
public String toString() {
136+
return getName();
137+
}
138+
139+
@Override
140+
public Object execute(VirtualFrame frame) {
141+
if (CompilerDirectives.inCompiledCode()) {
142+
assertFalse(CompilerDirectives.inCompilationRoot());
143+
}
144+
return 99;
145+
}
146+
147+
@CompilerDirectives.TruffleBoundary
148+
private void assertFalse(boolean inCompilationRoot) {
149+
Assert.assertFalse(inCompilationRoot);
150+
}
151+
152+
@Override
153+
public String getName() {
154+
return METHOD_INLINED;
155+
}
156+
});
157+
return runtime.createCallTarget(new RootNode(this) {
158+
159+
@Child DirectCallNode callNode = runtime.createDirectCallNode(rootCallTarget);
160+
161+
@Override
162+
public String toString() {
163+
return getName();
164+
}
165+
166+
@Override
167+
public String getName() {
168+
return COMPILATION_ROOT_NAME;
169+
}
170+
171+
@Override
172+
public Object execute(VirtualFrame frame) {
173+
return callNode.call();
174+
}
175+
});
176+
}
177+
}
178+
}

0 commit comments

Comments
 (0)