Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/isle/veri/veri_engine/src/main.rs
1693 views
1
//! Prototype verification tool for Cranelift's ISLE lowering rules.
2
3
use clap::{ArgAction, Parser};
4
use cranelift_codegen_meta::{generate_isle, isle::get_isle_compilations};
5
use std::path::PathBuf;
6
use std::{env, fs};
7
use veri_engine_lib::verify::verify_rules;
8
use veri_engine_lib::Config;
9
10
#[derive(Parser)]
11
#[clap(about, version, author)]
12
struct Args {
13
/// Path to codegen crate directory.
14
#[clap(long, required = true)]
15
codegen: std::path::PathBuf,
16
17
/// Sets the input file
18
#[clap(short, long)]
19
input: Option<String>,
20
21
/// Which LHS root to verify
22
#[clap(short, long, default_value = "lower")]
23
term: String,
24
25
/// Which width types to verify
26
#[clap(long)]
27
widths: Option<Vec<String>>,
28
29
/// Which named rule to verify
30
#[clap(long)]
31
names: Option<Vec<String>>,
32
33
/// Don't use the prelude ISLE files
34
#[clap(short, long, action=ArgAction::SetTrue)]
35
noprelude: bool,
36
37
/// Include the aarch64 files
38
#[clap(short, long, action=ArgAction::SetTrue)]
39
aarch64: bool,
40
41
/// Include the x64 files
42
#[clap(short, long, action=ArgAction::SetTrue)]
43
x64: bool,
44
45
/// Don't check for distinct possible models
46
#[clap(long, action=ArgAction::SetTrue)]
47
nodistinct: bool,
48
}
49
50
impl Args {
51
fn isle_input_files(&self) -> anyhow::Result<Vec<std::path::PathBuf>> {
52
// Generate ISLE files.
53
let cur_dir = env::current_dir().expect("Can't access current working directory");
54
let gen_dir = cur_dir.join("output");
55
if !std::path::Path::new(gen_dir.as_path()).exists() {
56
fs::create_dir_all(gen_dir.as_path()).unwrap();
57
}
58
generate_isle(gen_dir.as_path()).expect("Can't generate ISLE");
59
60
let inst_specs_isle = self.codegen.join("src").join("inst_specs.isle");
61
62
// Lookup ISLE compilations.
63
let compilations = get_isle_compilations(&self.codegen, gen_dir.as_path());
64
65
let name = match (self.aarch64, self.x64) {
66
(true, false) => "aarch64",
67
(false, true) => "x64",
68
_ => panic!("aarch64 of x64 backend must be provided"),
69
};
70
71
let mut inputs = compilations
72
.lookup(name)
73
.ok_or(anyhow::format_err!("unknown ISLE compilation: {}", name))?
74
.inputs();
75
inputs.push(inst_specs_isle);
76
77
// Return inputs from the matching compilation, if any.
78
Ok(inputs)
79
}
80
}
81
82
fn main() -> anyhow::Result<()> {
83
env_logger::init();
84
let args = Args::parse();
85
86
let valid_widths = ["I8", "I16", "I32", "I64"];
87
if let Some(widths) = &args.widths {
88
for w in widths {
89
let w_str = w.as_str();
90
if !valid_widths.contains(&w_str) {
91
panic!("Invalid width type: {w}");
92
}
93
}
94
}
95
96
let inputs = if args.noprelude {
97
vec![PathBuf::from(
98
args.input.expect("Missing input file in noprelude mode"),
99
)]
100
} else {
101
args.isle_input_files()?
102
};
103
104
let names = if let Some(names) = args.names {
105
let mut names = names;
106
names.sort();
107
names.dedup();
108
Some(names)
109
} else {
110
None
111
};
112
113
let config = Config {
114
term: args.term,
115
names,
116
distinct_check: !args.nodistinct,
117
custom_verification_condition: None,
118
custom_assumptions: None,
119
};
120
121
verify_rules(inputs, &config, &args.widths)
122
.map_err(|e| anyhow::anyhow!("failed to compile ISLE: {:?}", e))
123
}
124
125