Path: blob/main/cranelift/isle/veri/veri_engine/src/main.rs
1693 views
//! Prototype verification tool for Cranelift's ISLE lowering rules.12use clap::{ArgAction, Parser};3use cranelift_codegen_meta::{generate_isle, isle::get_isle_compilations};4use std::path::PathBuf;5use std::{env, fs};6use veri_engine_lib::verify::verify_rules;7use veri_engine_lib::Config;89#[derive(Parser)]10#[clap(about, version, author)]11struct Args {12/// Path to codegen crate directory.13#[clap(long, required = true)]14codegen: std::path::PathBuf,1516/// Sets the input file17#[clap(short, long)]18input: Option<String>,1920/// Which LHS root to verify21#[clap(short, long, default_value = "lower")]22term: String,2324/// Which width types to verify25#[clap(long)]26widths: Option<Vec<String>>,2728/// Which named rule to verify29#[clap(long)]30names: Option<Vec<String>>,3132/// Don't use the prelude ISLE files33#[clap(short, long, action=ArgAction::SetTrue)]34noprelude: bool,3536/// Include the aarch64 files37#[clap(short, long, action=ArgAction::SetTrue)]38aarch64: bool,3940/// Include the x64 files41#[clap(short, long, action=ArgAction::SetTrue)]42x64: bool,4344/// Don't check for distinct possible models45#[clap(long, action=ArgAction::SetTrue)]46nodistinct: bool,47}4849impl Args {50fn isle_input_files(&self) -> anyhow::Result<Vec<std::path::PathBuf>> {51// Generate ISLE files.52let cur_dir = env::current_dir().expect("Can't access current working directory");53let gen_dir = cur_dir.join("output");54if !std::path::Path::new(gen_dir.as_path()).exists() {55fs::create_dir_all(gen_dir.as_path()).unwrap();56}57generate_isle(gen_dir.as_path()).expect("Can't generate ISLE");5859let inst_specs_isle = self.codegen.join("src").join("inst_specs.isle");6061// Lookup ISLE compilations.62let compilations = get_isle_compilations(&self.codegen, gen_dir.as_path());6364let name = match (self.aarch64, self.x64) {65(true, false) => "aarch64",66(false, true) => "x64",67_ => panic!("aarch64 of x64 backend must be provided"),68};6970let mut inputs = compilations71.lookup(name)72.ok_or(anyhow::format_err!("unknown ISLE compilation: {}", name))?73.inputs();74inputs.push(inst_specs_isle);7576// Return inputs from the matching compilation, if any.77Ok(inputs)78}79}8081fn main() -> anyhow::Result<()> {82env_logger::init();83let args = Args::parse();8485let valid_widths = ["I8", "I16", "I32", "I64"];86if let Some(widths) = &args.widths {87for w in widths {88let w_str = w.as_str();89if !valid_widths.contains(&w_str) {90panic!("Invalid width type: {w}");91}92}93}9495let inputs = if args.noprelude {96vec![PathBuf::from(97args.input.expect("Missing input file in noprelude mode"),98)]99} else {100args.isle_input_files()?101};102103let names = if let Some(names) = args.names {104let mut names = names;105names.sort();106names.dedup();107Some(names)108} else {109None110};111112let config = Config {113term: args.term,114names,115distinct_check: !args.nodistinct,116custom_verification_condition: None,117custom_assumptions: None,118};119120verify_rules(inputs, &config, &args.widths)121.map_err(|e| anyhow::anyhow!("failed to compile ISLE: {:?}", e))122}123124125