Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 76c1d56

Browse files
committed
Reduce the memory footprint of dsymutil. (NFC)
This (partially) fixes a regression introduced by https://reviews.llvm.org/D43945 / r327399, which parallelized DwarfLinker. This patch avoids parsing and allocating the memory for all input DIEs up front and instead only allocates them in the concurrent loop in the AnalyzeLambda. At the end of the loop the memory from the LinkContext is cleared again. This reduces the peak memory needed to link the debug info of a non-modular build of the Swift compiler by >3GB. rdar://problem/43444464 Differential Revision: https://reviews.llvm.org/D51078 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340650 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9a40255 commit 76c1d56

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

tools/dsymutil/DwarfLinker.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,7 @@ class DwarfLinker {
15701570

15711571
/// Clear compile units and ranges.
15721572
void Clear() {
1573+
DwarfContext.reset(nullptr);
15731574
CompileUnits.clear();
15741575
Ranges.clear();
15751576
}
@@ -1605,7 +1606,7 @@ class DwarfLinker {
16051606
OffsetsStringPool &OffsetsStringPool,
16061607
UniquingStringPool &UniquingStringPoolStringPool,
16071608
DeclContextTree &ODRContexts, unsigned &UnitID,
1608-
unsigned Indent = 0);
1609+
unsigned Indent = 0, bool Quiet = false);
16091610

16101611
/// Recursively add the debug info in this clang module .pcm
16111612
/// file (and all the modules imported by it in a bottom-up fashion)
@@ -1616,7 +1617,7 @@ class DwarfLinker {
16161617
RangesTy &Ranges, OffsetsStringPool &OffsetsStringPool,
16171618
UniquingStringPool &UniquingStringPool,
16181619
DeclContextTree &ODRContexts, unsigned &UnitID,
1619-
unsigned Indent = 0);
1620+
unsigned Indent = 0, bool Quiet = false);
16201621

