diff --git a/Makefile b/Makefile index 31ec128..204eae4 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ generate_ir: @python3 scripts/src2ir.py clean_ir: - @rm examples/ir/*.ll + @rm examples/ir/*/*.ll clean_and_generate_ir: clean_ir generate_ir diff --git a/scripts/src2ir.py b/scripts/src2ir.py index 160e7a3..b04f5b7 100644 --- a/scripts/src2ir.py +++ b/scripts/src2ir.py @@ -1,36 +1,34 @@ import os import subprocess -def convert_cpp_to_ir(source_folder, ir_folder): - for file in os.listdir(source_folder): - if file.endswith('.cpp'): +def convert_src_to_ir(source_folder, ir_folder): + # walk through all subdirectories and the corresponding source files + for root, _, files in os.walk(source_folder): + for file in files: + # get relative path from `source_folder` to maintain structure + rel_path = os.path.relpath(root, source_folder) base_name = os.path.splitext(file)[0] - source_path = os.path.join(source_folder, file) - ir_path = os.path.join(ir_folder, f"{base_name}_cpp.ll") - if not os.path.exists(ir_path): - # note for the clang++ command: - # -O0: disable optimizations - # -S: output assembly (llvm ir in this case) - # -emit-llvm: generate llvm ir instead of native assembly - command = f"clang++ -O0 -S -emit-llvm {source_path} -o {ir_path}" - subprocess.run(command, shell=True, check=True) - print(f"converted {file} to {ir_path}") + + # create corresponding ir folder structure + ir_subfolder = os.path.join(ir_folder, rel_path) + if not os.path.exists(ir_subfolder): + os.makedirs(ir_subfolder) + + source_path = os.path.join(root, file) + if file.endswith('.cpp'): + ir_path = os.path.join(ir_subfolder, f"{base_name}_cpp.ll") + elif file.endswith('.rs'): + ir_path = os.path.join(ir_subfolder, f"{base_name}_rs.ll") else: - print(f"ir file {ir_path} already exists, skipping conversion.") - -def convert_rs_to_ir(source_folder, ir_folder): - for file in os.listdir(source_folder): - if file.endswith('.rs'): - base_name = os.path.splitext(file)[0] - source_path = os.path.join(source_folder, file) - ir_path = os.path.join(ir_folder, f"{base_name}_rs.ll") + assert False, f"unsupported file type: {file}" + if not os.path.exists(ir_path): - # note for the rustc command: - # --emit=llvm-ir: output llvm ir - # --crate-type=lib: compile as a library - command = f"rustc --emit=llvm-ir --crate-type=lib {source_path} -o {ir_path}" + if file.endswith('.cpp'): + command = f"clang++ -O0 -S -emit-llvm {source_path} -o {ir_path}" + elif file.endswith('.rs'): + command = f"rustc --emit=llvm-ir --crate-type=lib {source_path} -o {ir_path}" subprocess.run(command, shell=True, check=True) - print(f"converted {file} to {ir_path}") + print(f"converted {source_path} to {ir_path}") else: print(f"ir file {ir_path} already exists, skipping conversion.") @@ -41,8 +39,7 @@ def main(): if not os.path.exists(ir_folder): os.makedirs(ir_folder) - convert_cpp_to_ir(source_folder, ir_folder) - convert_rs_to_ir(source_folder, ir_folder) + convert_src_to_ir(source_folder, ir_folder) if __name__ == "__main__": main() diff --git a/src/Preprocessor.h b/src/Preprocessor.h index 085bdcb..6aa3c89 100644 --- a/src/Preprocessor.h +++ b/src/Preprocessor.h @@ -29,8 +29,8 @@ class Preprocessor { exit(1); } - cpp_path_ = DEFAULT_IR_DIR + base_name_ + CPP_IR_SUFFIX; - rust_path_ = DEFAULT_IR_DIR + base_name_ + RUST_IR_SUFFIX; + cpp_path_ = DEFAULT_IR_DIR + base_name_ + "/" + base_name_ + CPP_IR_SUFFIX; + rust_path_ = DEFAULT_IR_DIR + base_name_ + "/" + base_name_ + RUST_IR_SUFFIX; argv.push_back(&cpp_path_[0]); argv.push_back(&rust_path_[0]);