diff options
Diffstat (limited to 'bolt/utils/nfc-check-setup.py')
-rwxr-xr-x | bolt/utils/nfc-check-setup.py | 147 |
1 files changed, 102 insertions, 45 deletions
diff --git a/bolt/utils/nfc-check-setup.py b/bolt/utils/nfc-check-setup.py index 275ac7b..d8666e2 100755 --- a/bolt/utils/nfc-check-setup.py +++ b/bolt/utils/nfc-check-setup.py @@ -7,6 +7,8 @@ import subprocess import sys import textwrap +msg_prefix = "\n> NFC-Mode:" + def get_relevant_bolt_changes(dir: str) -> str: # Return a list of bolt source changes that are relevant to testing. all_changes = subprocess.run( @@ -42,14 +44,32 @@ def get_git_ref_or_rev(dir: str) -> str: cmd_rev = "git rev-parse --short HEAD" return subprocess.check_output(shlex.split(cmd_rev), cwd=dir, text=True).strip() +def switch_back( + switch_back: bool, stash: bool, source_dir: str, old_ref: str, new_ref: str +): + # Switch back to the current revision if needed and inform the user of where + # the HEAD is. Must be called after checking out the previous commit on all + # exit paths. + if switch_back: + print(f"{msg_prefix} Switching back to current revision..") + if stash: + subprocess.run(shlex.split("git stash pop"), cwd=source_dir) + subprocess.run(shlex.split(f"git checkout {old_ref}"), cwd=source_dir) + else: + print( + f"The repository {source_dir} has been switched from {old_ref} " + f"to {new_ref}. Local changes were stashed. Switch back using\n\t" + f"git checkout {old_ref}\n" + ) def main(): parser = argparse.ArgumentParser( description=textwrap.dedent( """ - This script builds two versions of BOLT (with the current and - previous revision) and sets up symlink for llvm-bolt-wrapper. - Passes the options through to llvm-bolt-wrapper. + This script builds two versions of BOLT: + llvm-bolt.new, using the current revision, and llvm-bolt.old using + the previous revision. These can be used to check whether the + current revision changes BOLT's functional behavior. """ ) ) @@ -60,6 +80,12 @@ def main(): help="Path to BOLT build directory, default is current " "directory", ) parser.add_argument( + "--create-wrapper", + default=False, + action="store_true", + help="Sets up llvm-bolt as a symlink to llvm-bolt-wrapper. Passes the options through to llvm-bolt-wrapper.", + ) + parser.add_argument( "--check-bolt-sources", default=False, action="store_true", @@ -76,28 +102,42 @@ def main(): default="HEAD^", help="Revision to checkout to compare vs HEAD", ) + + # When creating a wrapper, pass any unknown arguments to it. Otherwise, die. args, wrapper_args = parser.parse_known_args() - bolt_path = f"{args.build_dir}/bin/llvm-bolt" + if not args.create_wrapper and len(wrapper_args) > 0: + parser.parse_args() + # Find the repo directory. source_dir = None - # find the repo directory - with open(f"{args.build_dir}/CMakeCache.txt") as f: - for line in f: - m = re.match(r"LLVM_SOURCE_DIR:STATIC=(.*)", line) - if m: - source_dir = m.groups()[0] - if not source_dir: - sys.exit("Source directory is not found") - - script_dir = os.path.dirname(os.path.abspath(__file__)) - wrapper_path = f"{script_dir}/llvm-bolt-wrapper.py" - # build the current commit + try: + CMCacheFilename = f"{args.build_dir}/CMakeCache.txt" + with open(CMCacheFilename) as f: + for line in f: + m = re.match(r"LLVM_SOURCE_DIR:STATIC=(.*)", line) + if m: + source_dir = m.groups()[0] + if not source_dir: + raise Exception(f"Source directory not found: '{CMCacheFilename}'") + except Exception as e: + sys.exit(e) + + # Clean the previous llvm-bolt if it exists. + bolt_path = f"{args.build_dir}/bin/llvm-bolt" + if os.path.exists(bolt_path): + os.remove(bolt_path) + + # Build the current commit. + print(f"{msg_prefix} Building current revision..") subprocess.run( shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir ) - # rename llvm-bolt + + if not os.path.exists(bolt_path): + sys.exit(f"Failed to build the current revision: '{bolt_path}'") + + # Rename llvm-bolt and memorize the old hash for logging. os.replace(bolt_path, f"{bolt_path}.new") - # memorize the old hash for logging old_ref = get_git_ref_or_rev(source_dir) if args.check_bolt_sources: @@ -110,7 +150,7 @@ def main(): print(f"BOLT source changes were found:\n{file_changes}") open(marker, "a").close() - # determine whether a stash is needed + # Determine whether a stash is needed. stash = subprocess.run( shlex.split("git status --porcelain"), cwd=source_dir, @@ -119,42 +159,59 @@ def main(): text=True, ).stdout if stash: - # save local changes before checkout + # Save local changes before checkout. subprocess.run(shlex.split("git stash push -u"), cwd=source_dir) - # check out the previous/cmp commit + + # Check out the previous/cmp commit and get its commit hash for logging. subprocess.run(shlex.split(f"git checkout -f {args.cmp_rev}"), cwd=source_dir) - # get the parent commit hash for logging new_ref = get_git_ref_or_rev(source_dir) - # build the previous commit + + # Build the previous commit. + print(f"{msg_prefix} Building previous revision..") subprocess.run( shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir ) - # rename llvm-bolt + + # Rename llvm-bolt. + if not os.path.exists(bolt_path): + print(f"Failed to build the previous revision: '{bolt_path}'") + switch_back(args.switch_back, stash, source_dir, old_ref, new_ref) + sys.exit(1) os.replace(bolt_path, f"{bolt_path}.old") - # set up llvm-bolt-wrapper.ini - ini = subprocess.check_output( - shlex.split(f"{wrapper_path} {bolt_path}.old {bolt_path}.new") + wrapper_args, - text=True, + + # Symlink llvm-bolt-wrapper + if args.create_wrapper: + print(f"{msg_prefix} Creating llvm-bolt wrapper..") + script_dir = os.path.dirname(os.path.abspath(__file__)) + wrapper_path = f"{script_dir}/llvm-bolt-wrapper.py" + try: + # Set up llvm-bolt-wrapper.ini + ini = subprocess.check_output( + shlex.split(f"{wrapper_path} {bolt_path}.old {bolt_path}.new") + + wrapper_args, + text=True, + ) + with open(f"{args.build_dir}/bin/llvm-bolt-wrapper.ini", "w") as f: + f.write(ini) + os.symlink(wrapper_path, bolt_path) + except Exception as e: + print("Failed to create a wrapper:\n" + str(e)) + switch_back(args.switch_back, stash, source_dir, old_ref, new_ref) + sys.exit(1) + + switch_back(args.switch_back, stash, source_dir, old_ref, new_ref) + + print( + f"{msg_prefix} Completed!\nBuild directory {args.build_dir} is ready for" + " NFC-Mode comparison between the two revisions." ) - with open(f"{args.build_dir}/bin/llvm-bolt-wrapper.ini", "w") as f: - f.write(ini) - # symlink llvm-bolt-wrapper - os.symlink(wrapper_path, bolt_path) - if args.switch_back: - if stash: - subprocess.run(shlex.split("git stash pop"), cwd=source_dir) - subprocess.run(shlex.split(f"git checkout {old_ref}"), cwd=source_dir) - else: + + if args.create_wrapper: print( - f"The repository {source_dir} has been switched from {old_ref} " - f"to {new_ref}. Local changes were stashed. Switch back using\n\t" - f"git checkout {old_ref}\n" + "Can run BOLT tests using:\n" + "\tbin/llvm-lit -sv tools/bolt/test\nor\n" + "\tbin/llvm-lit -sv tools/bolttests" ) - print( - f"Build directory {args.build_dir} is ready to run BOLT tests, e.g.\n" - "\tbin/llvm-lit -sv tools/bolt/test\nor\n" - "\tbin/llvm-lit -sv tools/bolttests" - ) if __name__ == "__main__": |