16211622
/// Flags passed to DwarfLinker::lookForDIEsToKeep
16221623
enum TravesalFlags {
@@ -3900,7 +3901,7 @@ bool DwarfLinker::registerModuleReference(
39003901
const DWARFDie &CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
39013902
const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
39023903
UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
3903-
unsigned &UnitID, unsigned Indent) {
3904+
unsigned &UnitID, unsigned Indent, bool Quiet) {
39043905
std::string PCMfile = dwarf::toString(
39053906
CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
39063907
if (PCMfile.empty())
@@ -3912,11 +3913,12 @@ bool DwarfLinker::registerModuleReference(
39123913

39133914
std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
39143915
if (Name.empty()) {
3915-
reportWarning("Anonymous module skeleton CU for " + PCMfile, DMO);
3916+
if (!Quiet)
3917+
reportWarning("Anonymous module skeleton CU for " + PCMfile, DMO);
39163918
return true;
39173919
}
39183920

3919-
if (Options.Verbose) {
3921+
if (!Quiet && Options.Verbose) {
39203922
outs().indent(Indent);
39213923
outs() << "Found clang module reference " << PCMfile;
39223924
}
@@ -3926,24 +3928,24 @@ bool DwarfLinker::registerModuleReference(
39263928
// FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
39273929
// fixed in clang, only warn about DWO_id mismatches in verbose mode.
39283930
// ASTFileSignatures will change randomly when a module is rebuilt.
3929-
if (Options.Verbose && (Cached->second != DwoId))
3931+
if (!Quiet && Options.Verbose && (Cached->second != DwoId))
39303932
reportWarning(Twine("hash mismatch: this object file was built against a "
39313933
"different version of the module ") +
39323934
PCMfile,
39333935
DMO);
3934-
if (Options.Verbose)
3936+
if (!Quiet && Options.Verbose)
39353937
outs() << " [cached].\n";
39363938
return true;
39373939
}
3938-
if (Options.Verbose)
3940+
if (!Quiet && Options.Verbose)
39393941
outs() << " ...\n";
39403942

39413943
// Cyclic dependencies are disallowed by Clang, but we still
39423944
// shouldn't run into an infinite loop, so mark it as processed now.
39433945
ClangModules.insert({PCMfile, DwoId});
39443946
if (Error E = loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap, DMO,
39453947
Ranges, StringPool, UniquingStringPool,
3946-
ODRContexts, UnitID, Indent + 2)) {
3948+
ODRContexts, UnitID, Indent + 2, Quiet)) {
39473949
consumeError(std::move(E));
39483950
return false;
39493951
}
@@ -3965,14 +3967,12 @@ DwarfLinker::loadObject(BinaryHolder &BinaryHolder, const DebugMapObject &Obj,
39653967
return ErrOrObj;
39663968
}
39673969

3968-
Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
3969-
StringRef ModuleName, uint64_t DwoId,
3970-
DebugMap &ModuleMap,
3971-
const DebugMapObject &DMO, RangesTy &Ranges,
3972-
OffsetsStringPool &StringPool,
3973-
UniquingStringPool &UniquingStringPool,
3974-
DeclContextTree &ODRContexts,
3975-
unsigned &UnitID, unsigned Indent) {
3970+
Error DwarfLinker::loadClangModule(
3971+
StringRef Filename, StringRef ModulePath, StringRef ModuleName,
3972+
uint64_t DwoId, DebugMap &ModuleMap, const DebugMapObject &DMO,
3973+
RangesTy &Ranges, OffsetsStringPool &StringPool,
3974+
UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
3975+
unsigned &UnitID, unsigned Indent, bool Quiet) {
39763976
SmallString<80> Path(Options.PrependPath);
39773977
if (sys::path::is_relative(Filename))
39783978
sys::path::append(Path, ModulePath, Filename);
@@ -4030,7 +4030,7 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
40304030
auto CUDie = CU->getUnitDIE(false);
40314031
if (!registerModuleReference(CUDie, *CU, ModuleMap, DMO, Ranges, StringPool,
40324032
UniquingStringPool, ODRContexts, UnitID,
4033-
Indent)) {
4033+
Indent, Quiet)) {
40344034
if (Unit) {
40354035
std::string Err =
40364036
(Filename +
@@ -4044,7 +4044,7 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
40444044
// ASTFileSignatures will change randomly when a module is rebuilt.
40454045
uint64_t PCMDwoId = getDwoId(CUDie, *CU);
40464046
if (PCMDwoId != DwoId) {
4047-
if (Options.Verbose)
4047+
if (!Quiet && Options.Verbose)
40484048
reportWarning(
40494049
Twine("hash mismatch: this object file was built against a "
40504050
"different version of the module ") +
@@ -4066,7 +4066,7 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
40664066
}
40674067
if (!Unit->getOrigUnit().getUnitDIE().hasChildren())
40684068
return Error::success();
4069-
if (Options.Verbose) {
4069+
if (!Quiet && Options.Verbose) {
40704070
outs().indent(Indent);
40714071
outs() << "cloning .debug_info from " << Filename << "\n";
40724072
}
@@ -4289,12 +4289,10 @@ bool DwarfLinker::link(const DebugMap &Map) {
42894289
CUDie.dump(outs(), 0, DumpOpts);
42904290
}
42914291

4292-
if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
4293-
!registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO,
4294-
LinkContext.Ranges, OffsetsStringPool,
4295-
UniquingStringPool, ODRContexts, UnitID)) {
4296-
LinkContext.CompileUnits.push_back(llvm::make_unique<CompileUnit>(
4297-
*CU, UnitID++, !Options.NoODR && !Options.Update, ""));
4292+
if (CUDie && !LLVM_UNLIKELY(Options.Update)) {
4293+
registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO,
4294+
LinkContext.Ranges, OffsetsStringPool,
4295+
UniquingStringPool, ODRContexts, UnitID);
42984296
maybeUpdateMaxDwarfVersion(CU->getVersion());
42994297
}
43004298
}
@@ -4316,13 +4314,31 @@ bool DwarfLinker::link(const DebugMap &Map) {
43164314
for (unsigned i = 0, e = NumObjects; i != e; ++i) {
43174315
auto &LinkContext = ObjectContexts[i];
43184316

4319-
if (!LinkContext.ObjectFile) {
4317+
if (!LinkContext.ObjectFile || !LinkContext.DwarfContext) {
43204318
std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
43214319
ProcessedFiles.set(i);
43224320
ProcessedFilesConditionVariable.notify_one();
43234321
continue;
43244322
}
43254323

4324+
for (const auto &CU : LinkContext.DwarfContext->compile_units()) {
4325+
// The !registerModuleReference() condition effectively skips
4326+
// over fully resolved skeleton units. This second pass of
4327+
// registerModuleReferences doesn't do any new work, but it
4328+
// will collect top-level errors, which are suppressed. Module
4329+
// warnings were already displayed in the first iteration.
4330+
bool Quiet = true;
4331+
auto CUDie = CU->getUnitDIE(false);
4332+
if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
4333+
!registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO,
4334+
LinkContext.Ranges, OffsetsStringPool,
4335+
UniquingStringPool, ODRContexts, UnitID,
4336+
Quiet)) {
4337+
LinkContext.CompileUnits.push_back(llvm::make_unique<CompileUnit>(
4338+
*CU, UnitID++, !Options.NoODR && !Options.Update, ""));
4339+
}
4340+
}
4341+
43264342
// Now build the DIE parent links that we will use during the next phase.
43274343
for (auto &CurrentUnit : LinkContext.CompileUnits)
43284344
analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,

0 commit comments

Comments
 (0)