@@ -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 ();
@@ -227,6 +227,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
227227 LayoutMap = nullptr ;
228228 StringRepresentation = Other.StringRepresentation ;
229229 BigEndian = Other.BigEndian ;
230+ ByteWidth = Other.ByteWidth ;
230231 AllocaAddrSpace = Other.AllocaAddrSpace ;
231232 ProgramAddrSpace = Other.ProgramAddrSpace ;
232233 DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace ;
@@ -246,7 +247,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
246247
247248bool DataLayout::operator ==(const DataLayout &Other) const {
248249 // NOTE: StringRepresentation might differ, it is not canonicalized.
249- return BigEndian == Other.BigEndian &&
250+ return BigEndian == Other.BigEndian && ByteWidth == Other. ByteWidth &&
250251 AllocaAddrSpace == Other.AllocaAddrSpace &&
251252 ProgramAddrSpace == Other.ProgramAddrSpace &&
252253 DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
@@ -308,7 +309,7 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
308309// / - the value is not a multiple of the byte width;
309310// / - the value converted to byte amount is not not a power of two.
310311static Error parseAlignment (StringRef Str, Align &Alignment, StringRef Name,
311- bool AllowZero = false ) {
312+ unsigned ByteWidth, bool AllowZero = false ) {
312313 if (Str.empty ())
313314 return createStringError (Name + " alignment component cannot be empty" );
314315
@@ -323,7 +324,6 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
323324 return Error::success ();
324325 }
325326
326- constexpr unsigned ByteWidth = 8 ;
327327 if (Value % ByteWidth || !isPowerOf2_32 (Value / ByteWidth))
328328 return createStringError (
329329 Name + " alignment must be a power of two times the byte width" );
@@ -332,6 +332,36 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
332332 return Error::success ();
333333}
334334
335+ Error DataLayout::parseByteSpec (StringRef Spec) {
336+ // b:<size>
337+ assert (Spec.front () == ' b' );
338+ StringRef Rest = Spec.drop_front ();
339+ if (!Rest.consume_front (" :" ) || Rest.empty ())
340+ return createSpecFormatError (" b:<size>" );
341+
342+ if (Error Err = parseSize (Rest, ByteWidth))
343+ return Err;
344+
345+ if (ByteWidth != 8 && ByteWidth != 16 && ByteWidth != 32 )
346+ return createStringError (" unsupported byte width" );
347+
348+ // The default specs are for targets with 8-bit bytes. If the explicitly
349+ // specified byte width is different from 8, reset the default values.
350+ if (ByteWidth != 8 ) {
351+ // Byte-sized integers must be one byte aligned. It's hard to guess
352+ // reasonable defaults for other types, so just don't provide them
353+ // and expect the target to do it.
354+ IntSpecs.assign ({PrimitiveSpec{ByteWidth, Align (1 ), Align (1 )}});
355+ FloatSpecs.clear ();
356+ VectorSpecs.clear ();
357+ PointerSpecs.clear ();
358+ StructABIAlignment = Align (1 );
359+ StructPrefAlignment = Align (1 );
360+ }
361+
362+ return Error::success ();
363+ }
364+
335365Error DataLayout::parsePrimitiveSpec (StringRef Spec) {
336366 // [ifv]<size>:<abi>[:<pref>]
337367 SmallVector<StringRef, 3 > Components;
@@ -349,7 +379,7 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
349379
350380 // ABI alignment.
351381 Align ABIAlign;
352- if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" ))
382+ if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" , ByteWidth ))
353383 return Err;
354384
355385 if (Specifier == ' i' && BitWidth == 8 && ABIAlign != 1 )
@@ -358,7 +388,8 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
358388 // Preferred alignment. Optional, defaults to the ABI alignment.
359389 Align PrefAlign = ABIAlign;
360390 if (Components.size () > 2 )
361- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
391+ if (Error Err =
392+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
362393 return Err;
363394
364395 if (PrefAlign < ABIAlign)
@@ -389,14 +420,15 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
389420
390421 // ABI alignment. Required. Can be zero, meaning use one byte alignment.
391422 Align ABIAlign;
392- if (Error Err =
393- parseAlignment (Components[ 1 ], ABIAlign, " ABI " , /* AllowZero=*/ true ))
423+ if (Error Err = parseAlignment (Components[ 1 ], ABIAlign, " ABI " , ByteWidth,
424+ /* AllowZero=*/ true ))
394425 return Err;
395426
396427 // Preferred alignment. Optional, defaults to the ABI alignment.
397428 Align PrefAlign = ABIAlign;
398429 if (Components.size () > 2 )
399- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
430+ if (Error Err =
431+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
400432 return Err;
401433
402434 if (PrefAlign < ABIAlign)
@@ -430,14 +462,15 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
430462
431463 // ABI alignment. Required, cannot be zero.
432464 Align ABIAlign;
433- if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" ))
465+ if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" , ByteWidth ))
434466 return Err;
435467
436468 // Preferred alignment. Optional, defaults to the ABI alignment.
437469 // Cannot be zero.
438470 Align PrefAlign = ABIAlign;
439471 if (Components.size () > 3 )
440- if (Error Err = parseAlignment (Components[3 ], PrefAlign, " preferred" ))
472+ if (Error Err =
473+ parseAlignment (Components[3 ], PrefAlign, " preferred" , ByteWidth))
441474 return Err;
442475
443476 if (PrefAlign < ABIAlign)
@@ -521,7 +554,7 @@ Error DataLayout::parseSpecification(
521554 if (Rest.empty ())
522555 return createSpecFormatError (" S<size>" );
523556 Align Alignment;
524- if (Error Err = parseAlignment (Rest, Alignment, " stack natural" ))
557+ if (Error Err = parseAlignment (Rest, Alignment, " stack natural" , ByteWidth ))
525558 return Err;
526559 StackNaturalAlign = Alignment;
527560 break ;
@@ -544,7 +577,7 @@ Error DataLayout::parseSpecification(
544577 Twine (Type) + " '" );
545578 }
546579 Align Alignment;
547- if (Error Err = parseAlignment (Rest, Alignment, " ABI" ))
580+ if (Error Err = parseAlignment (Rest, Alignment, " ABI" , ByteWidth ))
548581 return Err;
549582 FunctionPtrAlign = Alignment;
550583 break ;
@@ -616,10 +649,25 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
616649
617650 // Split the data layout string into specifications separated by '-' and
618651 // parse each specification individually, updating internal data structures.
619- SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
620- for (StringRef Spec : split (LayoutString, ' -' )) {
652+ SmallVector<StringRef, 16 > Specs;
653+ LayoutString.split (Specs, ' -' );
654+
655+ // On the first pass, diagnose empty specifications and parse the byte
656+ // specification if there is one. The latter is necessary because other
657+ // specifications may need the byte width for validation and to convert
658+ // bit alignments to byte alignments.
659+ for (StringRef Spec : Specs) {
621660 if (Spec.empty ())
622661 return createStringError (" empty specification is not allowed" );
662+ if (Spec.front () == ' b' )
663+ if (Error Err = parseByteSpec (Spec))
664+ return Err;
665+ }
666+
667+ SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
668+ for (StringRef Spec : split (LayoutString, ' -' )) {
669+ if (Spec.front () == ' b' )
670+ continue ;
623671 if (Error Err = parseSpecification (Spec, NonIntegralAddressSpaces))
624672 return Err;
625673 }
@@ -667,6 +715,7 @@ void DataLayout::setPrimitiveSpec(char Specifier, uint32_t BitWidth,
667715
668716const DataLayout::PointerSpec &
669717DataLayout::getPointerSpec (uint32_t AddrSpace) const {
718+ assert (!PointerSpecs.empty () && " No pointer specs are defined" );
670719 if (AddrSpace != 0 ) {
671720 auto I = lower_bound (PointerSpecs, AddrSpace, LessPointerAddrSpace ());
672721 if (I != PointerSpecs.end () && I->AddrSpace == AddrSpace)
@@ -737,14 +786,13 @@ Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
737786}
738787
739788unsigned DataLayout::getPointerSize (unsigned AS) const {
740- return divideCeil (getPointerSpec (AS).BitWidth , 8 );
789+ return divideCeil (getPointerSpec (AS).BitWidth , ByteWidth );
741790}
742791
743792unsigned DataLayout::getMaxIndexSize () const {
744793 unsigned MaxIndexSize = 0 ;
745794 for (const PointerSpec &Spec : PointerSpecs)
746- MaxIndexSize =
747- std::max (MaxIndexSize, (unsigned )divideCeil (Spec.BitWidth , 8 ));
795+ MaxIndexSize = std::max (MaxIndexSize, divideCeil (Spec.BitWidth , ByteWidth));
748796
749797 return MaxIndexSize;
750798}
@@ -757,7 +805,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
757805}
758806
759807unsigned DataLayout::getIndexSize (unsigned AS) const {
760- return divideCeil (getPointerSpec (AS).IndexBitWidth , 8 );
808+ return divideCeil (getPointerSpec (AS).IndexBitWidth , ByteWidth );
761809}
762810
763811unsigned DataLayout::getIndexTypeSizeInBits (Type *Ty) const {
@@ -821,7 +869,7 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
821869 // approximation of reality, and if the user wanted something less
822870 // less conservative, they should have specified it explicitly in the data
823871 // layout.
824- return Align (PowerOf2Ceil (BitWidth / 8 ));
872+ return Align (PowerOf2Ceil (BitWidth / ByteWidth ));
825873 }
826874 case Type::FixedVectorTyID:
827875 case Type::ScalableVectorTyID: {
0 commit comments