diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/IR/DebugLoc.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'llvm/lib/IR/DebugLoc.cpp')
-rw-r--r-- | llvm/lib/IR/DebugLoc.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index 34c9d026b19a..bdea52180f74 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -67,6 +67,46 @@ void DebugLoc::setImplicitCode(bool ImplicitCode) { } } +DebugLoc DebugLoc::replaceInlinedAtSubprogram( + const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx, + DenseMap<const MDNode *, MDNode *> &Cache) { + SmallVector<DILocation *> LocChain; + DILocation *CachedResult = nullptr; + + // Collect the inline chain, stopping if we find a location that has already + // been processed. + for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) { + if (auto It = Cache.find(Loc); It != Cache.end()) { + CachedResult = cast<DILocation>(It->second); + break; + } + LocChain.push_back(Loc); + } + + DILocation *UpdatedLoc = CachedResult; + if (!UpdatedLoc) { + // 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 = DILocalScope::cloneScopeForSubprogram( + *LocToUpdate->getScope(), NewSP, Ctx, Cache); + UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(), + LocToUpdate->getColumn(), NewScope); + Cache[LocToUpdate] = UpdatedLoc; + } + + // Recreate the location chain, bottom-up, starting at the new scope (or a + // cached result). + for (const DILocation *LocToUpdate : reverse(LocChain)) { + UpdatedLoc = + DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(), + LocToUpdate->getScope(), UpdatedLoc); + Cache[LocToUpdate] = UpdatedLoc; + } + + return UpdatedLoc; +} + DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, LLVMContext &Ctx, DenseMap<const MDNode *, MDNode *> &Cache) { |