core/irrt: comment build.rs & move irrt to its own dir

To prepare for future IRRT implementations, and to also make cargo
only have to watch a single directory.
This commit is contained in:
lyken 2024-07-12 21:52:55 +08:00
parent 474e0ab809
commit 0bf66745c1
2 changed files with 26 additions and 10 deletions

View File

@ -8,7 +8,12 @@ use std::{
}; };
fn main() { fn main() {
const FILE: &str = "src/codegen/irrt/irrt.cpp"; // Define relevant directories
let out_dir = env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir);
let irrt_dir = Path::new("irrt");
let irrt_cpp_path = irrt_dir.join("irrt.cpp");
/* /*
* HACK: Sadly, clang doesn't let us emit generic LLVM bitcode. * HACK: Sadly, clang doesn't let us emit generic LLVM bitcode.
@ -16,7 +21,6 @@ fn main() {
*/ */
let flags: &[&str] = &[ let flags: &[&str] = &[
"--target=wasm32", "--target=wasm32",
FILE,
"-x", "-x",
"c++", "c++",
"-fno-discard-value-names", "-fno-discard-value-names",
@ -34,12 +38,13 @@ fn main() {
"-Werror=return-type", "-Werror=return-type",
"-o", "-o",
"-", "-",
irrt_cpp_path.to_str().unwrap(),
]; ];
println!("cargo:rerun-if-changed={FILE}"); // Tell Cargo to rerun if any file under `irrt_dir` (recursive) changes
let out_dir = env::var("OUT_DIR").unwrap(); println!("cargo:rerun-if-changed={}", irrt_dir.to_str().unwrap());
let out_path = Path::new(&out_dir);
// Compile IRRT and capture the LLVM IR output
let output = Command::new("clang-irrt") let output = Command::new("clang-irrt")
.args(flags) .args(flags)
.output() .output()
@ -53,6 +58,11 @@ fn main() {
let output = std::str::from_utf8(&output.stdout).unwrap().replace("\r\n", "\n"); let output = std::str::from_utf8(&output.stdout).unwrap().replace("\r\n", "\n");
let mut filtered_output = String::with_capacity(output.len()); let mut filtered_output = String::with_capacity(output.len());
// Filter out irrelevant IR
//
// Regex:
// - `(?ms:^define.*?\}$)` captures LLVM `define` blocks
// - `(?m:^declare.*?$)` captures LLVM `declare` lines
let regex_filter = Regex::new(r"(?ms:^define.*?\}$)|(?m:^declare.*?$)").unwrap(); let regex_filter = Regex::new(r"(?ms:^define.*?\}$)|(?m:^declare.*?$)").unwrap();
for f in regex_filter.captures_iter(&output) { for f in regex_filter.captures_iter(&output) {
assert_eq!(f.len(), 1); assert_eq!(f.len(), 1);
@ -64,18 +74,24 @@ fn main() {
.unwrap() .unwrap()
.replace_all(&filtered_output, ""); .replace_all(&filtered_output, "");
println!("cargo:rerun-if-env-changed=DEBUG_DUMP_IRRT"); // For debugging
if env::var("DEBUG_DUMP_IRRT").is_ok() { // Doing `DEBUG_DUMP_IRRT=1 cargo build -p nac3core` dumps the LLVM IR generated
let mut file = File::create(out_path.join("irrt.ll")).unwrap(); const DEBUG_DUMP_IRRT: &str = "DEBUG_DUMP_IRRT";
println!("cargo:rerun-if-env-changed={DEBUG_DUMP_IRRT}");
if env::var(DEBUG_DUMP_IRRT).is_ok() {
let mut file = File::create(out_dir.join("irrt.ll")).unwrap();
file.write_all(output.as_bytes()).unwrap(); file.write_all(output.as_bytes()).unwrap();
let mut file = File::create(out_path.join("irrt-filtered.ll")).unwrap();
let mut file = File::create(out_dir.join("irrt-filtered.ll")).unwrap();
file.write_all(filtered_output.as_bytes()).unwrap(); file.write_all(filtered_output.as_bytes()).unwrap();
} }
// Assemble the emitted and filtered IR to .bc
// That .bc will be integrated into nac3core's codegen
let mut llvm_as = Command::new("llvm-as-irrt") let mut llvm_as = Command::new("llvm-as-irrt")
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.arg("-o") .arg("-o")
.arg(out_path.join("irrt.bc")) .arg(out_dir.join("irrt.bc"))
.spawn() .spawn()
.unwrap(); .unwrap();
llvm_as.stdin.as_mut().unwrap().write_all(filtered_output.as_bytes()).unwrap(); llvm_as.stdin.as_mut().unwrap().write_all(filtered_output.as_bytes()).unwrap();