@@ -329,6 +329,12 @@ static cl::opt<bool> KeepARanges(
329
329
" keep or generate .debug_aranges section if .gdb_index is written" ),
330
330
cl::Hidden, cl::cat(BoltCategory));
331
331
332
+ static cl::opt<unsigned >
333
+ DebugThreadCount (" debug-thread-count" ,
334
+ cl::desc (" specifies thread count for the multithreading "
335
+ " for updating DWO debug info" ),
336
+ cl::init(1 ), cl::cat(BoltCategory));
337
+
332
338
static cl::opt<std::string> DwarfOutputPath (
333
339
" dwarf-output-path" ,
334
340
cl::desc (" Path to where .dwo files will be written out to." ), cl::init(" " ),
@@ -475,8 +481,8 @@ static void emitDWOBuilder(const std::string &DWOName,
475
481
DWARFUnit &SplitCU, DWARFUnit &CU,
476
482
DebugLocWriter &LocWriter,
477
483
DebugStrOffsetsWriter &StrOffstsWriter,
478
- DebugStrWriter &StrWriter,
479
- GDBIndex &GDBIndexSection ) {
484
+ DebugStrWriter &StrWriter, GDBIndex &GDBIndexSection,
485
+ DebugRangesSectionWriter &TempRangesSectionWriter ) {
480
486
// Populate debug_info and debug_abbrev for current dwo into StringRef.
481
487
DWODIEBuilder.generateAbbrevs ();
482
488
DWODIEBuilder.finish ();
@@ -532,7 +538,7 @@ static void emitDWOBuilder(const std::string &DWOName,
532
538
OverriddenSections[Kind] = Contents;
533
539
}
534
540
Rewriter.writeDWOFiles (CU, OverriddenSections, DWOName, LocWriter,
535
- StrOffstsWriter, StrWriter);
541
+ StrOffstsWriter, StrWriter, TempRangesSectionWriter );
536
542
}
537
543
538
544
using DWARFUnitVec = std::vector<DWARFUnit *>;
@@ -646,7 +652,6 @@ void DWARFRewriter::updateDebugInfo() {
646
652
*StrWriter);
647
653
GDBIndex GDBIndexSection (BC);
648
654
auto processSplitCU = [&](DWARFUnit &Unit, DWARFUnit &SplitCU,
649
- DIEBuilder &DIEBlder,
650
655
DebugRangesSectionWriter &TempRangesSectionWriter,
651
656
DebugAddrWriter &AddressWriter,
652
657
const std::string &DWOName,
@@ -669,7 +674,7 @@ void DWARFRewriter::updateDebugInfo() {
669
674
670
675
emitDWOBuilder (DWOName, DWODIEBuilder, *this , SplitCU, Unit,
671
676
DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter,
672
- GDBIndexSection);
677
+ GDBIndexSection, TempRangesSectionWriter );
673
678
};
674
679
auto processMainBinaryCU = [&](DWARFUnit &Unit, DIEBuilder &DIEBlder) {
675
680
std::optional<DWARFUnit *> SplitCU;
@@ -716,9 +721,13 @@ void DWARFRewriter::updateDebugInfo() {
716
721
finalizeTypeSections (DIEBlder, *Streamer, GDBIndexSection);
717
722
718
723
CUPartitionVector PartVec = partitionCUs (*BC.DwCtx );
724
+ const unsigned int ThreadCount =
725
+ std::min (opts::DebugThreadCount, opts::ThreadCount);
719
726
for (std::vector<DWARFUnit *> &Vec : PartVec) {
720
727
DIEBlder.buildCompileUnits (Vec);
721
728
llvm::SmallVector<std::unique_ptr<DIEBuilder>, 72 > DWODIEBuildersByCU;
729
+ ThreadPoolInterface &ThreadPool =
730
+ ParallelUtilities::getThreadPool (ThreadCount);
722
731
for (DWARFUnit *CU : DIEBlder.getProcessedCUs ()) {
723
732
createRangeLocListAddressWriters (*CU);
724
733
std::optional<DWARFUnit *> SplitCU;
@@ -729,9 +738,9 @@ void DWARFRewriter::updateDebugInfo() {
729
738
continue ;
730
739
DebugAddrWriter &AddressWriter =
731
740
*AddressWritersByCU[CU->getOffset ()].get ();
732
- DebugRangesSectionWriter * TempRangesSectionWriter =
733
- CU->getVersion () >= 5 ? RangeListsWritersByCU[*DWOId].get ()
734
- : LegacyRangesWritersByCU[*DWOId].get ();
741
+ DebugRangesSectionWriter & TempRangesSectionWriter =
742
+ CU->getVersion () >= 5 ? * RangeListsWritersByCU[*DWOId].get ()
743
+ : * LegacyRangesWritersByCU[*DWOId].get ();
735
744
std::optional<std::string> DwarfOutputPath =
736
745
opts::DwarfOutputPath.empty ()
737
746
? std::nullopt
@@ -744,9 +753,17 @@ void DWARFRewriter::updateDebugInfo() {
744
753
*DWODIEBuildersByCU.emplace_back (std::move (DWODIEBuilderPtr)).get ();
745
754
if (CU->getVersion () >= 5 )
746
755
StrOffstsWriter->finalizeSection (*CU, DIEBlder);
747
- processSplitCU (*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter,
748
- AddressWriter, DWOName, DwarfOutputPath, DWODIEBuilder);
756
+ // Important to capture CU and SplitCU by value here, otherwise when the
757
+ // thread is executed at some point after the current iteration of the
758
+ // loop, dereferencing CU/SplitCU in the call to processSplitCU means it
759
+ // will dereference a different variable than the one intended, causing a
760
+ // seg fault.
761
+ ThreadPool.async ([&, DwarfOutputPath, DWOName, CU, SplitCU] {
762
+ processSplitCU (*CU, **SplitCU, TempRangesSectionWriter, AddressWriter,
763
+ DWOName, DwarfOutputPath, DWODIEBuilder);
764
+ });
749
765
}
766
+ ThreadPool.wait ();
750
767
for (std::unique_ptr<DIEBuilder> &DWODIEBuilderPtr : DWODIEBuildersByCU)
751
768
DWODIEBuilderPtr->updateDebugNamesTable ();
752
769
for (DWARFUnit *CU : DIEBlder.getProcessedCUs ())
@@ -1807,7 +1824,8 @@ std::optional<StringRef> updateDebugData(
1807
1824
void DWARFRewriter::writeDWOFiles (
1808
1825
DWARFUnit &CU, const OverriddenSectionsMap &OverridenSections,
1809
1826
const std::string &DWOName, DebugLocWriter &LocWriter,
1810
- DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter) {
1827
+ DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter,
1828
+ DebugRangesSectionWriter &TempRangesSectionWriter) {
1811
1829
// Setup DWP code once.
1812
1830
DWARFContext *DWOCtx = BC.getDWOContext ();
1813
1831
const uint64_t DWOId = *CU.getDWOId ();
@@ -1854,9 +1872,8 @@ void DWARFRewriter::writeDWOFiles(
1854
1872
1855
1873
DebugRangeListsSectionWriter *RangeListssWriter = nullptr ;
1856
1874
if (CU.getVersion () == 5 ) {
1857
- assert (RangeListsWritersByCU.count (DWOId) != 0 &&
1858
- " No RangeListsWriter for DWO ID." );
1859
- RangeListssWriter = RangeListsWritersByCU[DWOId].get ();
1875
+ RangeListssWriter =
1876
+ llvm::dyn_cast<DebugRangeListsSectionWriter>(&TempRangesSectionWriter);
1860
1877
1861
1878
// Handling .debug_rnglists.dwo separately. The original .o/.dwo might not
1862
1879
// have .debug_rnglists so won't be part of the loop below.
0 commit comments