From b2ef3f3d57a5e12e266f897c172966dff6fdbb4c Mon Sep 17 00:00:00 2001 From: Artem Pianykh Date: Thu, 12 Sep 2024 15:23:43 -0700 Subject: [PATCH] [NFC][Utils] Extract BuildDebugInfoMDMap from CloneFunctionInto Summary: Extract the logic to build up a metadata map to use in metadata cloning into a separate function. Test Plan: ninja check-llvm-unit check-llvm stack-info: PR: https://github.com/llvm/llvm-project/pull/118622, branch: users/artempyanykh/fast-coro-upstream/3 --- llvm/include/llvm/Transforms/Utils/Cloning.h | 8 ++ llvm/lib/Transforms/Utils/CloneFunction.cpp | 89 +++++++++++--------- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index 3c8f2cbfaa9b8..7858c9d9def0d 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -220,6 +220,14 @@ DISubprogram *CollectDebugInfoForCloning(const Function &F, CloneFunctionChangeType Changes, DebugInfoFinder &DIFinder); +/// Build a map of debug info to use during Metadata cloning. +/// Returns true if cloning would need module level changes and false if there +/// would only be local changes. +bool BuildDebugInfoMDMap(DenseMap &MD, + CloneFunctionChangeType Changes, + DebugInfoFinder &DIFinder, + DISubprogram *SPClonedWithinModule); + /// This class captures the data input to the InlineFunction call, and records /// the auxiliary results produced by it. class InlineFunctionInfo { diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index d038117090e4c..6dc5f601b7fca 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -152,6 +152,54 @@ DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F, return SPClonedWithinModule; } +bool llvm::BuildDebugInfoMDMap(DenseMap &MD, + CloneFunctionChangeType Changes, + DebugInfoFinder &DIFinder, + DISubprogram *SPClonedWithinModule) { + bool ModuleLevelChanges = Changes > CloneFunctionChangeType::LocalChangesOnly; + if (Changes < CloneFunctionChangeType::DifferentModule && + DIFinder.subprogram_count() > 0) { + // Turn on module-level changes, since we need to clone (some of) the + // debug info metadata. + // + // FIXME: Metadata effectively owned by a function should be made + // local, and only that local metadata should be cloned. + ModuleLevelChanges = true; + + auto mapToSelfIfNew = [&MD](MDNode *N) { + // Avoid clobbering an existing mapping. + (void)MD.try_emplace(N, N); + }; + + // Avoid cloning types, compile units, and (other) subprograms. + SmallPtrSet MappedToSelfSPs; + for (DISubprogram *ISP : DIFinder.subprograms()) { + if (ISP != SPClonedWithinModule) { + mapToSelfIfNew(ISP); + MappedToSelfSPs.insert(ISP); + } + } + + // If a subprogram isn't going to be cloned skip its lexical blocks as well. + for (DIScope *S : DIFinder.scopes()) { + auto *LScope = dyn_cast(S); + if (LScope && MappedToSelfSPs.count(LScope->getSubprogram())) + mapToSelfIfNew(S); + } + + for (DICompileUnit *CU : DIFinder.compile_units()) + mapToSelfIfNew(CU); + + for (DIType *Type : DIFinder.types()) + mapToSelfIfNew(Type); + } else { + assert(!SPClonedWithinModule && + "Subprogram should be in DIFinder->subprogram_count()..."); + } + + return ModuleLevelChanges; +} + // Clone OldFunc into NewFunc, transforming the old arguments into references to // VMap values. void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, @@ -210,45 +258,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning(*OldFunc, Changes, DIFinder); - if (Changes < CloneFunctionChangeType::DifferentModule && - DIFinder.subprogram_count() > 0) { - // Turn on module-level changes, since we need to clone (some of) the - // debug info metadata. - // - // FIXME: Metadata effectively owned by a function should be made - // local, and only that local metadata should be cloned. - ModuleLevelChanges = true; - - auto mapToSelfIfNew = [&VMap](MDNode *N) { - // Avoid clobbering an existing mapping. - (void)VMap.MD().try_emplace(N, N); - }; - - // Avoid cloning types, compile units, and (other) subprograms. - SmallPtrSet MappedToSelfSPs; - for (DISubprogram *ISP : DIFinder.subprograms()) { - if (ISP != SPClonedWithinModule) { - mapToSelfIfNew(ISP); - MappedToSelfSPs.insert(ISP); - } - } - - // If a subprogram isn't going to be cloned skip its lexical blocks as well. - for (DIScope *S : DIFinder.scopes()) { - auto *LScope = dyn_cast(S); - if (LScope && MappedToSelfSPs.count(LScope->getSubprogram())) - mapToSelfIfNew(S); - } - - for (DICompileUnit *CU : DIFinder.compile_units()) - mapToSelfIfNew(CU); - - for (DIType *Type : DIFinder.types()) - mapToSelfIfNew(Type); - } else { - assert(!SPClonedWithinModule && - "Subprogram should be in DIFinder->subprogram_count()..."); - } + ModuleLevelChanges = + BuildDebugInfoMDMap(VMap.MD(), Changes, DIFinder, SPClonedWithinModule); const auto RemapFlag = ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges; // Duplicate the metadata that is attached to the cloned function.