Commit Graph

275 Commits

Author SHA1 Message Date
Mike Ash
93fae78e04 [IRGen][Runtime] Add emit-into-client retain/release calls for Darwin ARM64.
This is currently disabled by default. Building the client library can be enabled with the CMake option SWIFT_BUILD_CLIENT_RETAIN_RELEASE, and using the library can be enabled with the flags -Xfrontend -enable-client-retain-release.

To improve retain/release performance, we build a static library containing optimized implementations of the fast paths of swift_retain, swift_release, and the corresponding bridgeObject functions. This avoids going through a stub to make a cross-library call.

IRGen gains awareness of these new functions and emits calls to them when the functionality is enabled and the target supports them. Two options are added to force use of them on or off: -enable-client-retain-release and -disable-client-retain-release. When enabled, the compiler auto-links the static library containing the implementations.

The new calls also use LLVM's preserve_most calling convention. Since retain/release doesn't need a large number of scratch registers, this is mostly harmless for the implementation, while allowing callers to improve code size and performance by spilling fewer registers around refcounting calls. (Experiments with an even more aggressive calling convention preserving x2 and up showed an insignificant savings in code size, so preserve_most seems to be a good middle ground.)

Since the implementations are embedded into client binaries, any change in the runtime's refcounting implementation needs to stay compatible with this new fast path implementation. This is ensured by having the implementation use a runtime-provided mask to check whether it can proceed into its fast path. The mask is provided as the address of the absolute symbol _swift_retainRelease_slowpath_mask_v1. If that mask ANDed with the object's current refcount field is non-zero, then we take the slow path. A future runtime that changes the refcounting implementation can adjust this mask to match, or set the mask to all 1s to disable the old embedded fast path entirely (as long as the new representation never uses 0 as a valid refcount field value).

As part of this work, the overall approach for bridgeObjectRetain is changed slightly. Previously, it would mask off the spare bits from the native pointer and then call through to swift_retain. This either lost the spare bits in the return value (when tail calling swift_retain) which is problematic since it's supposed to return its parameter, or it required pushing a stack frame which is inefficient. Now, swift_retain takes on the responsibility of masking off spare bits from the parameter and preserving them in the return value. This is a trivial addition to the fast path (just a quick mask and an extra register for saving the original value) and makes bridgeObjectRetain quite a bit more efficient when implemented correctly to return the exact value it was passed.

The runtime's implementations of swift_retain/release are now also marked as preserve_most so that they can be tail called from the client library. preserve_most is compatible with callers expecting the standard calling convention so this doesn't break any existing clients. Some ugly tricks were needed to prevent the compiler from creating unnecessary stack frames with the new calling convention. Avert your eyes.

To allow back deployment, the runtime now has aliases for these functions called swift_retain_preservemost and swift_release_preservemost. The client library brings weak definitions of these functions that save the extra registers and call through to swift_retain/release. This allows them to work correctly on older runtimes, with a small performance penalty, while still running at full speed on runtimes that have the new preservemost symbols.

Although this is only supported on Darwin at the moment, it shouldn't be too much work to adapt it to other ARM64 targets. We need to ensure the assembly plays nice with the other platforms' assemblers, and make sure the implementation is correct for the non-ObjC-interop case.

