From b0dda26c7a11cdb0cf5981c4aa497e0ab30013a6 Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Fri, 1 Sep 2023 10:17:15 +0800 Subject: [PATCH 1/6] alive2script --- alive2script.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 alive2script.py diff --git a/alive2script.py b/alive2script.py new file mode 100644 index 000000000000..e7afd86bf63b --- /dev/null +++ b/alive2script.py @@ -0,0 +1,92 @@ +import re +import os +import sys +import subprocess +from itertools import permutations + +def extract_opt_options(file_path): + with open(file_path, 'r') as file: + content = file.read() + + pattern = r'; RUN:.*\bopt\b ([^\|]*)' + matches = re.findall(pattern, content) + if matches: + opt_options = [] + for match in matches: + options = match.strip().split() + opt_options.extend(options) + + # Replace %s in each option with the input file path + current_file_path = os.path.abspath(file_path) + opt_options_with_path = [opt.replace('%s', current_file_path) for opt in opt_options] + + optionX_options = [opt for opt in opt_options_with_path if re.match(r'-option', opt)] + print("\n所有形式为 -optionX= 的属于 opt 工具的选项:") + for option in optionX_options: + print(option) + + other_options = [opt for opt in opt_options_with_path if opt not in optionX_options] + print("\n所有其他属于 opt 工具的选项:") + for option in other_options: + print(option) + return optionX_options, other_options + else: + print("未找到属于 opt 工具的选项") + return [] + +def run_opt(input_file, opt_options): + opt_command = f"opt {' '.join(opt_options)} {input_file} -o {input_file}.bc" + try: + subprocess.run(opt_command, shell=True, check=True) + return f"{input_file}.bc" + except subprocess.CalledProcessError: + print("运行 opt 工具失败") + return None + +def run_alive_tv(input_file, bc_file): + alive_tv_command = f"alive-tv {input_file} {bc_file}" + try: + result = subprocess.run(alive_tv_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if "Transformation seems to be correct!" in result.stdout: + return True + else: + return False + except subprocess.CalledProcessError: + print("运行 alive-tv 工具失败") + return False + +def test_optionX_combinations(input_file, optionX_options, other_opt_options): + + unique_optionX_combinations = set() + + for r in range(1, len(optionX_options) + 1): + for combination in permutations(optionX_options, r): + sorted_combination = tuple(sorted(combination)) + if sorted_combination not in unique_optionX_combinations: + unique_optionX_combinations.add(sorted_combination) + + all_opt_options = list(combination) + other_opt_options + bc_file = run_opt(input_file, all_opt_options) + if bc_file: + if run_alive_tv(input_file, bc_file): + print(f"成功的选项组合: {combination}") + success_found = True + else: + print(f"失败的选项组合: {combination}") + failure_found = True + else: + print(f"选项组合无法运行 opt 工具: {combination}") + failure_found = True + + + if bc_file: + os.remove(bc_file) + + +if len(sys.argv) != 2: + print("请提供一个 LLVM IR 文件的路径作为命令行参数") +else: + llvm_ir_path = sys.argv[1] + optionX_options, other_opt_options = extract_opt_options(llvm_ir_path) + if optionX_options: + test_optionX_combinations(llvm_ir_path, optionX_options, other_opt_options) -- Gitee From 70466bee7b4e047d2012263c2a5c9130fc5a9d78 Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Mon, 18 Sep 2023 16:50:58 +0800 Subject: [PATCH 2/6] script commit --- README_Alive2Script.md | 12 +++++ alive2script.py | 111 ++++++++++++++++++++++++----------------- instList.txt | 57 +++++++++++++++++++++ 3 files changed, 135 insertions(+), 45 deletions(-) create mode 100644 README_Alive2Script.md create mode 100644 instList.txt diff --git a/README_Alive2Script.md b/README_Alive2Script.md new file mode 100644 index 000000000000..b3ddffa8aba9 --- /dev/null +++ b/README_Alive2Script.md @@ -0,0 +1,12 @@ +# READ ME + +### This merge includes two files +#### alive2script.py and instList.txt + +a. Run the script using the command python alive2script.py test.ll, where test.ll is the test file. + +b. This script can automatically identify and distinguish the tools and options to be tested. Please write the tool and options after ; RUN:. + +c. Some custom options are already listed in instList.txt. To test specific options, add them to this file. Each option should occupy one line. When an option may have values like =true or =false, you only need to add the part before the = sign to the file. For example, -force-customized-pipeline= should be written as -force-customized-pipeline= in the file. + +d. This script can recognize multiple RUN markers in a single file. diff --git a/alive2script.py b/alive2script.py index e7afd86bf63b..2de7bf4fbe2b 100644 --- a/alive2script.py +++ b/alive2script.py @@ -1,46 +1,65 @@ +#!/usr/bin/env python3 import re import os import sys import subprocess from itertools import permutations -def extract_opt_options(file_path): +# function to read options from the instList.txt file +def read_bisheng_options(file_path): + with open(file_path, 'r') as file: + options = [line.strip() for line in file.readlines()] + return options + +def extract_opt_options(file_path, bisheng_options): with open(file_path, 'r') as file: content = file.read() - pattern = r'; RUN:.*\bopt\b ([^\|]*)' - matches = re.findall(pattern, content) - if matches: - opt_options = [] - for match in matches: - options = match.strip().split() - opt_options.extend(options) + tool_info_list = [] + + # Define a pattern to match a single RUN line + run_pattern = r'; RUN:(.*?)(?=\n; RUN:|$)' + run_matches = re.finditer(run_pattern, content, re.DOTALL) + + for run_match in run_matches: + run_content = run_match.group(1).strip() + # Extract the tool name from the RUN line + tool_name_match = re.search(r'(\w+)', run_content) + if tool_name_match: + tool_name = tool_name_match.group(1) + else: + continue # Skip if tool name is not found + + # Extract options from the RUN line + tool_option_match = re.search(r'\b' + re.escape(tool_name) + r'\b\s+(.*)', run_content) + if tool_option_match: + tool_options = tool_option_match.group(1).strip().split() + else: + tool_options = [] + # Replace %s in each option with the input file path current_file_path = os.path.abspath(file_path) - opt_options_with_path = [opt.replace('%s', current_file_path) for opt in opt_options] - - optionX_options = [opt for opt in opt_options_with_path if re.match(r'-option', opt)] - print("\n所有形式为 -optionX= 的属于 opt 工具的选项:") - for option in optionX_options: - print(option) - - other_options = [opt for opt in opt_options_with_path if opt not in optionX_options] - print("\n所有其他属于 opt 工具的选项:") - for option in other_options: - print(option) - return optionX_options, other_options - else: - print("未找到属于 opt 工具的选项") - return [] - -def run_opt(input_file, opt_options): - opt_command = f"opt {' '.join(opt_options)} {input_file} -o {input_file}.bc" + tool_options_with_path = [opt.replace('%s', current_file_path) for opt in tool_options] + + # Match options in the IR file with options in bisheng_options + need_test_option = [opt for opt in tool_options_with_path if any(bisheng_opt in opt for bisheng_opt in bisheng_options)] + + # Store options other than those in need_test_option + other_options = [opt for opt in tool_options_with_path if opt not in need_test_option] + + tool_info_list.append((tool_name, other_options, need_test_option)) + + return tool_info_list + + +def run_tool(input_file, tool_options, tool_name): + tool_command = f"{tool_name} {' '.join(tool_options)} {input_file} -o {input_file}.bc" try: - subprocess.run(opt_command, shell=True, check=True) + subprocess.run(tool_command, shell=True, check=True) return f"{input_file}.bc" except subprocess.CalledProcessError: - print("运行 opt 工具失败") + print(f"Failed to run the {tool_name} tool") return None def run_alive_tv(input_file, bc_file): @@ -52,41 +71,43 @@ def run_alive_tv(input_file, bc_file): else: return False except subprocess.CalledProcessError: - print("运行 alive-tv 工具失败") + print("Failed to run the alive-tv tool") return False -def test_optionX_combinations(input_file, optionX_options, other_opt_options): +def test_optionX_combinations(input_file, need_test_option, other_options, tool_name): unique_optionX_combinations = set() - for r in range(1, len(optionX_options) + 1): - for combination in permutations(optionX_options, r): + for r in range(1, len(need_test_option) + 1): + for combination in permutations(need_test_option, r): sorted_combination = tuple(sorted(combination)) if sorted_combination not in unique_optionX_combinations: unique_optionX_combinations.add(sorted_combination) - all_opt_options = list(combination) + other_opt_options - bc_file = run_opt(input_file, all_opt_options) + all_tool_options = list(combination) + other_options + bc_file = run_tool(input_file, all_tool_options,tool_name) if bc_file: if run_alive_tv(input_file, bc_file): - print(f"成功的选项组合: {combination}") - success_found = True + print(f"Successful option combination for '{tool_name}': {combination}") else: - print(f"失败的选项组合: {combination}") - failure_found = True + print(f"Failed option combination for '{tool_name}': {combination}") else: - print(f"选项组合无法运行 opt 工具: {combination}") - failure_found = True + print(f"{tool_name} couldn't run this Option combination : {combination}") if bc_file: os.remove(bc_file) - if len(sys.argv) != 2: - print("请提供一个 LLVM IR 文件的路径作为命令行参数") + print("Please provide the path to an LLVM IR file as a command-line argument") else: llvm_ir_path = sys.argv[1] - optionX_options, other_opt_options = extract_opt_options(llvm_ir_path) - if optionX_options: - test_optionX_combinations(llvm_ir_path, optionX_options, other_opt_options) + bisheng_option_file = "instList.txt" + bisheng_options = read_bisheng_options(bisheng_option_file) + + tool_info_list = extract_opt_options(llvm_ir_path, bisheng_options) + + for tool_info in tool_info_list: + tool_name, other_options, need_test_option = tool_info + if need_test_option: + test_optionX_combinations(llvm_ir_path, need_test_option, other_options, tool_name) diff --git a/instList.txt b/instList.txt new file mode 100644 index 000000000000..619127eee26a --- /dev/null +++ b/instList.txt @@ -0,0 +1,57 @@ +-force-customized-pipeline= +-sad-pattern-recognition= +-instcombine-ctz-array= +-aarch64-loopcond-opt= +-aarch64-hadd-generation= +-enable-loop-split= +-enable-mem-chk-simplification= +-aarch64-ldp-stp-noq= +-enable-func-arg-analysis= +-enable-modest-vectorization-unrolling-factors= +-instcombine-shrink-vector-element= +-instcombine-reorder-sum-of-reduce-add= +-replace-fortran-mem-alloc= +-enable-pg-math-call-simplification= +-instcombine-gep-common= +-enable-sroa-after-unroll= +-disable-recursive-bonus= +-disable-recip-sqrt-opt= +-disable-loop-aware-reassociation= +-enable-gzipcrc32= +-enable-aes= +-enable-plle= +-plle-hotpathcost-threshold= +-plle-bf-lowerbound= +-enable-merge-reversed-icmps= +-Hx,70,0x20000000 +-update-iv-scev +-gep-common +-gep-common= +-gep-cluster-min= +-gep-loop-mindepth= +-array-restructuring +-enable-array-restructuring= +-skip-array-restructuring-codegen= +-struct-peel +-enable-struct-peel= +-struct-peel-skip-transform= +-struct-peel-this= +-fopenmp-reduction-duplicate +-fopenmp-firstprivatize-locals +-sort-ivusers-before-lsr +-foverflow-shift-alt-behavior +-Mx,218,0x1 +-warn-large-symbols= +-instcombine-simplify-mul64= +-replace-sqrt-compare-by-square= +-enable-combine-sqrt-exp= +-loop-load-widen-patterns= +-enable-aggressive-inline= +-shift rounding +-aggressive-instcombine-simplify-sqr64= +-enable-value-spec= +-vspec-min-select-users= +-vspec-search-users-depth= +-relaxed-ordering-level= +-enable-highlevel-branch-prediction= +-enable-branch-metadata -mllvm -enable-boscc= \ No newline at end of file -- Gitee From d1072518fc3c0cd82a4a32eb2c945989a5b43539 Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Wed, 20 Sep 2023 05:46:17 +0800 Subject: [PATCH 3/6] script fix --- alive2script.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/alive2script.py b/alive2script.py index 2de7bf4fbe2b..03336bb1d688 100644 --- a/alive2script.py +++ b/alive2script.py @@ -14,16 +14,19 @@ def read_bisheng_options(file_path): def extract_opt_options(file_path, bisheng_options): with open(file_path, 'r') as file: content = file.read() - tool_info_list = [] - # Define a pattern to match a single RUN line run_pattern = r'; RUN:(.*?)(?=\n; RUN:|$)' run_matches = re.finditer(run_pattern, content, re.DOTALL) - for run_match in run_matches: run_content = run_match.group(1).strip() - + # Find the index of the first '|' character + first_pipe_index = run_content.find('|') + + if first_pipe_index != -1: + # Split run_content at the first '|' character + run_content = run_content[:first_pipe_index] + # Extract the tool name from the RUN line tool_name_match = re.search(r'(\w+)', run_content) if tool_name_match: @@ -66,7 +69,7 @@ def run_alive_tv(input_file, bc_file): alive_tv_command = f"alive-tv {input_file} {bc_file}" try: result = subprocess.run(alive_tv_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - if "Transformation seems to be correct!" in result.stdout: + if "Transformation seems to be correct!" in result.stdout and "ERROR" not in result.stdout: return True else: return False @@ -77,7 +80,6 @@ def run_alive_tv(input_file, bc_file): def test_optionX_combinations(input_file, need_test_option, other_options, tool_name): unique_optionX_combinations = set() - for r in range(1, len(need_test_option) + 1): for combination in permutations(need_test_option, r): sorted_combination = tuple(sorted(combination)) @@ -90,7 +92,7 @@ def test_optionX_combinations(input_file, need_test_option, other_options, tool_ if run_alive_tv(input_file, bc_file): print(f"Successful option combination for '{tool_name}': {combination}") else: - print(f"Failed option combination for '{tool_name}': {combination}") + print(f"Error: Failed option combination for '{tool_name}': {combination}") else: print(f"{tool_name} couldn't run this Option combination : {combination}") -- Gitee From ea13da52dbbda86f4f9f6dcc96079148fcf1e202 Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Thu, 28 Sep 2023 12:21:14 +0800 Subject: [PATCH 4/6] Debug info --- alive2script.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/alive2script.py b/alive2script.py index 03336bb1d688..e37bf5baea53 100644 --- a/alive2script.py +++ b/alive2script.py @@ -95,8 +95,6 @@ def test_optionX_combinations(input_file, need_test_option, other_options, tool_ print(f"Error: Failed option combination for '{tool_name}': {combination}") else: print(f"{tool_name} couldn't run this Option combination : {combination}") - - if bc_file: os.remove(bc_file) -- Gitee From a64cb956a4aff102e2429179392994f466c8253b Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Thu, 28 Sep 2023 12:44:16 +0800 Subject: [PATCH 5/6] debug info --- alive2script.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/alive2script.py b/alive2script.py index e37bf5baea53..962d07038537 100644 --- a/alive2script.py +++ b/alive2script.py @@ -57,7 +57,9 @@ def extract_opt_options(file_path, bisheng_options): def run_tool(input_file, tool_options, tool_name): - tool_command = f"{tool_name} {' '.join(tool_options)} {input_file} -o {input_file}.bc" + tool_command = f"{tool_name} {' '.join(tool_options)} -o {input_file}.bc" + if "-debug" in sys.argv: + print(f"----------------------Debug Info: Testing: '{tool_command}'") try: subprocess.run(tool_command, shell=True, check=True) return f"{input_file}.bc" @@ -95,10 +97,12 @@ def test_optionX_combinations(input_file, need_test_option, other_options, tool_ print(f"Error: Failed option combination for '{tool_name}': {combination}") else: print(f"{tool_name} couldn't run this Option combination : {combination}") + + if bc_file: os.remove(bc_file) -if len(sys.argv) != 2: +if len(sys.argv) < 2: print("Please provide the path to an LLVM IR file as a command-line argument") else: llvm_ir_path = sys.argv[1] @@ -109,5 +113,11 @@ else: for tool_info in tool_info_list: tool_name, other_options, need_test_option = tool_info + + if "-debug" in sys.argv: + print(f"Debug Info for '{tool_name}':") + print(f" need_test_option: {need_test_option}") + print(f" other_options: {other_options}") + if need_test_option: - test_optionX_combinations(llvm_ir_path, need_test_option, other_options, tool_name) + test_optionX_combinations(llvm_ir_path, need_test_option, other_options, tool_name) \ No newline at end of file -- Gitee From 4ab743612cf5fd25287313f5514250da8184fd4a Mon Sep 17 00:00:00 2001 From: yuan-shaobai <2659799534@qq.com> Date: Sat, 7 Oct 2023 21:16:32 +0800 Subject: [PATCH 6/6] readme fix --- README_Alive2Script.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README_Alive2Script.md b/README_Alive2Script.md index b3ddffa8aba9..3082ab1e3bd2 100644 --- a/README_Alive2Script.md +++ b/README_Alive2Script.md @@ -10,3 +10,5 @@ b. This script can automatically identify and distinguish the tools and options c. Some custom options are already listed in instList.txt. To test specific options, add them to this file. Each option should occupy one line. When an option may have values like =true or =false, you only need to add the part before the = sign to the file. For example, -force-customized-pipeline= should be written as -force-customized-pipeline= in the file. d. This script can recognize multiple RUN markers in a single file. + +e.Optional debug mode, add the '-debug' option after the input file to output detailed information about the script execution. (for example : python alive2script.py xxx.ll -debug) \ No newline at end of file -- Gitee