[llvm] [Utils] Extract ProcessSubprogramAttachment from CloneFunctionInto (PR #114537)
Artem Pianykh via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 12 02:50:54 PST 2024
https://github.com/artempyanykh updated https://github.com/llvm/llvm-project/pull/114537
>From e2b2ee868cf17d2738b655dbe2389caf366ef0c5 Mon Sep 17 00:00:00 2001
From: Artem Pianykh <arr at fb.com>
Date: Thu, 12 Sep 2024 14:55:28 -0700
Subject: [PATCH 1/3] [Utils] Extract ProcessSubprogramAttachment from
CloneFunctionInto
Summary:
Consolidate the logic in a single function. We do an extra pass over Instructions but this is
necessary to untangle things and extract metadata cloning in a future diff.
Test Plan:
ninja check-llvm-unit
---
llvm/include/llvm/Transforms/Utils/Cloning.h | 9 +++
llvm/lib/Transforms/Utils/CloneFunction.cpp | 61 +++++++++++++-------
2 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 1e8ef0102450e4..c5be1cce4fff89 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -207,6 +207,15 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr);
+/// Process function's subprogram attachment to collect relevant debug
+/// information in DIFinder.
+///
+/// Returns DISubprogram of the cloned function when cloning into the same
+/// module or nullptr otherwise.
+DISubprogram *ProcessSubprogramAttachment(const Function &F,
+ CloneFunctionChangeType Changes,
+ DebugInfoFinder &DIFinder);
+
/// 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 a2d38717f38d14..3a0a160b046965 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -137,6 +137,29 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
OldAttrs.getRetAttrs(), NewArgAttrs));
}
+DISubprogram *llvm::ProcessSubprogramAttachment(const Function &F,
+ CloneFunctionChangeType Changes,
+ DebugInfoFinder &DIFinder) {
+ DISubprogram *SPClonedWithinModule = nullptr;
+ if (Changes < CloneFunctionChangeType::DifferentModule) {
+ SPClonedWithinModule = F.getSubprogram();
+ }
+ if (SPClonedWithinModule)
+ DIFinder.processSubprogram(SPClonedWithinModule);
+
+ const Module *M = F.getParent();
+ if (Changes != CloneFunctionChangeType::ClonedModule && M) {
+ // Inspect instructions to process e.g. DILexicalBlocks of inlined functions
+ for (const auto &BB : F) {
+ for (const auto &I : BB) {
+ DIFinder.processInstruction(*M, I);
+ }
+ }
+ }
+
+ return SPClonedWithinModule;
+}
+
// Clone OldFunc into NewFunc, transforming the old arguments into references to
// VMap values.
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
@@ -169,23 +192,19 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
// duplicate instructions and then freeze them in the MD map. We also record
// information about dbg.value and dbg.declare to avoid duplicating the
// types.
- std::optional<DebugInfoFinder> DIFinder;
+ DebugInfoFinder DIFinder;
// Track the subprogram attachment that needs to be cloned to fine-tune the
// mapping within the same module.
- DISubprogram *SPClonedWithinModule = nullptr;
if (Changes < CloneFunctionChangeType::DifferentModule) {
+ // Need to find subprograms, types, and compile units.
+
assert((NewFunc->getParent() == nullptr ||
NewFunc->getParent() == OldFunc->getParent()) &&
"Expected NewFunc to have the same parent, or no parent");
-
- // Need to find subprograms, types, and compile units.
- DIFinder.emplace();
-
- SPClonedWithinModule = OldFunc->getSubprogram();
- if (SPClonedWithinModule)
- DIFinder->processSubprogram(SPClonedWithinModule);
} else {
+ // Need to find all the compile units.
+
assert((NewFunc->getParent() == nullptr ||
NewFunc->getParent() != OldFunc->getParent()) &&
"Expected NewFunc to have different parents, or no parent");
@@ -193,20 +212,22 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
if (Changes == CloneFunctionChangeType::DifferentModule) {
assert(NewFunc->getParent() &&
"Need parent of new function to maintain debug info invariants");
-
- // Need to find all the compile units.
- DIFinder.emplace();
}
}
+ DISubprogram *SPClonedWithinModule =
+ ProcessSubprogramAttachment(*OldFunc, Changes, DIFinder);
+
// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
// recursive functions into themselves.
for (const BasicBlock &BB : *OldFunc) {
// Create a new basic block and copy instructions into it!
- BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo,
- DIFinder ? &*DIFinder : nullptr);
+ // NOTE: don't pass DIFinder becase instructions' debug info was process in
+ // ProcessSubprogramAttachment. This will be further cleaned up.
+ BasicBlock *CBB =
+ CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo, nullptr);
// Add basic block mapping.
VMap[&BB] = CBB;
@@ -229,7 +250,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
}
if (Changes < CloneFunctionChangeType::DifferentModule &&
- DIFinder->subprogram_count() > 0) {
+ DIFinder.subprogram_count() > 0) {
// Turn on module-level changes, since we need to clone (some of) the
// debug info metadata.
//
@@ -244,7 +265,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
// Avoid cloning types, compile units, and (other) subprograms.
SmallPtrSet<const DISubprogram *, 16> MappedToSelfSPs;
- for (DISubprogram *ISP : DIFinder->subprograms()) {
+ for (DISubprogram *ISP : DIFinder.subprograms()) {
if (ISP != SPClonedWithinModule) {
mapToSelfIfNew(ISP);
MappedToSelfSPs.insert(ISP);
@@ -252,16 +273,16 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
}
// If a subprogram isn't going to be cloned skip its lexical blocks as well.
- for (DIScope *S : DIFinder->scopes()) {
+ for (DIScope *S : DIFinder.scopes()) {
auto *LScope = dyn_cast<DILocalScope>(S);
if (LScope && MappedToSelfSPs.count(LScope->getSubprogram()))
mapToSelfIfNew(S);
}
- for (DICompileUnit *CU : DIFinder->compile_units())
+ for (DICompileUnit *CU : DIFinder.compile_units())
mapToSelfIfNew(CU);
- for (DIType *Type : DIFinder->types())
+ for (DIType *Type : DIFinder.types())
mapToSelfIfNew(Type);
} else {
assert(!SPClonedWithinModule &&
@@ -315,7 +336,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallPtrSet<const void *, 8> Visited;
for (auto *Operand : NMD->operands())
Visited.insert(Operand);
- for (auto *Unit : DIFinder->compile_units()) {
+ for (auto *Unit : DIFinder.compile_units()) {
MDNode *MappedUnit =
MapMetadata(Unit, VMap, RF_None, TypeMapper, Materializer);
if (Visited.insert(MappedUnit).second)
>From e3e9051a0af8f3bf42931fe12bf9bbfaa57b5554 Mon Sep 17 00:00:00 2001
From: Artem Pianykh <arr at fb.com>
Date: Tue, 12 Nov 2024 02:04:36 -0800
Subject: [PATCH 2/3] fixup! [Utils] Extract ProcessSubprogramAttachment from
CloneFunctionInto
---
llvm/lib/Transforms/Utils/CloneFunction.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 3a0a160b046965..8e3f5a2f213e36 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -24,6 +24,7 @@
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
@@ -150,11 +151,8 @@ DISubprogram *llvm::ProcessSubprogramAttachment(const Function &F,
const Module *M = F.getParent();
if (Changes != CloneFunctionChangeType::ClonedModule && M) {
// Inspect instructions to process e.g. DILexicalBlocks of inlined functions
- for (const auto &BB : F) {
- for (const auto &I : BB) {
- DIFinder.processInstruction(*M, I);
- }
- }
+ for (const auto &I : instructions(F))
+ DIFinder.processInstruction(*M, I);
}
return SPClonedWithinModule;
>From 08946bc6325843af9371e1fd2550cc574f5da6d2 Mon Sep 17 00:00:00 2001
From: Artem Pianykh <arr at fb.com>
Date: Tue, 12 Nov 2024 02:42:46 -0800
Subject: [PATCH 3/3] amend! [Utils] Extract CollectDebugInfoForCloning from
CloneFunctionInto
---
llvm/include/llvm/Transforms/Utils/Cloning.h | 15 ++++++++++-----
llvm/lib/Transforms/Utils/CloneFunction.cpp | 10 +++++-----
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index c5be1cce4fff89..28a2dd79e10a2f 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -207,14 +207,19 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr);
-/// Process function's subprogram attachment to collect relevant debug
-/// information in DIFinder.
+/// Collect debug information such as types, compile units, and other
+/// subprograms that are reachable from \p F and can be considered global for
+/// the purposes of cloning (and hence not needing to be cloned).
+///
+/// The latter depends on \p Changes: when cloning into the same module we
+/// process \p F's subprogram and instructions; when into a cloned module,
+/// neither of those.
///
/// Returns DISubprogram of the cloned function when cloning into the same
/// module or nullptr otherwise.
-DISubprogram *ProcessSubprogramAttachment(const Function &F,
- CloneFunctionChangeType Changes,
- DebugInfoFinder &DIFinder);
+DISubprogram *CollectDebugInfoForCloning(const Function &F,
+ CloneFunctionChangeType Changes,
+ DebugInfoFinder &DIFinder);
/// This class captures the data input to the InlineFunction call, and records
/// the auxiliary results produced by it.
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 8e3f5a2f213e36..48152e2ad140eb 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -138,9 +138,9 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
OldAttrs.getRetAttrs(), NewArgAttrs));
}
-DISubprogram *llvm::ProcessSubprogramAttachment(const Function &F,
- CloneFunctionChangeType Changes,
- DebugInfoFinder &DIFinder) {
+DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F,
+ CloneFunctionChangeType Changes,
+ DebugInfoFinder &DIFinder) {
DISubprogram *SPClonedWithinModule = nullptr;
if (Changes < CloneFunctionChangeType::DifferentModule) {
SPClonedWithinModule = F.getSubprogram();
@@ -214,7 +214,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
}
DISubprogram *SPClonedWithinModule =
- ProcessSubprogramAttachment(*OldFunc, Changes, DIFinder);
+ CollectDebugInfoForCloning(*OldFunc, Changes, DIFinder);
// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
@@ -223,7 +223,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
// Create a new basic block and copy instructions into it!
// NOTE: don't pass DIFinder becase instructions' debug info was process in
- // ProcessSubprogramAttachment. This will be further cleaned up.
+ // CollectDebugInfoForCloning. This will be further cleaned up.
BasicBlock *CBB =
CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo, nullptr);
More information about the llvm-commits
mailing list