1 use clap::Parser;
2 use std::path::PathBuf;
3
4 mod bugpoint;
5 mod cat;
6 mod compile;
7 mod disasm;
8 mod interpret;
9 mod print_cfg;
10 mod run;
11 mod utils;
12
13 #[cfg(feature = "souper-harvest")]
14 mod souper_harvest;
15
16 /// Cranelift code generator utility.
17 #[derive(Parser)]
18 enum 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)]
36 struct 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)]
52 struct 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)]
74 struct CompiledWithoutSupportOptions {}
75
main() -> anyhow::Result<()>76 fn main() -> anyhow::Result<()> {
77 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]
verify_cli()120 fn verify_cli() {
121 use clap::CommandFactory;
122 Commands::command().debug_assert()
123 }
124