diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1580,6 +1580,13 @@ /// chain. DISubprogram *getSubprogram() const; + /// Traverses the scope chain rooted at RootScope until it hits a Subprogram, + /// recreating the chain with "NewSP" instead. + static DILocalScope * + cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP, + LLVMContext &Ctx, + DenseMap &Cache); + /// Get the first non DILexicalBlockFile scope of this scope. /// /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -974,6 +974,35 @@ return const_cast(this); } +DILocalScope *DILocalScope::cloneScopeForSubprogram( + DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx, + DenseMap &Cache) { + SmallVector ScopeChain; + DIScope *CachedResult = nullptr; + + for (DIScope *Scope = &RootScope; !isa(Scope); + Scope = Scope->getScope()) { + if (auto It = Cache.find(Scope); It != Cache.end()) { + CachedResult = cast(It->second); + break; + } + ScopeChain.push_back(Scope); + } + + // Recreate the scope chain, bottom-up, starting at the new subprogram (or a + // cached result). + DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP; + for (DIScope *ScopeToUpdate : reverse(ScopeChain)) { + TempMDNode ClonedScope = ScopeToUpdate->clone(); + cast(*ClonedScope).replaceScope(UpdatedScope); + UpdatedScope = + cast(MDNode::replaceWithUniqued(std::move(ClonedScope))); + Cache[ScopeToUpdate] = UpdatedScope; + } + + return cast(UpdatedScope); +} + DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) { return StringSwitch(Flag) #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME) diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -67,37 +67,6 @@ } } -/// Traverses the scope chain rooted at RootScope until it hits a Subprogram, -/// recreating the chain with "NewSP" instead. -static DIScope * -cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP, - LLVMContext &Ctx, - DenseMap &Cache) { - SmallVector ScopeChain; - DIScope *CachedResult = nullptr; - - for (DIScope *Scope = &RootScope; !isa(Scope); - Scope = Scope->getScope()) { - if (auto It = Cache.find(Scope); It != Cache.end()) { - CachedResult = cast(It->second); - break; - } - ScopeChain.push_back(Scope); - } - - // Recreate the scope chain, bottom-up, starting at the new subprogram (or a - // cached result). - DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP; - for (DIScope *ScopeToUpdate : reverse(ScopeChain)) { - TempMDNode ClonedScope = ScopeToUpdate->clone(); - cast(*ClonedScope).replaceScope(UpdatedScope); - UpdatedScope = - cast(MDNode::replaceWithUniqued(std::move(ClonedScope))); - Cache[ScopeToUpdate] = UpdatedScope; - } - return UpdatedScope; -} - DebugLoc DebugLoc::replaceInlinedAtSubprogram( const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap &Cache) { @@ -119,8 +88,8 @@ // If no cache hits, then back() is the end of the inline chain, that is, // the DILocation whose scope ends in the Subprogram to be replaced. DILocation *LocToUpdate = LocChain.pop_back_val(); - DIScope *NewScope = - cloneScopeForSubprogram(*LocToUpdate->getScope(), NewSP, Ctx, Cache); + DIScope *NewScope = DILocalScope::cloneScopeForSubprogram( + *LocToUpdate->getScope(), NewSP, Ctx, Cache); UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(), NewScope); Cache[LocToUpdate] = UpdatedLoc;