@@ -46,7 +46,7 @@ using namespace llvm;
4646// ===----------------------------------------------------------------------===//
4747
4848StructLayout::StructLayout (StructType *ST, const DataLayout &DL)
49- : StructSize(TypeSize::getFixed(0 )) {
49+ : StructSize(TypeSize::getFixed(0 )), ByteWidth(DL.getByteWidth()) {
5050 assert (!ST->isOpaque () && " Cannot get layout of opaque structs" );
5151 IsPadded = false ;
5252 NumElements = ST->getNumElements ();
@@ -226,6 +226,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
226226 LayoutMap = nullptr ;
227227 StringRepresentation = Other.StringRepresentation ;
228228 BigEndian = Other.BigEndian ;
229+ ByteWidth = Other.ByteWidth ;
229230 AllocaAddrSpace = Other.AllocaAddrSpace ;
230231 ProgramAddrSpace = Other.ProgramAddrSpace ;
231232 DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace ;
@@ -245,7 +246,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
245246
246247bool DataLayout::operator ==(const DataLayout &Other) const {
247248 // NOTE: StringRepresentation might differ, it is not canonicalized.
248- return BigEndian == Other.BigEndian &&
249+ return BigEndian == Other.BigEndian && ByteWidth == Other. ByteWidth &&
249250 AllocaAddrSpace == Other.AllocaAddrSpace &&
250251 ProgramAddrSpace == Other.ProgramAddrSpace &&
251252 DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
@@ -307,7 +308,7 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
307308// / - the value is not a multiple of the byte width;
308309// / - the value converted to byte amount is not not a power of two.
309310static Error parseAlignment (StringRef Str, Align &Alignment, StringRef Name,
310- bool AllowZero = false ) {
311+ unsigned ByteWidth, bool AllowZero = false ) {
311312 if (Str.empty ())
312313 return createStringError (Name + " alignment component cannot be empty" );
313314
@@ -322,7 +323,6 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
322323 return Error::success ();
323324 }
324325
325- constexpr unsigned ByteWidth = 8 ;
326326 if (Value % ByteWidth || !isPowerOf2_32 (Value / ByteWidth))
327327 return createStringError (
328328 Name + " alignment must be a power of two times the byte width" );
@@ -331,6 +331,36 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
331331 return Error::success ();
332332}
333333
334+ Error DataLayout::parseByteSpec (StringRef Spec) {
335+ // b:<size>
336+ assert (Spec.front () == ' b' );
337+ StringRef Rest = Spec.drop_front ();
338+ if (!Rest.consume_front (" :" ) || Rest.empty ())
339+ return createSpecFormatError (" b:<size>" );
340+
341+ if (Error Err = parseSize (Rest, ByteWidth))
342+ return Err;
343+
344+ if (ByteWidth != 8 && ByteWidth != 16 && ByteWidth != 32 )
345+ return createStringError (" unsupported byte width" );
346+
347+ // The default specs are for targets with 8-bit bytes. If the explicitly
348+ // specified byte width is different from 8, reset the default values.
349+ if (ByteWidth != 8 ) {
350+ // Byte-sized integers must be one byte aligned. It's hard to guess
351+ // reasonable defaults for other types, so just don't provide them
352+ // and expect the target to do it.
353+ IntSpecs.assign ({PrimitiveSpec{ByteWidth, Align (1 ), Align (1 )}});
354+ FloatSpecs.clear ();
355+ VectorSpecs.clear ();
356+ PointerSpecs.clear ();
357+ StructABIAlignment = Align (1 );
358+ StructPrefAlignment = Align (1 );
359+ }
360+
361+ return Error::success ();
362+ }
363+
334364Error DataLayout::parsePrimitiveSpec (StringRef Spec) {
335365 // [ifv]<size>:<abi>[:<pref>]
336366 SmallVector<StringRef, 3 > Components;
@@ -348,7 +378,7 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
348378
349379 // ABI alignment.
350380 Align ABIAlign;
351- if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" ))
381+ if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" , ByteWidth ))
352382 return Err;
353383
354384 if (Specifier == ' i' && BitWidth == 8 && ABIAlign != 1 )
@@ -357,7 +387,8 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
357387 // Preferred alignment. Optional, defaults to the ABI alignment.
358388 Align PrefAlign = ABIAlign;
359389 if (Components.size () > 2 )
360- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
390+ if (Error Err =
391+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
361392 return Err;
362393
363394 if (PrefAlign < ABIAlign)
@@ -388,14 +419,15 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
388419
389420 // ABI alignment. Required. Can be zero, meaning use one byte alignment.
390421 Align ABIAlign;
391- if (Error Err =
392- parseAlignment (Components[ 1 ], ABIAlign, " ABI " , /* AllowZero=*/ true ))
422+ if (Error Err = parseAlignment (Components[ 1 ], ABIAlign, " ABI " , ByteWidth,
423+ /* AllowZero=*/ true ))
393424 return Err;
394425
395426 // Preferred alignment. Optional, defaults to the ABI alignment.
396427 Align PrefAlign = ABIAlign;
397428 if (Components.size () > 2 )
398- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
429+ if (Error Err =
430+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
399431 return Err;
400432
401433 if (PrefAlign < ABIAlign)
@@ -429,14 +461,15 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
429461
430462 // ABI alignment. Required, cannot be zero.
431463 Align ABIAlign;
432- if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" ))
464+ if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" , ByteWidth ))
433465 return Err;
434466
435467 // Preferred alignment. Optional, defaults to the ABI alignment.
436468 // Cannot be zero.
437469 Align PrefAlign = ABIAlign;
438470 if (Components.size () > 3 )
439- if (Error Err = parseAlignment (Components[3 ], PrefAlign, " preferred" ))
471+ if (Error Err =
472+ parseAlignment (Components[3 ], PrefAlign, " preferred" , ByteWidth))
440473 return Err;
441474
442475 if (PrefAlign < ABIAlign)
@@ -520,7 +553,7 @@ Error DataLayout::parseSpecification(
520553 if (Rest.empty ())
521554 return createSpecFormatError (" S<size>" );
522555 Align Alignment;
523- if (Error Err = parseAlignment (Rest, Alignment, " stack natural" ))
556+ if (Error Err = parseAlignment (Rest, Alignment, " stack natural" , ByteWidth ))
524557 return Err;
525558 StackNaturalAlign = Alignment;
526559 break ;
@@ -543,7 +576,7 @@ Error DataLayout::parseSpecification(
543576 Twine (Type) + " '" );
544577 }
545578 Align Alignment;
546- if (Error Err = parseAlignment (Rest, Alignment, " ABI" ))
579+ if (Error Err = parseAlignment (Rest, Alignment, " ABI" , ByteWidth ))
547580 return Err;
548581 FunctionPtrAlign = Alignment;
549582 break ;
@@ -615,10 +648,25 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
615648
616649 // Split the data layout string into specifications separated by '-' and
617650 // parse each specification individually, updating internal data structures.
618- SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
619- for (StringRef Spec : split (LayoutString, ' -' )) {
651+ SmallVector<StringRef, 16 > Specs;
652+ LayoutString.split (Specs, ' -' );
653+
654+ // On the first pass, diagnose empty specifications and parse the byte
655+ // specification if there is one. The latter is necessary because other
656+ // specifications may need the byte width for validation and to convert
657+ // bit alignments to byte alignments.
658+ for (StringRef Spec : Specs) {
620659 if (Spec.empty ())
621660 return createStringError (" empty specification is not allowed" );
661+ if (Spec.front () == ' b' )
662+ if (Error Err = parseByteSpec (Spec))
663+ return Err;
664+ }
665+
666+ SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
667+ for (StringRef Spec : split (LayoutString, ' -' )) {
668+ if (Spec.front () == ' b' )
669+ continue ;
622670 if (Error Err = parseSpecification (Spec, NonIntegralAddressSpaces))
623671 return Err;
624672 }
@@ -666,6 +714,7 @@ void DataLayout::setPrimitiveSpec(char Specifier, uint32_t BitWidth,
666714
667715const DataLayout::PointerSpec &
668716DataLayout::getPointerSpec (uint32_t AddrSpace) const {
717+ assert (!PointerSpecs.empty () && " No pointer specs are defined" );
669718 if (AddrSpace != 0 ) {
670719 auto I = lower_bound (PointerSpecs, AddrSpace, LessPointerAddrSpace ());
671720 if (I != PointerSpecs.end () && I->AddrSpace == AddrSpace)
@@ -736,7 +785,7 @@ Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
736785}
737786
738787unsigned DataLayout::getPointerSize (unsigned AS) const {
739- return divideCeil (getPointerSpec (AS).BitWidth , 8 );
788+ return divideCeil (getPointerSpec (AS).BitWidth , ByteWidth );
740789}
741790
742791unsigned DataLayout::getPointerTypeSizeInBits (Type *Ty) const {
@@ -747,7 +796,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
747796}
748797
749798unsigned DataLayout::getIndexSize (unsigned AS) const {
750- return divideCeil (getPointerSpec (AS).IndexBitWidth , 8 );
799+ return divideCeil (getPointerSpec (AS).IndexBitWidth , ByteWidth );
751800}
752801
753802unsigned DataLayout::getIndexTypeSizeInBits (Type *Ty) const {
@@ -811,7 +860,7 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
811860 // approximation of reality, and if the user wanted something less
812861 // less conservative, they should have specified it explicitly in the data
813862 // layout.
814- return Align (PowerOf2Ceil (BitWidth / 8 ));
863+ return Align (PowerOf2Ceil (BitWidth / ByteWidth ));
815864 }
816865 case Type::FixedVectorTyID:
817866 case Type::ScalableVectorTyID: {
0 commit comments