aboutsummaryrefslogtreecommitdiff
path: root/pgo_tools/update_llvm_manifest.py
diff options
context:
space:
mode:
Diffstat (limited to 'pgo_tools/update_llvm_manifest.py')
-rwxr-xr-xpgo_tools/update_llvm_manifest.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/pgo_tools/update_llvm_manifest.py b/pgo_tools/update_llvm_manifest.py
new file mode 100755
index 00000000..7fff6f8d
--- /dev/null
+++ b/pgo_tools/update_llvm_manifest.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Updates the Manifest file for LLVM.
+
+Often used to pull a new PGO profile in.
+"""
+
+import argparse
+import contextlib
+import logging
+from pathlib import Path
+import re
+import subprocess
+import sys
+from typing import Generator, List
+
+import pgo_tools
+
+
+@contextlib.contextmanager
+def temporarily_add_llvm_next_pgo_to_src_uri(
+ llvm_9999_ebuild: Path,
+) -> Generator[None, None, None]:
+ old_contents = llvm_9999_ebuild.read_text(encoding="utf-8")
+
+ profdata_prefix = "gs://chromeos-localmirror/distfiles/llvm-profdata-"
+ profdata_re = re.compile(
+ # Leave room for a suffix on this, in case we're on the Nth version of
+ # llvm-profdata for some reason.
+ re.escape(profdata_prefix + "${LLVM_HASH}")
+ + r"\S*\.xz\s"
+ )
+ found_urls = list(profdata_re.finditer(old_contents))
+ if len(found_urls) != 1:
+ raise ValueError(
+ f"Want 1 instance of {profdata_re} in {llvm_9999_ebuild}; found "
+ f"{len(found_urls)}"
+ )
+
+ # Insert the new profdata URL right after the old one. The combination of
+ # USE variables gating this file doesn't have to make sense; the URL just
+ # has to be visible to Portage.
+
+ # Note that the regex ended with `\s`, so `.end()` will be after a space.
+ insert_url = profdata_prefix + "${LLVM_NEXT_HASH}.xz "
+ insert_point = found_urls[0].end()
+ new_contents = (
+ old_contents[:insert_point] + insert_url + old_contents[insert_point:]
+ )
+
+ llvm_9999_ebuild.write_text(new_contents, encoding="utf-8")
+ try:
+ yield
+ finally:
+ llvm_9999_ebuild.write_text(old_contents, encoding="utf-8")
+
+
+def update_manifest(llvm_9999_ebuild: Path):
+ subprocess.run(
+ ["ebuild", llvm_9999_ebuild, "manifest"],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def main(argv: List[str]) -> None:
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ pgo_tools.exit_if_not_in_chroot()
+
+ my_dir = Path(__file__).resolve().parent
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--llvm-next",
+ action="store_true",
+ help="Also update for the llvm-next PGO profile.",
+ )
+ parser.add_argument(
+ "--chromiumos-overlay",
+ default=my_dir.parent.parent / "chromiumos-overlay",
+ type=Path,
+ help="The chromiumos-overlay directory to work in. Default %(default)s",
+ )
+ opts = parser.parse_args(argv)
+
+ llvm_9999 = opts.chromiumos_overlay / "sys-devel/llvm/llvm-9999.ebuild"
+ if opts.llvm_next:
+ with temporarily_add_llvm_next_pgo_to_src_uri(llvm_9999):
+ update_manifest(llvm_9999)
+ else:
+ update_manifest(llvm_9999)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])