|
| 1 | +//! Stuff for handling `#[target_feature]` (needed for unsafe check). |
| 2 | +
|
| 3 | +use std::sync::LazyLock; |
| 4 | + |
| 5 | +use hir_def::attr::Attrs; |
| 6 | +use hir_def::tt; |
| 7 | +use intern::{sym,Symbol}; |
| 8 | +use rustc_hash::{FxHashMap,FxHashSet}; |
| 9 | + |
| 10 | +#[derive(Debug,Default)] |
| 11 | +pubstructTargetFeatures{ |
| 12 | +pub(crate)enabled:FxHashSet<Symbol>, |
| 13 | +} |
| 14 | + |
| 15 | +implTargetFeatures{ |
| 16 | +pubfnfrom_attrs(attrs:&Attrs) -> Self{ |
| 17 | +letmut result = TargetFeatures::from_attrs_no_implications(attrs); |
| 18 | + result.expand_implications(); |
| 19 | + result |
| 20 | +} |
| 21 | + |
| 22 | +fnexpand_implications(&mutself){ |
| 23 | +let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS); |
| 24 | +letmut queue = self.enabled.iter().cloned().collect::<Vec<_>>(); |
| 25 | +whileletSome(feature) = queue.pop(){ |
| 26 | +ifletSome(implications) = all_implications.get(&feature){ |
| 27 | +for implication in implications { |
| 28 | +ifself.enabled.insert(implication.clone()){ |
| 29 | + queue.push(implication.clone()); |
| 30 | +} |
| 31 | +} |
| 32 | +} |
| 33 | +} |
| 34 | +} |
| 35 | + |
| 36 | +/// Retrieves the target features from the attributes, and does not expand the target features implied by them. |
| 37 | +pub(crate)fnfrom_attrs_no_implications(attrs:&Attrs) -> Self{ |
| 38 | +let enabled = attrs |
| 39 | +.by_key(&sym::target_feature) |
| 40 | +.tt_values() |
| 41 | +.filter_map(|tt| { |
| 42 | +match tt.token_trees().flat_tokens(){ |
| 43 | +[ |
| 44 | + tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), |
| 45 | + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct{char:'=', .. })), |
| 46 | + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal{kind: tt::LitKind::Str,symbol: features, .. })), |
| 47 | +]if enable_ident.sym == sym::enable => Some(features), |
| 48 | + _ => None, |
| 49 | +} |
| 50 | +}) |
| 51 | +.flat_map(|features| features.as_str().split(',').map(Symbol::intern)) |
| 52 | +.collect(); |
| 53 | +Self{ enabled } |
| 54 | +} |
| 55 | +} |
| 56 | + |
| 57 | +// List of the target features each target feature implies. |
| 58 | +// Ideally we'd depend on rustc for this, but rustc_target doesn't compile on stable, |
| 59 | +// and t-compiler prefers for it to stay this way. |
| 60 | + |
| 61 | +staticTARGET_FEATURE_IMPLICATIONS:LazyLock<FxHashMap<Symbol,Box<[Symbol]>>> = |
| 62 | +LazyLock::new(|| { |
| 63 | +letmut result = FxHashMap::<Symbol,FxHashSet<Symbol>>::default(); |
| 64 | +for&(feature_str, implications)inTARGET_FEATURE_IMPLICATIONS_RAW{ |
| 65 | +let feature = Symbol::intern(feature_str); |
| 66 | +let implications = implications.iter().copied().map(Symbol::intern); |
| 67 | +// Some target features appear in two archs, e.g. Arm and x86. |
| 68 | +// Sometimes they contain different implications, e.g. `aes`. |
| 69 | +// We should probably choose by the active arch, but for now just merge them. |
| 70 | + result.entry(feature).or_default().extend(implications); |
| 71 | +} |
| 72 | +letmut result = result |
| 73 | +.into_iter() |
| 74 | +.map(|(feature, implications)| (feature,Box::from_iter(implications))) |
| 75 | +.collect::<FxHashMap<_,_>>(); |
| 76 | + result.shrink_to_fit(); |
| 77 | + result |
| 78 | +}); |
| 79 | + |
| 80 | +// spellchecker:off |
| 81 | +constTARGET_FEATURE_IMPLICATIONS_RAW:&[(&str,&[&str])] = &[ |
| 82 | +// Arm |
| 83 | +("aes",&["neon"]), |
| 84 | +("dotprod",&["neon"]), |
| 85 | +("fp-armv8",&["vfp4"]), |
| 86 | +("fp16",&["neon"]), |
| 87 | +("i8mm",&["neon"]), |
| 88 | +("neon",&["vfp3"]), |
| 89 | +("sha2",&["neon"]), |
| 90 | +("v6",&["v5te"]), |
| 91 | +("v6k",&["v6"]), |
| 92 | +("v6t2",&["v6k","thumb2"]), |
| 93 | +("v7",&["v6t2"]), |
| 94 | +("v8",&["v7"]), |
| 95 | +("vfp3",&["vfp2","d32"]), |
| 96 | +("vfp4",&["vfp3"]), |
| 97 | +// Aarch64 |
| 98 | +("aes",&["neon"]), |
| 99 | +("dotprod",&["neon"]), |
| 100 | +("dpb2",&["dpb"]), |
| 101 | +("f32mm",&["sve"]), |
| 102 | +("f64mm",&["sve"]), |
| 103 | +("fcma",&["neon"]), |
| 104 | +("fhm",&["fp16"]), |
| 105 | +("fp16",&["neon"]), |
| 106 | +("fp8",&["faminmax","lut","bf16"]), |
| 107 | +("fp8dot2",&["fp8dot4"]), |
| 108 | +("fp8dot4",&["fp8fma"]), |
| 109 | +("fp8fma",&["fp8"]), |
| 110 | +("jsconv",&["neon"]), |
| 111 | +("lse128",&["lse"]), |
| 112 | +("rcpc2",&["rcpc"]), |
| 113 | +("rcpc3",&["rcpc2"]), |
| 114 | +("rdm",&["neon"]), |
| 115 | +("sha2",&["neon"]), |
| 116 | +("sha3",&["sha2"]), |
| 117 | +("sm4",&["neon"]), |
| 118 | +("sme",&["bf16"]), |
| 119 | +("sme-b16b16",&["bf16","sme2","sve-b16b16"]), |
| 120 | +("sme-f16f16",&["sme2"]), |
| 121 | +("sme-f64f64",&["sme"]), |
| 122 | +("sme-f8f16",&["sme-f8f32"]), |
| 123 | +("sme-f8f32",&["sme2","fp8"]), |
| 124 | +("sme-fa64",&["sme","sve2"]), |
| 125 | +("sme-i16i64",&["sme"]), |
| 126 | +("sme2",&["sme"]), |
| 127 | +("sme2p1",&["sme2"]), |
| 128 | +("ssve-fp8dot2",&["ssve-fp8dot4"]), |
| 129 | +("ssve-fp8dot4",&["ssve-fp8fma"]), |
| 130 | +("ssve-fp8fma",&["sme2","fp8"]), |
| 131 | +("sve",&["neon"]), |
| 132 | +("sve-b16b16",&["bf16"]), |
| 133 | +("sve2",&["sve"]), |
| 134 | +("sve2-aes",&["sve2","aes"]), |
| 135 | +("sve2-bitperm",&["sve2"]), |
| 136 | +("sve2-sha3",&["sve2","sha3"]), |
| 137 | +("sve2-sm4",&["sve2","sm4"]), |
| 138 | +("sve2p1",&["sve2"]), |
| 139 | +("v8.1a",&["crc","lse","rdm","pan","lor","vh"]), |
| 140 | +("v8.2a",&["v8.1a","ras","dpb"]), |
| 141 | +("v8.3a",&["v8.2a","rcpc","paca","pacg","jsconv"]), |
| 142 | +("v8.4a",&["v8.3a","dotprod","dit","flagm"]), |
| 143 | +("v8.5a",&["v8.4a","ssbs","sb","dpb2","bti"]), |
| 144 | +("v8.6a",&["v8.5a","bf16","i8mm"]), |
| 145 | +("v8.7a",&["v8.6a","wfxt"]), |
| 146 | +("v8.8a",&["v8.7a","hbc","mops"]), |
| 147 | +("v8.9a",&["v8.8a","cssc"]), |
| 148 | +("v9.1a",&["v9a","v8.6a"]), |
| 149 | +("v9.2a",&["v9.1a","v8.7a"]), |
| 150 | +("v9.3a",&["v9.2a","v8.8a"]), |
| 151 | +("v9.4a",&["v9.3a","v8.9a"]), |
| 152 | +("v9.5a",&["v9.4a"]), |
| 153 | +("v9a",&["v8.5a","sve2"]), |
| 154 | +// x86 |
| 155 | +("aes",&["sse2"]), |
| 156 | +("amx-bf16",&["amx-tile"]), |
| 157 | +("amx-complex",&["amx-tile"]), |
| 158 | +("amx-fp16",&["amx-tile"]), |
| 159 | +("amx-int8",&["amx-tile"]), |
| 160 | +("avx",&["sse4.2"]), |
| 161 | +("avx2",&["avx"]), |
| 162 | +("avx512bf16",&["avx512bw"]), |
| 163 | +("avx512bitalg",&["avx512bw"]), |
| 164 | +("avx512bw",&["avx512f"]), |
| 165 | +("avx512cd",&["avx512f"]), |
| 166 | +("avx512dq",&["avx512f"]), |
| 167 | +("avx512f",&["avx2","fma","f16c"]), |
| 168 | +("avx512fp16",&["avx512bw","avx512vl","avx512dq"]), |
| 169 | +("avx512ifma",&["avx512f"]), |
| 170 | +("avx512vbmi",&["avx512bw"]), |
| 171 | +("avx512vbmi2",&["avx512bw"]), |
| 172 | +("avx512vl",&["avx512f"]), |
| 173 | +("avx512vnni",&["avx512f"]), |
| 174 | +("avx512vp2intersect",&["avx512f"]), |
| 175 | +("avx512vpopcntdq",&["avx512f"]), |
| 176 | +("avxifma",&["avx2"]), |
| 177 | +("avxneconvert",&["avx2"]), |
| 178 | +("avxvnni",&["avx2"]), |
| 179 | +("avxvnniint16",&["avx2"]), |
| 180 | +("avxvnniint8",&["avx2"]), |
| 181 | +("f16c",&["avx"]), |
| 182 | +("fma",&["avx"]), |
| 183 | +("gfni",&["sse2"]), |
| 184 | +("kl",&["sse2"]), |
| 185 | +("pclmulqdq",&["sse2"]), |
| 186 | +("sha",&["sse2"]), |
| 187 | +("sha512",&["avx2"]), |
| 188 | +("sm3",&["avx"]), |
| 189 | +("sm4",&["avx2"]), |
| 190 | +("sse2",&["sse"]), |
| 191 | +("sse3",&["sse2"]), |
| 192 | +("sse4.1",&["ssse3"]), |
| 193 | +("sse4.2",&["sse4.1"]), |
| 194 | +("sse4a",&["sse3"]), |
| 195 | +("ssse3",&["sse3"]), |
| 196 | +("vaes",&["avx2","aes"]), |
| 197 | +("vpclmulqdq",&["avx","pclmulqdq"]), |
| 198 | +("widekl",&["kl"]), |
| 199 | +("xop",&[/*"fma4", */"avx","sse4a"]), |
| 200 | +("xsavec",&["xsave"]), |
| 201 | +("xsaveopt",&["xsave"]), |
| 202 | +("xsaves",&["xsave"]), |
| 203 | +// Hexagon |
| 204 | +("hvx-length128b",&["hvx"]), |
| 205 | +// PowerPC |
| 206 | +("power10-vector",&["power9-vector"]), |
| 207 | +("power8-altivec",&["altivec"]), |
| 208 | +("power8-crypto",&["power8-altivec"]), |
| 209 | +("power8-vector",&["vsx","power8-altivec"]), |
| 210 | +("power9-altivec",&["power8-altivec"]), |
| 211 | +("power9-vector",&["power8-vector","power9-altivec"]), |
| 212 | +("vsx",&["altivec"]), |
| 213 | +// MIPS |
| 214 | +// RISC-V |
| 215 | +("a",&["zaamo","zalrsc"]), |
| 216 | +("d",&["f"]), |
| 217 | +("zabha",&["zaamo"]), |
| 218 | +("zdinx",&["zfinx"]), |
| 219 | +("zfh",&["zfhmin"]), |
| 220 | +("zfhmin",&["f"]), |
| 221 | +("zhinx",&["zhinxmin"]), |
| 222 | +("zhinxmin",&["zfinx"]), |
| 223 | +("zk",&["zkn","zkr","zkt"]), |
| 224 | +("zkn",&["zbkb","zbkc","zbkx","zkne","zknd","zknh"]), |
| 225 | +("zks",&["zbkb","zbkc","zbkx","zksed","zksh"]), |
| 226 | +// WASM |
| 227 | +("relaxed-simd",&["simd128"]), |
| 228 | +// BPF |
| 229 | +("alu32",&[]), |
| 230 | +// CSKY |
| 231 | +("10e60",&["7e10"]), |
| 232 | +("2e3",&["e2"]), |
| 233 | +("3e3r2",&["3e3r1","doloop"]), |
| 234 | +("3e3r3",&["doloop"]), |
| 235 | +("3e7",&["2e3"]), |
| 236 | +("7e10",&["3e7"]), |
| 237 | +("e1",&["elrw"]), |
| 238 | +("e2",&["e2"]), |
| 239 | +("mp",&["2e3"]), |
| 240 | +("mp1e2",&["3e7"]), |
| 241 | +// LoongArch |
| 242 | +("d",&["f"]), |
| 243 | +("lasx",&["lsx"]), |
| 244 | +("lsx",&["d"]), |
| 245 | +// IBM Z |
| 246 | +("nnp-assist",&["vector"]), |
| 247 | +("vector-enhancements-1",&["vector"]), |
| 248 | +("vector-enhancements-2",&["vector-enhancements-1"]), |
| 249 | +("vector-packed-decimal",&["vector"]), |
| 250 | +("vector-packed-decimal-enhancement",&["vector-packed-decimal"]), |
| 251 | +("vector-packed-decimal-enhancement-2",&["vector-packed-decimal-enhancement"]), |
| 252 | +// SPARC |
| 253 | +// m68k |
| 254 | +("isa-68010",&["isa-68000"]), |
| 255 | +("isa-68020",&["isa-68010"]), |
| 256 | +("isa-68030",&["isa-68020"]), |
| 257 | +("isa-68040",&["isa-68030","isa-68882"]), |
| 258 | +("isa-68060",&["isa-68040"]), |
| 259 | +("isa-68882",&["isa-68881"]), |
| 260 | +]; |
| 261 | +// spellchecker:on |
0 commit comments