rdar://122595871
2025-10-27 12:00:28 -04:00
swift-ci
367f0082fc Merge remote-tracking branch 'origin/main' into rebranch 2025-07-22 22:17:45 -07:00
Anthony Latsis
b04d6085f3 IRGen: Address llvm::InsertPosition ctor deprecation
See https://github.com/llvm/llvm-project/pull/102608.
2025-07-21 12:50:39 +01:00
Anthony Latsis
3ba8ab4094 IRGen: Address llvm::Instruction::{move,insert}Before deprecations
See 79499f010d.
2025-07-21 12:41:18 +01:00
Anthony Latsis
ed1d70fb3b IRGen: Address llvm::PointerType::get(Unqual) deprecations
See https://github.com/llvm/llvm-project/pull/134517.
2025-07-21 12:37:15 +01:00
Anthony Latsis
f8577a2731 IRGen: Address llvm::Type::getPointerTo deprecation
See https://github.com/llvm/llvm-project/pull/113331.
2025-07-21 12:37:15 +01:00
Anthony Latsis
08e02af30d LLVMPasses: Remove no longer needed call to removed LLVM method
See https://github.com/llvm/llvm-project/pull/143746.
2025-07-19 02:00:36 +01:00
Anthony Latsis
bb9fb7286e LLVMPasses: Switch from obsoleted llvm::IRHash to llvm::stable_hash
Per 1941c5180b91d792200d5e868d45c96e99bda35e (llvm-project).
2025-04-24 01:52:45 +01:00
Anthony Latsis
f93aba0770 IRGen, LLVMPasses: Switch from obsoleted nocapture to captures(none)
Per 29441e4f5fa5f5c7709f7cf180815ba97f611297 (llvm-project).
2025-04-24 01:52:45 +01:00
Anthony Latsis
0d2d6cb8a0 IRGen, LLVMPasses: Switch from obsoleted APIs to llvm::getPointerAuthStableSipHash
Per d68f8b96b1ff39cfcfcad94d5b16d28adaf6b5d0 (llvm-project).
2025-04-24 01:52:45 +01:00
Saleem Abdulrasool
ec70054c93 IRGen: further generalise runtime function generation
This adjusts the runtime function declaration handling to track the
owning module for the well known functions. This allows us to ensure
that we are able to properly identify if the symbol should be imported
or not when building the shared libraries. This will require a
subsequent tweak to allow for checking for static library linkage to
ensure that we do not mark the symbol as DLLImport when doing static
linking.
2025-01-15 13:54:34 -08:00
Ben Barham
565645723d [rebranch] Add another missing llvm/IR/Module.h include
More `Module.h`.
2024-09-16 16:18:12 -07:00
Ben Barham
a7b50f357f Merge remote-tracking branch 'origin/main' into manual-main-merge
Conflicts:
  - `lib/Driver/ToolChains.cpp` conflicting with the `addAllArgs` rename
    for multiple options
2024-09-16 13:53:18 -07:00
Arnold Schwaighofer
eaf90dff38 IRGen: Add metadata for async funclets denoting frame entry and frame exists
Adds sections `__TEXT,__swift_as_entry`, and `__TEXT,__swift_as_ret` that
contain relative pointers to async functlets modelling async function entries,
and function returns, respectively.

Emission of the sections can be trigger with the frontend option
`-Xfrontend -enable-async-frame-push-pop-metadata`.

This is done by:

