Skip to content

Commit 7f2f829

Browse files
jmorsetstellar
authored andcommitted
Revert sharing subprograms across CUs
This patch is a revert of e08f205. In that patch, DW_TAG_subprograms were permitted to be referenced across CU boundaries, to improve stack trace construction using call site information. Unfortunately, as documented in PR48790, the way that subprograms are "owned" by dwarf units is sufficiently complicated that subprograms end up in unexpected units, invalidating cross-unit references. There's no obvious way to easily fix this, and several attempts have failed. Revert this to ensure correct DWARF is always emitted. Three tests change in addition to the reversion, but they're all very light alterations. Differential Revision: https://reviews.llvm.org/D107076 (cherry picked from commit d4ce9e4) Signed-off-by: Jeremy Morse <[email protected]> Conflicts: llvm/test/DebugInfo/X86/convert-loclist.ll
1 parent ae5ed5d commit 7f2f829

14 files changed

+135
-375
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,7 @@ DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
11621162
}
11631163

11641164
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
1165-
DIE *CalleeDIE,
1165+
const DISubprogram *CalleeSP,
11661166
bool IsTail,
11671167
const MCSymbol *PCAddr,
11681168
const MCSymbol *CallAddr,
@@ -1176,7 +1176,8 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
11761176
addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
11771177
MachineLocation(CallReg));
11781178
} else {
1179-
assert(CalleeDIE && "No DIE for call site entry origin");
1179+
DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
1180+
assert(CalleeDIE && "Could not create DIE for call site entry origin");
11801181
addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
11811182
*CalleeDIE);
11821183
}

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,14 @@ class DwarfCompileUnit final : public DwarfUnit {
249249
dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;
250250

251251
/// Construct a call site entry DIE describing a call within \p Scope to a
252-
/// callee described by \p CalleeDIE.
253-
/// \p CalleeDIE is a declaration or definition subprogram DIE for the callee.
254-
/// For indirect calls \p CalleeDIE is set to nullptr.
252+
/// callee described by \p CalleeSP.
255253
/// \p IsTail specifies whether the call is a tail call.
256254
/// \p PCAddr points to the PC value after the call instruction.
257255
/// \p CallAddr points to the PC value at the call instruction (or is null).
258256
/// \p CallReg is a register location for an indirect call. For direct calls
259257
/// the \p CallReg is set to 0.
260-
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, DIE *CalleeDIE, bool IsTail,
261-
const MCSymbol *PCAddr,
258+
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
259+
bool IsTail, const MCSymbol *PCAddr,
262260
const MCSymbol *CallAddr, unsigned CallReg);
263261
/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
264262
/// were collected by the \ref collectCallSiteParameters.

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -587,14 +587,6 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
587587
}
588588
}
589589

590-
DIE &DwarfDebug::constructSubprogramDefinitionDIE(const DISubprogram *SP) {
591-
DICompileUnit *Unit = SP->getUnit();
592-
assert(SP->isDefinition() && "Subprogram not a definition");
593-
assert(Unit && "Subprogram definition without parent unit");
594-
auto &CU = getOrCreateDwarfCompileUnit(Unit);
595-
return *CU.getOrCreateSubprogramDIE(SP);
596-
}
597-
598590
/// Represents a parameter whose call site value can be described by applying a
599591
/// debug expression to a register in the forwarded register worklist.
600592
struct FwdRegParamInfo {
@@ -945,7 +937,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
945937
continue;
946938

947939
unsigned CallReg = 0;
948-
DIE *CalleeDIE = nullptr;
940+
const DISubprogram *CalleeSP = nullptr;
949941
const Function *CalleeDecl = nullptr;
950942
if (CalleeOp.isReg()) {
951943
CallReg = CalleeOp.getReg();
@@ -955,19 +947,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
955947
CalleeDecl = dyn_cast<Function>(CalleeOp.getGlobal());
956948
if (!CalleeDecl || !CalleeDecl->getSubprogram())
957949
continue;
958-
const DISubprogram *CalleeSP = CalleeDecl->getSubprogram();
959-
960-
if (CalleeSP->isDefinition()) {
961-
// Ensure that a subprogram DIE for the callee is available in the
962-
// appropriate CU.
963-
CalleeDIE = &constructSubprogramDefinitionDIE(CalleeSP);
964-
} else {
965-
// Create the declaration DIE if it is missing. This is required to
966-
// support compilation of old bitcode with an incomplete list of
967-
// retained metadata.
968-
CalleeDIE = CU.getOrCreateSubprogramDIE(CalleeSP);
969-
}
970-
assert(CalleeDIE && "Must have a DIE for the callee");
950+
CalleeSP = CalleeDecl->getSubprogram();
971951
}
972952

973953
// TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
@@ -1004,7 +984,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
1004984
<< (IsTail ? " [IsTail]" : "") << "\n");
1005985

