#!/usr/bin/python3
# Generate Intel taken branches Linux perf event script for autofdo profiling.

# Copyright (C) 2016-2025 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# Run it with perf record -b -e EVENT program ...
# The Linux Kernel needs to support the PMU of the current CPU, and
# It will likely not work in VMs.
# Add --all to print for all cpus, otherwise for current cpu.
# Add --script to generate shell script to run correct event.
#
# Requires internet (https) access. This may require setting up a proxy
# with export https_proxy=...
#
import urllib.request
import sys
import json
import argparse
import collections
import os
import fnmatch

baseurl = "https://raw.githubusercontent.com/intel/perfmon/main"

target_events = ('BR_INST_RETIRED.NEAR_TAKEN',
                 'BR_INST_EXEC.TAKEN',
                 'BR_INST_RETIRED.TAKEN_JCC',
                 'BR_INST_TYPE_RETIRED.COND_TAKEN')

ap = argparse.ArgumentParser()
ap.add_argument('--all', '-a', help='Print for all CPUs', action='store_true')
ap.add_argument('--script', help='Generate shell script', action='store_true')
args = ap.parse_args()

eventmap = collections.defaultdict(list)

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("Downloading", eventurl, file = sys.stderr)
    u = urllib.request.urlopen(eventurl)
    events = json.loads(u.read())["Events"]
    u.close()

    found = 0
    for j in events:
        if j['EventName'] in target_events:
            event = "cpu/event=%s,umask=%s/" % (j['EventCode'], j['UMask'])
            if 'PEBS' in j and int(j['PEBS']) > 0:
                event += "p"
            if args.script:
                eventmap[event].append(model)
            else:
                print(j['EventName'], "event for model", model, "is", event)
            found += 1
    return found

if not args.all:
    cpu = get_cpustr()
    if not cpu:
        sys.exit("Unknown CPU type")

url = baseurl + "/mapfile.csv"
print("Downloading", url, file = sys.stderr)
u = urllib.request.urlopen(url)
found = 0
cpufound = 0
for j in u:
    n = j.rstrip().decode().split(',')
    if len(n) >= 4 and (args.all or fnmatch.fnmatch(cpu, n[0])) and n[3] == "core":
        components = n[0].split("-")
        model = components[2]
        model = int(model, 16)
        cpufound += 1
        found += find_event(baseurl + n[2], model)
u.close()

if args.script:
    print(r'''#!/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 --script --all in gcc source

# usages:
# gcc-auto-profile program             (profile program and children)
# gcc-auto-profile -a sleep X          (profile all for X secs, may need root)
# gcc-auto-profile -p PID sleep X      (profile PID)
# 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.
#

FLAGS=u

if [ "$1" = "--kernel" ] ; then
  FLAGS=k
  shift
fi
if [ "$1" = "--all" ] ; then
  FLAGS=uk
  shift
fi

if grep -q AuthenticAMD /proc/cpuinfo ; then
  vendor=AMD
  if ! grep -q " brs" /proc/cpuinfo && ! grep -q amd_lbr_v2 /proc/cpuinfo ; then
    echo >&2 "AMD CPU with brs (Zen 3) or amd_lbr_v2 (Zen 4+) feature is required"
    exit 1
  fi
elif grep -q Intel /proc/cpuinfo ; then
  vendor=Intel
else
  echo >&2 "Only AMD and Intel CPUs supported"
  exit 1
fi

if grep -q hypervisor /proc/cpuinfo ; then
  echo >&2 "Warning: branch profiling may not be functional in VMs"
fi

case `test $vendor = Intel && grep -E -q "^cpu family\s*: 6" /proc/cpuinfo &&
  grep -E "^model\s*:" /proc/cpuinfo | head -n1` in''')
    for event, mod in eventmap.items():
        for m in mod[:-1]:
            print("model*:\ %s|\\" % m)
        print(r'model*:\ %s) E="%s$FLAGS" ;;' % (mod[-1], event))
    print(r'''*)
        if perf list br_inst_retired | grep -q br_inst_retired.near_taken ; then
            E=br_inst_retired.near_taken:p
        elif perf list ex_ret_brn_tkn | grep -q ex_ret_brn_tkn ; then
            E=ex_ret_brn_tkn:P$FLAGS
        elif $vendor = Intel ; then
echo >&2 "Unknown Intel CPU. Run contrib/gen_autofdo_event.py --all --script to update script."
	  exit 1
        else
echo >&2 "AMD CPU without support for ex_ret_brn_tkn event"
	  exit 1
        fi ;;''')
    print(r"esac")
    print(r"set -x")
    print(r'if ! perf record -e $E -b "$@" ; then')
    print(r'  # PEBS may not actually be working even if the processor supports it')
    print(r'  # (e.g., in a virtual machine). Trying to run without /p.')
    print(r'  set +x')
    print(r'  echo >&2 "Retrying without /p."')
    print(r'  E="$(echo "${E}" | sed -e \'s/\/p/\//\ -e s/:p//)"')
    print(r'  set -x')
    print(r'  exec perf record -e $E -b "$@"')
    print(r' set +x')
    print(r'fi')

if cpufound == 0 and not args.all:
    sys.exit('CPU %s not found' % cpu)

if found == 0:
    sys.exit('Branch event not found')
