Skip to content

Commit 25287fe

Browse files
David Huaboris-spas
authored andcommitted
[GR-61337] Properly use sampled method profiles for inlining decisions
PullRequest: graal/21520
2 parents 5bcb772 + dd73319 commit 25287fe

File tree

4 files changed

+102
-18
lines changed

4 files changed

+102
-18
lines changed

sdk/mx.sdk/mx_sdk_benchmark.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,27 @@ def run_launcher(self, cmd, args, cwd):
287287
return code, out, dims
288288

289289

290+
# The uncompressed file from perf script is ~25x bigger than the compressed file
291+
ADJUSTED_ITERS_FOR_PERF = {
292+
"renaissance": {
293+
"finagle-chirper": 10, # Default: 90 iters, 7GB compressed perf file
294+
"fj-kmeans": 15, # Default: 30 iters, 520MB compressed perf file
295+
"scala-stm-bench7": 20, # Default: 60 iters, 840MB compressed perf file
296+
"philosophers": 10, # Default: 30 iters, 900MB compressed perf file
297+
"akka-uct": 5, # Default: 24 iters, 2GB compressed perf file
298+
"finagle-http": 5 # Default: 12 iters, 1.3GB compressed perf file
299+
},
300+
"dacapo": {
301+
"sunflow": 15 # Default: 49 iters, 1.2GB compressed perf file
302+
}
303+
}
304+
305+
NUM_ITERS_FLAG_NAME = {
306+
"renaissance": "-r",
307+
"dacapo": "-n"
308+
}
309+
310+
290311
class NativeImageBenchmarkConfig:
291312
def __init__(self, vm: NativeImageVM, bm_suite: BenchmarkSuite | NativeImageBenchmarkMixin, args):
292313
self.bm_suite = bm_suite
@@ -308,6 +329,11 @@ def __init__(self, vm: NativeImageVM, bm_suite: BenchmarkSuite | NativeImageBenc
308329
not (vm.safepoint_sampler or vm.pgo_sampler_only or vm.pgo_use_perf))
309330
self.extra_agent_profile_run_args = bm_suite.extra_agent_profile_run_arg(self.benchmark_name, args,
310331
list(image_run_args))
332+
if vm.pgo_use_perf and self.benchmark_suite_name in ADJUSTED_ITERS_FOR_PERF and self.benchmark_name in ADJUSTED_ITERS_FOR_PERF[self.benchmark_suite_name]:
333+
# For some benches the number of iters in the instrument-run stage is too much for perf, the generated files are too large.
334+
desired_iters = ADJUSTED_ITERS_FOR_PERF[self.benchmark_suite_name][self.benchmark_name]
335+
mx.log(f"Adjusting number of iters for instrument-run stage to {desired_iters}")
336+
self.extra_profile_run_args = adjust_arg_with_number(NUM_ITERS_FLAG_NAME[self.benchmark_suite_name], desired_iters, self.extra_profile_run_args)
311337
self.params = ['extra-image-build-argument', 'extra-jvm-arg', 'extra-run-arg', 'extra-agent-run-arg',
312338
'extra-profile-run-arg',
313339
'extra-agent-profile-run-arg', 'benchmark-output-dir', 'stages', 'skip-agent-assertions']
@@ -1569,7 +1595,7 @@ def run_stage_instrument_run(self):
15691595
image_run_cmd += self.config.extra_jvm_args
15701596
image_run_cmd += self.config.extra_profile_run_args
15711597
if self.pgo_use_perf:
1572-
image_run_cmd = ['perf', 'record', '-o', f'{self.config.perf_data_path}', '--call-graph', 'fp,2048', '--freq=999'] + image_run_cmd
1598+
image_run_cmd = ['perf', 'record', '-o', f'{self.config.perf_data_path}', '--call-graph', 'fp', '--freq=999'] + image_run_cmd
15731599

15741600
with self.get_stage_runner() as s:
15751601
if self.pgo_use_perf:
@@ -3747,6 +3773,15 @@ def _strip_arg_with_number_gen(_strip_arg, _args):
37473773
result = _strip_arg_with_number_gen(strip_arg, result)
37483774
return list(result)
37493775

