@@ -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 ();
@@ -214,6 +214,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
214214 LayoutMap = nullptr ;
215215 StringRepresentation = Other.StringRepresentation ;
216216 BigEndian = Other.BigEndian ;
217+ ByteWidth = Other.ByteWidth ;
217218 AllocaAddrSpace = Other.AllocaAddrSpace ;
218219 ProgramAddrSpace = Other.ProgramAddrSpace ;
219220 DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace ;
@@ -233,7 +234,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
233234
234235bool DataLayout::operator ==(const DataLayout &Other) const {
235236 // NOTE: StringRepresentation might differ, it is not canonicalized.
236- return BigEndian == Other.BigEndian &&
237+ return BigEndian == Other.BigEndian && ByteWidth == Other. ByteWidth &&
237238 AllocaAddrSpace == Other.AllocaAddrSpace &&
238239 ProgramAddrSpace == Other.ProgramAddrSpace &&
239240 DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
@@ -295,7 +296,7 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
295296// / - the value is not a multiple of the byte width;
296297// / - the value converted to byte amount is not not a power of two.
297298static Error parseAlignment (StringRef Str, Align &Alignment, StringRef Name,
298- bool AllowZero = false ) {
299+ unsigned ByteWidth, bool AllowZero = false ) {
299300 if (Str.empty ())
300301 return createStringError (Name + " alignment component cannot be empty" );
301302
@@ -310,7 +311,6 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
310311 return Error::success ();
311312 }
312313
313- constexpr unsigned ByteWidth = 8 ;
314314 if (Value % ByteWidth || !isPowerOf2_32 (Value / ByteWidth))
315315 return createStringError (
316316 Name + " alignment must be a power of two times the byte width" );
@@ -319,6 +319,36 @@ static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
319319 return Error::success ();
320320}
321321
322+ Error DataLayout::parseByteSpec (StringRef Spec) {
323+ // b:<size>
324+ assert (Spec.front () == ' b' );
325+ StringRef Rest = Spec.drop_front ();
326+ if (!Rest.consume_front (" :" ) || Rest.empty ())
327+ return createSpecFormatError (" b:<size>" );
328+
329+ if (Error Err = parseSize (Rest, ByteWidth))
330+ return Err;
331+
332+ if (ByteWidth != 8 && ByteWidth != 16 && ByteWidth != 32 )
333+ return createStringError (" unsupported byte width" );
334+
335+ // The default specs are for targets with 8-bit bytes. If the explicitly
336+ // specified byte width is different from 8, reset the default values.
337+ if (ByteWidth != 8 ) {
338+ // Byte-sized integers must be one byte aligned. It's hard to guess
339+ // reasonable defaults for other types, so just don't provide them
340+ // and expect the target to do it.
341+ IntSpecs.assign ({PrimitiveSpec{ByteWidth, Align (1 ), Align (1 )}});
342+ FloatSpecs.clear ();
343+ VectorSpecs.clear ();
344+ PointerSpecs.clear ();
345+ StructABIAlignment = Align (1 );
346+ StructPrefAlignment = Align (1 );
347+ }
348+
349+ return Error::success ();
350+ }
351+
322352Error DataLayout::parsePrimitiveSpec (StringRef Spec) {
323353 // [ifv]<size>:<abi>[:<pref>]
324354 SmallVector<StringRef, 3 > Components;
@@ -336,7 +366,7 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
336366
337367 // ABI alignment.
338368 Align ABIAlign;
339- if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" ))
369+ if (Error Err = parseAlignment (Components[1 ], ABIAlign, " ABI" , ByteWidth ))
340370 return Err;
341371
342372 if (Specifier == ' i' && BitWidth == 8 && ABIAlign != 1 )
@@ -345,7 +375,8 @@ Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
345375 // Preferred alignment. Optional, defaults to the ABI alignment.
346376 Align PrefAlign = ABIAlign;
347377 if (Components.size () > 2 )
348- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
378+ if (Error Err =
379+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
349380 return Err;
350381
351382 if (PrefAlign < ABIAlign)
@@ -376,14 +407,15 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
376407
377408 // ABI alignment. Required. Can be zero, meaning use one byte alignment.
378409 Align ABIAlign;
379- if (Error Err =
380- parseAlignment (Components[ 1 ], ABIAlign, " ABI " , /* AllowZero=*/ true ))
410+ if (Error Err = parseAlignment (Components[ 1 ], ABIAlign, " ABI " , ByteWidth,
411+ /* AllowZero=*/ true ))
381412 return Err;
382413
383414 // Preferred alignment. Optional, defaults to the ABI alignment.
384415 Align PrefAlign = ABIAlign;
385416 if (Components.size () > 2 )
386- if (Error Err = parseAlignment (Components[2 ], PrefAlign, " preferred" ))
417+ if (Error Err =
418+ parseAlignment (Components[2 ], PrefAlign, " preferred" , ByteWidth))
387419 return Err;
388420
389421 if (PrefAlign < ABIAlign)
@@ -437,14 +469,15 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
437469
438470 // ABI alignment. Required, cannot be zero.
439471 Align ABIAlign;
440- if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" ))
472+ if (Error Err = parseAlignment (Components[2 ], ABIAlign, " ABI" , ByteWidth ))
441473 return Err;
442474
443475 // Preferred alignment. Optional, defaults to the ABI alignment.
444476 // Cannot be zero.
445477 Align PrefAlign = ABIAlign;
446478 if (Components.size () > 3 )
447- if (Error Err = parseAlignment (Components[3 ], PrefAlign, " preferred" ))
479+ if (Error Err =
480+ parseAlignment (Components[3 ], PrefAlign, " preferred" , ByteWidth))
448481 return Err;
449482
450483 if (PrefAlign < ABIAlign)
@@ -528,7 +561,7 @@ Error DataLayout::parseSpecification(
528561 if (Rest.empty ())
529562 return createSpecFormatError (" S<size>" );
530563 Align Alignment;
531- if (Error Err = parseAlignment (Rest, Alignment, " stack natural" ))
564+ if (Error Err = parseAlignment (Rest, Alignment, " stack natural" , ByteWidth ))
532565 return Err;
533566 StackNaturalAlign = Alignment;
534567 break ;
@@ -551,7 +584,7 @@ Error DataLayout::parseSpecification(
551584 Twine (Type) + " '" );
552585 }
553586 Align Alignment;
554- if (Error Err = parseAlignment (Rest, Alignment, " ABI" ))
587+ if (Error Err = parseAlignment (Rest, Alignment, " ABI" , ByteWidth ))
555588 return Err;
556589 FunctionPtrAlign = Alignment;
557590 break ;
@@ -623,10 +656,25 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
623656
624657 // Split the data layout string into specifications separated by '-' and
625658 // parse each specification individually, updating internal data structures.
626- SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
627- for (StringRef Spec : split (LayoutString, ' -' )) {
659+ SmallVector<StringRef, 16 > Specs;
660+ LayoutString.split (Specs, ' -' );
661+
662+ // On the first pass, diagnose empty specifications and parse the byte
663+ // specification if there is one. The latter is necessary because other
664+ // specifications may need the byte width for validation and to convert
665+ // bit alignments to byte alignments.
666+ for (StringRef Spec : Specs) {
628667 if (Spec.empty ())
629668 return createStringError (" empty specification is not allowed" );
669+ if (Spec.front () == ' b' )
670+ if (Error Err = parseByteSpec (Spec))
671+ return Err;
672+ }
673+
674+ SmallVector<unsigned , 8 > NonIntegralAddressSpaces;
675+ for (StringRef Spec : split (LayoutString, ' -' )) {
676+ if (Spec.front () == ' b' )
677+ continue ;
630678 if (Error Err = parseSpecification (Spec, NonIntegralAddressSpaces))
631679 return Err;
632680 }
@@ -674,6 +722,7 @@ void DataLayout::setPrimitiveSpec(char Specifier, uint32_t BitWidth,
674722
675723const DataLayout::PointerSpec &
676724DataLayout::getPointerSpec (uint32_t AddrSpace) const {
725+ assert (!PointerSpecs.empty () && " No pointer specs are defined" );
677726 if (AddrSpace != 0 ) {
678727 auto I = lower_bound (PointerSpecs, AddrSpace, LessPointerAddrSpace ());
679728 if (I != PointerSpecs.end () && I->AddrSpace == AddrSpace)
@@ -752,7 +801,7 @@ Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
752801}
753802
754803unsigned DataLayout::getPointerSize (unsigned AS) const {
755- return divideCeil (getPointerSpec (AS).BitWidth , 8 );
804+ return divideCeil (getPointerSpec (AS).BitWidth , ByteWidth );
756805}
757806
758807unsigned DataLayout::getPointerTypeSizeInBits (Type *Ty) const {
@@ -763,7 +812,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
763812}
764813
765814unsigned DataLayout::getIndexSize (unsigned AS) const {
766- return divideCeil (getPointerSpec (AS).IndexBitWidth , 8 );
815+ return divideCeil (getPointerSpec (AS).IndexBitWidth , ByteWidth );
767816}
768817
769818unsigned DataLayout::getIndexTypeSizeInBits (Type *Ty) const {
@@ -827,7 +876,7 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
827876 // approximation of reality, and if the user wanted something less
828877 // less conservative, they should have specified it explicitly in the data
829878 // layout.
830- return Align (PowerOf2Ceil (BitWidth / 8 ));
879+ return Align (PowerOf2Ceil (BitWidth / ByteWidth ));
831880 }
832881 case Type::FixedVectorTyID:
833882 case Type::ScalableVectorTyID: {
0 commit comments