Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Show First 20 Lines • Show All 1,356 Lines • ▼ Show 20 Lines | static bool shouldBeMustTail(const CallInst &CI, const Function &F) { | ||||||||||
return true; | return true; | ||||||||||
} | } | ||||||||||
// Add musttail to any resume instructions that is immediately followed by a | // Add musttail to any resume instructions that is immediately followed by a | ||||||||||
// suspend (i.e. ret). We do this even in -O0 to support guaranteed tail call | // suspend (i.e. ret). We do this even in -O0 to support guaranteed tail call | ||||||||||
// for symmetrical coroutine control transfer (C++ Coroutines TS extension). | // for symmetrical coroutine control transfer (C++ Coroutines TS extension). | ||||||||||
// This transformation is done only in the resume part of the coroutine that has | // This transformation is done only in the resume part of the coroutine that has | ||||||||||
// identical signature and calling convention as the coro.resume call. | // identical signature and calling convention as the coro.resume call. | ||||||||||
static void addMustTailToCoroResumes(Function &F) { | static void addMustTailToCoroResumes(Function &F, TargetTransformInfo &TTI) { | ||||||||||
bool changed = false; | bool changed = false; | ||||||||||
// Collect potential resume instructions. | // Collect potential resume instructions. | ||||||||||
SmallVector<CallInst *, 4> Resumes; | SmallVector<CallInst *, 4> Resumes; | ||||||||||
for (auto &I : instructions(F)) | for (auto &I : instructions(F)) | ||||||||||
if (auto *Call = dyn_cast<CallInst>(&I)) | if (auto *Call = dyn_cast<CallInst>(&I)) | ||||||||||
if (shouldBeMustTail(*Call, F)) | if (shouldBeMustTail(*Call, F)) | ||||||||||
Resumes.push_back(Call); | Resumes.push_back(Call); | ||||||||||
// Set musttail on those that are followed by a ret instruction. | // Set musttail on those that are followed by a ret instruction. | ||||||||||
for (CallInst *Call : Resumes) | for (CallInst *Call : Resumes) | ||||||||||
if (simplifyTerminatorLeadingToRet(Call->getNextNode())) { | // Skip targets which don't support tail call on the specific case. | ||||||||||
if (TTI.supportsTailCallFor(Call) && | |||||||||||
simplifyTerminatorLeadingToRet(Call->getNextNode())) { | |||||||||||
ChuanqiXuUnsubmitted Done ReplyInline Actions
ChuanqiXu: | |||||||||||
Call->setTailCallKind(CallInst::TCK_MustTail); | Call->setTailCallKind(CallInst::TCK_MustTail); | ||||||||||
changed = true; | changed = true; | ||||||||||
} | } | ||||||||||
if (changed) | if (changed) | ||||||||||
removeUnreachableBlocks(F); | removeUnreachableBlocks(F); | ||||||||||
} | } | ||||||||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | static void splitSwitchCoroutine(Function &F, coro::Shape &Shape, | ||||||||||
postSplitCleanup(*CleanupClone); | postSplitCleanup(*CleanupClone); | ||||||||||
// Adding musttail call to support symmetric transfer. | // Adding musttail call to support symmetric transfer. | ||||||||||
// Skip targets which don't support tail call. | // Skip targets which don't support tail call. | ||||||||||
// | // | ||||||||||
// FIXME: Could we support symmetric transfer effectively without musttail | // FIXME: Could we support symmetric transfer effectively without musttail | ||||||||||
// call? | // call? | ||||||||||
if (TTI.supportsTailCalls()) | if (TTI.supportsTailCalls()) | ||||||||||
addMustTailToCoroResumes(*ResumeClone); | addMustTailToCoroResumes(*ResumeClone, TTI); | ||||||||||
// Store addresses resume/destroy/cleanup functions in the coroutine frame. | // Store addresses resume/destroy/cleanup functions in the coroutine frame. | ||||||||||
updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone); | updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone); | ||||||||||
assert(Clones.empty()); | assert(Clones.empty()); | ||||||||||
Clones.push_back(ResumeClone); | Clones.push_back(ResumeClone); | ||||||||||
Clones.push_back(DestroyClone); | Clones.push_back(DestroyClone); | ||||||||||
Clones.push_back(CleanupClone); | Clones.push_back(CleanupClone); | ||||||||||
▲ Show 20 Lines • Show All 527 Lines • Show Last 20 Lines |