@@ -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 ();
@@ -225,6 +225,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
225225 LayoutMap = nullptr ;
226226 StringRepresentation = Other.StringRepresentation ;
227227 BigEndian = Other.BigEndian ;
228+ ByteWidth = Other.ByteWidth ;
228229 AllocaAddrSpace = Other.AllocaAddrSpace ;
229230 ProgramAddrSpace = Other.ProgramAddrSpace ;
230231 DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace ;
@@ -246,7 +247,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
246247bool DataLayout::operator ==(const DataLayout &Other) const {
247248 // NOTE: StringRepresentation might differ, it is not canonicalized.
248249 // FIXME: NonIntegralAddressSpaces isn't compared.
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)
@@ -519,7 +552,7 @@ Error DataLayout::parseSpecification(StringRef Spec) {
519552 if (Rest.empty ())
520553 return createSpecFormatError (" S<size>" );
521554 Align Alignment;
522- if (Error Err = parseAlignment (Rest, Alignment, " stack natural" ))
555+ if (Error Err = parseAlignment (Rest, Alignment, " stack natural" , ByteWidth ))
523556 return Err;
524557 StackNaturalAlign = Alignment;
525558 break ;
@@ -542,7 +575,7 @@ Error DataLayout::parseSpecification(StringRef Spec) {
542575 Twine (Type) + " '" );
543576 }
544577 Align Alignment;
545- if (Error Err = parseAlignment (Rest, Alignment, " ABI" ))
578+ if (Error Err = parseAlignment (Rest, Alignment, " ABI" , ByteWidth ))
546579 return Err;
547580 FunctionPtrAlign = Alignment;
548581 break ;
@@ -614,9 +647,24 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
614647
615648 // Split the data layout string into specifications separated by '-' and
616649 // parse each specification individually, updating internal data structures.
617- for (StringRef Spec : split (LayoutString, ' -' )) {
650+ SmallVector<StringRef, 16 > Specs;
651+ LayoutString.split (Specs, ' -' );
652+
653+ // On the first pass, diagnose empty specifications and parse the byte
654+ // specification if there is one. The latter is necessary because other
655+ // specifications may need the byte width for validation and to convert
656+ // bit alignments to byte alignments.
657+ for (StringRef Spec : Specs) {
618658 if (Spec.empty ())
619659 return createStringError (" empty specification is not allowed" );
660+ if (Spec.front () == ' b' )
661+ if (Error Err = parseByteSpec (Spec))
662+ return Err;
663+ }
664+
665+ for (StringRef Spec : split (LayoutString, ' -' )) {
666+ if (Spec.front () == ' b' )
667+ continue ;
620668 if (Error Err = parseSpecification (Spec))
621669 return Err;
622670 }
@@ -654,6 +702,7 @@ void DataLayout::setPrimitiveSpec(char Specifier, uint32_t BitWidth,
654702
655703const DataLayout::PointerSpec &
656704DataLayout::getPointerSpec (uint32_t AddrSpace) const {
705+ assert (!PointerSpecs.empty () && " No pointer specs are defined" );
657706 if (AddrSpace != 0 ) {
658707 auto I = lower_bound (PointerSpecs, AddrSpace, LessPointerAddrSpace ());
659708 if (I != PointerSpecs.end () && I->AddrSpace == AddrSpace)
@@ -723,14 +772,13 @@ Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
723772}
724773
725774unsigned DataLayout::getPointerSize (unsigned AS) const {
726- return divideCeil (getPointerSpec (AS).BitWidth , 8 );
775+ return divideCeil (getPointerSpec (AS).BitWidth , ByteWidth );
727776}
728777
729778unsigned DataLayout::getMaxIndexSize () const {
730779 unsigned MaxIndexSize = 0 ;
731780 for (const PointerSpec &Spec : PointerSpecs)
732- MaxIndexSize =
733- std::max (MaxIndexSize, (unsigned )divideCeil (Spec.BitWidth , 8 ));
781+ MaxIndexSize = std::max (MaxIndexSize, divideCeil (Spec.BitWidth , ByteWidth));
734782
735783 return MaxIndexSize;
736784}
@@ -743,7 +791,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
743791}
744792
745793unsigned DataLayout::getIndexSize (unsigned AS) const {
746- return divideCeil (getPointerSpec (AS).IndexBitWidth , 8 );
794+ return divideCeil (getPointerSpec (AS).IndexBitWidth , ByteWidth );
747795}
748796
749797unsigned DataLayout::getIndexTypeSizeInBits (Type *Ty) const {
@@ -807,7 +855,7 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
807855 // approximation of reality, and if the user wanted something less
808856 // less conservative, they should have specified it explicitly in the data
809857 // layout.
810- return Align (PowerOf2Ceil (BitWidth / 8 ));
858+ return Align (PowerOf2Ceil (getTypeStoreSize (Ty). getFixedValue () ));
811859 }
812860 case Type::FixedVectorTyID:
813861 case Type::ScalableVectorTyID: {
0 commit comments