From cda5cba3d779fcb791faf7509cb2144cc99634f8 Mon Sep 17 00:00:00 2001 From: Shaokai Jerry Lin Date: Sat, 30 Nov 2024 17:11:43 -0500 Subject: [PATCH] Use the new pass manager --- src/clang_helper.py | 54 ++++++++----------- src/command_utils.py | 12 +++++ src/inliner.py | 2 +- src/unroller.py | 5 +- .../programs/ext_func/ext_lib_test/inline.py | 2 +- .../programs/if_elif_else/if_elif_else.c | 33 ------------ test/tacle_test/programs/loops/convert.py | 4 +- test/tacle_test/wcet_test.py | 3 ++ 8 files changed, 43 insertions(+), 72 deletions(-) create mode 100644 src/command_utils.py diff --git a/src/clang_helper.py b/src/clang_helper.py index a82794e..9ea8388 100644 --- a/src/clang_helper.py +++ b/src/clang_helper.py @@ -10,6 +10,7 @@ from defaults import logger from file_helper import remove_files from project_configuration import ProjectConfiguration +import command_utils def compile_to_llvm_for_exec(c_filepath: str, output_file_folder: str, output_name: str, extra_libs: List[str]=[], extra_flags: List[str]=[], readable: bool = False) -> str: @@ -40,13 +41,13 @@ def compile_to_llvm_for_exec(c_filepath: str, output_file_folder: str, output_na commands: List[str] = ["clang", "-emit-llvm", "-O0", "-o", output_file, "-c", file_to_compile] + extra_flags for lib in extra_libs: commands.append(f"-I{lib}") - subprocess.run(commands, check=True) + command_utils.run(commands) if readable: # translate for .ll automatically. ll_output_file: str = os.path.join(output_file_folder, f"{output_name}.ll") commands = ["llvm-dis", output_file, "-o", ll_output_file] - subprocess.run(commands, check=True) + command_utils.run(commands) return output_file @@ -81,16 +82,18 @@ def compile_to_llvm_for_analysis(c_filepath: str , output_file_folder: str, outp file_to_compile: str = c_filepath output_file: str = os.path.join(output_file_folder, f"{output_name}.bc") - commands: List[str] = ["clang", "-emit-llvm", "-Xclang","-disable-O0-optnone", "-c", file_to_compile, "-o", output_file] + extra_flags + # "-Wno-implicit-function-declaration" is required so that clang + # does not report "undeclared function '__assert_fail'" + commands: List[str] = ["clang", "-emit-llvm", "-Xclang","-disable-O0-optnone", "-Wno-implicit-function-declaration", "-c", file_to_compile, "-o", output_file] + extra_flags for lib in extra_libs: commands.append(f"-I{lib}") - subprocess.run(commands, check=True) + command_utils.run(commands, shell=True) if readable: # translate for .ll automatically. (optional) ll_output_file: str = os.path.join(output_file_folder, f"{output_name}.ll") commands = ["llvm-dis", output_file, "-o", ll_output_file] - subprocess.run(commands, check=True) + command_utils.run(commands) return output_file def bc_to_executable(bc_filepath: str, output_folder: str, output_name: str, extra_libs: List[str]=[], extra_flags: List[str]=[]) -> str: @@ -123,7 +126,7 @@ def bc_to_executable(bc_filepath: str, output_folder: str, output_name: str, ext clang_commands.extend(["-I", lib]) # Run clang to compile the bitcode into an executable - subprocess.run(clang_commands, check=True) + command_utils.run(clang_commands) return executable_file @@ -149,7 +152,7 @@ def dump_object(object_filepath: str, output_folder: str, output_name: str) -> s output_file: str = os.path.join(output_folder, f"{output_name}.dmp") commands: List[str] = ["riscv32-unknown-elf-objdump", "--target=riscv32", "-march=rv32i", object_filepath, "-c", "-o", output_file] - subprocess.check_call(commands) + command_utils.run(commands) return output_file def generate_dot_file(bc_filename: str, bc_file_folder: str, output_name: str = "main") -> str: @@ -172,8 +175,8 @@ def generate_dot_file(bc_filename: str, bc_file_folder: str, output_name: str = output_file: str = f".{output_name}.dot" cur_cwd: str = os.getcwd() os.chdir(bc_file_folder) # opt generates .dot in cwd - commands: List[str] = ["opt", "-dot-cfg", "-S", "-enable-new-pm=0","-disable-output", bc_filename ] - subprocess.check_call(commands) + commands: List[str] = ["opt", "-passes=dot-cfg", "-S", "-disable-output", bc_filename] + command_utils.run(commands) os.chdir(cur_cwd) return output_file @@ -204,13 +207,12 @@ def inline_functions(bc_filepath: str, output_file_folder: str, output_name: str output_file: str = os.path.join(output_file_folder, f"{output_name}.bc") commands: List[str] = ["opt", - "-enable-new-pm=0", - "-always-inline", - "-inline", "-inline-threshold=10000000", + "-passes=\"always-inline,inline\"" + "-inline-threshold=10000000", "-S", bc_filepath, "-o", output_file] - - logger.info(subprocess.run(commands, check=True)) + + command_utils.run(commands) return output_file @@ -242,28 +244,16 @@ def unroll_loops(bc_filepath: str, output_file_folder: str, output_name: str, pr # return bc_filepath output_file: str = os.path.join(output_file_folder, f"{output_name}.bc") + # Related but unused passes: + # -unroll-threshold=10000000, -unroll-count=4, + # -unroll-allow-partial, -instcombine, + # -reassociate, -indvars, -mem2reg commands: List[str] = ["opt", - "-enable-new-pm=0", - # "-mem2reg", - "-simplifycfg", - "-loops", - "-lcssa", - "-loop-simplify", - "-loop-rotate", - "-indvars", - "-loop-unroll", - "-simplifycfg", - # "-unroll-threshold=10000000", - # "-unroll-count=4", - # "-unroll-allow-partial", - # "-instcombine", - # "-reassociate", - # "-indvars", + "-passes='simplifycfg,loops,lcssa,loop-simplify,loop-rotate,indvars,loop-unroll'" "-S", bc_filepath, - # "-o", temp_output_file] "-o", output_file] - logger.info(subprocess.run(commands, check=True)) + command_utils.run(commands) return output_file diff --git a/src/command_utils.py b/src/command_utils.py new file mode 100644 index 0000000..174fa54 --- /dev/null +++ b/src/command_utils.py @@ -0,0 +1,12 @@ +import subprocess +import sys + +def run(command, shell=False): + print(f"==> Executing command: {' '.join(command)}") + result = subprocess.run(command, shell, check=True) + if result.returncode != 0: + print(f"Error running command: {command}") + print(result.stdout) + print(result.stderr) + sys.exit(1) + return result.stdout \ No newline at end of file diff --git a/src/inliner.py b/src/inliner.py index a2762bd..12b5608 100644 --- a/src/inliner.py +++ b/src/inliner.py @@ -72,7 +72,7 @@ def assemble_bitcode(input_file, output_file): run_command(f"llvm-as {input_file} -o {output_file}") def inline_bitcode(input_file, output_file): - run_command(f"opt -enable-new-pm=0 -always-inline -inline -inline-threshold=10000000 {input_file} -o {output_file}") + run_command(f"opt -passes=\"always-inline,inline\" -inline-threshold=10000000 {input_file} -o {output_file}") def generate_cfg(input_file): run_command(f"opt -dot-cfg {input_file}") diff --git a/src/unroller.py b/src/unroller.py index 4bde495..386cc55 100644 --- a/src/unroller.py +++ b/src/unroller.py @@ -33,15 +33,14 @@ def unroll_llvm_ir(input_ir, output_ir): """ Generate LLVM Intermediate Representation (.ll file) from LLVM bitcode. """ - command = f"opt -enable-new-pm=0 -loop-unroll -S {input_ir} -o {output_ir}" + command = f"opt -passes=loop-unroll -S {input_ir} -o {output_ir}" run_command(command, f"Generating LLVM IR from {input_ir}") - def generate_llvm_dag(output_bc): """ Generate LLVM DAG (.dot file) using opt. """ - command = f"opt -dot-cfg -S -enable-new-pm=0 -disable-output {output_bc}" + command = f"opt -passes=dot-cfg -S -disable-output {output_bc}" run_command(command, f"Generating LLVM DAG from bitcode {output_bc}") def modify_loop_branches_to_next_block(input_file_path, output_file_path): diff --git a/test/tacle_test/programs/ext_func/ext_lib_test/inline.py b/test/tacle_test/programs/ext_func/ext_lib_test/inline.py index aa90b4e..9126f7d 100644 --- a/test/tacle_test/programs/ext_func/ext_lib_test/inline.py +++ b/test/tacle_test/programs/ext_func/ext_lib_test/inline.py @@ -44,7 +44,7 @@ def assemble_bitcode(input_file, output_file): run_command(f"llvm-as {input_file} -o {output_file}") def inline_functions(input_file, output_file): - run_command(f"opt -enable-new-pm=0 -always-inline -inline -inline-threshold=10000000 {input_file} -o {output_file}") + run_command(f"opt -passes=always-inline,inline -inline-threshold=10000000 {input_file} -o {output_file}") def generate_cfg(input_file): run_command(f"opt -dot-cfg {input_file}") diff --git a/test/tacle_test/programs/if_elif_else/if_elif_else.c b/test/tacle_test/programs/if_elif_else/if_elif_else.c index 94c564f..a69a421 100644 --- a/test/tacle_test/programs/if_elif_else/if_elif_else.c +++ b/test/tacle_test/programs/if_elif_else/if_elif_else.c @@ -1,42 +1,9 @@ #include -#include #include #include int abs(int x); -// int test (int x) { -// // if (x < 0 && b < 0) { -// // // sleep(5); -// // return 1; -// // } else if (x < 0 && b == 0) { -// // return 2; -// // } else if (x < 0 && b > 0) { -// // return 3; -// // } else if (x == 0 && b < 0) { -// // return 4; -// // // } else if (x == 0 && b == 0) { -// // // return 5; -// // // } else if (x == 0 && b > 0) { -// // // return 6; -// // // } else if (x > 0 && b < 0) { -// // // return 7; -// // // } else if (x > 0 && b == 0) { -// // // return 8; -// // } else { -// // return 9; -// // } -// if(x > 0) { -// return 1; -// } else { -// return 0; -// } -// } - -// int abs(int x) { -// return x >= 0 ? x : -x; -// } - int test(int x){ if (abs(x) == 4) { return 0; diff --git a/test/tacle_test/programs/loops/convert.py b/test/tacle_test/programs/loops/convert.py index b66dcf0..1ee2592 100644 --- a/test/tacle_test/programs/loops/convert.py +++ b/test/tacle_test/programs/loops/convert.py @@ -33,7 +33,7 @@ def unroll_llvm_ir(input_ir, output_ir): """ Generate LLVM Intermediate Representation (.ll file) from LLVM bitcode. """ - command = f"opt -enable-new-pm=0 -loop-unroll -S {input_ir} -o {output_ir}" + command = f"opt -passes=loop-unroll -S {input_ir} -o {output_ir}" run_command(command, f"Generating LLVM IR from {input_ir}") @@ -42,7 +42,7 @@ def generate_llvm_dag(output_bc): Generate LLVM DAG (.dot file) using llc and opt tools. """ # Use llc to create DAG - command = f"opt -dot-cfg -S -enable-new-pm=0 -disable-output {output_bc}" + command = f"opt -passes=dot-cfg -S -disable-output {output_bc}" run_command(command, f"Generating LLVM DAG from bitcode {output_bc}") def modify_loop_branches_to_next_block(input_file_path, output_file_path): diff --git a/test/tacle_test/wcet_test.py b/test/tacle_test/wcet_test.py index d6c68b0..da7ffcb 100644 --- a/test/tacle_test/wcet_test.py +++ b/test/tacle_test/wcet_test.py @@ -80,6 +80,8 @@ class TestBitcnt2Flexpret(TestFlexpretBackend): config_path = "./programs/bitcount/config.yaml" class TestBitcnt2X86(TestX86Backend): config_path = "./programs/bitcount/config.yaml" +class TestBitcnt2ARM(TestARMBackend): + config_path = "./programs/bitcount/config.yaml" @@ -128,6 +130,7 @@ class TestCountNegativeARM(TestARMBackend): # suite.addTests(loader.loadTestsFromTestCase(TestIfElifElseX86)) # suite.addTests(loader.loadTestsFromTestCase(TestBinarysearchARM)) suite.addTests(loader.loadTestsFromTestCase(TestIfElifElseARM)) + # suite.addTests(loader.loadTestsFromTestCase(TestBitcnt2ARM)) # suite.addTests(loader.loadTestsFromTestCase(TestPrimeARM)) # suite.addTests(loader.loadTestsFromTestCase(TestCountNegativeARM))