@@ -152,6 +152,7 @@ bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
152
152
return AddrSpace == Other.AddrSpace && BitWidth == Other.BitWidth &&
153
153
ABIAlign == Other.ABIAlign && PrefAlign == Other.PrefAlign &&
154
154
IndexBitWidth == Other.IndexBitWidth &&
155
+ SentinelValue == Other.SentinelValue &&
155
156
IsNonIntegral == Other.IsNonIntegral ;
156
157
}
157
158
@@ -206,9 +207,10 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
206
207
};
207
208
208
209
// Default pointer type specifications.
209
- constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = {
210
- // p0:64:64:64:64
211
- {0 , 64 , Align::Constant<8 >(), Align::Constant<8 >(), 64 , false },
210
+ const DataLayout::PointerSpec DefaultPointerSpecs[] = {
211
+ // p0:64:64:64:64:0
212
+ {0 , 64 , Align::Constant<8 >(), Align::Constant<8 >(), 64 , APInt (64 , 0 ),
213
+ false },
212
214
};
213
215
214
216
DataLayout::DataLayout ()
@@ -296,6 +298,22 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
296
298
return Error::success ();
297
299
}
298
300
301
+ static Error parseSentinelValue (StringRef Str, APInt &V) {
302
+ if (Str.empty ())
303
+ return createStringError (" sentinel value component cannot be empty" );
304
+ if (Str.size () != 1 )
305
+ return createStringError (" sentinel value component must be a '0' or 'f'" );
306
+ if (Str[0 ] == ' 0' ) {
307
+ V.clearAllBits ();
308
+ return Error::success ();
309
+ }
310
+ if (Str[0 ] == ' f' ) {
311
+ V.setAllBits ();
312
+ return Error::success ();
313
+ }
314
+ return createStringError (" sentinel value component must be a '0' or 'f'" );
315
+ }
316
+
299
317
// / Attempts to parse an alignment component of a specification.
300
318
// /
301
319
// / On success, returns the value converted to byte amount in \p Alignment.
@@ -409,13 +427,14 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
409
427
}
410
428
411
429
Error DataLayout::parsePointerSpec (StringRef Spec) {
412
- // p[<n>]:<size>:<abi>[:<pref>[:<idx>]]
430
+ // p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>] ]]
413
431
SmallVector<StringRef, 5 > Components;
414
432
assert (Spec.front () == ' p' );
415
433
Spec.drop_front ().split (Components, ' :' );
416
434
417
- if (Components.size () < 3 || Components.size () > 5 )
418
- return createSpecFormatError (" p[<n>]:<size>:<abi>[:<pref>[:<idx>]]" );
435
+ if (Components.size () < 3 || Components.size () > 6 )
436
+ return createSpecFormatError (
437
+ " p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]" );
419
438
420
439
// Address space. Optional, defaults to 0.
421
440
unsigned AddrSpace = 0 ;
@@ -454,8 +473,14 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
454
473
return createStringError (
455
474
" index size cannot be larger than the pointer size" );
456
475
476
+ APInt SentinelValue (BitWidth, 0 );
477
+ if (Components.size () > 5 ) {
478
+ if (Error Err = parseSentinelValue (Components[5 ], SentinelValue))
479
+ return Err;
480
+ }
481
+
457
482
setPointerSpec (AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
458
- false );
483
+ SentinelValue, /* IsNonIntegral= */ false );
459
484
return Error::success ();
460
485
}
461
486
@@ -631,7 +656,7 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
631
656
// the spec for AS0, and we then update that to mark it non-integral.
632
657
const PointerSpec &PS = getPointerSpec (AS);
633
658
setPointerSpec (AS, PS.BitWidth , PS.ABIAlign , PS.PrefAlign , PS.IndexBitWidth ,
634
- true );
659
+ PS. SentinelValue , /* IsNonIntegral= */ true );
635
660
}
636
661
637
662
return Error::success ();
@@ -679,16 +704,19 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const {
679
704
680
705
void DataLayout::setPointerSpec (uint32_t AddrSpace, uint32_t BitWidth,
681
706
Align ABIAlign, Align PrefAlign,
682
- uint32_t IndexBitWidth, bool IsNonIntegral) {
707
+ uint32_t IndexBitWidth, APInt SentinelValue,
708
+ bool IsNonIntegral) {
683
709
auto I = lower_bound (PointerSpecs, AddrSpace, LessPointerAddrSpace ());
684
710
if (I == PointerSpecs.end () || I->AddrSpace != AddrSpace) {
685
711
PointerSpecs.insert (I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
686
- IndexBitWidth, IsNonIntegral});
712
+ IndexBitWidth, SentinelValue,
713
+ IsNonIntegral});
687
714
} else {
688
715
I->BitWidth = BitWidth;
689
716
I->ABIAlign = ABIAlign;
690
717
I->PrefAlign = PrefAlign;
691
718
I->IndexBitWidth = IndexBitWidth;
719
+ I->SentinelValue = SentinelValue;
692
720
I->IsNonIntegral = IsNonIntegral;
693
721
}
694
722
}
@@ -1020,3 +1048,10 @@ Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
1020
1048
}
1021
1049
return Alignment;
1022
1050
}
1051
+
1052
+ APInt DataLayout::getSentinelPointerValue (unsigned AS) const {
1053
+ auto I = lower_bound (PointerSpecs, AS, LessPointerAddrSpace ());
1054
+ if (I != PointerSpecs.end () || I->AddrSpace == AS)
1055
+ return I->SentinelValue ;
1056
+ return PointerSpecs[0 ].SentinelValue ;
1057
+ }
0 commit comments