[llvm] [DWARFLinker] Make ODR uniquing deterministic (PR #194777)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 29 06:02:13 PDT 2026
================
@@ -1419,46 +1419,42 @@ DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
DIEGenerator &TypeDIEGenerator,
dwarf::Tag DieTag, bool IsDeclaration,
bool IsParentDeclaration) {
- DIE *DefinitionDie = TypeDescriptor->Die;
- // Do not allocate any new DIE if definition DIE is already met.
- if (DefinitionDie)
- return nullptr;
-
- DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
- bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
-
- if (IsDeclaration && !DeclarationDie) {
- // Alocate declaration DIE.
- DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
- if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
- NewDie))
- return NewDie;
- } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
- // Overwrite existing declaration DIE if it's parent is also an declaration
- // while parent of current declaration DIE is a definition.
- if (TypeDescriptor->ParentIsDeclaration.compare_exchange_strong(
- OldParentIsDeclaration, false)) {
- DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
- TypeDescriptor->DeclarationDie = NewDie;
- return NewDie;
- }
- } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
- // Alocate declaration DIE since parent of current DIE is marked as
- // declaration.
- DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
- if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
- NewDie))
- return NewDie;
- } else if (!IsDeclaration && !IsParentDeclaration) {
- // Allocate definition DIE.
- DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
- if (TypeDescriptor->Die.compare_exchange_strong(DefinitionDie, NewDie)) {
+ // Use a per-type spinlock and CU priority to ensure the earliest CU in link
+ // order always wins the type slot, producing deterministic output regardless
+ // of thread scheduling.
+ unsigned Priority = getDeterministicPriority();
+
+ // Speculatively allocate the DIE outside the lock so the critical section
+ // only covers the priority check and pointer store. If we lose, the DIE
+ // is leaked into the bump allocator.
+ DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
----------------
alx32 wrote:
Every CU that's the lowest-priority seen so far fully clones and emits accelerator records, only to be filtered later by `getFinalDie()`. When several CUs race on the same type, most of that work gets thrown away — the leaked DIEs, patches, and accel records all pile up in the bump allocator. If it's straightforward, could we check priority first (load `DiePriority`/`DeclarationDiePriority` under the lock) and only `createDIE`/`clone`/`save` when this CU can actually win?
https://github.com/llvm/llvm-project/pull/194777
More information about the llvm-commits
mailing list