diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-12-25 22:30:44 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-12-25 22:30:44 +0000 |
| commit | 77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (patch) | |
| tree | 5c0eb39553003b9c75a901af6bc4ddabd6f2f28c /llvm/lib/Transforms/Coroutines/CoroFrame.cpp | |
| parent | f65dcba83ce5035ab88a85fe17628b447eb56e1b (diff) | |
Diffstat (limited to 'llvm/lib/Transforms/Coroutines/CoroFrame.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index ac3d078714ce..a0d12865bd3a 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1237,8 +1237,10 @@ namespace { struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> { using Base = PtrUseVisitor<AllocaUseVisitor>; AllocaUseVisitor(const DataLayout &DL, const DominatorTree &DT, - const CoroBeginInst &CB, const SuspendCrossingInfo &Checker) - : PtrUseVisitor(DL), DT(DT), CoroBegin(CB), Checker(Checker) {} + const CoroBeginInst &CB, const SuspendCrossingInfo &Checker, + bool ShouldUseLifetimeStartInfo) + : PtrUseVisitor(DL), DT(DT), CoroBegin(CB), Checker(Checker), + ShouldUseLifetimeStartInfo(ShouldUseLifetimeStartInfo) {} void visit(Instruction &I) { Users.insert(&I); @@ -1390,6 +1392,7 @@ private: SmallPtrSet<Instruction *, 4> Users{}; SmallPtrSet<IntrinsicInst *, 2> LifetimeStarts{}; bool MayWriteBeforeCoroBegin{false}; + bool ShouldUseLifetimeStartInfo{true}; mutable llvm::Optional<bool> ShouldLiveOnFrame{}; @@ -1398,7 +1401,7 @@ private: // more precise. We look at every pair of lifetime.start intrinsic and // every basic block that uses the pointer to see if they cross suspension // points. The uses cover both direct uses as well as indirect uses. - if (!LifetimeStarts.empty()) { + if (ShouldUseLifetimeStartInfo && !LifetimeStarts.empty()) { for (auto *I : Users) for (auto *S : LifetimeStarts) if (Checker.isDefinitionAcrossSuspend(*S, I)) @@ -2484,8 +2487,15 @@ static void collectFrameAllocas(Function &F, coro::Shape &Shape, continue; } DominatorTree DT(F); + // The code that uses lifetime.start intrinsic does not work for functions + // with loops without exit. Disable it on ABIs we know to generate such + // code. + bool ShouldUseLifetimeStartInfo = + (Shape.ABI != coro::ABI::Async && Shape.ABI != coro::ABI::Retcon && + Shape.ABI != coro::ABI::RetconOnce); AllocaUseVisitor Visitor{F.getParent()->getDataLayout(), DT, - *Shape.CoroBegin, Checker}; + *Shape.CoroBegin, Checker, + ShouldUseLifetimeStartInfo}; Visitor.visitPtr(*AI); if (!Visitor.getShouldLiveOnFrame()) continue; @@ -2572,9 +2582,15 @@ void coro::salvageDebugInfo( DVI->setExpression(Expr); /// It makes no sense to move the dbg.value intrinsic. if (!isa<DbgValueInst>(DVI)) { - if (auto *InsertPt = dyn_cast<Instruction>(Storage)) + if (auto *II = dyn_cast<InvokeInst>(Storage)) + DVI->moveBefore(II->getNormalDest()->getFirstNonPHI()); + else if (auto *CBI = dyn_cast<CallBrInst>(Storage)) + DVI->moveBefore(CBI->getDefaultDest()->getFirstNonPHI()); + else if (auto *InsertPt = dyn_cast<Instruction>(Storage)) { + assert(!InsertPt->isTerminator() && + "Unimaged terminator that could return a storage."); DVI->moveAfter(InsertPt); - else if (isa<Argument>(Storage)) + } else if (isa<Argument>(Storage)) DVI->moveAfter(F->getEntryBlock().getFirstNonPHI()); } } @@ -2664,7 +2680,10 @@ void coro::buildCoroutineFrame(Function &F, Shape &Shape) { } } - sinkLifetimeStartMarkers(F, Shape, Checker); + if (Shape.ABI != coro::ABI::Async && Shape.ABI != coro::ABI::Retcon && + Shape.ABI != coro::ABI::RetconOnce) + sinkLifetimeStartMarkers(F, Shape, Checker); + if (Shape.ABI != coro::ABI::Async || !Shape.CoroSuspends.empty()) collectFrameAllocas(F, Shape, Checker, FrameData.Allocas); LLVM_DEBUG(dumpAllocas(FrameData.Allocas)); |