* IRGen adding a `async_entry` function attribute to async functions.
* LLVM's coroutine splitting identifying continuation funclets that
  model the return from an async function call by adding the function
  attribute `async_ret`.  (see #llvm-project/pull/9204)
* An LLVM pass that keys off these two function attribute and emits the
  metadata into the above mention sections.

rdar://134460666
2024-09-03 08:44:16 -07:00
Ben Barham
5b4cd16647 [rebranch] Add missing llvm/IR/Module.h include
`llvm/IR/Module.h` was presumably being transitively included
previously.
2024-07-31 08:54:35 -07:00
Xi Ge
736ccef626 Merge remote-tracking branch 'apple/main' into rebranch 2024-06-20 15:16:55 -07:00
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
swift-ci
0bbe4a8055 Merge remote-tracking branch 'origin/main' into rebranch 2024-06-17 10:14:25 -07:00
Kuba Mracek
f572000d94 [ARCOpts] Don't move releases before landingpads 2024-06-15 13:12:43 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Ben Barham
bb9764cd1c [Opt] Make sure to set IsNewDbgInfoFormat when creating functions
This would be done automatically if the module was passed into
`Function::Create`, but we're quite specific about its insert location,
so just set it manually instead.
2024-04-08 08:58:59 -07:00
Ben Barham
2d05569626 [Opt] Move uses of FunctionHash to StructuralHash
These were consolidated in LLVM in 64da0be1fc06ee2199bd27c980736986e0eccd9d.
2024-04-08 08:58:59 -07:00
Ben Barham
9779c18da3 Rename startswith to starts_with
LLVM is presumably moving towards `std::string_view` -
`StringRef::startswith` is deprecated on tip. `SmallString::startswith`
was just renamed there (maybe with some small deprecation inbetween, but
if so, we've missed it).

The `SmallString::startswith` references were moved to
`.str().starts_with()`, rather than adding the `starts_with` on
`stable/20230725` as we only had a few of them. Open to switching that
over if anyone feels strongly though.
2024-03-13 22:25:47 -07:00
Ben Barham
f292ec9784 Use the new template deduction guides rather than makeArrayRef
LLVM has removed `make*ArrayRef`, migrate all references to their
constructor equivalent.
2024-02-23 20:04:51 -08:00
Rick van Voorden
f8ae46b3f3 [inclusive-language] changed sanity to soundness 2024-01-25 18:18:02 -08:00
Arnold Schwaighofer
2f94890e5f IRGen: Remove supportsTypedPointers, getNonOpaquePointerElementType, isOpaqueOrPointeeTypeMatches
Typed pointers are no longer supported by llvm.

rdar://121083958
2024-01-17 07:33:30 -08:00
swift-ci
b57534c4db Merge remote-tracking branch 'origin/main' into rebranch 2023-08-16 21:40:49 -07:00
Erik Eckstein
fda5549908 SwiftMergeFunctionsPass: fix a problem with opaque pointers
Need to insert a cast for the return type of a call to a merged function.

Fixes an LLVM verifier crash.

rdar://113901800
2023-08-16 18:19:26 +02:00
Ben Barham
249f2d030a [rebranch] Correct read only argument memory and apply in getRuntimeFn
`ReadOnly, ArgMemOnly` previously meant `can only read argument memory`.
But with the rebranch changes, this became `(can only read *all* memory)
and (can read or write argument memory)`. Use `ArgMemReadOnly` for this
instead.

To expand on this, these attributes (prior to memory effects) used to be
split into two. There was the *kind* of access, eg.
```
readnone
readonly
writeonly
```
and the accessed *location*, eg.
```
argmemonly
inaccessiblememonly
inaccessiblemem_or_argmemonly
```

So `RuntimeFunctions.def` would use `ReadOnly, ArgMemOnly` to mean `can
only read argument memory`.

In the previous rebranch commits, this was changed such that `ReadOnly`
mapped to `MemoryEffectsBase::readOnly()` and `ArgMemOnly` to
`MemoryEffectsBase::argMemOnly()`.

And there lies the issue -
  - `MemoryEffectsBase::readOnly()` == `MemoryEffectsBase(Ref)` ie. all
    locations can only read
  - `MemoryEffectsBase::argMemOnly()` == `MemoryEffectsBase(ArgMem,
    ModRef)`, ie. can only access argument memory

But then OR'ing those together this would become:
```
ArgMem: ModRef, InaccessibleMem: Ref, Other: Ref
```
rather than the previously intended:
```
ArgMem: Ref, InaccessibleMem: NoModRef, Other: NoModRef
```
2023-08-10 22:03:50 -07:00
Arnold Schwaighofer
ad88fc6cbe Revert "[rebranch] Pass memory effects through to getRuntimeFn" 2023-08-09 10:27:10 -07:00
Ben Barham
b4ad633de7 [rebranch] Pass memory effects through to getRuntimeFn
These were being lost in the `IRGenModule::get##ID##Fn()`
implementation.
2023-08-08 13:50:16 -07:00
Evan Wilde
8ce6ee8dd1 Updating API usages
LLVM deprecated, renamed, and removed a bunch of APIs. This patch
contains a lot of the changes needed to deal with that.

The SetVector type changed the template parameters.

APInt updated multiple names, countPopulation became popcount,
getAllOnesValue became getAllOnes, getNullValue became getZero, etc...

Clang type nullability check stopped taking a clang AST context.

The LLVM IRGen Function type stopped exposing basic block list directly,
but gained enough API surface that the translation isn't too bad.
(GenControl.cpp, LLVMMergeFunctions.cpp)

llvm::Optional had a transform function. That was being used in a couple
of places, so I've added a new implementation under STLExtras that
transforms valid optionals, otherwise it returns nullopt.
2023-07-17 10:53:42 -07:00
Evan Wilde
df30fffcd1 Remove dbg addr intrinsic splitting pass
The llvm DbgAddr intrinsic was removed upstream, removing the DbgAddr
block splitting pass to get the compiler building.
2023-07-17 10:53:42 -07:00
Evan Wilde
41d59b215a Update Triple.h location
Triple moved from ADT to TargetParser. Updating includes to reflect
that.
2023-07-17 10:53:42 -07:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Erik Eckstein
190fea8acc IRGen: getPointerElementType -> getNonOpaquePointerElementType
`getPointerElementType` is deprecated in a newer LLVM.
2022-11-14 20:36:09 +01:00
Arnold Schwaighofer
39194124bb Fix SwiftMergeFunctions pass for opaque pointers
Under opaque pointers there is not need to fix-up byval and structret
attributes.
2022-10-20 11:03:51 -07:00
Arnold Schwaighofer
1cb6b4a82a SwiftMergeFunction: Rewrite the byval/structret attributes when we bitcast the function type
rdar://101089253
2022-10-13 17:07:48 -07:00
Arnold Schwaighofer
d810b0f7e4 IRGen: Pass the elementType of pointers through to operations
In preparation for moving to llvm's opaque pointer representation
replace getPointerElementType and CreateCall/CreateLoad/Store uses that
dependent on the address operand's pointer element type.

This means an `Address` carries the element type and we use
`FunctionPointer` in more places or read the function type off the
`llvm::Function`.
2022-10-03 15:27:12 -07:00
Arnold Schwaighofer
5c9eab0f6c Update Swift's LLVM passes to include new pass manager versions 2022-07-15 08:22:32 -07:00
Gabriel Secula
7e298df39f LLVMMergeFunctions: Must not merge function calls to objc_sendMsg$...
It is special.

rdar://91008731
rdar://91087454
2022-03-31 11:11:53 -07:00
Michael Gottesman
5acbeed5a4 [debug-info-canonicalization] Add support for propagating debug info from alloc_stack. 2022-03-22 12:34:15 -07:00
Michael Gottesman
a553b874ce [move-function] Rather than breaking block at the SIL level after moved dbg_value, do it late as an LLVM pass on llvm.dbg.addr
This has a few nice benefits:

1. The splitting happens after LLVM optimizations have run. This ensures that
LLVM will not join these blocks no matter what! The author of this commit has
found that in certain cases LLVM does this even at -Onone. By running this late,
we get the benefit we are looking for: working around the bad SelectionDAG
behavior.

2. This block splitting is just a workaround for the above mentioned unfortunate
SelectionDAG behavior. By doing this when we remove the workaround, we will not
have to update SIL level tests... instead we will just remove a small LLVM pass.

Some additional notes:

1. Only moved values will ever have llvm.dbg.addr emitted today, so we do not
have to worry about this impacting the rest of the language.

2. The pass's behavior is tested at the IR level by move_function_dbginfo.swift.
2022-03-07 19:55:21 -08:00
Evan Wilde
52c5f1a5f1 Fix build failure in LLVMMergeFunctions
- 3e1c787b3160bed4146d3b2b5f922aeed3caafd7 `arg_operands` was replaced with `args`.
 - 80ea2bb57450a65cc724565ecfc9971ad93a3f15 `get*Attributes` was replaced with `get*Attrs`
2021-10-21 13:40:42 -07:00
Meghana Gupta
87cde88aca Fix for a crash due to performLocalReleaseMotion and performLocalRetainMotion (#38150)
In low level LLVMARCOptimizer, during canonicalization we don't rauw the result of RT_Retain with its arg similarly to RT_ObjCRetain and RT_BridgeRetain.
And during performLocalReleaseMotion, we assert that we have canonicalized RT_Retain.
In a release compiler, if we optimize such an RT_Retain with a RT_Release, then this can result in a compiler crash

Similarly not rauw'ing, can cause a crash due to performLocalRetainMotion

Fixes rdar://79238115
2021-06-30 15:40:15 -07:00
Michael Gottesman
9412f19802 [cmake] Change set_swift_llvm_is_available to set definitions on a specific target.
Otherwise we set it on all targets/languages in a subdirectory (I forgot if it
propagates up). Regardless, this type of viral stuff is something we want to
move away from since it creates a code that is a "forall" piece of code rather
than a piece of code that only effects a single target.

I also conditionalized the actual definitions being added on the compiled file's
language being C,CXX,OBJC,OBJCXX since as we add Swift sources to the host side
of the compiler, we will not want these flags to propagate to Swift sources.
2021-05-19 13:22:02 -07:00
Arnold Schwaighofer
cf9ed6e4e0 Disable swift function merging for swift async functions
It breaks withCheckedContinuation.

I have not gotten to the bottom of why. But for now disable the pass for
all async functions until we can fix it.

rdar://77166575
2021-04-29 11:45:52 -07:00
Varun Gandhi
b78e3b8615 Use musttail when merging swifttail calls.
Fixes rdar://75899459.
2021-03-26 16:38:19 -07:00
Minhyuk Kim
53d1fc481e Replace usages of .find(Key) != .end() to .contains(Key) in llvm sets 2021-02-06 18:24:20 +09:00
Minhyuk Kim
e924cf6104 Replace usages of StringRef.find(Key) != StringRef::npos to StringRef.contains(Key) 2021-02-04 00:42:04 +09:00