-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DebugInfo] Emit skeleton to avoid mismatching inlining flags #153568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-debuginfo Author: Qiu Chaofan (ecnelises) ChangesThis actually reverts 4181205. The original commit omits unit with all symbols inlined into current one, which leads to crash when a module using split-dwarf inlined a function from another module with mismatched split-dwarf-inlining option. This revert guarantees that DIEs are created in both DWO and the skeleton sections whenever split-dwarf is active. Full diff: https://github.com/llvm/llvm-project/pull/153568.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index c27f100775625..afa8511981e23 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -558,18 +558,14 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
// was inlined from another compile unit.
- if (useSplitDwarf() && !shareAcrossDWOCUs() && !SP->getUnit()->getSplitDebugInlining())
- // Avoid building the original CU if it won't be used
- SrcCU.constructAbstractSubprogramScopeDIE(Scope);
- else {
- auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
- if (auto *SkelCU = CU.getSkeleton()) {
- (shareAcrossDWOCUs() ? CU : SrcCU)
- .constructAbstractSubprogramScopeDIE(Scope);
- if (CU.getCUNode()->getSplitDebugInlining())
- SkelCU->constructAbstractSubprogramScopeDIE(Scope);
- } else
- CU.constructAbstractSubprogramScopeDIE(Scope);
+ auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
+ if (auto *SkelCU = CU.getSkeleton()) {
+ (shareAcrossDWOCUs() ? CU : SrcCU)
+ .constructAbstractSubprogramScopeDIE(Scope);
+ if (CU.getCUNode()->getSplitDebugInlining())
+ SkelCU->constructAbstractSubprogramScopeDIE(Scope);
+ } else {
+ CU.constructAbstractSubprogramScopeDIE(Scope);
}
}
diff --git a/llvm/test/DebugInfo/X86/split-dwarf-omit-empty.ll b/llvm/test/DebugInfo/X86/split-dwarf-omit-empty.ll
index f4cee1ec78b1d..95aae44b679d5 100644
--- a/llvm/test/DebugInfo/X86/split-dwarf-omit-empty.ll
+++ b/llvm/test/DebugInfo/X86/split-dwarf-omit-empty.ll
@@ -38,7 +38,7 @@ entry:
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 304054) (llvm/trunk 304080)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false)
!1 = !DIFile(filename: "a.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
!2 = !{}
-!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "clang version 5.0.0 (trunk 304054) (llvm/trunk 304080)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false)
+!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "clang version 5.0.0 (trunk 304054) (llvm/trunk 304080)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: true)
!4 = !DIFile(filename: "b.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
!5 = !{!"clang version 5.0.0 (trunk 304054) (llvm/trunk 304080)"}
!6 = !{i32 2, !"Dwarf Version", i32 4}
|
Hrm - could you describe this a bit more verbosely/with an example perhaps? I can't quite picture it straight-off. Example of a case where the previous optimization continues to apply - and an example where this bug shows up. Are there any false positives/false negatives? (do we end up producing empty CUs under certain circumstances with this new patch applied?) |
This actually reverts 4181205. The original commit omits unit with all symbols inlined into current one, which leads to crash when a module using split-dwarf inlined a function from another module with mismatched split-dwarf-inlining option. This revert guarantees that DIEs are created in both DWO and the skeleton sections whenever split-dwarf is active.
86481fc
to
b1357f0
Compare
hi @dwblaikie This comes from a real-world thin-lto case which triggers a crash: A static library containing bitcode files were compiled with debug info but split-inlining is false. The library is linked into final application builtin with -gsplit-dwarf (split-inlining=true). In such case, when a function from the bitcode archive is inlined, compiler sees
|
Gentle ping |
So, if I recall correctly, the original patch (just linking it here for my own benefit, passing through the recommit linked above: f2f898a ) addressed a real scalability problem with DWARF and ThinLTO. Specifically, using split-dwarf-inlining with ThinLTO meant creating a lot of tiny CUs for all the imported CUs in each backend compile. This massively increases the number of CUs and causes storage and debugger scalability issues. So, I guess a few questions, but maybe the simplest to start with: if this reverts the original patch, how does it not regress the original test case: If the originally tested/desired behavior is preserved otherwise, that seems fine? Might be worth testing the original revision and one before it - perhaps I made a mistake in the test case, and it doesn't actually represent behavior fixed by the original patch? (though I'm pretty sure there was some functional change that was important in that patch - so if the test doesn't cover that functionality, it probably suggests we need a better test - not that the original patch is fine to revert (& that a better test might demonstrate problems with this new patch, perhaps, that we need to figure out how to account for)) |
I see that e731a26 seems to have handled this to avoid creating a lot of tiny CUs for all the imported CUs in each backend compile in this scenario. if (useSplitDwarf() &&
!shareAcrossDWOCUs() &&
(!DIUnit->getSplitDebugInlining() ||
DIUnit->getEmissionKind() == DICompileUnit::FullDebug) &&
!CUMap.empty()) {
return *CUMap.begin()->second;
} Please correct me if I'm mistaken.
To be precise, this change isn't a simple revert. It enables correct handling of the case where a function from a CU with |
That sounds plausible/vaguely like my recollection from way-back when. Thanks for doing the archaeology here.
Not sure I follow - looking at the text of the change it does look like a revert. Is there some difference in the code this patch is adding compared to the code that was removed back in the original? It's probably fine that it's a straight revert - given the functionality of the original patch was fixed more broadly with the other patch you mentioned. |
if (useSplitDwarf() && !shareAcrossDWOCUs() && !SP->getUnit()->getSplitDebugInlining())
// Avoid building the original CU if it won't be used
SrcCU.constructAbstractSubprogramScopeDIE(Scope); it will only generate an abstract subprogram in the current DWO for the inlined function of the CU without if (auto *SkelCU = TheCU.getSkeleton())
if (!LScopes.getAbstractScopesList().empty() &&
TheCU.getCUNode()->getSplitDebugInlining())
SkelCU->constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel); This will trigger an assertion error when creating a child DIE for the inlined function in the skeleton by the CU with /*
if (useSplitDwarf() && !shareAcrossDWOCUs() && !SP->getUnit()->getSplitDebugInlining())
// Avoid building the original CU if it won't be used
SrcCU.constructAbstractSubprogramScopeDIE(Scope);
*/ Remove this if-statement logic to ensure that the abstract subprogram is properly generated in the skeleton unit, while e731a26 ensures that redundant tiny CUs will not be generated. I think the logic is roughly like that. |
Thanks! Yes, e731a26 already addressed the issue of split-dwarf-omit-empty.ll added by 4181205.
Technically this is a revert. I did not try an old enough LLVM to exactly contain the commit and test whether it has the ICE at that time. Anyway since the original issue is resolved by a later commit (e731a26), and reverting this fixes another ICE, this can also be regarded as a fix, I think which is what @Sockke means. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good - thanks for walking me through it, doing the archaeology, etc.
This actually reverts 4181205.
The original commit omits unit with all symbols inlined into current one, which leads to crash when a module using split-dwarf inlined a function from another module with mismatched split-dwarf-inlining option. This revert guarantees that DIEs are created in both DWO and the skeleton sections whenever split-dwarf is active.