gen_autofdo_event.py was stumbling on models with stepping so I updated the script to handle this case similar to the code in https://github.com/andikleen/pmu-tools/blob/c6a5f63aede19def8886d6a8b74d7a55c38ca947/event_download.py
The second change was to tolerate cases when the CPU supports PEBS but the perf command with /p fails. This can happen in, e.g., a virtual machine. I regenerated gcc-auto-profile using the updated script. contrib/ChangeLog: * gen_autofdo_event.py: handle stepping, non-working PEBS gcc/ChangeLog: * config/i386/gcc-auto-profile: regenerate --- contrib/gen_autofdo_event.py | 54 ++++++++++++++++++++++---------- gcc/config/i386/gcc-auto-profile | 41 +++++++++++++++++++----- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/contrib/gen_autofdo_event.py b/contrib/gen_autofdo_event.py index c97460c61c6..1eb6f1d6d85 100755 --- a/contrib/gen_autofdo_event.py +++ b/contrib/gen_autofdo_event.py @@ -46,20 +46,29 @@ args = ap.parse_args() eventmap = collections.defaultdict(list) -def get_cpu_str(): - with open('/proc/cpuinfo', 'r') as c: - vendor, fam, model = None, None, None - for j in c: - n = j.split() - if n[0] == 'vendor_id': - vendor = n[2] - elif n[0] == 'model' and n[1] == ':': - model = int(n[2]) - elif n[0] == 'cpu' and n[1] == 'family': - fam = int(n[3]) - if vendor and fam and model: - return "%s-%d-%X" % (vendor, fam, model), model - return None, None +def get_cpustr(): + cpuinfo = os.getenv("CPUINFO") + if cpuinfo is None: + cpuinfo = '/proc/cpuinfo' + f = open(cpuinfo, 'r') + cpu = [None, None, None, None] + for j in f: + n = j.split() + if n[0] == 'vendor_id': + cpu[0] = n[2] + elif n[0] == 'model' and n[1] == ':': + cpu[2] = int(n[2]) + elif n[0] == 'cpu' and n[1] == 'family': + cpu[1] = int(n[3]) + elif n[0] == 'stepping' and n[1] == ':': + cpu[3] = int(n[2]) + if all(v is not None for v in cpu): + break + # stepping for SKX only + stepping = cpu[0] == "GenuineIntel" and cpu[1] == 6 and cpu[2] == 0x55 + if stepping: + return "%s-%d-%X-%X" % tuple(cpu) + return "%s-%d-%X" % tuple(cpu)[:3] def find_event(eventurl, model): print >>sys.stderr, "Downloading", eventurl @@ -81,7 +90,7 @@ def find_event(eventurl, model): return found if not args.all: - cpu, model = get_cpu_str() + cpu = get_cpu_str() if not cpu: sys.exit("Unknown CPU type") @@ -94,7 +103,8 @@ for j in u: n = j.rstrip().split(',') if len(n) >= 4 and (args.all or n[0] == cpu) and n[3] == "core": if args.all: - vendor, fam, model = n[0].split("-") + components = n[0].split("-") + model = components[2] model = int(model, 16) cpufound += 1 found += find_event(baseurl + n[2], model) @@ -146,7 +156,17 @@ case `egrep -q "^cpu family\s*: 6" /proc/cpuinfo && echo >&2 "Unknown CPU. Run contrib/gen_autofdo_event.py --all --script to update script." exit 1 ;;''' print "esac" - print 'exec perf record -e $E -b "$@"' + print "set -x" + print 'if ! perf record -e $E -b "$@" ; then' + print ' # PEBS may not actually be working even if the processor supports it' + print ' # (e.g., in a virtual machine). Trying to run without /p.' + print ' set +x' + print ' echo >&2 "Retrying without /p."' + print ' E="$(echo "${E}" | sed -e \'s/\/p/\//\')"' + print ' set -x' + print ' exec perf record -e $E -b "$@"' + print ' set +x' + print 'fi' if cpufound == 0 and not args.all: sys.exit('CPU %s not found' % cpu) diff --git a/gcc/config/i386/gcc-auto-profile b/gcc/config/i386/gcc-auto-profile index 5da5c63cd84..56f64cbff1f 100755 --- a/gcc/config/i386/gcc-auto-profile +++ b/gcc/config/i386/gcc-auto-profile @@ -1,7 +1,7 @@ #!/bin/sh -# profile workload for gcc profile feedback (autofdo) using Linux perf -# auto generated. to regenerate for new CPUs run -# contrib/gen_autofdo_event.py --shell --all in gcc source +# Profile workload for gcc profile feedback (autofdo) using Linux perf. +# Auto generated. To regenerate for new CPUs run +# contrib/gen_autofdo_event.py --script --all in gcc source # usages: # gcc-auto-profile program (profile program and children) @@ -10,7 +10,7 @@ # gcc-auto-profile --kernel -a sleep X (profile kernel) # gcc-auto-profile --all -a sleep X (profile kernel and user space) -# identify branches taken event for CPU +# Identify branches taken event for CPU. # FLAGS=u @@ -37,7 +37,12 @@ case `egrep -q "^cpu family\s*: 6" /proc/cpuinfo && egrep "^model\s*:" /proc/cpuinfo | head -n1` in model*:\ 55|\ model*:\ 77|\ -model*:\ 76) E="cpu/event=0xC4,umask=0xFE/p$FLAGS" ;; +model*:\ 76|\ +model*:\ 92|\ +model*:\ 95|\ +model*:\ 87|\ +model*:\ 133|\ +model*:\ 122) E="cpu/event=0xC4,umask=0xFE/p$FLAGS" ;; model*:\ 42|\ model*:\ 45|\ model*:\ 58|\ @@ -48,9 +53,16 @@ model*:\ 70|\ model*:\ 63|\ model*:\ 61|\ model*:\ 71|\ +model*:\ 79|\ model*:\ 86|\ model*:\ 78|\ -model*:\ 94) E="cpu/event=0xC4,umask=0x20/p$FLAGS" ;; +model*:\ 94|\ +model*:\ 142|\ +model*:\ 158|\ +model*:\ 165|\ +model*:\ 166|\ +model*:\ 85|\ +model*:\ 85) E="cpu/event=0xC4,umask=0x20/p$FLAGS" ;; model*:\ 46|\ model*:\ 30|\ model*:\ 31|\ @@ -63,8 +75,23 @@ model*:\ 38|\ model*:\ 39|\ model*:\ 54|\ model*:\ 53) E="cpu/event=0x88,umask=0x41/p$FLAGS" ;; +model*:\ 126|\ +model*:\ 140|\ +model*:\ 141|\ +model*:\ 106|\ +model*:\ 108) E="cpu/event=0xc4,umask=0x20/p$FLAGS" ;; *) echo >&2 "Unknown CPU. Run contrib/gen_autofdo_event.py --all --script to update script." exit 1 ;; esac -exec perf record -e $E -b "$@" +set -x +if ! perf record -e $E -b "$@" ; then + # PEBS may not actually be working even if the processor supports it + # (e.g., in a virtual machine). Trying to run without /p. + set +x + echo >&2 "Retrying without /p." + E="$(echo "${E}" | sed -e 's/\/p/\//')" + set -x + exec perf record -e $E -b "$@" + set +x +fi -- 2.25.1