@@ -11,7 +11,7 @@ use tracing::{debug, trace};
1111use crate :: {
1212 AbiAlign , Align , BackendRepr , FieldsShape , HasDataLayout , IndexSlice , IndexVec , Integer ,
1313 LayoutData , Niche , NonZeroUsize , Primitive , ReprOptions , Scalar , Size , StructKind , TagEncoding ,
14- Variants , WrappingRange ,
14+ TargetDataLayout , Variants , WrappingRange ,
1515} ;
1616
1717mod coroutine;
@@ -143,58 +143,32 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
143143 } )
144144 }
145145
146- pub fn simd_type <
146+ pub fn scalable_vector_type < FieldIdx , VariantIdx , F > (
147+ & self ,
148+ element : F ,
149+ count : u64 ,
150+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F >
151+ where
147152 FieldIdx : Idx ,
148153 VariantIdx : Idx ,
149154 F : AsRef < LayoutData < FieldIdx , VariantIdx > > + fmt:: Debug ,
150- > (
155+ {
156+ vector_type_layout ( VectorKind :: Scalable , self . cx . data_layout ( ) , element, count)
157+ }
158+
159+ pub fn simd_type < FieldIdx , VariantIdx , F > (
151160 & self ,
152161 element : F ,
153162 count : u64 ,
154163 repr_packed : bool ,
155- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
156- let elt = element. as_ref ( ) ;
157- if count == 0 {
158- return Err ( LayoutCalculatorError :: ZeroLengthSimdType ) ;
159- } else if count > crate :: MAX_SIMD_LANES {
160- return Err ( LayoutCalculatorError :: OversizedSimdType {
161- max_lanes : crate :: MAX_SIMD_LANES ,
162- } ) ;
163- }
164-
165- let BackendRepr :: Scalar ( e_repr) = elt. backend_repr else {
166- return Err ( LayoutCalculatorError :: NonPrimitiveSimdType ( element) ) ;
167- } ;
168-
169- // Compute the size and alignment of the vector
170- let dl = self . cx . data_layout ( ) ;
171- let size =
172- elt. size . checked_mul ( count, dl) . ok_or_else ( || LayoutCalculatorError :: SizeOverflow ) ?;
173- let ( repr, align) = if repr_packed && !count. is_power_of_two ( ) {
174- // Non-power-of-two vectors have padding up to the next power-of-two.
175- // If we're a packed repr, remove the padding while keeping the alignment as close
176- // to a vector as possible.
177- ( BackendRepr :: Memory { sized : true } , AbiAlign { abi : Align :: max_aligned_factor ( size) } )
178- } else {
179- ( BackendRepr :: SimdVector { element : e_repr, count } , dl. llvmlike_vector_align ( size) )
180- } ;
181- let size = size. align_to ( align. abi ) ;
182-
183- Ok ( LayoutData {
184- variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
185- fields : FieldsShape :: Arbitrary {
186- offsets : [ Size :: ZERO ] . into ( ) ,
187- memory_index : [ 0 ] . into ( ) ,
188- } ,
189- backend_repr : repr,
190- largest_niche : elt. largest_niche ,
191- uninhabited : false ,
192- size,
193- align,
194- max_repr_align : None ,
195- unadjusted_abi_align : elt. align . abi ,
196- randomization_seed : elt. randomization_seed . wrapping_add ( Hash64 :: new ( count) ) ,
197- } )
164+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F >
165+ where
166+ FieldIdx : Idx ,
167+ VariantIdx : Idx ,
168+ F : AsRef < LayoutData < FieldIdx , VariantIdx > > + fmt:: Debug ,
169+ {
170+ let kind = if repr_packed { VectorKind :: PackedFixed } else { VectorKind :: Fixed } ;
171+ vector_type_layout ( kind, self . cx . data_layout ( ) , element, count)
198172 }
199173
200174 /// Compute the layout for a coroutine.
@@ -455,6 +429,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
455429 BackendRepr :: Scalar ( ..)
456430 | BackendRepr :: ScalarPair ( ..)
457431 | BackendRepr :: SimdVector { .. }
432+ | BackendRepr :: ScalableVector { .. }
458433 | BackendRepr :: Memory { .. } => repr,
459434 } ,
460435 } ;
@@ -526,7 +501,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
526501 hide_niches ( a) ;
527502 hide_niches ( b) ;
528503 }
529- BackendRepr :: SimdVector { element, count : _ } => hide_niches ( element) ,
504+ BackendRepr :: SimdVector { element, .. }
505+ | BackendRepr :: ScalableVector { element, .. } => hide_niches ( element) ,
530506 BackendRepr :: Memory { sized : _ } => { }
531507 }
532508 st. largest_niche = None ;
@@ -1525,3 +1501,67 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
15251501 s
15261502 }
15271503}
1504+
1505+ enum VectorKind {
1506+ /// `#[rustc_scalable_vector]`
1507+ Scalable ,
1508+ /// `#[repr(simd, packed)]`
1509+ PackedFixed ,
1510+ /// `#[repr(simd)]`
1511+ Fixed ,
1512+ }
1513+
1514+ fn vector_type_layout < FieldIdx , VariantIdx , F > (
1515+ kind : VectorKind ,
1516+ dl : & TargetDataLayout ,
1517+ element : F ,
1518+ count : u64 ,
1519+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F >
1520+ where
1521+ FieldIdx : Idx ,
1522+ VariantIdx : Idx ,
1523+ F : AsRef < LayoutData < FieldIdx , VariantIdx > > + fmt:: Debug ,
1524+ {
1525+ let elt = element. as_ref ( ) ;
1526+ if count == 0 {
1527+ return Err ( LayoutCalculatorError :: ZeroLengthSimdType ) ;
1528+ } else if count > crate :: MAX_SIMD_LANES {
1529+ return Err ( LayoutCalculatorError :: OversizedSimdType { max_lanes : crate :: MAX_SIMD_LANES } ) ;
1530+ }
1531+
1532+ let BackendRepr :: Scalar ( element) = elt. backend_repr else {
1533+ return Err ( LayoutCalculatorError :: NonPrimitiveSimdType ( element) ) ;
1534+ } ;
1535+
1536+ // Compute the size and alignment of the vector
1537+ let size =
1538+ elt. size . checked_mul ( count, dl) . ok_or_else ( || LayoutCalculatorError :: SizeOverflow ) ?;
1539+ let ( repr, align) = match kind {
1540+ VectorKind :: Scalable => {
1541+ ( BackendRepr :: ScalableVector { element, count } , dl. llvmlike_vector_align ( size) )
1542+ }
1543+ // Non-power-of-two vectors have padding up to the next power-of-two.
1544+ // If we're a packed repr, remove the padding while keeping the alignment as close
1545+ // to a vector as possible.
1546+ VectorKind :: PackedFixed if !count. is_power_of_two ( ) => {
1547+ ( BackendRepr :: Memory { sized : true } , AbiAlign { abi : Align :: max_aligned_factor ( size) } )
1548+ }
1549+ VectorKind :: PackedFixed | VectorKind :: Fixed => {
1550+ ( BackendRepr :: SimdVector { element, count } , dl. llvmlike_vector_align ( size) )
1551+ }
1552+ } ;
1553+ let size = size. align_to ( align. abi ) ;
1554+
1555+ Ok ( LayoutData {
1556+ variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
1557+ fields : FieldsShape :: Arbitrary { offsets : [ Size :: ZERO ] . into ( ) , memory_index : [ 0 ] . into ( ) } ,
1558+ backend_repr : repr,
1559+ largest_niche : elt. largest_niche ,
1560+ uninhabited : false ,
1561+ size,
1562+ align,
1563+ max_repr_align : None ,
1564+ unadjusted_abi_align : elt. align . abi ,
1565+ randomization_seed : elt. randomization_seed . wrapping_add ( Hash64 :: new ( count) ) ,
1566+ } )
1567+ }
0 commit comments