polydat_core/compile/jit/
host_isa.rs1use cranelift_codegen::isa::OwnedTargetIsa;
12use cranelift_codegen::settings;
13
14#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct EffectiveIsa {
18 pub triple: String,
20 pub polydat_register_bits: u16,
23 pub cranelift_version: &'static str,
25 enabled_flags: Vec<&'static str>,
27}
28
29impl EffectiveIsa {
30 pub fn detect() -> Result<Self, String> {
32 let isa = build_host_isa(settings::builder())?;
33 let mut enabled_flags: Vec<_> = isa
34 .isa_flags()
35 .into_iter()
36 .filter(|flag| flag.as_bool() == Some(true))
37 .map(|flag| flag.name)
38 .collect();
39 enabled_flags.sort_unstable();
40
41 Ok(Self {
42 triple: isa.triple().to_string(),
43 polydat_register_bits: 128,
44 cranelift_version: cranelift_native::VERSION,
45 enabled_flags,
46 })
47 }
48
49 pub fn has_flag(&self, flag: &str) -> bool {
51 self.enabled_flags.binary_search(&flag).is_ok()
52 }
53
54 pub fn enabled_flags(&self) -> &[&'static str] {
56 &self.enabled_flags
57 }
58
59 pub fn fingerprint(&self) -> String {
61 format!(
62 "{}|clif={}|reg={}|{}",
63 self.triple,
64 self.cranelift_version,
65 self.polydat_register_bits,
66 self.enabled_flags.join(",")
67 )
68 }
69}
70
71pub(crate) fn build_host_isa(
74 shared_flag_builder: settings::Builder,
75) -> Result<OwnedTargetIsa, String> {
76 let isa_builder =
77 cranelift_native::builder().map_err(|e| format!("native ISA detection failed: {e}"))?;
78 isa_builder
79 .finish(settings::Flags::new(shared_flag_builder))
80 .map_err(|e| format!("native ISA build failed: {e}"))
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn capability_record_matches_native_x86_detection() {
89 let caps = EffectiveIsa::detect().expect("host ISA");
90 assert_eq!(caps.polydat_register_bits, 128);
91 assert!(!caps.fingerprint().is_empty());
92
93 #[cfg(target_arch = "x86_64")]
94 {
95 assert_eq!(
96 caps.has_flag("has_avx"),
97 std::is_x86_feature_detected!("avx")
98 );
99 assert_eq!(
100 caps.has_flag("has_avx2"),
101 std::is_x86_feature_detected!("avx2")
102 );
103 assert_eq!(
104 caps.has_flag("has_fma"),
105 std::is_x86_feature_detected!("fma")
106 );
107 }
108 }
109}