Index: llvm/include/llvm/DWARFLinker/DWARFLinker.h =================================================================== --- llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -361,8 +361,6 @@ /// Given a DIE, update its incompleteness based on whether the DIEs it /// references are incomplete. UpdateRefIncompleteness, - /// Given a DIE, mark it as ODR Canonical if applicable. - MarkODRCanonicalDie, }; /// This class represents an item in the work list. The type defines what kind @@ -468,9 +466,8 @@ const DWARFFile &File, SmallVectorImpl &Worklist); - /// Mark context corresponding to the specified \p Die as having canonical - /// die, if applicable. - void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU); + /// Mark DIEs as ODR canonical. + void markDIEsAsODRCanonical(const DWARFDie &DIE, CompileUnit &CU); /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries. /// Index: llvm/lib/DWARFLinker/DWARFLinker.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFLinker.cpp +++ llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -634,13 +634,24 @@ return !Info.Incomplete && Info.Ctxt != CU.getInfo(Info.ParentIdx).Ctxt; } -void DWARFLinker::markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU) { - CompileUnit::DIEInfo &Info = CU.getInfo(Die); +/// Iterate over all the DIEs in the CU and mark the context of the ones that +/// are ODR canonical. +void DWARFLinker::markDIEsAsODRCanonical(const DWARFDie &Die, CompileUnit &CU) { + std::vector Worklist; + Worklist.push_back(Die); + + while (!Worklist.empty()) { + const DWARFDie Current = Worklist.back(); + Worklist.pop_back(); + + CompileUnit::DIEInfo &Info = CU.getInfo(Current); + if (Info.Keep && isODRCanonicalCandidate(Current, CU) && + !Info.Ctxt->hasCanonicalDIE()) + Info.Ctxt->setHasCanonicalDIE(); - Info.ODRMarkingDone = true; - if (Info.Keep && isODRCanonicalCandidate(Die, CU) && - !Info.Ctxt->hasCanonicalDIE()) - Info.Ctxt->setHasCanonicalDIE(); + for (auto Child : reverse(Current.children())) + Worklist.push_back(Child); + } } /// Look at DIEs referenced by the given DIE and decide whether they should be @@ -780,9 +791,6 @@ lookForParentDIEsToKeep(Current.AncestorIdx, Current.CU, Current.Flags, Worklist); continue; - case WorklistItemType::MarkODRCanonicalDie: - markODRCanonicalDie(Current.Die, Current.CU); - continue; case WorklistItemType::LookForDIEsToKeep: break; } @@ -805,16 +813,6 @@ Current.Flags = shouldKeepDIE(AddressesMap, Ranges, Current.Die, File, Current.CU, MyInfo, Current.Flags); - // We need to mark context for the canonical die in the end of normal - // traversing(not TF_DependencyWalk) or after normal traversing if die - // was not marked as kept. - if (!(Current.Flags & TF_DependencyWalk) || - (MyInfo.ODRMarkingDone && !MyInfo.Keep)) { - if (Current.CU.hasODR() || MyInfo.InModuleScope) - Worklist.emplace_back(Current.Die, Current.CU, - WorklistItemType::MarkODRCanonicalDie); - } - // Finish by looking for child DIEs. Because of the LIFO worklist we need // to schedule that work before any subsequent items are added to the // worklist. @@ -2535,12 +2533,15 @@ CurrentUnit->markEverythingAsKept(); copyInvariantDebugSection(*OptContext.File.Dwarf); } else { - for (auto &CurrentUnit : OptContext.CompileUnits) + for (auto &CurrentUnit : OptContext.CompileUnits) { lookForDIEsToKeep(*OptContext.File.Addresses, OptContext.File.Addresses->getValidAddressRanges(), OptContext.CompileUnits, CurrentUnit->getOrigUnit().getUnitDIE(), OptContext.File, *CurrentUnit, 0); + markDIEsAsODRCanonical(CurrentUnit->getOrigUnit().getUnitDIE(), + *CurrentUnit); + } } // The calls to applyValidRelocs inside cloneDIE will walk the reloc