[LLD][COFF] Emit tail merge pdata for delay load thunks on ARM64EC (#116810)
[llvm-project.git] / bolt / utils / nfc-check-setup.py
blob710b183505853745d5d8ab16406aea6d18906ff6
1 #!/usr/bin/env python3
2 import argparse
3 import os
4 import re
5 import shlex
6 import subprocess
7 import sys
8 import textwrap
11 def get_git_ref_or_rev(dir: str) -> str:
12 # Run 'git symbolic-ref -q --short HEAD || git rev-parse --short HEAD'
13 cmd_ref = "git symbolic-ref -q --short HEAD"
14 ref = subprocess.run(
15 shlex.split(cmd_ref), cwd=dir, text=True, stdout=subprocess.PIPE
17 if not ref.returncode:
18 return ref.stdout.strip()
19 cmd_rev = "git rev-parse --short HEAD"
20 return subprocess.check_output(shlex.split(cmd_rev), cwd=dir, text=True).strip()
23 def main():
24 parser = argparse.ArgumentParser(
25 description=textwrap.dedent(
26 """
27 This script builds two versions of BOLT (with the current and
28 previous revision) and sets up symlink for llvm-bolt-wrapper.
29 Passes the options through to llvm-bolt-wrapper.
30 """
33 parser.add_argument(
34 "build_dir",
35 nargs="?",
36 default=os.getcwd(),
37 help="Path to BOLT build directory, default is current " "directory",
39 parser.add_argument(
40 "--switch-back",
41 default=False,
42 action="store_true",
43 help="Checkout back to the starting revision",
45 parser.add_argument(
46 "--cmp-rev",
47 default="HEAD^",
48 help="Revision to checkout to compare vs HEAD",
50 args, wrapper_args = parser.parse_known_args()
51 bolt_path = f"{args.build_dir}/bin/llvm-bolt"
53 source_dir = None
54 # find the repo directory
55 with open(f"{args.build_dir}/CMakeCache.txt") as f:
56 for line in f:
57 m = re.match(r"LLVM_SOURCE_DIR:STATIC=(.*)", line)
58 if m:
59 source_dir = m.groups()[0]
60 if not source_dir:
61 sys.exit("Source directory is not found")
63 script_dir = os.path.dirname(os.path.abspath(__file__))
64 wrapper_path = f"{script_dir}/llvm-bolt-wrapper.py"
65 # build the current commit
66 subprocess.run(
67 shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir
69 # rename llvm-bolt
70 os.replace(bolt_path, f"{bolt_path}.new")
71 # memorize the old hash for logging
72 old_ref = get_git_ref_or_rev(source_dir)
74 # determine whether a stash is needed
75 stash = subprocess.run(
76 shlex.split("git status --porcelain"),
77 cwd=source_dir,
78 stdout=subprocess.PIPE,
79 stderr=subprocess.STDOUT,
80 text=True,
81 ).stdout
82 if stash:
83 # save local changes before checkout
84 subprocess.run(shlex.split("git stash push -u"), cwd=source_dir)
85 # check out the previous/cmp commit
86 subprocess.run(shlex.split(f"git checkout -f {args.cmp_rev}"), cwd=source_dir)
87 # get the parent commit hash for logging
88 new_ref = get_git_ref_or_rev(source_dir)
89 # build the previous commit
90 subprocess.run(
91 shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir
93 # rename llvm-bolt
94 os.replace(bolt_path, f"{bolt_path}.old")
95 # set up llvm-bolt-wrapper.ini
96 ini = subprocess.check_output(
97 shlex.split(f"{wrapper_path} {bolt_path}.old {bolt_path}.new") + wrapper_args,
98 text=True,
100 with open(f"{args.build_dir}/bin/llvm-bolt-wrapper.ini", "w") as f:
101 f.write(ini)
102 # symlink llvm-bolt-wrapper
103 os.symlink(wrapper_path, bolt_path)
104 if args.switch_back:
105 if stash:
106 subprocess.run(shlex.split("git stash pop"), cwd=source_dir)
107 subprocess.run(shlex.split(f"git checkout {old_ref}"), cwd=source_dir)
108 else:
109 print(
110 f"The repository {source_dir} has been switched from {old_ref} "
111 f"to {new_ref}. Local changes were stashed. Switch back using\n\t"
112 f"git checkout {old_ref}\n"
114 print(
115 f"Build directory {args.build_dir} is ready to run BOLT tests, e.g.\n"
116 "\tbin/llvm-lit -sv tools/bolt/test\nor\n"
117 "\tbin/llvm-lit -sv tools/bolttests"
121 if __name__ == "__main__":
122 main()