I’m using the LLVM coroutine intrinsics in a front-end project and noticed that lifetime markers are only used by the switched-resume lowering to optimize the coroutine frame size (disclaimer: I don’t know much about LLVM coroutines). For instance, I have the following IR:
define void @spilled_alloca_af(ptr %0) {
%2 = call token @llvm.coro.id.async(i32 32, i32 8, i32 0, ptr @spilled_alloca_afp)
%3 = call ptr @llvm.coro.begin(token %2, ptr null)
%4 = getelementptr inbounds i8, ptr %3, i32 -32
%5 = call ptr @llvm.coro.async.resume()
%6 = getelementptr inbounds i8, ptr %3, i32 -32
%7 = getelementptr inbounds { ptr, { ptr, ptr }, i32 }, ptr %6, i32 0, i32 0
store ptr %5, ptr %7, align 8
%8 = call { ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0s(i32 0, ptr %5, ptr @__kgen_coro_ctxt_proj_fn, ptr @spilled_alloca_af.suspend)
%9 = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr %9)
call void @bar(ptr %9)
call void @llvm.lifetime.end.p0(i64 4, ptr %9)
%10 = getelementptr inbounds i8, ptr %3, i32 -32
%11 = call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr %3, i1 false, ptr @__kgen_coro_end_fn, ptr %10)
ret void
}
Where the alloca
and its lifetime markers are all after the suspend point. Ideally, the first resume function would look like
define internal void @spilled_alloca_af.resume.0(ptr %0) {
entryresume.0:
%3 = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %3)
call void @bar(ptr nonnull %3)
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %3)
// ...
ret void
}
But I’m seeing the alloca being put into the coroutine frame instead. In CoroFrame.cpp I see
// 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);
My question is: why? Does the Async ABI always generate code like this, and if it can be avoided, can this be made configurable?