@@ -18,6 +18,7 @@ use rustc_session::config::{PrintKind, PrintRequest};
1818use rustc_span:: Symbol ;
1919use rustc_target:: spec:: { MergeFunctions , PanicStrategy , SmallDataThresholdSupport } ;
2020use rustc_target:: target_features:: { RUSTC_SPECIAL_FEATURES , RUSTC_SPECIFIC_FEATURES } ;
21+ use smallvec:: SmallVec ;
2122
2223use crate :: back:: write:: create_informational_target_machine;
2324use crate :: errors:: {
@@ -179,27 +180,27 @@ impl<'a> TargetFeatureFoldStrength<'a> {
179180
180181pub ( crate ) struct LLVMFeature < ' a > {
181182 llvm_feature_name : & ' a str ,
182- dependency : Option < TargetFeatureFoldStrength < ' a > > ,
183+ dependencies : SmallVec < [ TargetFeatureFoldStrength < ' a > ; 10 ] > ,
183184}
184185
185186impl < ' a > LLVMFeature < ' a > {
186187 fn new ( llvm_feature_name : & ' a str ) -> Self {
187- Self { llvm_feature_name, dependency : None }
188+ Self { llvm_feature_name, dependencies : SmallVec :: new ( ) }
188189 }
189190
190- fn with_dependency (
191+ fn with_dependencies (
191192 llvm_feature_name : & ' a str ,
192- dependency : TargetFeatureFoldStrength < ' a > ,
193+ dependencies : SmallVec < [ TargetFeatureFoldStrength < ' a > ; 10 ] > ,
193194 ) -> Self {
194- Self { llvm_feature_name, dependency : Some ( dependency ) }
195+ Self { llvm_feature_name, dependencies : dependencies }
195196 }
196197
197198 fn contains ( & self , feat : & str ) -> bool {
198199 self . iter ( ) . any ( |dep| dep == feat)
199200 }
200201
201202 fn iter ( & ' a self ) -> impl Iterator < Item = & ' a str > {
202- let dependencies = self . dependency . iter ( ) . map ( |feat| feat. as_str ( ) ) ;
203+ let dependencies = self . dependencies . iter ( ) . map ( |feat| feat. as_str ( ) ) ;
203204 std:: iter:: once ( self . llvm_feature_name ) . chain ( dependencies)
204205 }
205206}
@@ -209,7 +210,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
209210 type IntoIter = impl Iterator < Item = & ' a str > ;
210211
211212 fn into_iter ( self ) -> Self :: IntoIter {
212- let dependencies = self . dependency . into_iter ( ) . map ( |feat| feat. as_str ( ) ) ;
213+ let dependencies = self . dependencies . into_iter ( ) . map ( |feat| feat. as_str ( ) ) ;
213214 std:: iter:: once ( self . llvm_feature_name ) . chain ( dependencies)
214215 }
215216}
@@ -239,10 +240,12 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
239240 & * sess. target . arch
240241 } ;
241242 match ( arch, s) {
242- ( "x86" , "sse4.2" ) => Some ( LLVMFeature :: with_dependency (
243- "sse4.2" ,
244- TargetFeatureFoldStrength :: EnableOnly ( "crc32" ) ,
245- ) ) ,
243+ ( "x86" , "sse4.2" ) => {
244+ let dependencies: SmallVec < [ TargetFeatureFoldStrength ; 10 ] > = SmallVec :: from_buf (
245+ TargetFeatureFoldStrength :: EnableOnly ( "crc32" ) ,
246+ ) ;
247+ Some ( LLVMFeature :: with_dependencies ( "sse4.2" , dependencies) )
248+ }
246249 ( "x86" , "pclmulqdq" ) => Some ( LLVMFeature :: new ( "pclmul" ) ) ,
247250 ( "x86" , "rdrand" ) => Some ( LLVMFeature :: new ( "rdrnd" ) ) ,
248251 ( "x86" , "bmi1" ) => Some ( LLVMFeature :: new ( "bmi" ) ) ,
@@ -262,7 +265,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
262265 ( "aarch64" , "flagm2" ) => Some ( LLVMFeature :: new ( "altnzcv" ) ) ,
263266 // Rust ties fp and neon together.
264267 ( "aarch64" , "neon" ) => {
265- Some ( LLVMFeature :: with_dependency ( "neon" , TargetFeatureFoldStrength :: Both ( "fp-armv8" ) ) )
268+ let dependencies: SmallVec < [ TargetFeatureFoldStrength ; 10 ] > = SmallVec :: from_buf (
269+ TargetFeatureFoldStrength :: Both ( "fp-armv8" ) ,
270+ ) ;
271+ Some ( LLVMFeature :: with_dependencies ( "neon" , dependencies) )
266272 }
267273 // In LLVM neon implicitly enables fp, but we manually enable
268274 // neon when a feature only implicitly enables fp
@@ -275,7 +281,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
275281 ( "riscv32" | "riscv64" , "zacas" ) if get_version ( ) . 0 < 20 => None ,
276282 // Enable the evex512 target feature if an avx512 target feature is enabled.
277283 ( "x86" , s) if s. starts_with ( "avx512" ) => {
278- Some ( LLVMFeature :: with_dependency ( s, TargetFeatureFoldStrength :: EnableOnly ( "evex512" ) ) )
284+ let dependencies: SmallVec < [ TargetFeatureFoldStrength ; 10 ] > = SmallVec :: from_buf (
285+ TargetFeatureFoldStrength :: EnableOnly ( "evex512" ) ,
286+ ) ;
287+ Some ( LLVMFeature :: with_dependencies ( s, dependencies) )
279288 }
280289 // Support for `wide-arithmetic` will first land in LLVM 20 as part of
281290 // llvm/llvm-project#111598
@@ -765,7 +774,7 @@ pub(crate) fn global_llvm_features(
765774 "{}{}" ,
766775 enable_disable, llvm_feature. llvm_feature_name
767776 ) )
768- . chain ( llvm_feature. dependency . into_iter ( ) . filter_map (
777+ . chain ( llvm_feature. dependencies . into_iter ( ) . filter_map (
769778 move |feat| match ( enable, feat) {
770779 ( _, TargetFeatureFoldStrength :: Both ( f) )
771780 | ( true , TargetFeatureFoldStrength :: EnableOnly ( f) ) => {
0 commit comments