[bazel] Restore libpfm as a conditional dependency for exegesis.

We used to have `pfm` built into exegesis, although since it's an external dependency we marked it as a manual target. Because of this we didn't have buildbot coverage and so we removed it in D134510 after we had a few breakages that weren't caught. This adds it back, but with three possible states similar to the story with `mpfr`, i.e. it can either be disabled, built from external sources (git/make), or use whatever `-lpfm` is installed on the system.

This change is modeled after D119547. Like that patch, the default is off (matching the status quo), but unlike that patch we don't enable it for CI because IIRC we don't have the package installed there, and building from source might be expensive. We could  enable it later either after installing it on buildbot machines or by measuring build cost and deeming it OK.

Reviewed By: GMNGeoffrey

Differential Revision: https://reviews.llvm.org/D138470
diff --git a/utils/bazel/.bazelrc b/utils/bazel/.bazelrc
index f15da71..b2b472b 100644
--- a/utils/bazel/.bazelrc
+++ b/utils/bazel/.bazelrc
@@ -168,9 +168,10 @@
 # Speedup bazel using a ramdisk.
 build:ci --sandbox_base=/dev/shm
 
-# Use system's mpfr instead of building it from source.
+# Use system's mpfr and pfm instead of building it from source.
 # This is non hermetic but helps with compile time.
 build:ci --@llvm-project//libc:mpfr=system
+build:ci --@llvm-project//llvm:pfm=system
 
 # Don't build/test targets tagged with "nobuildkite".
 build:ci --build_tag_filters=-nobuildkite
diff --git a/utils/bazel/WORKSPACE b/utils/bazel/WORKSPACE
index 337b9ce7..37bc155 100644
--- a/utils/bazel/WORKSPACE
+++ b/utils/bazel/WORKSPACE
@@ -4,7 +4,7 @@
 
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
-load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository", "new_git_repository")
 
 SKYLIB_VERSION = "1.3.0"
 
@@ -19,8 +19,8 @@
 
 new_local_repository(
     name = "llvm-raw",
-    path = "../../",
     build_file_content = "# empty",
+    path = "../../",
 )
 
 load("@llvm-raw//utils/bazel:configure.bzl", "llvm_configure")
@@ -81,11 +81,12 @@
 
 git_repository(
     name = "rules_foreign_cc",
+    remote = "https://github.com/bazelbuild/rules_foreign_cc.git",
     tag = "0.9.0",
-    remote = "https://github.com/bazelbuild/rules_foreign_cc.git"
 )
 
 load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
+
 rules_foreign_cc_dependencies()
 
 maybe(
@@ -110,3 +111,10 @@
     urls = ["https://www.mpfr.org/mpfr-current/mpfr-4.1.1.tar.gz"],
 )
 
+maybe(
+    new_git_repository,
+    name = "pfm",
+    build_file = "@llvm-raw//utils/bazel/third_party_build:pfm.BUILD",
+    remote = "https://git.code.sf.net/p/perfmon2/libpfm4",
+    tag = "v4.12.1",
+)
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index efc63bb..5ea8dc0 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -2,6 +2,7 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
 load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
 load(":tblgen.bzl", "gentbl")
 load(":config.bzl", "llvm_config_defines")
@@ -2722,6 +2723,50 @@
     ],
 )
 
+# A flag to pick which `pfm` to use for Exegesis.
+# Usage: `--@llvm-project//llvm:pfm=<disable|external|system>`.
+# Flag documentation: https://bazel.build/extending/config
+string_flag(
+    name = "pfm",
+    build_setting_default = "external",
+    values = [
+        "disable",  # Don't include pfm at all
+        "external",  # Build pfm from source
+        "system",  # Use system pfm (non hermetic)
+    ],
+)
+
+config_setting(
+    name = "pfm_disable",
+    flag_values = {":pfm": "disable"},
+)
+
+config_setting(
+    name = "pfm_external",
+    flag_values = {":pfm": "external"},
+)
+
+config_setting(
+    name = "pfm_system",
+    flag_values = {":pfm": "system"},
+)
+
+cc_library(
+    name = "maybe_pfm",
+    # We want dependencies of this library to have -DHAVE_LIBPFM conditionally
+    # defined, so we set `defines` instead of `copts`.
+    defines = select({
+        ":pfm_external": ["HAVE_LIBPFM=1"],
+        ":pfm_system": ["HAVE_LIBPFM=1"],
+        "//conditions:default": [],
+    }),
+    deps = select({
+        ":pfm_external": ["@pfm//:pfm_external"],
+        ":pfm_system": ["@pfm//:pfm_system"],
+        "//conditions:default": [],
+    }),
+)
+
 cc_library(
     name = "Exegesis",
     srcs = glob([
@@ -2758,6 +2803,7 @@
         ":Support",
         ":Target",
         ":config",
+        ":maybe_pfm",
     ],
 )
 
diff --git a/utils/bazel/third_party_build/pfm.BUILD b/utils/bazel/third_party_build/pfm.BUILD
new file mode 100644
index 0000000..fe908d4
--- /dev/null
+++ b/utils/bazel/third_party_build/pfm.BUILD
@@ -0,0 +1,31 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("@rules_foreign_cc//foreign_cc:defs.bzl", "make_variant")
+
+filegroup(
+    name = "sources",
+    srcs = glob(["**"]),
+)
+
+make_variant(
+    name = "pfm",
+    copts = ["-w"],
+    lib_name = "libpfm",
+    lib_source = ":sources",
+    toolchain = "@rules_foreign_cc//toolchains:preinstalled_autoconf_toolchain",
+    visibility = ["//visibility:public"],
+)
+
+alias(
+    name = "pfm_external",
+    actual = "@pfm//:pfm_",
+    visibility = ["//visibility:public"],
+)
+
+cc_library(
+    name = "pfm_system",
+    linkopts = ["-lpfm"],
+    visibility = ["//visibility:public"],
+)