We need to be able to call function pointers. Inline the dispatch
function.
rdar://70097093
Paths
| Differential D91098
[coro] Async coroutines: Allow more than 3 arguments in the dispatch function ClosedPublic Authored by aschwaighofer on Nov 9 2020, 1:04 PM.
Details Summary We need to be able to call function pointers. Inline the dispatch rdar://70097093
Diff Detail
Event TimelineComment Actions Semantically, it is not needed. But without inlining here this helper dispatch function thunk will remain at O0 because inlining is not run again. Comment Actions I am worried about introducing unnecessary thunks that the debugger has to step through. Comment Actions What is this function being inlined? We expect the frontend to emit a thunk that glues things together? Comment Actions Yes, frontend is expected to emit a thunk that models the tail call to the function at the suspend point. This prevents code moving in between the tail call and return before coroutine splitting and allows for specifying how to perform the call (e.g pointer authentication). define internal hidden void @__suspend_dispatch_3.1(i8* %0, %task* %1, %executor* %2, %context* %3) { entry: %4 = bitcast i8* %0 to void (%task*, %executor*, %context*)* tail call swiftcc void %4(%task* %1, %executor* %2, %context* %3) ret void } define linkonce_odr hidden i8* @__resume_project_context(i8* %0) { entry: %1 = bitcast i8* %0 to i8** %2 = load i8*, i8** %1, align 8 ret i8* %2 } %resume_func = call i8* @llvm.coro.async.resume() %24 = call { i8*, i8*, i8* } (i8*, i8*, ...) @llvm.coro.suspend.async( i8* %resume_func, i8* bitcast (i8* (i8*)* @__resume_project_context to i8*), i8* bitcast (void (i8*, %task*, %executor*, %context*)* @__suspend_dispatch_3.1 to i8*), i8* %fun_ptr, %task* %0, %executor* %1, %context* %22) Comment Actions Transfer the debug location from the suspend point to the functions called at and after the suspend point (context projection). Comment Actions I see. This LGTM as an immediate fix, then. I wonder if we shouldn't have a different IR design, though. Maybe we should lower directly to IR that uses a pattern more like the SIL get_unsafe_continuation pattern? i.e. %0 = call token @llvm.coro.async.continuation() // returns the continuation function pointer; must be used by exactly one suspend ... // somewhere in here we store the continuation into the child context call void @llvm.coro.async.suspend(token %0) I can't remember if we discussed and discarded this. Comment Actions Oh, unfortunately llvm.coro.async.continuation wouldn't be able to just return the continuation function pointer; there would have to be a llvm.coro.async.get_continuation_function intrinsic. But we do something similar with the alloc intrinsics. Comment Actions Use the function argument index instead of the function argument in Coerce the arguments of the tail call function at a suspend point. The LLVM This revision was landed with ongoing or failed builds. Closed by commit rG431337662ee0: [coro] Async coroutines: Allow more than 3 arguments in the dispatch function (authored by aschwaighofer). · Explain Why This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 304672 llvm/include/llvm/IR/Intrinsics.td
llvm/lib/Transforms/Coroutines/CoroFrame.cpp
llvm/lib/Transforms/Coroutines/CoroInstr.h
llvm/lib/Transforms/Coroutines/CoroSplit.cpp
llvm/lib/Transforms/Coroutines/Coroutines.cpp
llvm/test/Transforms/Coroutines/coro-async.ll
|
InlineRes will be unused in a release build. Add (void)?