clif_util/
clif-util.rs

1use clap::Parser;
2use std::path::PathBuf;
3
4mod bugpoint;
5mod cat;
6mod compile;
7mod disasm;
8mod interpret;
9mod print_cfg;
10mod run;
11mod utils;
12
13#[cfg(feature = "souper-harvest")]
14mod souper_harvest;
15
16/// Cranelift code generator utility.
17#[derive(Parser)]
18enum Commands {
19    Test(TestOptions),
20    Run(run::Options),
21    Interpret(interpret::Options),
22    Cat(cat::Options),
23    PrintCfg(print_cfg::Options),
24    Compile(compile::Options),
25    Pass(PassOptions),
26    Bugpoint(bugpoint::Options),
27
28    #[cfg(feature = "souper-harvest")]
29    SouperHarvest(souper_harvest::Options),
30    #[cfg(not(feature = "souper-harvest"))]
31    SouperHarvest(CompiledWithoutSupportOptions),
32}
33
34/// Run Cranelift tests
35#[derive(Parser)]
36struct TestOptions {
37    /// Be more verbose
38    #[arg(short, long)]
39    verbose: bool,
40
41    /// Print pass timing report for test
42    #[arg(short = 'T')]
43    time_passes: bool,
44
45    /// Specify an input file to be used. Use '-' for stdin.
46    #[arg(required = true)]
47    files: Vec<PathBuf>,
48}
49
50/// Run specified pass(es) on an input file.
51#[derive(Parser)]
52struct PassOptions {
53    /// Be more verbose
54    #[arg(short, long)]
55    verbose: bool,
56
57    /// Print pass timing report for test
58    #[arg(short = 'T')]
59    time_passes: bool,
60
61    /// Specify an input file to be used. Use '-' for stdin.
62    file: PathBuf,
63
64    /// Specify the target architecture.
65    target: String,
66
67    /// Specify pass(es) to be run on the input file
68    #[arg(required = true)]
69    passes: Vec<String>,
70}
71
72/// (Compiled without support for this subcommand)
73#[derive(Parser)]
74struct CompiledWithoutSupportOptions {}
75
76fn main() -> anyhow::Result<()> {
77    pretty_env_logger::init();
78
79    match Commands::parse() {
80        Commands::Cat(c) => cat::run(&c)?,
81        Commands::Run(r) => run::run(&r)?,
82        Commands::Interpret(i) => interpret::run(&i)?,
83        Commands::PrintCfg(p) => print_cfg::run(&p)?,
84        Commands::Compile(c) => compile::run(&c)?,
85        Commands::Bugpoint(b) => bugpoint::run(&b)?,
86
87        #[cfg(feature = "souper-harvest")]
88        Commands::SouperHarvest(s) => souper_harvest::run(&s)?,
89        #[cfg(not(feature = "souper-harvest"))]
90        Commands::SouperHarvest(_) => anyhow::bail!(
91            "Error: clif-util was compiled without support for the `souper-harvest` \
92             subcommand",
93        ),
94
95        Commands::Test(t) => {
96            cranelift_filetests::run(
97                t.verbose,
98                t.time_passes,
99                &t.files
100                    .iter()
101                    .map(|f| f.display().to_string())
102                    .collect::<Vec<_>>(),
103            )?;
104        }
105        Commands::Pass(p) => {
106            cranelift_filetests::run_passes(
107                p.verbose,
108                p.time_passes,
109                &p.passes,
110                &p.target,
111                &p.file.display().to_string(),
112            )?;
113        }
114    }
115
116    Ok(())
117}
118
119#[test]
120fn verify_cli() {
121    use clap::CommandFactory;
122    Commands::command().debug_assert()
123}