Skip to content

[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

Merged
merged 14 commits into from
Apr 23, 2025

Conversation

bnbarham
Copy link

@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 and SpillUtils.cpp. The buildShapeFromRetconInst you added had a similar refactoring upstream as well (into coro::AnyRetconABI::init + CreateNewABI).

@ahmedbougacha yours were mostly clean cherry-picks, just conflicts with all the new RISCV_VLSCall_* calling conventions.

… 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)
@bnbarham bnbarham force-pushed the cherry-missing-from-20240723 branch from f0d816b to 9d398ec Compare April 21, 2025 22:38
@bnbarham
Copy link
Author

@swift-ci please test llvm

@bnbarham bnbarham force-pushed the cherry-missing-from-20240723 branch from 9d398ec to 98637c9 Compare April 22, 2025 01:55
@bnbarham
Copy link
Author

@swift-ci please test llvm

@bnbarham
Copy link
Author

(there's an extra param that has to be passed in llvm/include/llvm/IR/Attributes.td now)

Copy link

@artemcm artemcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for the parts covering #9470. Thank you @bnbarham.

@bnbarham bnbarham force-pushed the cherry-missing-from-20240723 branch from 98637c9 to 3cf00f5 Compare April 23, 2025 02:42
nate-chandler and others added 13 commits April 22, 2025 20:48
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)
Apply to dynamic retcon coroutines the machinery added in
2937f8d for async coroutines.

And test aligning of allocas with large alignments.

rdar://148782254
(cherry picked from commit 9281ab2)
@bnbarham bnbarham force-pushed the cherry-missing-from-20240723 branch from 3cf00f5 to 2218c69 Compare April 23, 2025 03:48
@bnbarham
Copy link
Author

@swift-ci please test llvm

Copy link

@nate-chandler nate-chandler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!

@bnbarham bnbarham merged commit 39f1ef9 into swiftlang:next Apr 23, 2025
0 of 2 checks passed
@bnbarham bnbarham deleted the cherry-missing-from-20240723 branch April 23, 2025 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants