aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/CodeExtractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/CodeExtractor.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/CodeExtractor.cpp108
1 files changed, 59 insertions, 49 deletions
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 421f1f329f07..c1fe10504e45 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -15,7 +15,6 @@
#include "llvm/Transforms/Utils/CodeExtractor.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -138,7 +137,7 @@ static bool isBlockValidForExtraction(const BasicBlock &BB,
if (auto *UBB = CSI->getUnwindDest())
if (!Result.count(UBB))
return false;
- for (auto *HBB : CSI->handlers())
+ for (const auto *HBB : CSI->handlers())
if (!Result.count(const_cast<BasicBlock*>(HBB)))
return false;
continue;
@@ -831,6 +830,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
std::vector<Type *> ParamTy;
std::vector<Type *> AggParamTy;
ValueSet StructValues;
+ const DataLayout &DL = M->getDataLayout();
// Add the types of the input values to the function's argument list
for (Value *value : inputs) {
@@ -849,7 +849,8 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
AggParamTy.push_back(output->getType());
StructValues.insert(output);
} else
- ParamTy.push_back(PointerType::getUnqual(output->getType()));
+ ParamTy.push_back(
+ PointerType::get(output->getType(), DL.getAllocaAddrSpace()));
}
assert(
@@ -864,7 +865,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
StructType *StructTy = nullptr;
if (AggregateArgs && !AggParamTy.empty()) {
StructTy = StructType::get(M->getContext(), AggParamTy);
- ParamTy.push_back(PointerType::getUnqual(StructTy));
+ ParamTy.push_back(PointerType::get(StructTy, DL.getAllocaAddrSpace()));
}
LLVM_DEBUG({
@@ -902,26 +903,21 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
// Those attributes cannot be propagated safely. Explicitly list them
// here so we get a warning if new attributes are added.
case Attribute::AllocSize:
- case Attribute::ArgMemOnly:
case Attribute::Builtin:
case Attribute::Convergent:
- case Attribute::InaccessibleMemOnly:
- case Attribute::InaccessibleMemOrArgMemOnly:
case Attribute::JumpTable:
case Attribute::Naked:
case Attribute::NoBuiltin:
case Attribute::NoMerge:
case Attribute::NoReturn:
case Attribute::NoSync:
- case Attribute::ReadNone:
- case Attribute::ReadOnly:
case Attribute::ReturnsTwice:
case Attribute::Speculatable:
case Attribute::StackAlignment:
case Attribute::WillReturn:
- case Attribute::WriteOnly:
case Attribute::AllocKind:
case Attribute::PresplitCoroutine:
+ case Attribute::Memory:
continue;
// Those attributes should be safe to propagate to the extracted function.
case Attribute::AlwaysInline:
@@ -963,6 +959,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::NoCfCheck:
case Attribute::MustProgress:
case Attribute::NoProfile:
+ case Attribute::SkipProfile:
break;
// These attributes cannot be applied to functions.
case Attribute::Alignment:
@@ -980,6 +977,8 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::NoUndef:
case Attribute::NonNull:
case Attribute::Preallocated:
+ case Attribute::ReadNone:
+ case Attribute::ReadOnly:
case Attribute::Returned:
case Attribute::SExt:
case Attribute::StructRet:
@@ -989,6 +988,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::ZExt:
case Attribute::ImmArg:
case Attribute::ByRef:
+ case Attribute::WriteOnly:
// These are not really attributes.
case Attribute::None:
case Attribute::EndAttrKinds:
@@ -999,7 +999,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
newFunction->addFnAttr(Attr);
}
- newFunction->getBasicBlockList().push_back(newRootNode);
+ newFunction->insert(newFunction->end(), newRootNode);
// Create scalar and aggregate iterators to name all of the arguments we
// inserted.
@@ -1208,7 +1208,7 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), i);
GetElementPtrInst *GEP = GetElementPtrInst::Create(
StructArgTy, Struct, Idx, "gep_" + StructValues[i]->getName());
- codeReplacer->getInstList().push_back(GEP);
+ GEP->insertInto(codeReplacer, codeReplacer->end());
new StoreInst(StructValues[i], GEP, codeReplacer);
NumAggregatedInputs++;
}
@@ -1226,7 +1226,7 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
if (auto DL = newFunction->getEntryBlock().getTerminator()->getDebugLoc())
call->setDebugLoc(DL);
}
- codeReplacer->getInstList().push_back(call);
+ call->insertInto(codeReplacer, codeReplacer->end());
// Set swifterror parameter attributes.
for (unsigned SwiftErrArgNo : SwiftErrorArgs) {
@@ -1246,7 +1246,7 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), aggIdx);
GetElementPtrInst *GEP = GetElementPtrInst::Create(
StructArgTy, Struct, Idx, "gep_reload_" + outputs[i]->getName());
- codeReplacer->getInstList().push_back(GEP);
+ GEP->insertInto(codeReplacer, codeReplacer->end());
Output = GEP;
++aggIdx;
} else {
@@ -1258,8 +1258,8 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
codeReplacer);
Reloads.push_back(load);
std::vector<User *> Users(outputs[i]->user_begin(), outputs[i]->user_end());
- for (unsigned u = 0, e = Users.size(); u != e; ++u) {
- Instruction *inst = cast<Instruction>(Users[u]);
+ for (User *U : Users) {
+ Instruction *inst = cast<Instruction>(U);
if (!Blocks.count(inst->getParent()))
inst->replaceUsesOfWith(outputs[i], load);
}
@@ -1435,21 +1435,17 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
}
void CodeExtractor::moveCodeToFunction(Function *newFunction) {
- Function *oldFunc = (*Blocks.begin())->getParent();
- Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList();
- Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList();
-
auto newFuncIt = newFunction->front().getIterator();
for (BasicBlock *Block : Blocks) {
// Delete the basic block from the old function, and the list of blocks
- oldBlocks.remove(Block);
+ Block->removeFromParent();
// Insert this basic block into the new function
// Insert the original blocks after the entry block created
// for the new function. The entry block may be followed
// by a set of exit blocks at this point, but these exit
// blocks better be placed at the end of the new function.
- newFuncIt = newBlocks.insertAfter(newFuncIt, Block);
+ newFuncIt = newFunction->insert(std::next(newFuncIt), Block);
}
}
@@ -1538,7 +1534,8 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
assert(OldSP->getUnit() && "Missing compile unit for subprogram");
DIBuilder DIB(*OldFunc.getParent(), /*AllowUnresolved=*/false,
OldSP->getUnit());
- auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
+ auto SPType =
+ DIB.createSubroutineType(DIB.getOrCreateTypeArray(std::nullopt));
DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition |
DISubprogram::SPFlagOptimized |
DISubprogram::SPFlagLocalToUnit;
@@ -1555,18 +1552,25 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
// point to a variable in the wrong scope.
SmallDenseMap<DINode *, DINode *> RemappedMetadata;
SmallVector<Instruction *, 4> DebugIntrinsicsToDelete;
+ DenseMap<const MDNode *, MDNode *> Cache;
for (Instruction &I : instructions(NewFunc)) {
auto *DII = dyn_cast<DbgInfoIntrinsic>(&I);
if (!DII)
continue;
- // Point the intrinsic to a fresh label within the new function.
+ // Point the intrinsic to a fresh label within the new function if the
+ // intrinsic was not inlined from some other function.
if (auto *DLI = dyn_cast<DbgLabelInst>(&I)) {
+ if (DLI->getDebugLoc().getInlinedAt())
+ continue;
DILabel *OldLabel = DLI->getLabel();
DINode *&NewLabel = RemappedMetadata[OldLabel];
- if (!NewLabel)
- NewLabel = DILabel::get(Ctx, NewSP, OldLabel->getName(),
+ if (!NewLabel) {
+ DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
+ *OldLabel->getScope(), *NewSP, Ctx, Cache);
+ NewLabel = DILabel::get(Ctx, NewScope, OldLabel->getName(),
OldLabel->getFile(), OldLabel->getLine());
+ }
DLI->setArgOperand(0, MetadataAsValue::get(Ctx, NewLabel));
continue;
}
@@ -1587,17 +1591,23 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
DebugIntrinsicsToDelete.push_back(DVI);
continue;
}
-
- // Point the intrinsic to a fresh variable within the new function.
- DILocalVariable *OldVar = DVI->getVariable();
- DINode *&NewVar = RemappedMetadata[OldVar];
- if (!NewVar)
- NewVar = DIB.createAutoVariable(
- NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
- OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
- OldVar->getAlignInBits());
- DVI->setVariable(cast<DILocalVariable>(NewVar));
+ // If the variable was in the scope of the old function, i.e. it was not
+ // inlined, point the intrinsic to a fresh variable within the new function.
+ if (!DVI->getDebugLoc().getInlinedAt()) {
+ DILocalVariable *OldVar = DVI->getVariable();
+ DINode *&NewVar = RemappedMetadata[OldVar];
+ if (!NewVar) {
+ DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
+ *OldVar->getScope(), *NewSP, Ctx, Cache);
+ NewVar = DIB.createAutoVariable(
+ NewScope, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
+ OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
+ OldVar->getAlignInBits());
+ }
+ DVI->setVariable(cast<DILocalVariable>(NewVar));
+ }
}
+
for (auto *DII : DebugIntrinsicsToDelete)
DII->eraseFromParent();
DIB.finalizeSubprogram(NewSP);
@@ -1606,13 +1616,13 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
// function.
for (Instruction &I : instructions(NewFunc)) {
if (const DebugLoc &DL = I.getDebugLoc())
- I.setDebugLoc(DILocation::get(Ctx, DL.getLine(), DL.getCol(), NewSP));
+ I.setDebugLoc(
+ DebugLoc::replaceInlinedAtSubprogram(DL, *NewSP, Ctx, Cache));
// Loop info metadata may contain line locations. Fix them up.
- auto updateLoopInfoLoc = [&Ctx, NewSP](Metadata *MD) -> Metadata * {
+ auto updateLoopInfoLoc = [&Ctx, &Cache, NewSP](Metadata *MD) -> Metadata * {
if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
- return DILocation::get(Ctx, Loc->getLine(), Loc->getColumn(), NewSP,
- nullptr);
+ return DebugLoc::replaceInlinedAtSubprogram(Loc, *NewSP, Ctx, Cache);
return MD;
};
updateLoopMetadataDebugLocations(I, updateLoopInfoLoc);
@@ -1653,14 +1663,14 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
}
}
- // Remove @llvm.assume calls that will be moved to the new function from the
- // old function's assumption cache.
+ // Remove CondGuardInsts that will be moved to the new function from the old
+ // function's assumption cache.
for (BasicBlock *Block : Blocks) {
for (Instruction &I : llvm::make_early_inc_range(*Block)) {
- if (auto *AI = dyn_cast<AssumeInst>(&I)) {
+ if (auto *CI = dyn_cast<CondGuardInst>(&I)) {
if (AC)
- AC->unregisterAssumption(AI);
- AI->eraseFromParent();
+ AC->unregisterAssumption(CI);
+ CI->eraseFromParent();
}
}
}
@@ -1725,7 +1735,7 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
});
});
}
- newFuncRoot->getInstList().push_back(BranchI);
+ BranchI->insertInto(newFuncRoot, newFuncRoot->end());
ValueSet SinkingCands, HoistingCands;
BasicBlock *CommonExit = nullptr;
@@ -1778,7 +1788,7 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
auto Count = BFI->getProfileCountFromFreq(EntryFreq.getFrequency());
if (Count)
newFunction->setEntryCount(
- ProfileCount(Count.value(), Function::PCT_Real)); // FIXME
+ ProfileCount(*Count, Function::PCT_Real)); // FIXME
BFI->setBlockFreq(codeReplacer, EntryFreq.getFrequency());
}
@@ -1854,7 +1864,7 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
const Function &NewFunc,
AssumptionCache *AC) {
for (auto AssumeVH : AC->assumptions()) {
- auto *I = dyn_cast_or_null<CallInst>(AssumeVH);
+ auto *I = dyn_cast_or_null<CondGuardInst>(AssumeVH);
if (!I)
continue;
@@ -1866,7 +1876,7 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
// that were previously in the old function, but that have now been moved
// to the new function.
for (auto AffectedValVH : AC->assumptionsFor(I->getOperand(0))) {
- auto *AffectedCI = dyn_cast_or_null<CallInst>(AffectedValVH);
+ auto *AffectedCI = dyn_cast_or_null<CondGuardInst>(AffectedValVH);
if (!AffectedCI)
continue;
if (AffectedCI->getFunction() != &OldFunc)