-
Ryan Ziegler authoredRyan Ziegler authored
main.rs 2.75 KiB
extern crate clap;
use clap::Parser;
mod codegen;
mod dynconst;
mod env;
mod intrinsics;
mod parser;
mod locs;
mod semant;
mod ssa;
mod types;
use codegen::*;
use std::path::Path;
extern crate hercules_ir;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
src_file: String,
#[clap(short, long)]
verify: bool,
#[clap(long = "verify-all")]
verify_all: bool,
#[arg(short, long = "x-dot")]
x_dot: bool,
#[arg(short, long, value_name = "OUTPUT")]
output: Option<String>,
}
macro_rules! add_verified_pass {
($pm:ident, $args:ident, $pass:ident) => {
$pm.add_pass(hercules_opt::pass::Pass::$pass);
if $args.verify || $args.verify_all {
$pm.add_pass(hercules_opt::pass::Pass::Verify);
}
};
}
macro_rules! add_pass {
($pm:ident, $args:ident, $pass:ident) => {
$pm.add_pass(hercules_opt::pass::Pass::$pass);
if $args.verify_all {
$pm.add_pass(hercules_opt::pass::Pass::Verify);
}
};
}
fn main() {
let args = Cli::parse();
let src_file = args.src_file.clone();
let prg = semant::parse_and_analyze(args.src_file);
match prg {
Ok(prg) => {
let module = codegen_program(prg);
let mut pm = hercules_opt::pass::PassManager::new(module);
if args.verify || args.verify_all {
pm.add_pass(hercules_opt::pass::Pass::Verify);
}
add_verified_pass!(pm, args, PhiElim);
if args.x_dot {
pm.add_pass(hercules_opt::pass::Pass::Xdot(true));
}
add_pass!(pm, args, CCP);
add_pass!(pm, args, DCE);
add_pass!(pm, args, GVN);
add_pass!(pm, args, DCE);
add_pass!(pm, args, SROA);
if args.x_dot {
pm.add_pass(hercules_opt::pass::Pass::Xdot(true));
}
add_pass!(pm, args, Forkify);
add_pass!(pm, args, ForkGuardElim);
add_verified_pass!(pm, args, DCE);
if args.x_dot {
pm.add_pass(hercules_opt::pass::Pass::Xdot(true));
}
let src_file_path = Path::new(&src_file);
let module_name = String::from(src_file_path.file_stem().unwrap().to_str().unwrap());
let output_folder = match args.output {
Some(output_folder) => output_folder,
None => String::from(src_file_path.parent().unwrap().to_str().unwrap())
};
pm.add_pass(hercules_opt::pass::Pass::Codegen(output_folder, module_name));
let _ = pm.run_passes();
}
Err(errs) => {
for err in errs {
eprintln!("{}", err);
}
}
}
}