@@ -408,16 +408,21 @@ impl TargetDataLayout {
408
408
}
409
409
}
410
410
411
+ /// psABI-mandated alignment for a vector type, if any
411
412
#[ inline]
412
- pub fn vector_align ( & self , vec_size : Size ) -> AbiAndPrefAlign {
413
- for & ( size, align) in & self . vector_align {
414
- if size == vec_size {
415
- return align;
416
- }
417
- }
418
- // Default to natural alignment, which is what LLVM does.
419
- // That is, use the size, rounded up to a power of 2.
420
- AbiAndPrefAlign :: new ( Align :: from_bytes ( vec_size. bytes ( ) . next_power_of_two ( ) ) . unwrap ( ) )
413
+ fn cabi_vector_align ( & self , vec_size : Size ) -> Option < AbiAndPrefAlign > {
414
+ self . vector_align
415
+ . iter ( )
416
+ . find ( |( size, _align) | * size == vec_size)
417
+ . map ( |( _size, align) | * align)
418
+ }
419
+
420
+ /// an alignment resembling the one LLVM would pick for a vector
421
+ #[ inline]
422
+ pub fn llvmlike_vector_align ( & self , vec_size : Size ) -> AbiAndPrefAlign {
423
+ self . cabi_vector_align ( vec_size) . unwrap_or ( AbiAndPrefAlign :: new (
424
+ Align :: from_bytes ( vec_size. bytes ( ) . next_power_of_two ( ) ) . unwrap ( ) ,
425
+ ) )
421
426
}
422
427
}
423
428
@@ -810,20 +815,19 @@ impl Align {
810
815
self . bits ( ) . try_into ( ) . unwrap ( )
811
816
}
812
817
813
- /// Computes the best alignment possible for the given offset
814
- /// (the largest power of two that the offset is a multiple of).
818
+ /// Obtain the greatest factor of `size` that is an alignment
819
+ /// (the largest power of two the Size is a multiple of).
815
820
///
816
- /// N.B., for an offset of `0`, this happens to return `2^64`.
821
+ /// Note that all numbers are factors of 0
817
822
#[ inline]
818
- pub fn max_for_offset ( offset : Size ) -> Align {
819
- Align { pow2 : offset . bytes ( ) . trailing_zeros ( ) as u8 }
823
+ pub fn max_aligned_factor ( size : Size ) -> Align {
824
+ Align { pow2 : size . bytes ( ) . trailing_zeros ( ) as u8 }
820
825
}
821
826
822
- /// Lower the alignment, if necessary, such that the given offset
823
- /// is aligned to it (the offset is a multiple of the alignment).
827
+ /// Reduces Align to an aligned factor of `size`.
824
828
#[ inline]
825
- pub fn restrict_for_offset ( self , offset : Size ) -> Align {
826
- self . min ( Align :: max_for_offset ( offset ) )
829
+ pub fn restrict_for_offset ( self , size : Size ) -> Align {
830
+ self . min ( Align :: max_aligned_factor ( size ) )
827
831
}
828
832
}
829
833
@@ -1455,37 +1459,38 @@ impl BackendRepr {
1455
1459
matches ! ( * self , BackendRepr :: Scalar ( s) if s. is_bool( ) )
1456
1460
}
1457
1461
1458
- /// Returns the fixed alignment of this ABI, if any is mandated.
1459
- pub fn inherent_align < C : HasDataLayout > ( & self , cx : & C ) -> Option < AbiAndPrefAlign > {
1460
- Some ( match * self {
1461
- BackendRepr :: Scalar ( s ) => s . align ( cx ) ,
1462
- BackendRepr :: ScalarPair ( s1 , s2 ) => s1 . align ( cx ) . max ( s2 . align ( cx ) ) ,
1463
- BackendRepr :: Vector { element , count } => {
1464
- cx . data_layout ( ) . vector_align ( element . size ( cx) * count )
1465
- }
1466
- BackendRepr :: Memory { .. } => return None ,
1467
- } )
1462
+ /// The psABI alignment for a `Scalar` or `ScalarPair`
1463
+ ///
1464
+ /// `None` for other variants.
1465
+ pub fn scalar_align < C : HasDataLayout > ( & self , cx : & C ) -> Option < Align > {
1466
+ match * self {
1467
+ BackendRepr :: Scalar ( s ) => Some ( s . align ( cx ) . abi ) ,
1468
+ BackendRepr :: ScalarPair ( s1 , s2 ) => Some ( s1 . align ( cx ) . max ( s2 . align ( cx) ) . abi ) ,
1469
+ // The align of a Vector can vary in surprising ways
1470
+ BackendRepr :: Vector { .. } | BackendRepr :: Memory { .. } => None ,
1471
+ }
1468
1472
}
1469
1473
1470
- /// Returns the fixed size of this ABI, if any is mandated.
1471
- pub fn inherent_size < C : HasDataLayout > ( & self , cx : & C ) -> Option < Size > {
1472
- Some ( match * self {
1473
- BackendRepr :: Scalar ( s) => {
1474
- // No padding in scalars.
1475
- s. size ( cx)
1476
- }
1474
+ /// The psABI size for a `Scalar` or `ScalarPair`
1475
+ ///
1476
+ /// `None` for other variants
1477
+ pub fn scalar_size < C : HasDataLayout > ( & self , cx : & C ) -> Option < Size > {
1478
+ match * self {
1479
+ // No padding in scalars.
1480
+ BackendRepr :: Scalar ( s) => Some ( s. size ( cx) ) ,
1481
+ // May have some padding between the pair.
1477
1482
BackendRepr :: ScalarPair ( s1, s2) => {
1478
- // May have some padding between the pair.
1479
1483
let field2_offset = s1. size ( cx) . align_to ( s2. align ( cx) . abi ) ;
1480
- ( field2_offset + s2. size ( cx) ) . align_to ( self . inherent_align ( cx) ?. abi )
1484
+ let size = ( field2_offset + s2. size ( cx) ) . align_to (
1485
+ self . scalar_align ( cx)
1486
+ // We absolutely must have an answer here or everything is FUBAR.
1487
+ . unwrap ( ) ,
1488
+ ) ;
1489
+ Some ( size)
1481
1490
}
1482
- BackendRepr :: Vector { element, count } => {
1483
- // No padding in vectors, except possibly for trailing padding
1484
- // to make the size a multiple of align (e.g. for vectors of size 3).
1485
- ( element. size ( cx) * count) . align_to ( self . inherent_align ( cx) ?. abi )
1486
- }
1487
- BackendRepr :: Memory { .. } => return None ,
1488
- } )
1491
+ // The size of a Vector can vary in surprising ways
1492
+ BackendRepr :: Vector { .. } | BackendRepr :: Memory { .. } => None ,
1493
+ }
1489
1494
}
1490
1495
1491
1496
/// Discard validity range information and allow undef.
0 commit comments