aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp88
1 files changed, 67 insertions, 21 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 1d348213bfdb..87822ee85c2b 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -33,6 +33,7 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <map>
+#include <optional>
using namespace llvm;
#define DEBUG_TYPE "clone-function"
@@ -46,7 +47,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
if (BB->hasName())
NewBB->setName(BB->getName() + NameSuffix);
- bool hasCalls = false, hasDynamicAllocas = false;
+ bool hasCalls = false, hasDynamicAllocas = false, hasMemProfMetadata = false;
Module *TheModule = F ? F->getParent() : nullptr;
// Loop over all instructions, and copy them over.
@@ -57,10 +58,13 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
Instruction *NewInst = I.clone();
if (I.hasName())
NewInst->setName(I.getName() + NameSuffix);
- NewBB->getInstList().push_back(NewInst);
+ NewInst->insertInto(NewBB, NewBB->end());
VMap[&I] = NewInst; // Add instruction map to value.
- hasCalls |= (isa<CallInst>(I) && !I.isDebugOrPseudoInst());
+ if (isa<CallInst>(I) && !I.isDebugOrPseudoInst()) {
+ hasCalls = true;
+ hasMemProfMetadata |= I.hasMetadata(LLVMContext::MD_memprof);
+ }
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
if (!AI->isStaticAlloca()) {
hasDynamicAllocas = true;
@@ -70,6 +74,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
if (CodeInfo) {
CodeInfo->ContainsCalls |= hasCalls;
+ CodeInfo->ContainsMemProfMetadata |= hasMemProfMetadata;
CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas;
}
return NewBB;
@@ -100,12 +105,26 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
NewFunc->copyAttributesFrom(OldFunc);
NewFunc->setAttributes(NewAttrs);
+ const RemapFlags FuncGlobalRefFlags =
+ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges;
+
// Fix up the personality function that got copied over.
if (OldFunc->hasPersonalityFn())
- NewFunc->setPersonalityFn(
- MapValue(OldFunc->getPersonalityFn(), VMap,
- ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
- TypeMapper, Materializer));
+ NewFunc->setPersonalityFn(MapValue(OldFunc->getPersonalityFn(), VMap,
+ FuncGlobalRefFlags, TypeMapper,
+ Materializer));
+
+ if (OldFunc->hasPrefixData()) {
+ NewFunc->setPrefixData(MapValue(OldFunc->getPrefixData(), VMap,
+ FuncGlobalRefFlags, TypeMapper,
+ Materializer));
+ }
+
+ if (OldFunc->hasPrologueData()) {
+ NewFunc->setPrologueData(MapValue(OldFunc->getPrologueData(), VMap,
+ FuncGlobalRefFlags, TypeMapper,
+ Materializer));
+ }
SmallVector<AttributeSet, 4> NewArgAttrs(NewFunc->arg_size());
AttributeList OldAttrs = OldFunc->getAttributes();
@@ -132,7 +151,7 @@ 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.
- Optional<DebugInfoFinder> DIFinder;
+ std::optional<DebugInfoFinder> DIFinder;
// Track the subprogram attachment that needs to be cloned to fine-tune the
// mapping within the same module.
@@ -471,6 +490,7 @@ void PruningFunctionCloner::CloneBlock(
}
bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false;
+ bool hasMemProfMetadata = false;
// Loop over all instructions, and copy them over, DCE'ing as we go. This
// loop doesn't include the terminator.
@@ -487,8 +507,9 @@ void PruningFunctionCloner::CloneBlock(
}
// Eagerly remap operands to the newly cloned instruction, except for PHI
- // nodes for which we defer processing until we update the CFG.
- if (!isa<PHINode>(NewInst)) {
+ // nodes for which we defer processing until we update the CFG. Also defer
+ // debug intrinsic processing because they may contain use-before-defs.
+ if (!isa<PHINode>(NewInst) && !isa<DbgVariableIntrinsic>(NewInst)) {
RemapInstruction(NewInst, VMap,
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges);
@@ -514,8 +535,11 @@ void PruningFunctionCloner::CloneBlock(
if (II->hasName())
NewInst->setName(II->getName() + NameSuffix);
VMap[&*II] = NewInst; // Add instruction map to value.
- NewBB->getInstList().push_back(NewInst);
- hasCalls |= (isa<CallInst>(II) && !II->isDebugOrPseudoInst());
+ NewInst->insertInto(NewBB, NewBB->end());
+ if (isa<CallInst>(II) && !II->isDebugOrPseudoInst()) {
+ hasCalls = true;
+ hasMemProfMetadata |= II->hasMetadata(LLVMContext::MD_memprof);
+ }
if (CodeInfo) {
CodeInfo->OrigVMap[&*II] = NewInst;
@@ -573,7 +597,7 @@ void PruningFunctionCloner::CloneBlock(
Instruction *NewInst = OldTI->clone();
if (OldTI->hasName())
NewInst->setName(OldTI->getName() + NameSuffix);
- NewBB->getInstList().push_back(NewInst);
+ NewInst->insertInto(NewBB, NewBB->end());
VMap[OldTI] = NewInst; // Add instruction map to value.
if (CodeInfo) {
@@ -589,6 +613,7 @@ void PruningFunctionCloner::CloneBlock(
if (CodeInfo) {
CodeInfo->ContainsCalls |= hasCalls;
+ CodeInfo->ContainsMemProfMetadata |= hasMemProfMetadata;
CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas;
CodeInfo->ContainsDynamicAllocas |=
hasStaticAllocas && BB != &BB->getParent()->front();
@@ -628,6 +653,15 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
StartingInst = &StartingBB->front();
}
+ // Collect debug intrinsics for remapping later.
+ SmallVector<const DbgVariableIntrinsic *, 8> DbgIntrinsics;
+ for (const auto &BB : *OldFunc) {
+ for (const auto &I : BB) {
+ if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
+ DbgIntrinsics.push_back(DVI);
+ }
+ }
+
// Clone the entry block, and anything recursively reachable from it.
std::vector<const BasicBlock *> CloneWorklist;
PFC.CloneBlock(StartingBB, StartingInst->getIterator(), CloneWorklist);
@@ -650,7 +684,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
continue; // Dead block.
// Add the new block to the new function.
- NewFunc->getBasicBlockList().push_back(NewBB);
+ NewFunc->insert(NewFunc->end(), NewBB);
// Handle PHI nodes specially, as we have to remove references to dead
// blocks.
@@ -799,6 +833,19 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
VMap[OrigV] = I;
}
+ // Remap debug intrinsic operands now that all values have been mapped.
+ // Doing this now (late) preserves use-before-defs in debug intrinsics. If
+ // we didn't do this, ValueAsMetadata(use-before-def) operands would be
+ // replaced by empty metadata. This would signal later cleanup passes to
+ // remove the debug intrinsics, potentially causing incorrect locations.
+ for (const auto *DVI : DbgIntrinsics) {
+ if (DbgVariableIntrinsic *NewDVI =
+ cast_or_null<DbgVariableIntrinsic>(VMap.lookup(DVI)))
+ RemapInstruction(NewDVI, VMap,
+ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
+ TypeMapper, Materializer);
+ }
+
// Simplify conditional branches and switches with a constant operand. We try
// to prune these out when cloning, but if the simplification required
// looking through PHI nodes, those are only available after forming the full
@@ -856,7 +903,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
Dest->replaceAllUsesWith(&*I);
// Move all the instructions in the succ to the pred.
- I->getInstList().splice(I->end(), Dest->getInstList());
+ I->splice(I->end(), Dest);
// Remove the dest block.
Dest->eraseFromParent();
@@ -980,10 +1027,9 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
}
// Move them physically from the end of the block list.
- F->getBasicBlockList().splice(Before->getIterator(), F->getBasicBlockList(),
- NewPH);
- F->getBasicBlockList().splice(Before->getIterator(), F->getBasicBlockList(),
- NewLoop->getHeader()->getIterator(), F->end());
+ F->splice(Before->getIterator(), F, NewPH->getIterator());
+ F->splice(Before->getIterator(), F, NewLoop->getHeader()->getIterator(),
+ F->end());
return NewLoop;
}
@@ -1041,7 +1087,7 @@ void llvm::cloneNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
MDBuilder MDB(Context);
for (auto *ScopeList : NoAliasDeclScopes) {
- for (auto &MDOperand : ScopeList->operands()) {
+ for (const auto &MDOperand : ScopeList->operands()) {
if (MDNode *MD = dyn_cast<MDNode>(MDOperand)) {
AliasScopeNode SNANode(MD);
@@ -1066,7 +1112,7 @@ void llvm::adaptNoAliasScopes(Instruction *I,
auto CloneScopeList = [&](const MDNode *ScopeList) -> MDNode * {
bool NeedsReplacement = false;
SmallVector<Metadata *, 8> NewScopeList;
- for (auto &MDOp : ScopeList->operands()) {
+ for (const auto &MDOp : ScopeList->operands()) {
if (MDNode *MD = dyn_cast<MDNode>(MDOp)) {
if (auto *NewMD = ClonedScopes.lookup(MD)) {
NewScopeList.push_back(NewMD);