Hi Richard,
Here is v5 following v4 [1], my ping [2], and your review [3, 4].
PR126348 occurs when SCC unification or prevailing-declaration
replacement redirects an instance's origin to another input's early
DIE, leaving the concrete instance and its children referring to
different input descriptions. v5 preserves the input DIE reference
independently of that tree replacement and uses it for late DWARF.
Beyond the changes outlined in [2], addressing your dref_queue comment
moved the capture point: 2/3 saves input DIE references at stream-in,
before unification, and 3/3 keeps sparse slot-to-DIE records on decl
states so that function bodies, read later or copied unread by WPA,
still resolve their origins to the input's DIEs. The non-test diff is
407 insertions and 68 deletions.
Addressing your review [3]:
- add_abstract_origin_attribute: 1/3 uses dwarf2out_die_ref_for_decl
for both lookups. The ordinary lookup is not dead: only FUNCTION_DECL
and BLOCK instances get saved references, while parameters and
automatic variables keep their input origin trees; it also covers
instances without a saved reference, as now documented in the comment.
- dref_queue and hash-map garbage: 2/3 queues pending origins alongside
dref_queue and truncates them together when an SCC is unified, so
only retained owners are registered. Temporary per-file slot records
hold DIE references rather than trees, and the late map is a
GTY((cache)) table (1/3).
- TREE_PUBLIC / DECL_EXTERNAL checks and 2nd-level coverage: that
writer-side fallback is removed. 2/3 resolves origins at stream-in
from the input's own DIE references, and 3/3 extends this to
decl-state slots used by function bodies. Test coverage: pr126348
covers the split clone and an LGEN-inlined instance, pr126348-2
covers nested inlined subroutines (the split part inlined at link
time into an LGEN-inlined copy), and pr126348-3 covers
prevailing-decl replacement. The nested compile-time inlining and
mixed -g1/-g cases were checked with the reproducers in PR126348
comment 5.
- LTO_minor_version: the bump is dropped.
The origin-pointer check from v4 is also removed (covered by
pr126348-3), and cloning/inlining now propagate only existing saved
references.
While testing corner cases for v5, several other late-DWARF issues
turned up; I filed them with reduced reproducers under meta-bug
PR128652 [5], with the 11 COMDAT cases from [2] tracked as PR128616
[6]. This series covers PR126348: split clones, single and nested LGEN
inlining, prevailing-declaration replacement, and mixed -g1/-g inputs.
On ten GCC source files (-O2 -g -gdwarf-5 -flto=1 -flto-partition=one,
456,633 DIEs per build, base bd921def14a4):
trunk v5
Parent/child origin mismatch edges 10,146 951
of which cross-CU 9,424 9
Duplicate-name candidates 9,920 791
These are structural candidates, not confirmed bug counts. The
mismatch rows count parent/child edges, including same-CU cases; [2]
counted affected concrete function/inline instances in a different
twelve-file workload. The nine remaining cross-CU edges belong to
three inline instances of gimple_call_set_lhs (PR128616); most
remaining same-CU candidates involve constructor/destructor clone
origin chains (PR128619). Same-CU edges rise from 722 to 942 because
instances that trunk redirected to another CU now show that chain
within their own CU.
Resource measurements across three interleaved runs per compiler,
with four concurrent LGEN jobs and one LTRANS partition:
Median WPA peak RSS 73,700 -> 74,428 KiB (+0.99%)
Median LTRANS peak RSS 241,588 -> 238,628 KiB (-1.23%)
Median compile + link 87.058 -> 87.440 seconds (+0.44%)
LGEN object size +0.04%
WPA object size +1.86%
WPA decls sections +128.5 KiB (+6.39%)
The LTRANS RSS decrease was consistent across these three runs,
but I have not investigated its cause. The final .text is identical.
Bootstrapped and regression-tested on x86_64-pc-linux-gnu for C, C++,
Fortran, Objective-C and Objective-C++, plus bootstrap-lto and the
C/C++ LTO testsuites, with no new regressions.
v5 keeps the PR126348 fix self-contained within the current model.
The remaining cases in PR128652 (such as merged COMDAT body selection
in PR128616 and local-static scoping in PR124864) need more than
per-instance origin references. Along the lines of your remark in [4]
about a different representation than the tree of abstract origins, I
have tested a prototype that separates the original slot-to-DIE mapping
from the slot-to-tree mapping used by optimization and carries those
slot-to-DIE mappings directly to late DWARF. Late DWARF then combines
that original information with the optimized result according to each
DIE's semantics. I plan to discuss this in a separate RFC.
OK for trunk?
Thanks,
Longjun
[1] https://gcc.gnu.org/pipermail/gcc-patches/2026-August/728966.html
[2] https://gcc.gnu.org/pipermail/gcc-patches/2026-October/733945.html
[3] https://gcc.gnu.org/pipermail/gcc-patches/2026-October/734018.html
[4] https://gcc.gnu.org/pipermail/gcc-patches/2026-October/734019.html
[5] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128652
[6] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128616
Longjun Luo (3):
dwarf2out: Prefer an instance's saved abstract origin [PR126348]
lto: Preserve input origins before SCC unification [PR126348]
lto: Preserve input DIE references in decl states [PR126348]
gcc/cgraphclones.cc | 2 +
gcc/debug.cc | 21 ++++-
gcc/debug.h | 32 ++++---
gcc/dwarf2out.cc | 106 +++++++++++++++++-------
gcc/lto-section-in.cc | 22 +++++
gcc/lto-section-out.cc | 2 +
gcc/lto-streamer-in.cc | 87 +++++++++++++++++--
gcc/lto-streamer-out.cc | 52 +++++++++++-
gcc/lto-streamer.h | 71 +++++++++++++++-
gcc/lto/lto-common.cc | 58 ++++++++++---
gcc/testsuite/g++.dg/lto/pr126348-2_0.C | 17 ++++
gcc/testsuite/g++.dg/lto/pr126348-2_1.C | 21 +++++
gcc/testsuite/g++.dg/lto/pr126348-2_2.C | 11 +++
gcc/testsuite/g++.dg/lto/pr126348-3.h | 28 +++++++
gcc/testsuite/g++.dg/lto/pr126348-3_0.C | 24 ++++++
gcc/testsuite/g++.dg/lto/pr126348-3_1.C | 27 ++++++
gcc/testsuite/g++.dg/lto/pr126348-3_2.C | 14 ++++
gcc/testsuite/g++.dg/lto/pr126348.h | 28 +++++++
gcc/testsuite/g++.dg/lto/pr126348_0.C | 27 ++++++
gcc/testsuite/g++.dg/lto/pr126348_1.C | 28 +++++++
gcc/testsuite/g++.dg/lto/pr126348_2.C | 14 ++++
gcc/tree-inline.cc | 3 +
gcc/tree-streamer-in.cc | 16 ++--
gcc/tree-streamer.h | 3 +-
24 files changed, 646 insertions(+), 68 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-2_0.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-2_1.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-2_2.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-3.h
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-3_0.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-3_1.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348-3_2.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348.h
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348_0.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348_1.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr126348_2.C
--
2.53.0