Build ISLE DSL source text into generated Rust code. NB: This must happen *after* the `cranelift-codegen-meta` functions, since it consumes files generated by them.
(compilation: &IsleCompilation)
| 193 | /// NB: This must happen *after* the `cranelift-codegen-meta` functions, since |
| 194 | /// it consumes files generated by them. |
| 195 | fn run_compilation(compilation: &IsleCompilation) -> Result<(), Errors> { |
| 196 | use cranelift_isle as isle; |
| 197 | |
| 198 | eprintln!("Rebuilding {}", compilation.output.display()); |
| 199 | |
| 200 | let code = { |
| 201 | let file_paths = compilation |
| 202 | .inputs |
| 203 | .iter() |
| 204 | .chain(compilation.untracked_inputs.iter()); |
| 205 | |
| 206 | let mut options = isle::codegen::CodegenOptions::default(); |
| 207 | // Because we include!() the generated ISLE source, we cannot |
| 208 | // put the global pragmas (`#![allow(...)]`) in the ISLE |
| 209 | // source itself; we have to put them in the source that |
| 210 | // include!()s it. (See |
| 211 | // https://github.com/rust-lang/rust/issues/47995.) |
| 212 | options.exclude_global_allow_pragmas = true; |
| 213 | |
| 214 | // When `cranelift-codegen` is built with detailed tracing enabled, also |
| 215 | // ask the ISLE compiler to emit `log::{debug,trace}!` invocations in |
| 216 | // the generated code to help debug rule matching. |
| 217 | options.emit_logging = std::env::var("CARGO_FEATURE_TRACE_LOG").is_ok(); |
| 218 | |
| 219 | // Enable optional match-arm splitting in iterator terms for |
| 220 | // faster compile times in release builds. |
| 221 | // |
| 222 | // In debug builds, *always* split with an aggressive |
| 223 | // threshold, because we cannot rely on rustc doing regalloc |
| 224 | // on all of the local bindings to shrink the stack frame to a |
| 225 | // reasonable size. |
| 226 | if cfg!(debug_assertions) { |
| 227 | options.split_match_arms = true; |
| 228 | options.match_arm_split_threshold = Some(4); |
| 229 | } else { |
| 230 | options.split_match_arms = std::env::var("CARGO_FEATURE_ISLE_SPLIT_MATCH").is_ok(); |
| 231 | if let Ok(value) = std::env::var("ISLE_SPLIT_MATCH_THRESHOLD") { |
| 232 | options.match_arm_split_threshold = Some(value.parse().unwrap_or_else(|err| { |
| 233 | panic!("invalid ISLE_SPLIT_MATCH_THRESHOLD value '{value}': {err}"); |
| 234 | })); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | if let Ok(out_dir) = std::env::var("OUT_DIR") { |
| 239 | options.prefixes.push(isle::codegen::Prefix { |
| 240 | prefix: out_dir, |
| 241 | name: "<OUT_DIR>".to_string(), |
| 242 | }) |
| 243 | }; |
| 244 | |
| 245 | isle::compile::from_files(file_paths, &options)? |
| 246 | }; |
| 247 | |
| 248 | eprintln!( |
| 249 | "Writing ISLE-generated Rust code to {}", |
| 250 | compilation.output.display() |
| 251 | ); |
| 252 | std::fs::write(&compilation.output, code) |
no test coverage detected