Skip to content

Commit

Permalink
[NFC][Utils] Extract CloneFunctionBodyInto from CloneFunctionInto
Browse files Browse the repository at this point in the history
Summary:
This and previously extracted `CloneFunction*Into` functions will be used in later diffs.

Test Plan:
ninja check-llvm-unit check-llvm
  • Loading branch information
artempyanykh committed Dec 4, 2024
1 parent 4c89772 commit 4bda093
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 54 deletions.
34 changes: 21 additions & 13 deletions llvm/include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,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,
Expand All @@ -214,7 +223,7 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
///
void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
SmallVectorImpl<ReturnInst*> &Returns,
SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr);

Expand Down Expand Up @@ -360,32 +369,31 @@ void updateProfileCallee(
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
/// basic blocks and extract their scope. These are candidates for duplication
/// when cloning.
void identifyNoAliasScopesToClone(
ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
void identifyNoAliasScopesToClone(ArrayRef<BasicBlock *> BBs,
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);

/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
/// instruction range and extract their scope. These are candidates for
/// duplication when cloning.
void identifyNoAliasScopesToClone(
BasicBlock::iterator Start, BasicBlock::iterator End,
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
void identifyNoAliasScopesToClone(BasicBlock::iterator Start,
BasicBlock::iterator End,
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);

/// Duplicate the specified list of noalias decl scopes.
/// The 'Ext' string is added as an extension to the name.
/// Afterwards, the ClonedScopes contains the mapping of the original scope
/// MDNode onto the cloned scope.
/// Be aware that the cloned scopes are still part of the original scope domain.
void cloneNoAliasScopes(
ArrayRef<MDNode *> NoAliasDeclScopes,
DenseMap<MDNode *, MDNode *> &ClonedScopes,
StringRef Ext, LLVMContext &Context);
void cloneNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
DenseMap<MDNode *, MDNode *> &ClonedScopes,
StringRef Ext, LLVMContext &Context);

/// Adapt the metadata for the specified instruction according to the
/// provided mapping. This is normally used after cloning an instruction, when
/// some noalias scopes needed to be cloned.
void adaptNoAliasScopes(
llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
LLVMContext &Context);
void adaptNoAliasScopes(llvm::Instruction *I,
const DenseMap<MDNode *, MDNode *> &ClonedScopes,
LLVMContext &Context);

/// Clone the specified noalias decl scopes. Then adapt all instructions in the
/// NewBlocks basicblocks to the cloned versions.
Expand Down
96 changes: 55 additions & 41 deletions llvm/lib/Transforms/Utils/CloneFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,59 @@ 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,
Expand Down Expand Up @@ -281,47 +334,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
Expand Down

0 comments on commit 4bda093

Please sign in to comment.