-
Notifications
You must be signed in to change notification settings - Fork 339
[next] Cherry-pick commits on stable/20240723 but not next #10520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[next] Cherry-pick commits on stable/20240723 but not next #10520
Conversation
… instance which may differ from the one in the ASTContext As per swiftlang/swift#65930, Swift compiler's built-in Clang instance may require to perform type-checking against one OS version and compilation/code-generation against an earlier version. This change allows Swift to configure it's built-in Clang code-generator with a custom 'TargetInfo'. Part of rdar://113712186 (cherry picked from commit 9894e7a)
f0d816b
to
9d398ec
Compare
@swift-ci please test llvm |
9d398ec
to
98637c9
Compare
@swift-ci please test llvm |
(there's an extra param that has to be passed in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
98637c9
to
3cf00f5
Compare
Like async coroutines, it's fixed-per-function-size frame is caller allocated--the size is stored in a global "coro function pointer". Like retcon coroutines, dynamic allocations are performed via intrinsic-provided allocation and deallocation functions. Unlike both, it takes an allocator struct as an argument which is forwarded to the allocation/deallocation functions. (cherry picked from commit b0e1dc9)
When the coroutine is using the swiftcorocc convention, branch on the nullness of the allocator argument. If it's null, use a popless return. Otherwise, use a regular return. (cherry picked from commit 570f7b4)
Delete provisional coro.return intrinsic. (cherry picked from commit 3026ca3)
It became uncovered in swiftlang#10120 . Fix that here. (cherry picked from commit 82d3bcd)
When CoroSplit rewrites returns as unreachables, look for an llvm.ret.popless intrinsic before the return and delete it. Fixes a verification error. (cherry picked from commit 8abe108)
The 'swiftcorocc' calling convention is a variant of 'swiftcc', but additionally allows the 'swiftcorocc' function to have popless returns. "popless" returns don't fully restore the stack, thereby allowing the caller to access some stack allocations made in the 'swiftcorocc' callee. Calls to these functions don't restore SP (but do restore FP). So the most important characteristic of a 'swiftcorocc' call is that it forces the caller function to access its stack through FP, like it does with e.g., variable-size allocas. This patch only implements the 'swiftcorocc' keyword and CallingConv, but doesn't implement its support on any target yet. (cherry picked from commit 1bbe5a2)
It doesn't have any really interesting treatment, other than being passed in a fixed register. In most of our AArch64 calling conventions, that's X23. In effect, this is mostly similar to swiftself. rdar://135984630 (cherry picked from commit d257da7)
'swiftcorocc' calls are allowed to have "popless" returns, which don't fully restore the stack, thereby allowing the caller to access some stack allocations made in the 'swiftcorocc' callee. Concretely, calls to these functions don't restore SP (but do restore FP). So the most important characteristic of a 'swiftcorocc' call is that it forces the caller function to access its stack through FP, like it does with e.g., variable-size allocas. Support this on AArch64 by marking the frame as having a popless call, which we generally honor when we decide whether the frame needs FP and FP-based addressing, as we do today for variably-sized allocas. rdar://135984630 (cherry picked from commit 6f2f9bd)
Marks the following ret instruction as a "popless" return, one that does not not restore SP to its function-entry value (i.e., does not deallocate the stack frame), allowing allocations made in the function to be accessible by the caller. The function must be annotated with an appropriate target-specific calling convention, so the caller can generate stack accesses accordingly, generally by treating the call as a variably-sized alloca, so using FP-based addressing for its own frame rather than relying on statically known SP offsets. The single argument is forwarded as a return value, that must then be used as the operand to the following ret instruction. Calls to this intrinsic need to be musttail, but don't follow the other ABI requirements for musttail calls, since this is really annotating the ret. This doesn't implement any lowering, but only adds the intrinsic definition, basic verifier checks, and an inliner opt-out. rdar://135984630 (cherry picked from commit f563fd5)
On AArch64, swiftcorocc functions are the only functions yet that can support popless returns. In the backend, that's done by recognizing the musttail call to llvm.ret.popless preceding a ret instruction, and asking the target to adjust that ret to be popless. Throughout most of the backend, that's not an interesting difference. In frame lowering, these popless rets now induce several special behaviors in their (never shrink-wrapped) epilogues, all consequences of not restoring SP: - they of course don't do the SP adjustment or restore itself. - most importantly, they force the epilogue callee-save restores to be FP-based rather than SP-based. - they restore FP/LR last, as we still need the old FP, pointing at the frame being destroyed, to do the CSR restoring. - with ptrauth-returns, they first derive the entry SP from FP, into X16, to use as a discriminator for a standalone AUTIB. rdar://135984630 (cherry picked from commit 52307ab)
We originally had the intrinsic forward its return value to the ret to have musttail-like behavior, which ensured it was always preserved. Now that the intrinsic call is musttail but doesn't have any forwarded operands, it needs to be kept alive through other means. It might make sense to mark it as having side effects, and not duplicable, but that shouldn't be necessary, and it's as duplicable as any musttail call+ret sequence would be. Because of this, we can't rely on it being DCE'd in ISel either, so drop it explicitly in IRTranslator for GISel. We already had to do it in SDISel anyway. While there, explicitly reject it in FastISel. rdar://147236255 (cherry picked from commit 384770e)
In a swiftcorocc function, on the restoreless epilogue path (using llvm.ret.popless), we're using FP-based addressing to restore callee-saved registers, as we can't rely on SP having been restored to its initial value, since we're not restoring it at all. FP-based CSR restore is novel and bound to find interesting divergence from all of our existing epilogues. In this case, at least the problem is pretty simple, and was even visible in one of the original test case: we were missing the statically-sized locals. I haven't gotten to the point of convincing myself this is sufficient yet, and I'm confident I'm missing some other convoluted PEI-ism, but with this we can actually successfully run a bunch of end-to-end swift tests! While there, add an assert that checks that the FP/LR frame record itself is only ever loaded from FP+0, without an offset. If there's an offset from FP, we must have goofed somewhere, since that breaks the frame record linked list. rdar://147838968 (cherry picked from commit 8fc6907)
3cf00f5
to
2218c69
Compare
@swift-ci please test llvm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
@artemcm you had #9470 up, but it had a conflict now so fixed that here.
@nate-chandler the first commit is where most of the pain is (f1d437f) - there were a bunch of refactorings done upstream. See the new
CoroShape.h
andSpillUtils.cpp
. ThebuildShapeFromRetconInst
you added had a similar refactoring upstream as well (intocoro::AnyRetconABI::init
+CreateNewABI
).@ahmedbougacha yours were mostly clean cherry-picks, just conflicts with all the new
RISCV_VLSCall_*
calling conventions.