diff --git a/cranelift/codegen/build.rs b/cranelift/codegen/build.rs index 3ebb1c18c96e..38bf9182d453 100644 --- a/cranelift/codegen/build.rs +++ b/cranelift/codegen/build.rs @@ -136,161 +136,11 @@ fn main() { .unwrap(); } -/// Strip the current directory from the file paths, because `islec` -/// includes them in the generated source, and this helps us maintain -/// deterministic builds that don't include those local file paths. -fn make_isle_source_path_relative( - cur_dir: &std::path::PathBuf, - filename: std::path::PathBuf, -) -> std::path::PathBuf { - if let Ok(suffix) = filename.strip_prefix(&cur_dir) { - suffix.to_path_buf() - } else { - filename - } -} - -/// A list of compilations (transformations from ISLE source to -/// generated Rust source) that exist in the repository. -/// -/// This list is used either to regenerate the Rust source in-tree (if -/// the `rebuild-isle` feature is enabled), or to verify that the ISLE -/// source in-tree corresponds to the ISLE source that was last used -/// to rebuild the Rust source (if the `rebuild-isle` feature is not -/// enabled). -#[derive(Clone, Debug)] -struct IsleCompilations { - items: Vec, -} - -#[derive(Clone, Debug)] -struct IsleCompilation { - output: std::path::PathBuf, - inputs: Vec, - untracked_inputs: Vec, -} - -/// Construct the list of compilations (transformations from ISLE -/// source to generated Rust source) that exist in the repository. -fn get_isle_compilations( - crate_dir: &std::path::Path, - out_dir: &std::path::Path, -) -> Result { - let cur_dir = std::env::current_dir()?; - - // Preludes. - let clif_lower_isle = out_dir.join("clif_lower.isle"); - let clif_opt_isle = out_dir.join("clif_opt.isle"); - let prelude_isle = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude.isle")); - let prelude_opt_isle = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude_opt.isle")); - let prelude_lower_isle = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude_lower.isle")); - let inst_specs = make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("inst_specs.isle")); - - // Directory for mid-end optimizations. - let src_opts = make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("opts")); - // Directories for lowering backends. - let src_isa_x64 = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("x64")); - let src_isa_aarch64 = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("aarch64")); - let src_isa_s390x = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("s390x")); - - let src_isa_risc_v = - make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("riscv64")); - // This is a set of ISLE compilation units. - // - // The format of each entry is: - // - // (output Rust code file, input ISLE source files) - // - // There should be one entry for each backend that uses ISLE for lowering, - // and if/when we replace our peephole optimization passes with ISLE, there - // should be an entry for each of those as well. - // - // N.B.: add any new compilation outputs to - // `scripts/force-rebuild-isle.sh` if they do not fit the pattern - // `cranelift/codegen/src/isa/*/lower/isle/generated_code.rs`! - Ok(IsleCompilations { - items: vec![ - // The mid-end optimization rules. - IsleCompilation { - output: out_dir.join("isle_opt.rs"), - inputs: vec![ - prelude_isle.clone(), - prelude_opt_isle, - src_opts.join("arithmetic.isle"), - src_opts.join("bitops.isle"), - src_opts.join("cprop.isle"), - src_opts.join("extends.isle"), - src_opts.join("icmp.isle"), - src_opts.join("remat.isle"), - src_opts.join("selects.isle"), - src_opts.join("shifts.isle"), - src_opts.join("vector.isle"), - ], - untracked_inputs: vec![clif_opt_isle], - }, - // The x86-64 instruction selector. - IsleCompilation { - output: out_dir.join("isle_x64.rs"), - inputs: vec![ - prelude_isle.clone(), - prelude_lower_isle.clone(), - src_isa_x64.join("inst.isle"), - src_isa_x64.join("lower.isle"), - ], - untracked_inputs: vec![clif_lower_isle.clone()], - }, - // The aarch64 instruction selector. - IsleCompilation { - output: out_dir.join("isle_aarch64.rs"), - inputs: vec![ - prelude_isle.clone(), - prelude_lower_isle.clone(), - src_isa_aarch64.join("inst.isle"), - src_isa_aarch64.join("inst_neon.isle"), - inst_specs.clone(), - src_isa_aarch64.join("lower.isle"), - src_isa_aarch64.join("lower_dynamic_neon.isle"), - ], - untracked_inputs: vec![clif_lower_isle.clone()], - }, - // The s390x instruction selector. - IsleCompilation { - output: out_dir.join("isle_s390x.rs"), - inputs: vec![ - prelude_isle.clone(), - prelude_lower_isle.clone(), - src_isa_s390x.join("inst.isle"), - src_isa_s390x.join("lower.isle"), - ], - untracked_inputs: vec![clif_lower_isle.clone()], - }, - // The risc-v instruction selector. - IsleCompilation { - output: out_dir.join("isle_riscv64.rs"), - inputs: vec![ - prelude_isle.clone(), - prelude_lower_isle.clone(), - src_isa_risc_v.join("inst.isle"), - src_isa_risc_v.join("inst_vector.isle"), - src_isa_risc_v.join("lower.isle"), - ], - untracked_inputs: vec![clif_lower_isle.clone()], - }, - ], - }) -} - pub fn build_isle( crate_dir: &std::path::Path, isle_dir: &std::path::Path, ) -> Result<(), Box> { - let isle_compilations = get_isle_compilations(crate_dir, isle_dir)?; + let isle_compilations = meta::isle::get_isle_compilations(crate_dir, isle_dir)?; let mut had_error = false; for compilation in &isle_compilations.items { @@ -325,7 +175,7 @@ pub fn build_isle( /// /// NB: This must happen *after* the `cranelift-codegen-meta` functions, since /// it consumes files generated by them. -fn run_compilation(compilation: &IsleCompilation) -> Result<(), Errors> { +fn run_compilation(compilation: &meta::isle::IsleCompilation) -> Result<(), Errors> { use cranelift_isle as isle; eprintln!("Rebuilding {}", compilation.output.display()); diff --git a/cranelift/codegen/meta/src/isle.rs b/cranelift/codegen/meta/src/isle.rs new file mode 100644 index 000000000000..0ce9d5409c64 --- /dev/null +++ b/cranelift/codegen/meta/src/isle.rs @@ -0,0 +1,156 @@ +/// A list of compilations (transformations from ISLE source to +/// generated Rust source) that exist in the repository. +/// +/// This list is used either to regenerate the Rust source in-tree (if +/// the `rebuild-isle` feature is enabled), or to verify that the ISLE +/// source in-tree corresponds to the ISLE source that was last used +/// to rebuild the Rust source (if the `rebuild-isle` feature is not +/// enabled). +#[derive(Clone, Debug)] +pub struct IsleCompilations { + pub items: Vec, +} + +#[derive(Clone, Debug)] +pub struct IsleCompilation { + pub name: String, + pub output: std::path::PathBuf, + pub inputs: Vec, + pub untracked_inputs: Vec, +} + +/// Strip the current directory from the file paths, because `islec` +/// includes them in the generated source, and this helps us maintain +/// deterministic builds that don't include those local file paths. +fn make_isle_source_path_relative( + cur_dir: &std::path::PathBuf, + filename: std::path::PathBuf, +) -> std::path::PathBuf { + if let Ok(suffix) = filename.strip_prefix(&cur_dir) { + suffix.to_path_buf() + } else { + filename + } +} + +/// Construct the list of compilations (transformations from ISLE +/// source to generated Rust source) that exist in the repository. +pub fn get_isle_compilations( + crate_dir: &std::path::Path, + out_dir: &std::path::Path, +) -> Result { + let cur_dir = std::env::current_dir()?; + + // Preludes. + let clif_lower_isle = out_dir.join("clif_lower.isle"); + let clif_opt_isle = out_dir.join("clif_opt.isle"); + let prelude_isle = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude.isle")); + let prelude_opt_isle = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude_opt.isle")); + let prelude_lower_isle = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("prelude_lower.isle")); + let inst_specs = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("inst_specs.isle")); + + // Directory for mid-end optimizations. + let src_opts = make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("opts")); + // Directories for lowering backends. + let src_isa_x64 = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("x64")); + let src_isa_aarch64 = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("aarch64")); + let src_isa_s390x = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("s390x")); + + let src_isa_risc_v = + make_isle_source_path_relative(&cur_dir, crate_dir.join("src").join("isa").join("riscv64")); + // This is a set of ISLE compilation units. + // + // The format of each entry is: + // + // (output Rust code file, input ISLE source files) + // + // There should be one entry for each backend that uses ISLE for lowering, + // and if/when we replace our peephole optimization passes with ISLE, there + // should be an entry for each of those as well. + // + // N.B.: add any new compilation outputs to + // `scripts/force-rebuild-isle.sh` if they do not fit the pattern + // `cranelift/codegen/src/isa/*/lower/isle/generated_code.rs`! + Ok(IsleCompilations { + items: vec![ + // The mid-end optimization rules. + IsleCompilation { + name: "opt".to_string(), + output: out_dir.join("isle_opt.rs"), + inputs: vec![ + prelude_isle.clone(), + prelude_opt_isle, + src_opts.join("arithmetic.isle"), + src_opts.join("bitops.isle"), + src_opts.join("cprop.isle"), + src_opts.join("extends.isle"), + src_opts.join("icmp.isle"), + src_opts.join("remat.isle"), + src_opts.join("selects.isle"), + src_opts.join("shifts.isle"), + src_opts.join("vector.isle"), + ], + untracked_inputs: vec![clif_opt_isle], + }, + // The x86-64 instruction selector. + IsleCompilation { + name: "x64".to_string(), + output: out_dir.join("isle_x64.rs"), + inputs: vec![ + prelude_isle.clone(), + prelude_lower_isle.clone(), + src_isa_x64.join("inst.isle"), + src_isa_x64.join("lower.isle"), + ], + untracked_inputs: vec![clif_lower_isle.clone()], + }, + // The aarch64 instruction selector. + IsleCompilation { + name: "aarch64".to_string(), + output: out_dir.join("isle_aarch64.rs"), + inputs: vec![ + prelude_isle.clone(), + prelude_lower_isle.clone(), + src_isa_aarch64.join("inst.isle"), + src_isa_aarch64.join("inst_neon.isle"), + inst_specs.clone(), + src_isa_aarch64.join("lower.isle"), + src_isa_aarch64.join("lower_dynamic_neon.isle"), + ], + untracked_inputs: vec![clif_lower_isle.clone()], + }, + // The s390x instruction selector. + IsleCompilation { + name: "s390x".to_string(), + output: out_dir.join("isle_s390x.rs"), + inputs: vec![ + prelude_isle.clone(), + prelude_lower_isle.clone(), + src_isa_s390x.join("inst.isle"), + src_isa_s390x.join("lower.isle"), + ], + untracked_inputs: vec![clif_lower_isle.clone()], + }, + // The risc-v instruction selector. + IsleCompilation { + name: "riscv64".to_string(), + output: out_dir.join("isle_riscv64.rs"), + inputs: vec![ + prelude_isle.clone(), + prelude_lower_isle.clone(), + src_isa_risc_v.join("inst.isle"), + src_isa_risc_v.join("inst_vector.isle"), + src_isa_risc_v.join("lower.isle"), + ], + untracked_inputs: vec![clif_lower_isle.clone()], + }, + ], + }) +} diff --git a/cranelift/codegen/meta/src/lib.rs b/cranelift/codegen/meta/src/lib.rs index 689d3508b06c..a50d632c060d 100644 --- a/cranelift/codegen/meta/src/lib.rs +++ b/cranelift/codegen/meta/src/lib.rs @@ -7,6 +7,7 @@ mod srcgen; pub mod error; pub mod isa; +pub mod isle; mod gen_inst; mod gen_settings; diff --git a/cranelift/isle/veri/veri_engine/src/main.rs b/cranelift/isle/veri/veri_engine/src/main.rs index d142f5193a2a..e817a4c7c640 100644 --- a/cranelift/isle/veri/veri_engine/src/main.rs +++ b/cranelift/isle/veri/veri_engine/src/main.rs @@ -1,6 +1,7 @@ //! Prototype verification tool for Cranelift's ISLE lowering rules. use clap::{ArgAction, Parser}; +use cranelift_codegen_meta as meta; use std::env; use std::path::PathBuf; use veri_engine_lib::verify::verify_rules; @@ -60,6 +61,10 @@ fn main() { ); } + // Just confirm we can call get_isle_compilations from codegen meta here. + // TODO(mbm): use the right directories! use these! + let _isle_compilations = meta::isle::get_isle_compilations(&cur_dir, &cur_dir); + if args.aarch64 { inputs.push( cur_dir