3776+
def adjust_arg_with_number(arg_name, new_value: int, user_args):
3777+
"""
3778+
Sets the argument value of `arg_name` in `user_args` with `new_value`.
3779+
If `arg_name` is already present in `user_args`, the value will be replaced.
3780+
If `arg_name` is not already present, the argument and corresponding value will be added.
3781+
"""
3782+
3783+
return [arg_name, str(new_value)] + strip_args_with_number(arg_name, user_args)
3784+
37503785
class PerfInvokeProfileCollectionStrategy(Enum):
37513786
"""
37523787
The strategy for extracting virtual invoke method profiles from perf sampling data.

substratevm/mx.substratevm/mx_substratevm_benchmark.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,13 @@ def renaissance_additional_lib(self, lib):
216216
def extra_agent_run_arg(self, benchmark, args, image_run_args):
217217
user_args = super(RenaissanceNativeImageBenchmarkSuite, self).extra_agent_run_arg(benchmark, args, image_run_args)
218218
# remove -r X argument from image run args
219-
return ['-r', '1'] + mx_sdk_benchmark.strip_args_with_number('-r', user_args)
219+
return mx_sdk_benchmark.adjust_arg_with_number('-r', 1, user_args)
220220

221221
def extra_profile_run_arg(self, benchmark, args, image_run_args, should_strip_run_args):
222222
user_args = super(RenaissanceNativeImageBenchmarkSuite, self).extra_profile_run_arg(benchmark, args, image_run_args, should_strip_run_args)
223223
# remove -r X argument from image run args
224224
if should_strip_run_args:
225-
extra_profile_run_args = ['-r', '1'] + mx_sdk_benchmark.strip_args_with_number('-r', user_args)
225+
extra_profile_run_args = mx_sdk_benchmark.adjust_arg_with_number('-r', 1, user_args)
226226
else:
227227
extra_profile_run_args = user_args
228228

@@ -1213,7 +1213,7 @@ def run(self, benchmarks, bmSuiteArgs) -> mx_benchmark.DataPoints:
12131213
def extra_agent_run_arg(self, benchmark, args, image_run_args):
12141214
user_args = super(DaCapoNativeImageBenchmarkSuite, self).extra_agent_run_arg(benchmark, args, image_run_args)
12151215
# remove -n X argument from image run args
1216-
return ['-n', '1'] + mx_sdk_benchmark.strip_args_with_number('-n', user_args)
1216+
return mx_sdk_benchmark.adjust_arg_with_number('-n', 1, user_args)
12171217

12181218
def extra_profile_run_arg(self, benchmark, args, image_run_args, should_strip_run_args):
12191219
self.fixDataLocation()
@@ -1225,7 +1225,7 @@ def extra_profile_run_arg(self, benchmark, args, image_run_args, should_strip_ru
12251225

12261226
# remove -n X argument from image run args
12271227
if should_strip_run_args:
1228-
return ['-n', '1'] + mx_sdk_benchmark.strip_args_with_number('-n', user_args)
1228+
return mx_sdk_benchmark.adjust_arg_with_number('-n', 1, user_args)
12291229
else:
12301230
return user_args
12311231

@@ -1370,13 +1370,13 @@ def run(self, benchmarks, bmSuiteArgs) -> mx_benchmark.DataPoints:
13701370
def extra_agent_run_arg(self, benchmark, args, image_run_args):
13711371
user_args = super(ScalaDaCapoNativeImageBenchmarkSuite, self).extra_agent_run_arg(benchmark, args, image_run_args)
13721372
# remove -n X argument from image run args
1373-
return mx_sdk_benchmark.strip_args_with_number('-n', user_args) + ['-n', '1']
1373+
return mx_sdk_benchmark.adjust_arg_with_number('-n', 1, user_args)
13741374

13751375
def extra_profile_run_arg(self, benchmark, args, image_run_args, should_strip_run_args):
13761376
user_args = super(ScalaDaCapoNativeImageBenchmarkSuite, self).extra_profile_run_arg(benchmark, args, image_run_args, should_strip_run_args)
13771377
# remove -n X argument from image run args if the flag is true.
13781378
if should_strip_run_args:
1379-
return mx_sdk_benchmark.strip_args_with_number('-n', user_args) + ['-n', '1']
1379+
return mx_sdk_benchmark.adjust_arg_with_number('-n', 1, user_args)
13801380
else:
13811381
return user_args
13821382

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nodes/SubstrateMethodCallTargetNode.java

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@
4343
public final class SubstrateMethodCallTargetNode extends MethodCallTargetNode {
4444
public static final NodeClass<SubstrateMethodCallTargetNode> TYPE = NodeClass.create(SubstrateMethodCallTargetNode.class);
4545

46+
/**
47+
* Method profile inferred from a static type profile.
48+
*/
49+
private JavaMethodProfile staticMethodProfile;
50+
/**
51+
* Either the static method profile, or a dynamic method profile inferred from, for example,
52+
* sampling data.
53+
*/
4654
private JavaMethodProfile methodProfile;
4755

4856
/*
@@ -59,27 +67,68 @@ public SubstrateMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod t
5967
super(TYPE, invokeKind, targetMethod, arguments, returnStamp, typeProfile);
6068
}
6169

62-
public void setProfiles(JavaTypeProfile typeProfile, JavaMethodProfile methodProfile) {
63-
this.typeProfile = typeProfile;
64-
this.methodProfile = methodProfile;
65-
this.staticTypeProfile = typeProfile;
70+
public void setProfiles(JavaTypeProfile dynamicTypeProfile, JavaTypeProfile staticTypeProfile, JavaMethodProfile dynamicMethodProfile, JavaMethodProfile staticMethodProfile) {
71+
this.typeProfile = dynamicTypeProfile;
72+
this.methodProfile = dynamicMethodProfile;
73+
this.staticTypeProfile = staticTypeProfile;
74+
this.staticMethodProfile = staticMethodProfile;
6675
}
6776

68-
public void setProfiles(JavaTypeProfile typeProfile, JavaMethodProfile methodProfile, JavaTypeProfile staticTypeProfile) {
77+
public void setDynamicProfiles(JavaTypeProfile typeProfile, JavaMethodProfile methodProfile) {
6978
this.typeProfile = typeProfile;
7079
this.methodProfile = methodProfile;
71-
this.staticTypeProfile = staticTypeProfile;
7280
}
7381

82+
/**
83+
* Returns a dynamic method profile if one exists. Otherwise, returns a static method profile if
84+
* one exists. If neither exist, returns null.
85+
*/
7486
public JavaMethodProfile getMethodProfile() {
7587
return methodProfile;
7688
}
7789

90+
/**
91+
* Returns a static type profile if one exists. Otherwise, returns null.
92+
*/
7893
public JavaTypeProfile getStaticTypeProfile() {
7994
return staticTypeProfile;
8095
}
8196

97+
/**
98+
* Returns a static method profile if one exists. Otherwise, returns null.
99+
*/
100+
public JavaMethodProfile getStaticMethodProfile() {
101+
return staticMethodProfile;
102+
}
103+
104+
/**
105+
* Set a dynamic method profile.
106+
*/
82107
public void setJavaMethodProfile(JavaMethodProfile profile) {
83108
methodProfile = profile;
84109
}
110+
111+
/**
112+
* Returns true iff {@code this} has a dynamic type profile. A dynamic type profile can be
113+
* gathered by, for example, instrumentation. A static type profile (as produced by the static
114+
* analysis) does not count as a dynamic profile.
115+
*/
116+
public boolean hasDynamicTypeProfile() {
117+
if (typeProfile == null) {
118+
return false;
119+
}
120+
return !typeProfile.equals(staticTypeProfile);
121+
}
122+
123+
/**
124+
* Returns true iff {@code this} has a dynamic method profile. A dynamic method profile can be
125+
* gathered by, for example, instrumentation or perf samples. A static method profile (as
126+
* produced by the static analysis) does not count as a dynamic profile.
127+
*/
128+
public boolean hasDynamicMethodProfile() {
129+
if (methodProfile == null) {
130+
return false;
131+
}
132+
return !methodProfile.equals(staticMethodProfile);
133+
}
85134
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SubstrateStrengthenGraphs.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@
4444
import com.oracle.svm.hosted.code.SubstrateCompilationDirectives;
4545
import com.oracle.svm.hosted.imagelayer.HostedImageLayerBuildingSupport;
4646
import com.oracle.svm.hosted.meta.HostedType;
47-
48-
import com.oracle.svm.hosted.phases.DynamicAccessDetectionPhase;
4947
import com.oracle.svm.hosted.phases.AnalyzeJavaHomeAccessPhase;
48+
import com.oracle.svm.hosted.phases.DynamicAccessDetectionPhase;
5049

5150
import jdk.graal.compiler.graph.Node;
5251
import jdk.graal.compiler.nodes.ConstantNode;
@@ -149,13 +148,14 @@ protected FixedNode createUnreachable(StructuredGraph graph, CoreProviders provi
149148
@Override
150149
protected void setInvokeProfiles(Invoke invoke, JavaTypeProfile typeProfile, JavaMethodProfile methodProfile) {
151150
if (needsProfiles(invoke.asNode().graph())) {
152-
((SubstrateMethodCallTargetNode) invoke.callTarget()).setProfiles(typeProfile, methodProfile);
151+
((SubstrateMethodCallTargetNode) invoke.callTarget()).setProfiles(typeProfile, typeProfile, methodProfile, methodProfile);
153152
}
154153
}
155154

156-
protected void setInvokeProfiles(Invoke invoke, JavaTypeProfile typeProfile, JavaMethodProfile methodProfile, JavaTypeProfile staticTypeProfile) {
155+
protected void setInvokeProfiles(Invoke invoke, JavaTypeProfile typeProfile, JavaMethodProfile methodProfile, JavaTypeProfile staticTypeProfile, JavaMethodProfile staticMethodProfile) {
157156
if (needsProfiles(invoke.asNode().graph())) {
158-
((SubstrateMethodCallTargetNode) invoke.callTarget()).setProfiles(typeProfile, methodProfile, staticTypeProfile);
157+
SubstrateMethodCallTargetNode substrateCallTarget = (SubstrateMethodCallTargetNode) invoke.callTarget();
158+
substrateCallTarget.setProfiles(typeProfile, staticTypeProfile, methodProfile, staticMethodProfile);
159159
}
160160
}
161161

0 commit comments

Comments
 (0)