https://gcc.gnu.org/g:5df258ae1ad01fc75705a35296a29fd359121845

commit r16-8546-g5df258ae1ad01fc75705a35296a29fd359121845
Author: Dhruv Chawla <[email protected]>
Date:   Thu Feb 12 04:06:03 2026 +0000

    aarch64: AutoFDO: Add support for ARM SPE to autoprofiledbootstrap
    
    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 on both BRBE
    and SPE equipped machines.
    
    Signed-off-by: Dhruv Chawla <[email protected]>
    
    gcc/ChangeLog:
    
            * Makefile.in (AFDO_PROFILER): New variable.
            (PERF): Likewise.
            * config/aarch64/gcc-auto-profile: Detect and use ARM SPE events 
when
            invoking perf record.
            * configure: Regenerate.
            * configure.ac: Detect whether build has perf utility available and
            check for 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.

Diff:
---
 gcc/Makefile.in                     |  6 ++++
 gcc/c/Make-lang.in                  | 18 ++++++----
 gcc/config/aarch64/gcc-auto-profile |  5 +++
 gcc/configure                       | 68 +++++++++++++++++++++++++++++++++++++
 gcc/configure.ac                    | 24 +++++++++++++
 gcc/cp/Make-lang.in                 | 18 ++++++----
 gcc/lto/Make-lang.in                | 18 ++++++----
 gcc/testsuite/lib/profopt.exp       |  8 ++++-
 8 files changed, 146 insertions(+), 19 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 775080ef0f3d..8ecef4ccdc7f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1951,6 +1951,12 @@ $(ALL_HOST_BACKEND_OBJS): ALL_COMPILERFLAGS += 
-fauto-profile=all.fda
 $(ALL_HOST_BACKEND_OBJS): all.fda
 endif
 
+# Path to the perf utility
+PERF = @PERF@
+
+# 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 313bba888358..ecfa366afe32 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 `../stage1-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../stage1-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 `../prev-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../prev-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 b235e9660488..8f7502b30e36 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 --inherit -o perf.data -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 --inherit -o perf.data -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 94522a1d96eb..f843f3a4ed2c 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -632,6 +632,8 @@ ac_includes_default="\
 gt_needs=
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
+AFDO_PROFILER
+PERF
 CET_HOST_FLAGS
 LD_PICFLAG
 PICFLAG
@@ -35255,6 +35257,72 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# Extract the first word of "perf", so it can be a program name with args.
+set dummy perf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PERF+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PERF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERF="$PERF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PERF="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" 
>&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PERF" && ac_cv_path_PERF="no"
+  ;;
+esac
+fi
+PERF=$ac_cv_path_PERF
+if test -n "$PERF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERF" >&5
+$as_echo "$PERF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+AFDO_PROFILER=perf
+if test x$PERF != xno; then
+  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 $PERF; then
+       # Do not use perf_spe if BRBE is supported
+       if test ! -n "$($PERF record -j any,u -o /dev/null /bin/true 2>&1 | 
grep "PMU Hardware or event type doesn't support branch stack sampling.")"; then
+         AFDO_PROFILER=perf
+         aarch64_spe_support="using BRBE instead"
+       elif test -n "$($PERF list | grep arm_spe)"; then
+         AFDO_PROFILER=perf_spe
+         aarch64_spe_support=yes
+       fi
+      fi
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $aarch64_spe_support" 
>&5
+$as_echo "$aarch64_spe_support" >&6; }
+      ;;
+  esac
+fi
+
+
+
 # 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 fab3e3b62d14..cdf2997cb5f8 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -7904,6 +7904,30 @@ 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.])
 
+AC_PATH_PROG(PERF, perf, no)
+AFDO_PROFILER=perf
+if test x$PERF != xno; then
+  case "$cpu_type" in
+    aarch64)
+      AC_MSG_CHECKING(AArch64 build supports SPE profiling for 
autoprofiledbootstrap)
+      aarch64_spe_support=no
+      if test -x $PERF; then
+       # Do not use perf_spe if BRBE is supported
+       if test ! -n "$($PERF record -j any,u -o /dev/null /bin/true 2>&1 | 
grep "PMU Hardware or event type doesn't support branch stack sampling.")"; then
+         AFDO_PROFILER=perf
+         aarch64_spe_support="using BRBE instead"
+       elif test -n "$($PERF list | grep arm_spe)"; then
+         AFDO_PROFILER=perf_spe
+         aarch64_spe_support=yes
+       fi
+      fi
+      AC_MSG_RESULT($aarch64_spe_support)
+      ;;
+  esac
+fi
+AC_SUBST(PERF)
+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 6da26834f307..e262854face1 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 `../stage1-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../stage1-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 `../prev-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../prev-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 3d8c1f553765..a54bdf63c641 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 `../stage1-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../stage1-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 `../prev-gcc/xgcc$(exeext) 
--print-autofdo-gcov-version` || 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 
`../prev-gcc/xgcc$(exeext) --print-autofdo-gcov-version` || 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 d12665390036..7a03b38692c3 100644
--- a/gcc/testsuite/lib/profopt.exp
+++ b/gcc/testsuite/lib/profopt.exp
@@ -456,7 +456,13 @@ proc profopt-execute { src } {
                 set bprefix "afdo."
                set compiler [lindex $GCC_UNDER_TEST 0]
                set autofdo_version [string trim [lindex [remote_exec target 
"$compiler --print-autofdo-gcov-version"] 1] ]
-               set cmd "create_gcov --binary $execname1 
--profile=$tmpdir/$base.perf.data --gcov_version=$autofdo_version 
--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=$autofdo_version --gcov=$tmpdir/$bprefix$base.$ext"
                verbose "Running $cmd"
                set id [remote_spawn "" $cmd]
                if { $id < 0 } {

Reply via email to