[llvm] [DebugInfo] Add DWARFUnit::clearDWO() (PR #214899)
Rafael Auler via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 14:53:00 PDT 2026
https://github.com/rafaelauler updated https://github.com/llvm/llvm-project/pull/214899
>From 56085f9db55022a7eace22a3c1ebf7e1f877f39d Mon Sep 17 00:00:00 2001
From: Rafael Auler <rafaelauler at fb.com>
Date: Thu, 30 Jul 2026 18:45:01 -0700
Subject: [PATCH 1/3] [DebugInfo] Add DWARFUnit::clearDWO()
Add DWARFUnit::clearDWO() so a skeleton unit can drop the DWO context
it owns without being destroyed itself. Also add DWARFUnit::hasDWO()
to answer if that skeleton CU is currently caching a DWO context, so
users can easily look it up.
For example, BOLT opened a DWARFContext for every .dwo during
readDebugInfo and kept them all alive until teardown. On large
split-DWARF targets that is tens of GiB held
resident. clearDWO()/hasDWO() expose to users DWARFUnit's caching
capacity, allowing them to spontaneously drop the cache/look it
up/re-load it for memory management.
---
llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index bc5a0eb7c044f..593d0efc81568 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -461,6 +461,16 @@ class LLVM_ABI DWARFUnit {
: getUnitDIE(ExtractUnitDIEOnly);
}
+ /// Return the split unit this skeleton unit currently owns, or null if its
+ /// DWO context is not open.
+ DWARFUnit *getDWO() const { return DWO.get(); }
+
+ /// Release the DWO context owned by this skeleton unit, freeing the memory
+ /// held by its DWARFContext and parsed unit vector. This is safe to call once
+ /// the split-unit debug info has been fully processed; a subsequent
+ /// parseDWO() will transparently re-open it on demand.
+ void clearDWO() { DWO.reset(); }
+
const char *getCompilationDir();
std::optional<uint64_t> getDWOId() {
extractDIEsIfNeeded(/*CUDieOnly*/ true);
>From 24a22b03366fd39acee9797c0d1d3c93c09076ea Mon Sep 17 00:00:00 2001
From: Rafael Auler <rafaelauler at fb.com>
Date: Wed, 12 Aug 2026 17:24:01 -0700
Subject: [PATCH 2/3] Add use case for clearDWO in llvm-dwarfdump
---
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 22 +++++++++++++++-----
llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 9 ++++++++
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 70ce257a5804a..570620575cd0e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1021,8 +1021,12 @@ void DWARFContext::dump(
auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
OS << '\n' << Name << " contents:\n";
- if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
- for (const auto &U : Units) {
+ std::optional<uint64_t> DumpOffset = DumpOffsets[DIDT_ID_DebugInfo];
+ for (const auto &U : Units) {
+ // For dumping of DWOs, remember if unit is already holding its context in
+ // memory
+ const bool HadDWO = U->getDWO();
+ if (DumpOffset) {
U->getDIEForOffset(*DumpOffset)
.dump(OS, 0, DumpOpts.noImplicitRecursion());
DWARFDie CUDie = U->getUnitDIE(false);
@@ -1032,10 +1036,18 @@ void DWARFContext::dump(
->getDIEForOffset(*DumpOffset)
.dump(OS, 0, DumpOpts.noImplicitRecursion());
}
- }
- else
- for (const auto &U : Units)
+ } else {
U->dump(OS, DumpOpts);
+ }
+ // If our dump caused a new context for the non-skeleton unit in a DWO to
+ // be freshly opened, release it now. We won't re-use it. This avoids
+ // holding a lot of unnecessary anon memory while streaming through
+ // multiple DWOs (OTOH DWP is shared ctx, so better not to drop it
+ // otherwise it will be immediately reopened by the next non-skeleton CU).
+ const DWARFUnit *DWO = U->getDWO();
+ if (!HadDWO && DWO && !DWO->getContext().isDWP())
+ U->clearDWO();
+ }
};
if ((DumpType & DIDT_DebugInfo)) {
if (Explicit || getNumCompileUnits())
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 4d7fc7e3108bf..41f9b1dc88284 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -492,11 +492,20 @@ static void filterByName(
filterDieNames(CU.get());
if (DumpNonSkeleton) {
// If we have split DWARF, then recurse down into the .dwo files as well.
+ // Matching DIEs are printed as they are found and nothing here outlives
+ // them, so the split unit can be released instead of keeping every .dwo
+ // context resident until the end of the search.
+ const bool HadDWO = CU->getDWO();
DWARFDie CUDie = CU->getUnitDIE(false);
DWARFDie CUNonSkeletonDie = CU->getNonSkeletonUnitDIE(false);
// If we have a DWO file, we need to search it as well
if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie)
filterDieNames(CUNonSkeletonDie.getDwarfUnit());
+ const DWARFUnit *DWO = CU->getDWO();
+ // Don't release a DWP context -- it is the same for every non-skeleton CU
+ // and we benefit from keeping it resident to avoid the re-parse.
+ if (!HadDWO && DWO && !DWO->getContext().isDWP())
+ CU->clearDWO();
}
}
}
>From 0f54f2ecb3d0685bbaad3b463b6bbfb3e86c1349 Mon Sep 17 00:00:00 2001
From: Rafael Auler <rafaelauler at fb.com>
Date: Fri, 14 Aug 2026 14:52:24 -0700
Subject: [PATCH 3/3] Drop const in local
---
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 570620575cd0e..3cbfb0959e5f1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1025,7 +1025,7 @@ void DWARFContext::dump(
for (const auto &U : Units) {
// For dumping of DWOs, remember if unit is already holding its context in
// memory
- const bool HadDWO = U->getDWO();
+ bool HadDWO = U->getDWO();
if (DumpOffset) {
U->getDIEForOffset(*DumpOffset)
.dump(OS, 0, DumpOpts.noImplicitRecursion());
More information about the llvm-commits
mailing list