@@ -439,7 +439,9 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
439
439
return sampleprof_error::success;
440
440
}
441
441
442
- std::error_code SampleProfileReaderBinary::readFuncProfile () {
442
+ std::error_code
443
+ SampleProfileReaderBinary::readFuncProfile (const uint8_t *Start) {
444
+ Data = Start;
443
445
auto NumHeadSamples = readNumber<uint64_t >();
444
446
if (std::error_code EC = NumHeadSamples.getError ())
445
447
return EC;
@@ -461,7 +463,7 @@ std::error_code SampleProfileReaderBinary::readFuncProfile() {
461
463
462
464
std::error_code SampleProfileReaderBinary::read () {
463
465
while (!at_eof ()) {
464
- if (std::error_code EC = readFuncProfile ())
466
+ if (std::error_code EC = readFuncProfile (Data ))
465
467
return EC;
466
468
}
467
469
@@ -483,13 +485,15 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
483
485
return EC;
484
486
break ;
485
487
case SecLBRProfile:
486
- while (Data < Start + Size ) {
487
- if (std::error_code EC = readFuncProfile ())
488
- return EC;
489
- }
488
+ if (std::error_code EC = readFuncProfiles ())
489
+ return EC;
490
490
break ;
491
491
case SecProfileSymbolList:
492
- if (std::error_code EC = readProfileSymbolList (Size ))
492
+ if (std::error_code EC = readProfileSymbolList ())
493
+ return EC;
494
+ break ;
495
+ case SecFuncOffsetTable:
496
+ if (std::error_code EC = readFuncOffsetTable ())
493
497
return EC;
494
498
break ;
495
499
default :
@@ -498,15 +502,65 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
498
502
return sampleprof_error::success;
499
503
}
500
504
501
- std::error_code
502
- SampleProfileReaderExtBinary::readProfileSymbolList (uint64_t Size ) {
505
+ void SampleProfileReaderExtBinary::collectFuncsFrom (const Module &M) {
506
+ UseAllFuncs = false ;
507
+ FuncsToUse.clear ();
508
+ for (auto &F : M)
509
+ FuncsToUse.insert (FunctionSamples::getCanonicalFnName (F));
510
+ }
511
+
512
+ std::error_code SampleProfileReaderExtBinary::readFuncOffsetTable () {
513
+ auto Size = readNumber<uint64_t >();
514
+ if (std::error_code EC = Size .getError ())
515
+ return EC;
516
+
517
+ FuncOffsetTable.reserve (*Size );
518
+ for (uint32_t I = 0 ; I < *Size ; ++I) {
519
+ auto FName (readStringFromTable ());
520
+ if (std::error_code EC = FName.getError ())
521
+ return EC;
522
+
523
+ auto Offset = readNumber<uint64_t >();
524
+ if (std::error_code EC = Offset.getError ())
525
+ return EC;
526
+
527
+ FuncOffsetTable[*FName] = *Offset;
528
+ }
529
+ return sampleprof_error::success;
530
+ }
531
+
532
+ std::error_code SampleProfileReaderExtBinary::readFuncProfiles () {
533
+ const uint8_t *Start = Data;
534
+ if (UseAllFuncs) {
535
+ while (Data < End) {
536
+ if (std::error_code EC = readFuncProfile (Data))
537
+ return EC;
538
+ }
539
+ assert (Data == End && " More data is read than expected" );
540
+ return sampleprof_error::success;
541
+ }
542
+
543
+ for (auto Name : FuncsToUse) {
544
+ auto iter = FuncOffsetTable.find (Name);
545
+ if (iter == FuncOffsetTable.end ())
546
+ continue ;
547
+ const uint8_t *FuncProfileAddr = Start + iter->second ;
548
+ assert (FuncProfileAddr < End && " out of LBRProfile section" );
549
+ if (std::error_code EC = readFuncProfile (FuncProfileAddr))
550
+ return EC;
551
+ }
552
+ Data = End;
553
+ return sampleprof_error::success;
554
+ }
555
+
556
+ std::error_code SampleProfileReaderExtBinary::readProfileSymbolList () {
503
557
if (!ProfSymList)
504
558
ProfSymList = std::make_unique<ProfileSymbolList>();
505
559
506
- if (std::error_code EC = ProfSymList->read (Data, Size ))
560
+ if (std::error_code EC = ProfSymList->read (Data, End - Data ))
507
561
return EC;
508
562
509
- Data = Data + Size ;
563
+ Data = End ;
510
564
return sampleprof_error::success;
511
565
}
512
566
@@ -600,9 +654,9 @@ std::error_code SampleProfileReaderCompactBinary::read() {
600
654
601
655
for (auto Offset : OffsetsToUse) {
602
656
const uint8_t *SavedData = Data;
603
- Data = reinterpret_cast < const uint8_t *>(Buffer-> getBufferStart ()) +
604
- Offset;
605
- if (std::error_code EC = readFuncProfile ( ))
657
+ if (std::error_code EC = readFuncProfile (
658
+ reinterpret_cast < const uint8_t *>(Buffer-> getBufferStart ()) +
659
+ Offset ))
606
660
return EC;
607
661
Data = SavedData;
608
662
}
@@ -719,8 +773,16 @@ uint64_t SampleProfileReaderExtBinaryBase::getSectionSize(SecType Type) {
719
773
}
720
774
721
775
uint64_t SampleProfileReaderExtBinaryBase::getFileSize () {
722
- auto &LastEntry = SecHdrTable.back ();
723
- return LastEntry.Offset + LastEntry.Size ;
776
+ // Sections in SecHdrTable is not necessarily in the same order as
777
+ // sections in the profile because section like FuncOffsetTable needs
778
+ // to be written after section LBRProfile but needs to be read before
779
+ // section LBRProfile, so we cannot simply use the last entry in
780
+ // SecHdrTable to calculate the file size.
781
+ uint64_t FileSize = 0 ;
782
+ for (auto &Entry : SecHdrTable) {
783
+ FileSize = std::max (Entry.Offset + Entry.Size , FileSize);
784
+ }
785
+ return FileSize;
724
786
}
725
787
726
788
bool SampleProfileReaderExtBinaryBase::dumpSectionInfo (raw_ostream &OS) {
@@ -812,13 +874,11 @@ std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() {
812
874
return sampleprof_error::success;
813
875
}
814
876
815
- void SampleProfileReaderCompactBinary::collectFuncsToUse (const Module &M) {
877
+ void SampleProfileReaderCompactBinary::collectFuncsFrom (const Module &M) {
816
878
UseAllFuncs = false ;
817
879
FuncsToUse.clear ();
818
- for (auto &F : M) {
819
- StringRef CanonName = FunctionSamples::getCanonicalFnName (F);
820
- FuncsToUse.insert (CanonName);
821
- }
880
+ for (auto &F : M)
881
+ FuncsToUse.insert (FunctionSamples::getCanonicalFnName (F));
822
882
}
823
883
824
884
std::error_code SampleProfileReaderBinary::readSummaryEntry (
0 commit comments