On 24/02/26 02:37, Andrew Pinski wrote:
External email: Use caution opening links or attachments
On Tue, Feb 17, 2026 at 9:07 PM <[email protected]> wrote:
From: Dhruv Chawla <[email protected]>
This patch adds support for ARM SPE as a profiler to gcc-auto-profile
and the corresponding detection required for passing the
--profiler=perf_spe option to create_gcov when creating the GCOV files.
Errors from create_gcov are also set to be ignored. This is because some
of the profiles end up not including invocations of one of cc1, cc1plus or lto1
and trying to use them to generate the GCOV with the missing binary ends up
failing the create_gcov command. This is expected and is not an error condition.
For example:
perf buildid-list -i prev-libbacktrace/perf.data
aff9c7b2c5c294612904563fa3da88cb054d313d [kernel.kallsyms]
962097804b5c10ba831958fbb9609cb6d0c1101f /usr/bin/make
...
8227253257ca616415b6d90c8b94de71b314997c
/local/home/dhruvc/misc-testing/build-afdo-bootstrap-all/prev-gcc/xgcc
077d6240baadea4c3288e106b17164d164ea7b31
/local/home/dhruvc/misc-testing/build-afdo-bootstrap-all/prev-gcc/cc1
...
There is no instance of cc1plus or lto1 here, so create_gcov cannot be
run on this.
Autoprofilebootstrapped and regtested on aarch64-linux-gnu.
This is not a full review and most likely minor issues so you should
wait for others to send out a new version of the patch.
Signed-off-by: Dhruv Chawla <[email protected]>
gcc/ChangeLog:
* config/aarch64/gcc-auto-profile: Detect and use ARM SPE events when
invoking perf record.
gcc/c/ChangeLog:
* Make-lang.in: Add support for profiler type detection.
(create_fdas_for_cc1): Use $(PROFILER) when passing --profiler
to create_gcov. Ignore create_gcov failures by changing "|| exit 1" to
"|| exit 0".
gcc/cp/ChangeLog:
* Make-lang.in: Likewise.
(create_fdas_for_cc1plus): Likewise.
gcc/lto/ChangeLog:
* Make-lang.in: Likewise.
(create_fdas_for_lto1): Likewise.
Don't use likewise to carry over from one ChangeLog file to another.
Noted, thanks. Wasn't aware.
gcc/testsuite/ChangeLog:
* lib/profopt.exp (profopt-execute): Add support for profiler type
detection.
---
gcc/c/Make-lang.in | 6 ++++--
gcc/config/aarch64/gcc-auto-profile | 5 +++++
gcc/cp/Make-lang.in | 6 ++++--
gcc/lto/Make-lang.in | 6 ++++--
gcc/testsuite/lib/profopt.exp | 8 +++++++-
5 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index fd127caba91..547328bf8f6 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -95,6 +95,8 @@ components_in_prev_target = "libstdc++-v3 libsanitizer libvtv
libgcc libbacktrac
cc1.fda: create_fdas_for_cc1
$(PROFILE_MERGER) $(shell ls -ha cc1_*.fda) --output_file cc1.fda
-gcov_version 3
+PROFILER=$(shell [ -n "$$(perf list | grep arm_spe)" ] && echo perf_spe ||
echo perf)
Is there a way NOT to do it in c makefile but rather at the toplevel
makefile and pass it down? Maybe also do it instead in a configure
test rather directly in the makefile?
I will try to do this in configure then. I guess that is the best place for
this because this isn't something that ever varies in the build, though the
Makefile is much easier to modify.
+
create_fdas_for_cc1: ../stage1-gcc/cc1$(exeext) ../prev-gcc/$(PERF_DATA)
for component_in_prev in "$(components_in_prev)"; do \
perf_path=../prev-$$component_in_prev/$(PERF_DATA); \
@@ -102,7 +104,7 @@ create_fdas_for_cc1: ../stage1-gcc/cc1$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1_$$component_in_prev.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/cc1$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../stage1-gcc/cc1$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
@@ -112,7 +114,7 @@ create_fdas_for_cc1: ../stage1-gcc/cc1$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../prev-gcc/cc1$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../prev-gcc/cc1$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
diff --git a/gcc/config/aarch64/gcc-auto-profile
b/gcc/config/aarch64/gcc-auto-profile
index 4d5c2e34855..430a70b4e17 100755
--- a/gcc/config/aarch64/gcc-auto-profile
+++ b/gcc/config/aarch64/gcc-auto-profile
@@ -45,6 +45,11 @@ if [ "$use_brbe" = true ] ; then
set -x
perf record -j any,$FLAGS "$@"
set +x
+elif [ -n "$(perf list | grep arm_spe)" ] ; then
+ echo >&2 "Info: Using SPE to collect branch profiles"
+ set -x
+ perf record -e arm_spe_0/branch_filter=1/ "$@"
+ set +x
else
echo >&2 "Warning: branch profiling may not be functional without BRBE"
set -x
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 55be730f502..a1541d858a6 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -212,6 +212,8 @@ components_in_prev_target = "libstdc++-v3 libsanitizer
libvtv libgcc libbacktrac
cc1plus.fda: create_fdas_for_cc1plus
$(PROFILE_MERGER) $(shell ls -ha cc1plus_*.fda) --output_file
cc1plus.fda -gcov_version 3
+PROFILER=$(shell [ -n "$$(perf list | grep arm_spe)" ] && echo perf_spe ||
echo perf)
+
create_fdas_for_cc1plus: ../stage1-gcc/cc1plus$(exeext)
../prev-gcc/$(PERF_DATA)
for component_in_prev in "$(components_in_prev)"; do \
perf_path=../prev-$$component_in_prev/$(PERF_DATA); \
@@ -219,7 +221,7 @@ create_fdas_for_cc1plus: ../stage1-gcc/cc1plus$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1plus_$$component_in_prev.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/cc1plus$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../stage1-gcc/cc1plus$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
@@ -229,7 +231,7 @@ create_fdas_for_cc1plus: ../stage1-gcc/cc1plus$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=cc1plus_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../prev-gcc/cc1plus$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../prev-gcc/cc1plus$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index eacfe53ca14..8f7df0c104d 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -108,6 +108,8 @@ components_in_prev_target = "libstdc++-v3 libsanitizer
libvtv libgcc libbacktrac
lto1.fda: create_fdas_for_lto1
$(PROFILE_MERGER) $(shell ls -ha lto1_*.fda) --output_file lto1.fda
-gcov_version 3
+PROFILER=$(shell [ -n "$$(perf list | grep arm_spe)" ] && echo perf_spe ||
echo perf)
+
create_fdas_for_lto1: ../stage1-gcc/lto1$(exeext) ../prev-gcc/$(PERF_DATA)
for component_in_prev in "$(components_in_prev)"; do \
perf_path=../prev-$$component_in_prev/$(PERF_DATA); \
@@ -115,7 +117,7 @@ create_fdas_for_lto1: ../stage1-gcc/lto1$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=lto1_$$component_in_prev.fda; \
- $(CREATE_GCOV) -binary ../stage1-gcc/lto1$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../stage1-gcc/lto1$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
@@ -125,7 +127,7 @@ create_fdas_for_lto1: ../stage1-gcc/lto1$(exeext)
../prev-gcc/$(PERF_DATA)
echo $$perf_path; \
if [ -f $$perf_path ]; then \
profile_name=lto1_$$component_in_prev_target.fda; \
- $(CREATE_GCOV) -binary ../prev-gcc/lto1$(exeext) -gcov
$$profile_name -profile $$perf_path -gcov_version 3 || exit 1; \
+ $(CREATE_GCOV) -binary ../prev-gcc/lto1$(exeext) -gcov
$$profile_name -profile $$perf_path -profiler $(PROFILER) -gcov_version 3 ||
exit 0; \
fi; \
done;
diff --git a/gcc/testsuite/lib/profopt.exp b/gcc/testsuite/lib/profopt.exp
index c9f5ae53d49..a7e90e9a162 100644
--- a/gcc/testsuite/lib/profopt.exp
+++ b/gcc/testsuite/lib/profopt.exp
@@ -453,7 +453,13 @@ proc profopt-execute { src } {
# convert profile
if { $run_autofdo == 1 } {
set bprefix "afdo."
- set cmd "create_gcov --binary $execname1
--profile=$tmpdir/$base.perf.data --gcov_version=3 --gcov=$tmpdir/$bprefix$base.$ext"
+ # Determine the profiler type
+ if { [catch {exec sh -c "perf list | grep -q arm_spe"} result]
== 0 } {
+ set profiler "perf_spe"
+ } else {
+ set profiler "perf"
+ }
Does it make sense to do both styles for testing? I think so. For
right now doing one or the other is ok I guess. Also since we are
supporting remote testing now for profile how does this work? Does
autofdo testing work for remote testing in the first place? Maybe we
need to fix that.
I initially wanted to try doing this with remote_spawn / remote_exec but
I couldn't find a way to do it because I wasn't sure how to handle the
pipe / grep. I guess I can try doing that with Expect built-ins instead.
Thanks,
Andrew
+ set cmd "create_gcov --binary $execname1
--profile=$tmpdir/$base.perf.data --profiler=$profiler --gcov_version=3
--gcov=$tmpdir/$bprefix$base.$ext"
verbose "Running $cmd"
set id [remote_spawn "" $cmd]
if { $id < 0 } {
--
2.52.0
--
Regards,
Dhruv