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.

The patch also modifies the create_gcov invocation to make sure that the
corresponding component's profile is actually included in the perf.data
file. 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.

Signed-off-by: Dhruv Chawla <[email protected]>

gcc/ChangeLog:

        * Makefile.in (AFDO_PROFILER): New variable.
        * config/aarch64/gcc-auto-profile: Detect and use ARM SPE events when
        invoking perf record.
        * configure: Regenerate.
        * configure.ac: Detect ARM SPE-based profiling support when
        building on AArch64.

gcc/c/ChangeLog:

        * Make-lang.in (create_fdas_for_cc1): Use $(AFDO_PROFILER) when passing
        --profiler to create_gcov. Ensure that perf.data contains profile for
        cc1. Make the console output more useful.

gcc/cp/ChangeLog:

        * Make-lang.in (create_fdas_for_cc1plus): Use $(AFDO_PROFILER) when
        passing --profiler to create_gcov. Ensure that perf.data contains
        profile for cc1plus. Make the console output more useful.

gcc/lto/ChangeLog:

        * Make-lang.in (create_fdas_for_lto1): Use $(AFDO_PROFILER) when passing
        --profiler to create_gcov. Ensure that perf.data contains profile for
        lto1. Make the console output more useful.

gcc/testsuite/ChangeLog:

        * lib/profopt.exp (profopt-execute): Add support for profiler type
        detection.
---
 gcc/Makefile.in                     |  3 +++
 gcc/c/Make-lang.in                  | 18 ++++++++++++------
 gcc/config/aarch64/gcc-auto-profile |  5 +++++
 gcc/configure                       | 18 ++++++++++++++++++
 gcc/configure.ac                    | 15 +++++++++++++++
 gcc/cp/Make-lang.in                 | 18 ++++++++++++------
 gcc/lto/Make-lang.in                | 18 ++++++++++++------
 gcc/testsuite/lib/profopt.exp       |  8 +++++++-
 8 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b97cc7a0d13..c1146a294d4 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1951,6 +1951,9 @@ $(ALL_HOST_BACKEND_OBJS): ALL_COMPILERFLAGS += 
-fauto-profile=all.fda
 $(ALL_HOST_BACKEND_OBJS): all.fda
 endif
 
+# The profiler to be used by autoprofiledbootstrap
+AFDO_PROFILER = @AFDO_PROFILER@
+
 # This lists all host object files, whether they are included in this
 # compilation or not.
 ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS)
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index fd127caba91..96d081f60de 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -98,21 +98,27 @@ cc1.fda: create_fdas_for_cc1
 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); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/cc1$$' && echo 
yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../stage1-gcc/cc1$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo "  warning: $$perf_path is missing cc1!"; \
+           fi; \
          fi; \
        done;
 
        for component_in_prev_target in "$(components_in_prev_target)"; do \
          
perf_path=../prev-$(TARGET_SUBDIR)/$$component_in_prev_target/$(PERF_DATA); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/cc1$$' && echo 
yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../prev-gcc/cc1$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo "  warning: $$perf_path is missing cc1!"; \
+           fi; \
          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/configure b/gcc/configure
index a344e11b912..056099f9405 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -632,6 +632,7 @@ ac_includes_default="\
 gt_needs=
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
+AFDO_PROFILER
 CET_HOST_FLAGS
 LD_PICFLAG
 PICFLAG
@@ -35245,6 +35246,23 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+AFDO_PROFILER=perf
+case "$cpu_type" in
+  aarch64)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking AArch64 build supports 
SPE profiling for autoprofiledbootstrap" >&5
+$as_echo_n "checking AArch64 build supports SPE profiling for 
autoprofiledbootstrap... " >&6; }
+    aarch64_spe_support=no
+    if test -x /usr/bin/perf && test -n "$(/usr/bin/perf list | grep 
arm_spe)"; then
+      AFDO_PROFILER=perf_spe
+      aarch64_spe_support=yes
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $aarch64_spe_support" >&5
+$as_echo "$aarch64_spe_support" >&6; }
+    ;;
+esac
+
+
+
 # Check if the linker supports '-z now'
 ld_now_support=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z now option" >&5
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d12382d2fa3..04503800423 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -7894,6 +7894,21 @@ gif=`if test x$enable_x86_64_mfentry = xyes; then echo 
1; else echo 0; fi`
 AC_DEFINE_UNQUOTED(ENABLE_X86_64_MFENTRY, $gif,
 [Define to enable -mfentry by default on x86-64.])
 
+AFDO_PROFILER=perf
+case "$cpu_type" in
+  aarch64)
+    AC_MSG_CHECKING(AArch64 build supports SPE profiling for 
autoprofiledbootstrap)
+    aarch64_spe_support=no
+    if test -x /usr/bin/perf && test -n "$(/usr/bin/perf list | grep 
arm_spe)"; then
+      AFDO_PROFILER=perf_spe
+      aarch64_spe_support=yes
+    fi
+    AC_MSG_RESULT($aarch64_spe_support)
+    ;;
+esac
+
+AC_SUBST(AFDO_PROFILER)
+
 # Check if the linker supports '-z now'
 ld_now_support=no
 AC_MSG_CHECKING(linker -z now option)
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 55be730f502..73c5a0f16d1 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -215,21 +215,27 @@ cc1plus.fda: create_fdas_for_cc1plus
 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); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/cc1plus$$' && 
echo yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../stage1-gcc/cc1plus$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo "  warning: $$perf_path is missing cc1plus!"; \
+           fi; \
          fi; \
        done;
 
        for component_in_prev_target in "$(components_in_prev_target)"; do \
          
perf_path=../prev-$(TARGET_SUBDIR)/$$component_in_prev_target/$(PERF_DATA); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/cc1plus$$' && 
echo yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../prev-gcc/cc1plus$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo " warning: $$perf_path is missing cc1plus!"; \
+           fi; \
          fi; \
        done;
 
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index eacfe53ca14..e41b26c05fd 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -111,21 +111,27 @@ lto1.fda: create_fdas_for_lto1
 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); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/lto1$$' && echo 
yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../stage1-gcc/lto1$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo "  warning: $$perf_path is missing lto1!"; \
+           fi; \
          fi; \
        done;
 
        for component_in_prev_target in "$(components_in_prev_target)"; do \
          
perf_path=../prev-$(TARGET_SUBDIR)/$$component_in_prev_target/$(PERF_DATA); \
-         echo "Perf path:"; \
-         echo $$perf_path; \
+         echo "Perf path:" $$perf_path "..." `[ -f $$perf_path ] && echo 
exists || echo does not exist`; \
          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; \
+           if [ "x`perf buildid-list -i $$perf_path | grep '/lto1$$' && echo 
yes`" != "x" ]; then \
+             $(CREATE_GCOV) -binary ../prev-gcc/lto1$(exeext) -gcov 
$$profile_name -profile $$perf_path -profiler $(AFDO_PROFILER) -gcov_version 3 
|| exit 1; \
+           else \
+             echo "  warning: $$perf_path is missing lto1!"; \
+           fi; \
          fi; \
        done;
 
diff --git a/gcc/testsuite/lib/profopt.exp b/gcc/testsuite/lib/profopt.exp
index c9f5ae53d49..6b708d68c1e 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"
+               set profiler_check [string trim [lindex [remote_exec target 
"perf list | grep arm_spe"] 1]]
+               if {$profiler_check ne ""} {
+                   set profiler "perf_spe"
+               } else {
+                   set profiler "perf"
+               }
+               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

Reply via email to