1006986
DIE &CallSiteDIE = CU.constructCallSiteEntryDIE(
1007-
ScopeDIE, CalleeDIE, IsTail, PCAddr, CallAddr, CallReg);
987+
ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg);
1008988

1009989
// Optionally emit call-site-param debug info.
1010990
if (emitDebugEntryValues()) {
@@ -1121,6 +1101,11 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
11211101
NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
11221102
}
11231103

1104+
// Create DIEs for function declarations used for call site debug info.
1105+
for (auto Scope : DIUnit->getRetainedTypes())
1106+
if (auto *SP = dyn_cast_or_null<DISubprogram>(Scope))
1107+
NewCU.getOrCreateSubprogramDIE(SP);
1108+
11241109
CUMap.insert({DIUnit, &NewCU});
11251110
CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
11261111
return NewCU;

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,6 @@ class DwarfDebug : public DebugHandlerBase {
471471
/// Construct a DIE for this abstract scope.
472472
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
473473

474-
/// Construct a DIE for the subprogram definition \p SP and return it.
475-
DIE &constructSubprogramDefinitionDIE(const DISubprogram *SP);
476-
477474
/// Construct DIEs for call site entries describing the calls in \p MF.
478475
void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU,
479476
DIE &ScopeDIE, const MachineFunction &MF);

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,18 @@ int64_t DwarfUnit::getDefaultLowerBound() const {
186186

187187
/// Check whether the DIE for this MDNode can be shared across CUs.
188188
bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {
189-
// When the MDNode can be part of the type system (this includes subprogram
190-
// declarations *and* subprogram definitions, even local definitions), the
191-
// DIE must be shared across CUs.
189+
// When the MDNode can be part of the type system, the DIE can be shared
190+
// across CUs.
192191
// Combining type units and cross-CU DIE sharing is lower value (since
193192
// cross-CU DIE sharing is used in LTO and removes type redundancy at that
194193
// level already) but may be implementable for some value in projects
195194
// building multiple independent libraries with LTO and then linking those
196195
// together.
197196
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
198197
return false;
199-
return (isa<DIType>(D) || isa<DISubprogram>(D)) && !DD->generateTypeUnits();
198+
return (isa<DIType>(D) ||
199+
(isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&
200+
!DD->generateTypeUnits();
200201
}
201202

202203
DIE *DwarfUnit::getDIE(const DINode *D) const {

llvm/test/DebugInfo/AArch64/unretained-declaration-subprogram.ll

Lines changed: 0 additions & 44 deletions
This file was deleted.

llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param.mir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
# After w0 is clobbered, we should get an indirect parameter entry value for "f".
2323

24+
# DWARF-LABEL: DW_TAG_subprogram
25+
# DWARF: DW_AT_name ("baz")
26+
27+
# DWARF-LABEL: DW_TAG_subprogram
2428
# DWARF-LABEL: DW_TAG_formal_parameter
2529
# DWARF-NEXT: DW_AT_location
2630
# DWARF-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg0 W0+0

llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-orr-moves.mir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ body: |
159159
...
160160

161161
# CHECK: DW_TAG_GNU_call_site
162-
# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "call_int")
162+
# CHECK-NEXT: DW_AT_abstract_origin (0x0000002a "call_int")
163163
#
164164
# CHECK: DW_TAG_GNU_call_site_parameter
165165
# CHECK-NEXT: DW_AT_location (DW_OP_reg0 W0)
@@ -205,7 +205,7 @@ body: |
205205
...
206206

207207
# CHECK: DW_TAG_GNU_call_site
208-
# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "call_long")
208+
# CHECK-NEXT: DW_AT_abstract_origin (0x0000003e "call_long")
209209
#
210210
# CHECK: DW_TAG_GNU_call_site_parameter
211211
# CHECK-NEXT: DW_AT_location (DW_OP_reg0 W0)
@@ -265,7 +265,7 @@ body: |
265265
...
266266

267267
# CHECK: DW_TAG_GNU_call_site
268-
# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "call_int_int")
268+
# CHECK-NEXT: DW_AT_abstract_origin (0x00000052 "call_int_int")
269269
#
270270
# CHECK: DW_TAG_GNU_call_site_parameter
271271
# CHECK-NEXT: DW_AT_location (DW_OP_reg0 W0)

llvm/test/DebugInfo/MIR/X86/callsite-stack-value.mir

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# RUN: llc -start-after=livedebugvalues -mtriple=x86_64-apple-darwin -o - %s -filetype=obj \
22
# RUN: -emit-call-site-info | llvm-dwarfdump - | FileCheck %s -implicit-check-not=call_site_parameter
33

4-
# CHECK: DW_TAG_formal_parameter
5-
# CHECK-NEXT: DW_AT_location (DW_OP_reg17 XMM0)
4+
# CHECK-LABEL: DW_TAG_subprogram
5+
# CHECK: DW_AT_name ("f")
6+
# CHECK-LABEL: DW_TAG_subprogram
7+
# CHECK: DW_AT_name ("g")
8+
# CHECK: DW_TAG_formal_parameter
9+
# CHECK-NEXT: DW_AT_location (DW_OP_reg17 XMM0)
610

711
# struct S {
812
# float w;

llvm/test/DebugInfo/MIR/X86/debug-call-site-param.mir

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,17 @@
3939
# CHECK-GNU-NEXT: DW_AT_location (DW_OP_reg8 R8)
4040
# CHECK-GNU-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+3)
4141

42-
# CHECK-DWARF5: DW_TAG_call_site
43-
# CHECK-DWARF5: DW_AT_call_origin ([[getValue_SP:.*]])
42+
# CHECK-DWARF5: [[getValue_SP:.*]]: DW_TAG_subprogram
43+
# CHECK-DWARF5-NEXT: DW_AT_name ("getVal")
4444

45+
# CHECK-DWARF5: [[foo_SP:.*]]: DW_TAG_subprogram
46+
# CHECK-DWARF5-NEXT: DW_AT_name ("foo")
47+
48+
# CHECK-DWARF5: DW_TAG_call_site
49+
# CHECK-DWARF5: DW_AT_call_origin ([[getValue_SP]])
50+
#
4551
# CHECK-DWARF5: DW_TAG_call_site
46-
# CHECK-DWARF5: DW_AT_call_origin ([[foo_SP:.*]])
52+
# CHECK-DWARF5: DW_AT_call_origin ([[foo_SP]])
4753
# CHECK-DWARF5: DW_AT_call_return_pc {{.*}}
4854
# CHECK-DWARF5-EMPTY:
4955
# CHECK-DWARF5: DW_TAG_call_site_parameter
@@ -65,12 +71,6 @@
6571
# CHECK-DWARF5-NEXT: DW_AT_location (DW_OP_reg8 R8)
6672
# CHECK-DWARF5-NEXT: DW_AT_call_value (DW_OP_breg14 R14+3)
6773

68-
# CHECK-DWARF5: [[getValue_SP]]: DW_TAG_subprogram
69-
# CHECK-DWARF5-NEXT: DW_AT_name ("getVal")
70-
71-
# CHECK-DWARF5: [[foo_SP]]: DW_TAG_subprogram
72-
# CHECK-DWARF5-NEXT: DW_AT_name ("foo")
73-
7474
--- |
7575
; ModuleID = 'test.c'
7676
source_filename = "test.c"

0 commit comments

Comments
 (0)