[llvm] [NFC][Utils] Extract CloneFunctionBodyInto from CloneFunctionInto (PR #118624)
Artem Pianykh via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 10 23:48:42 PST 2024
https://github.com/artempyanykh updated https://github.com/llvm/llvm-project/pull/118624
>From a91e78306754e84ee8a3db320e52d0cf9d347bb6 Mon Sep 17 00:00:00 2001
From: Artem Pianykh <arr at fb.com>
Date: Thu, 12 Sep 2024 15:35:38 -0700
Subject: [PATCH 1/2] [NFC][Utils] Extract CloneFunctionMetadataInto from
CloneFunctionInto
Summary:
The new API expects the caller to populate the VMap. We need it this way
for a subsequent change around coroutine cloning.
Test Plan:
ninja check-llvm-unit check-llvm
stack-info: PR: https://github.com/llvm/llvm-project/pull/118623, branch: users/artempyanykh/fast-coro-upstream/4
---
llvm/include/llvm/Transforms/Utils/Cloning.h | 13 ++++++++++
llvm/lib/Transforms/Utils/CloneFunction.cpp | 25 +++++++++++++-------
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 7858c9d9def0da..06f21c236a1649 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -182,6 +182,19 @@ void CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);
+/// Clone OldFunc's metadata into NewFunc.
+///
+/// The caller is expected to populate \p VMap beforehand and set an appropriate
+/// \p RemapFlag. Subprograms/CUs/types that were already mapped to themselves
+/// won't be duplicated.
+///
+/// NOTE: This function doesn't clone !llvm.dbg.cu when cloning into a different
+/// module. Use CloneFunctionInto for that behavior.
+void CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
+ ValueToValueMapTy &VMap, RemapFlags RemapFlag,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
+
void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
const Instruction *StartingInst,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 6dc5f601b7fcaa..8b3070027aa548 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -200,6 +200,19 @@ bool llvm::BuildDebugInfoMDMap(DenseMap<const Metadata *, TrackingMDRef> &MD,
return ModuleLevelChanges;
}
+void llvm::CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
+ ValueToValueMapTy &VMap,
+ RemapFlags RemapFlag,
+ ValueMapTypeRemapper *TypeMapper,
+ ValueMaterializer *Materializer) {
+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ OldFunc.getAllMetadata(MDs);
+ for (auto MD : MDs) {
+ NewFunc.addMetadata(MD.first, *MapMetadata(MD.second, VMap, RemapFlag,
+ TypeMapper, Materializer));
+ }
+}
+
// Clone OldFunc into NewFunc, transforming the old arguments into references to
// VMap values.
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
@@ -262,15 +275,9 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
BuildDebugInfoMDMap(VMap.MD(), Changes, DIFinder, SPClonedWithinModule);
const auto RemapFlag = ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges;
- // Duplicate the metadata that is attached to the cloned function.
- // Subprograms/CUs/types that were already mapped to themselves won't be
- // duplicated.
- SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
- OldFunc->getAllMetadata(MDs);
- for (auto MD : MDs) {
- NewFunc->addMetadata(MD.first, *MapMetadata(MD.second, VMap, RemapFlag,
- TypeMapper, Materializer));
- }
+
+ CloneFunctionMetadataInto(*NewFunc, *OldFunc, VMap, RemapFlag, TypeMapper,
+ Materializer);
// 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
>From 1560bb07cb0c9ba43da6b99c472f93c72ea369f2 Mon Sep 17 00:00:00 2001
From: Artem Pyanykh <artem.pyanykh at gmail.com>
Date: Wed, 11 Dec 2024 07:23:08 +0000
Subject: [PATCH 2/2] [NFC][Utils] Extract CloneFunctionBodyInto from
CloneFunctionInto
Summary:
This and previously extracted `CloneFunction*Into` functions will be used in later diffs.
Test Plan:
ninja check-llvm-unit check-llvm
stack-info: PR: https://github.com/llvm/llvm-project/pull/118624, branch: users/artempyanykh/fast-coro-upstream/5
---
llvm/include/llvm/Transforms/Utils/Cloning.h | 9 ++
llvm/lib/Transforms/Utils/CloneFunction.cpp | 97 +++++++++++---------
2 files changed, 65 insertions(+), 41 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 06f21c236a1649..2fcb64206387ed 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -195,6 +195,15 @@ void CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);
+/// Clone OldFunc's body into NewFunc.
+void CloneFunctionBodyInto(Function &NewFunc, const Function &OldFunc,
+ ValueToValueMapTy &VMap, RemapFlags RemapFlag,
+ SmallVectorImpl<ReturnInst *> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = nullptr,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr);
+
void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
const Instruction *StartingInst,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 8b3070027aa548..d47633a05fce96 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -213,6 +213,60 @@ void llvm::CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
}
}
+void llvm::CloneFunctionBodyInto(Function &NewFunc, const Function &OldFunc,
+ ValueToValueMapTy &VMap, RemapFlags RemapFlag,
+ SmallVectorImpl<ReturnInst *> &Returns,
+ const char *NameSuffix,
+ ClonedCodeInfo *CodeInfo,
+ ValueMapTypeRemapper *TypeMapper,
+ ValueMaterializer *Materializer) {
+ if (OldFunc.isDeclaration())
+ return;
+
+ // 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);
+
+ // Add basic block mapping.
+ VMap[&BB] = CBB;
+
+ // It is only legal to clone a function if a block address within that
+ // function is never referenced outside of the function. Given that, we
+ // want to map block addresses from the old function to block addresses in
+ // the clone. (This is different from the generic ValueMapper
+ // implementation, which generates an invalid blockaddress when
+ // cloning a function.)
+ if (BB.hasAddressTaken()) {
+ Constant *OldBBAddr = BlockAddress::get(const_cast<Function *>(&OldFunc),
+ const_cast<BasicBlock *>(&BB));
+ VMap[OldBBAddr] = BlockAddress::get(&NewFunc, CBB);
+ }
+
+ // Note return instructions for the caller.
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
+ Returns.push_back(RI);
+ }
+
+ // Loop over all of the instructions in the new function, fixing up operand
+ // references as we go. This uses VMap to do all the hard work.
+ for (Function::iterator
+ BB = cast<BasicBlock>(VMap[&OldFunc.front()])->getIterator(),
+ BE = NewFunc.end();
+ BB != BE; ++BB)
+ // Loop over all instructions, fixing each one as we find it, and any
+ // attached debug-info records.
+ for (Instruction &II : *BB) {
+ RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer);
+ RemapDbgRecordRange(II.getModule(), II.getDbgRecordRange(), VMap,
+ RemapFlag, TypeMapper, Materializer);
+ }
+}
+
// Clone OldFunc into NewFunc, transforming the old arguments into references to
// VMap values.
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
@@ -279,47 +333,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
CloneFunctionMetadataInto(*NewFunc, *OldFunc, VMap, RemapFlag, TypeMapper,
Materializer);
- // 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);
-
- // Add basic block mapping.
- VMap[&BB] = CBB;
-
- // It is only legal to clone a function if a block address within that
- // function is never referenced outside of the function. Given that, we
- // want to map block addresses from the old function to block addresses in
- // the clone. (This is different from the generic ValueMapper
- // implementation, which generates an invalid blockaddress when
- // cloning a function.)
- if (BB.hasAddressTaken()) {
- Constant *OldBBAddr = BlockAddress::get(const_cast<Function *>(OldFunc),
- const_cast<BasicBlock *>(&BB));
- VMap[OldBBAddr] = BlockAddress::get(NewFunc, CBB);
- }
-
- // Note return instructions for the caller.
- if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
- Returns.push_back(RI);
- }
-
- // Loop over all of the instructions in the new function, fixing up operand
- // references as we go. This uses VMap to do all the hard work.
- for (Function::iterator
- BB = cast<BasicBlock>(VMap[&OldFunc->front()])->getIterator(),
- BE = NewFunc->end();
- BB != BE; ++BB)
- // Loop over all instructions, fixing each one as we find it, and any
- // attached debug-info records.
- for (Instruction &II : *BB) {
- RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer);
- RemapDbgRecordRange(II.getModule(), II.getDbgRecordRange(), VMap,
- RemapFlag, TypeMapper, Materializer);
- }
+ CloneFunctionBodyInto(*NewFunc, *OldFunc, VMap, RemapFlag, Returns,
+ NameSuffix, CodeInfo, TypeMapper, Materializer);
// Only update !llvm.dbg.cu for DifferentModule (not CloneModule). In the
// same module, the compile unit will already be listed (or not). When
More information about the llvm-commits
mailing list