Commit Graph

836 Commits

Author SHA1 Message Date
Erik Eckstein 7ea1b1b23e SIL: add a flag [projection] to index_addr
The `projection` flag indicates that `index_addr` projects an element address from an array base address, as opposed to being used for general pointer arithmetic.
When this flag is set, the result address can only reach the single element at the given index — it is not possible to chain multiple `index_addr` instructions to reach other array elements from the result.
Without this flag, the result may be used as the base of another `index_addr`, allowing arithmetic across element boundaries (e.g. an `index_addr` with index 1 followed by an `index_addr` with index 2 reaches the element at offset 3).

An `index_addr [projection]` is mandatory to go from an array base address to an element - even if it's the first element, i.e. the index is zero.
This means that the optimizer must not remove `index_addr [projection]` with a zero index.
2026-06-09 16:17:53 +02:00
Doug Gregor 92dcbd17c6 [SIL] Explicitly keep the code generation model in SILGlobalVariable
Just like we do with SILFunction, allow a code generation model to be
specified on a SILGlobalVariable and maintain that through the printed
and serialized forms.
2026-05-20 08:35:22 -07:00
Xi Ge 7972ea36ee Merge remote-tracking branch 'origin/main' into serialize-hidden-type-layout 2026-05-15 10:12:20 -07:00
Xi Ge 00897a0efb [Serialization] Add precomputed layout table for hidden types
Add the module-format machinery that lets a Swift library record the
physical layout of hidden types (currently limited to C types imported via internal bridging header).
into binary modules, so downstream consumers can pull the layouts of these hidden types without
loading the internal dependency.

To test this, this change also added a frontend action to print hidden types' layouts
from both the module under compilation and all the modules being imported.
2026-05-15 10:07:19 -07:00
Kavon Farvardin 19119ad88a introduce @_preInverseGenerics(except:)
@_preInverseGenerics(except: <inverses>) is an extension of the existing
@_preInverseGenerics attribute that provides selective control over which
inverse requirements are mangled into a declaration's symbol name.

While the bare @_preInverseGenerics strips all inverse constraints
(~Copyable and ~Escapable) from mangling, the 'except:' form allows specific
inverses to be retained. This is needed when a type like Span already had
~Copyable mangled into its ABI-stable symbols and now needs to retroactively
adopt ~Escapable without changing those existing symbols. You can now express
that with `@_preInverseGenerics(except: ~Copyable)` to strip-out every inverse
except ~Copyable to preserve the pre-existing ~Copyable-containing symbols.

It requires the new experimental feature `PreInverseGenericsExcept`.

rdar://176395527
2026-05-14 18:27:00 -07:00
Xi Ge 08776427a1 [AST] Introduce HiddenType for mangled-name placeholders
HiddenType is a new TypeBase subclass that carries a mangled name
without leaking the actual type definition. It serves as a type-slot
placeholder for stored-property types that have been elided from a
serialized binary module, so that the client side can either

(1) resolve this mangled name to the real type if the client has access to the owning module, or

(2) use the mangled name as a key to query abstract layout information also serialized in the binary module.

As an example — a library with a hidden field of a bridging-imported type:

```
    // Utility.h (internal bridging header)
    //   typedef struct { int value; } Wrapper;

    public struct S {
      private var w: Wrapper
      public var weight: Double
    }

  In the serialized module, the client's view reconstructs as:

    public struct S {
      private var w: @_hidden("$sSo7Wrappera")
      public var weight: Double
    }
```
2026-05-12 17:13:14 -07:00
Sam Pyankov c81247d22b Serialization: Statically assert OPTIONS_BLOCK's abbrev-code width
Add a LAST_RECORD_KIND_MARKER sentinel at the end of the
options_block::RecordKind enum and a static_assert in writeHeader that
verifies the block's code width can encode every abbreviation the
writer may allocate. A future record kind that would overflow the
current code size now fails the build instead of producing a silent
malformed-module regression.

rdar://176522412
2026-05-07 20:49:43 -07:00
Xi Ge b0bfb0b731 Merge branch 'main' into abbreviation-overflow 2026-05-07 09:24:45 -07:00
Sam Pyankov ba8bb64baf Serialization: Fix silent abbreviation-ID overflow in OPTIONS_BLOCK
OPTIONS_BLOCK has historically been opened with a 4-bit abbreviation code size (BCBlockRAII(Out, OPTIONS_BLOCK_ID, 4) in Serializer::writeHeader), which permits at most 12 user-defined abbreviations (IDs 4–15, after the four reserved bitstream codes). New option records have been added incrementally, for certain flag combinations the writer now emits 13 or more abbreviations in OPTIONS_BLOCK, one past the 12-abbreviation ceiling that a 4-bit code size allows.
When that happens, the writer assigns the new abbreviation ID 16, which does not fit in 4 bits; BitstreamWriter::EmitCode silently truncates it to 0, which the reader interprets as END_BLOCK. OPTIONS_BLOCK is then popped prematurely, later records are reinterpreted as (invalid) content in the enclosing CONTROL_BLOCK, and the module fails to load with error: malformed compiled module. Widening the code size to 6 bits raises the cap to 60 user abbreviations (IDs 4–63), accommodates every currently-emitted record with substantial headroom.

rdar://176281964
2026-05-06 15:03:55 -07:00
Artem Chikin 866371d73e [Source Warning Control] Rename '@warn' to '@diagnose'
Resolves rdar://173774670
2026-04-29 10:39:25 +01:00
Konrad Malawski 92b8c7bc7d bump module format 2026-04-28 09:21:44 -07:00
Konrad Malawski 003028c17c more rename followups for isNonisolated and the enum change 2026-04-28 09:21:23 -07:00
Konrad Malawski 77ac31d946 Rename to ActorIsolation::Kind::Nonisolated*Concurrent* 2026-04-28 09:21:23 -07:00
Konrad Malawski 3beefe5bd8 Rename CallerIsolationInheriting -> NonisolatedNonsending 2026-04-28 09:21:23 -07:00
Joe Groff 097b0d3400 SIL: Split unchecked_*_enum_data_addr according to ownership and effects.
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:

- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
  projection. It is only allowed for enums whose projection operation is
  nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
  invalidating the enum and leaving the payload to be further consumed.
  This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
  The instruction takes a second operand for "scratch" space, which the
  enum representation may be copied into in order to avoid invalidating the
  enum value, so the result is dependent on the lifetime of both the
  original enum and the scratch buffer. This allows for borrowing switches
  over resilient enums.

`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.

Fixes rdar://174952822.
2026-04-27 15:40:37 -07:00
Aidan Hall d779a13f2d LifetimeDependence: Closure capture dependencies 2026-04-24 16:14:21 +01:00
Doug Gregor f2eb7cb1a8 [SIL] Model @export(interface) and @export(implementation) on SIL functions
The `@export(interface)` and `@export(implementation)` attributes
SE-0497 are queried directly on AST nodes in several places within the
SIL pipeline. However, they don't persist when SIL functions are
serialized, meaning that clients of the original module might make
different assumptions about the availability of a given function's
definition.

Represent these attributes in a SIL function (as an optional
CodeGenerationModel), (de-)serialize them into the module, and add a
textual representation as SIL function attributes `[export_interface]`
and `[export_implementation]`.
2026-04-15 13:04:10 -07:00
Doug Gregor 8713c13bef Centralize computation of the "code generation model" for object code & SIL
For a given function, we might end up emitting it's definition as
object code, serialized SIL, or both. The @export, @inlinable, and
@inline(always) attributes provide control of this behavior at the
declaration level.

Centralize the query function that will look for each of these
attributes and map down to a specific "code generation model", whose 3
options follow the naming from SE-0497: interface, inlinable, and
implementation. Use this one computation to back the queries for
"always emit into client", "never emit into client", and "inlinable"
so we can't get inconsistent results from places that are doing
one-off checks for these attributes.
2026-04-15 13:03:55 -07:00
Pavel Yaskevich 5ded52d5b4 [Serialization] Store isolation in SILFunctionType records
Generalizes how isolation is stored for SILFunctionType and
makes it possible to store not just "erased" but any future
isolation we'd need to add as well.
2026-04-10 09:35:30 -07:00
Sam Pyankov a09cf04718 Serialize library level into .swiftmodule binary format
Add a LIBRARY_LEVEL record to the .swiftmodule options block so the
declared -library-level value survives across compilations. Without
this, imported modules have to always fell back to a path heuristic
that could only distinguish API vs SPI and never returned IPI.

rdar://174255626
2026-04-08 12:17:32 -07:00
Erik Eckstein 6d8aa71814 SIL: add conformance entries to SILVTable
Conformance entries are used for fast conformance lookup, which doesn't need to query the runtime's conformance lookup table.
A conformance entry specifies if the class conforms or does not conform to a protocol.
At runtime, a type cast instruction to an existential can directly load the witness table pointer from the VTable.
If null, the class does not conform to the protocol.
2026-04-03 07:49:33 +02:00
Arnold Schwaighofer 72bd56de5b [cmo] [aggresive] Don't attach the usableFromInline attribute
in the CMO pass in aggressive mode

Changing the AST mid-pipeline is probably not a good idea.

rdar://173172456
2026-03-23 14:11:02 -07:00
Allan Shortlidge 9cfdb17d7e AST: Reorder platforms in PlatformKinds.def.
This allows stable sorting of availability domains to result in an order that
looks more natural when printed in swiftinterface files.
2026-03-12 01:50:31 -07:00
Doug Gregor 204e9197f4 Merge pull request #87747 from DougGregor/oslog-section-name-global-var 2026-03-10 06:24:25 -07:00
Doug Gregor 454237a083 Allow the OSLog module to specify the log string section name
When building the `OSLog` module, look for a variable named
`osLogStringSectionName`. It must have a string literal as its
initializer, which provides the section name where the log strings
should be emitted. The `OSLog` module should contain something like
this:

    let osLogStringSectionName = "__TEXT,__logit"

When not present, the compiler will default to
`__TEXT,__oslogstring,cstring_literals`, which was previously the
hardcoded section name. Now, OSLog can customize the name.

Implements rdar://171571056
2026-03-09 10:27:54 -07:00
Aidan Hall 187cec62e7 [Serialization] Get lifetimes with LifetimeDependenceInfoRequest
Fixes: rdar://171315715
2026-03-04 17:08:13 +00:00
Adrian Prantl fa71d1da59 [Serialization] Store the explicit module map in swiftmodules
Currently only the top level dependencies get serialized in Swift modules. In
practice this is not enough information to fully replay a module import
sequence, especially when the dependencies include binary SDK modules that were
built elsewhere. In this case we cannot follow the links to its depenencies,
since they refer to paths on a different machine or unavailable CAS. During an
EBM build, the dependency scanner writes the complete list of dependencies into
a json file called the explicit Swift module map -- including the local
locations of the dependencies of binary SDK modules. Using this LLDB can replay
a module import with 100% accuracy.

rdar://170514919
2026-02-23 14:07:08 -08:00
Yuta Saito b5162b1804 [Serialization][wasm] Preserve wasm import metadata for SIL serialization (#87250)
Serialize/deserialize wasm import module/name for SIL serialization so inlined decls keep their import names. Otherwise, inlining a function with `@_extern(wasm)` would lose the import name and cause IRGen to emit an import from the default module "env".

Related links: https://github.com/swiftwasm/JavaScriptKit/pull/631 https://github.com/swiftwasm/JavaScriptKit/pull/628

Resolves https://github.com/swiftlang/swift/issues/87320
2026-02-23 19:24:50 +00:00
Aidan Hall fbb2da1526 Serialization: Add LifetimeDependenceInfo.isFromAnnotation to module format
The isFromAnnotation flag is set if and only if the lifetime originates from a
@lifetime or @_lifetime annotation in the source program.

isFromAnnotation==false means that the lifetime dependence checker would infer
the same lifetime if the Swift type or decl was printed without an annotation
for that dependency. More specifically, it means that the depenence was inferred
by the lifetime dependence checker.

Some dependencies on imported C/C++ decls are "inferred", but they either
correspond to explicit lifetime information in the source (smart pointers,
lifetimebound attribute) or are likely to differ from what the dependence
checker would infer. As such, we set the flag to true for all of them.
2026-02-05 14:50:04 +00:00
Kavon Farvardin 4a7cedcf1e Reparenting: introduce new attributes
A protocol that's been reparented declares it
by writing `@reparented` in its inheirtance clause
for each new parent. You can introduce a `@reparented`
parent to a pre-existing ABI-stable protocol's
inheritance hierarchy.

Only protocols declared to be  `@reparentable` can be
used to reparent other protocols. Adding or removing
the `@reparentable` attribute is ABI-breaking, as it
effects the type metadata layout. Thus, reparentable
protocols must be born as such to use them with
protocols that are already ABI-stable.

This set of changes does not include the actual
implementation of ABI-stable reparenting.
2026-02-03 16:39:19 -08:00
Joe Groff bc166d5a8c Add a Builtin.Borrow type.
This will represent the layout of a borrow of a value.
2026-01-23 07:46:50 -08:00
Erik Eckstein 18063707b5 Optimizer: enable complete OSSA lifetimes throughout the pass pipeline
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.

The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
2026-01-22 17:41:48 +01:00
Meghana Gupta 0f4790ac7d Update serialization/deserialization for the new OpaqueReadOwnership kinds 2026-01-20 10:33:28 -08:00
Michael Gottesman 5d0f2e3d5e [sil] Add [inferred-immutable] flag to alloc_box instruction
Introduce a new optional flag on the alloc_box SIL instruction to mark boxes as
inferred immutable, indicating that static analysis has proven they are never
written to despite having a mutable type.

The flag is preserved through serialization/deserialization and properly printed/parsed in textual SIL format.

I am doing this to prepare for treating these boxes as being Sendable when they
contain a sendable weak reference.
2026-01-16 09:09:47 -08:00
Tim Kientzle 8eabeeb8ca [SE-0474] Read2/Modify2 => YieldingBorrow/YieldingMutate
This updates a large number of internal symbols, function names,
and types to match the final approved terminology.  Matching the
surface language terminology and the compiler internals should
make the code easier for people to understand into the future.
2026-01-03 16:05:12 -08:00
Artem Chikin e593fd97a0 Add parsing for a declaration attribute '@warn' for source-level warning group behavior control 2025-12-12 10:14:14 -08:00
Hamish Knight 302e803b2f [AST] Store original lazy VarDecl for backing storage
Store the original VarDecl in the same map we use for tracking the
original wrapper var for property wrappers. This will allow us to
use the same logic to determine the original var for both.
2025-12-08 23:22:35 +00:00
Michael Gottesman 29229a9410 [sil] Add basic SIL support for alloc_stack [non_nested].
This means I just added the flag and added support for
cloning/printing/serializing the bit on alloc_stack.
2025-11-21 11:21:14 -08:00
Slava Pestov 27097430cc Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions
We need to serialize the underlying type substitution map for an
inlinable function. However, there is no reason to deserialize it
eagerly, since doing so can lead to cycles. It is better for
correctness and performance to only deserialize it when needed.

Technically this fixes a regression from #84299, but the actual
problem was there all along, it was just exposed by my change
on a specific project.

Fixes rdar://163301203.
2025-11-20 18:13:50 -05:00
Pavel Yaskevich 47805810be [AST/Serialization] Remove isCallerIsolated bit from ParamDecl
This was used primarily by the printer and doesn't work when
`nonisolated(nonsending)` is inferred, so let's remove it.
2025-11-11 16:07:19 -08:00
Doug Gregor 020b69d4b6 [SE-0497] Implement @export attribute syntax
Implement the @export(implementation) and @export(interface) attributes
to replace @_alwaysEmitIntoClient and @_neverEmitIntoClient. Provide a
warning + Fix-It to start staging out the very-new
@_neverEmitIntoClient. We'll hold off on pushing folks toward
@_alwaysEmitIntoClient for a little longer.
2025-11-07 22:00:40 -08:00
Doug Gregor f267f62f65 [SILGen] Consistently use SIL asmname for foreign function/variable references
Whenever we have a reference to a foreign function/variable in SIL, use
a mangled name at the SIL level with the C name in the asmname
attribute. The expands the use of asmname to three kinds of cases that
it hadn't been used in yet:

* Declarations imported from C headers/modules
* @_cdecl @implementation of C headers/modules
* @_cdecl functions in general

Some code within the SIL pipeline makes assumptions that the C names of
various runtime functions are reflected at the SIL level. For example,
the linking of Embedded Swift runtime functions is done by-name, and
some of those names refer to C functions (like `swift_retain`) and
others refer to Swift functions that use `@_silgen_name` (like
`swift_getDefaultExecutor`). Extend the serialized module format to
include a table that maps from the asmname of functions/variables over
to their mangled names, so we can look up functions by asmname if we
want. These tables could also be used for checking for declarations
that conflict on their asmname in the future. Right now, we leave it
up to LLVM or the linker to do the checking.

`@_silgen_name` is not affected by these changes, nor should it be:
that hidden feature is specifically meant to affect the name at the
SIL level.

The vast majority of test changes are SIL tests where we had expected
to see the C/C++/Objective-C names in the tests for references to
foreign entities, and now we see Swift mangled names (ending in To).
The SIL declarations themselves will have a corresponding asmname.

Notably, the IRGen tests have *not* changed, because we generally the
same IR as before. It's only the modeling at the SIL lever that has
changed.

Another part of rdar://137014448.
2025-10-29 19:35:55 -07:00
Allan Shortlidge 92227ad1cf AST: Introduce the Swift, anyAppleOS, and DriverKit platform kinds.
This change just stages in a few new platform kinds, without fully adding
support for them yet.

- The `Swift` platform represents availability of the Swift runtime across all
  platforms that support an ABI stable Swift runtime (see the pitch at
  https://forums.swift.org/t/pitch-swift-runtime-availability/82742).
- The `anyAppleOS` platform is an experimental platform that represents all of
  Apple's operating systems. This is intended to simplify writing availability
  for Apple's platforms by taking advantage of the new unified OS versioning
  system announced at WWDC 2025.
- The `DriverKit` platform corresponds to Apple DriverKit which is already
  supported by LLVM.
2025-10-27 19:15:04 -07:00
Meghana Gupta e116df3628 Introduce return_borrow instruction 2025-10-23 05:18:59 -07:00
Adrian Prantl a3529784a5 Merge pull request #84412 from adrian-prantl/159531233
Serialize module dependencies in swift module files
2025-10-22 16:25:57 -07:00
Allan Shortlidge 463bf91f68 AST: Rename Swift runtime availability domain to StandaloneSwiftRuntime.
This name will distinguish the standalone Swift runtime availability domain
from the domain for the built-in Swift runtime on supported targets.
2025-10-21 21:55:25 -07:00
Adrian Prantl c91211a5d2 Serialize explicit module dependencies in swift module files
For clients, such as the debugger, who do not have access the full
output of the dependency scanner, it is a huger performance and
correctness improvement if each explicitly built Swift module not just
serialized all its Clang .pcm dependencies (via the serialized Clang
compiler invocation) but also its direct Swift module dependencies.

This patch changes the Swift module format to store the absolute path
or cas cache key for each dependency in the INPUT block, and makes
sure the deserialization makes these available to the ESML.

rdar://150969755
2025-10-21 09:08:58 -07:00
Meghana Gupta a0c939bd3b Use @inout result convention for mutate accessors 2025-10-20 09:05:32 -07:00
Michael Gottesman fe9c21fd87 [sil] Add a new instruction cast_implicit_actor_to_optional_actor.
This instruction converts Builtin.ImplicitActor to Optional<any Actor>. In the
process of doing so, it masks out the bits we may have stolen from the witness
table pointer of Builtin.ImplicitActor. The bits that we mask out are the bottom
two bits of the top nibble of the TBI space on platforms that support TBI (that
is bit 60,61 on arm64). On platforms that do not support TBI, we just use the
bottom two tagged pointer bits (0,1).

By using an instruction, we avoid having to represent the bitmasking that we are
performing at the SIL level and can instead just make the emission of the
bitmasking an IRGen detail. It also allows us to move detection if we are
compiling for AArch64 to be an IRGen flag instead of a LangOpts flag.

The instruction is a guaranteed forwarding instruction since we want to treat
its result as a borrowed projection from the Builtin.ImplicitActor.
2025-10-16 10:52:04 -07:00
Doug Gregor 081b5cd1e8 [SIL] Serialize section name correctly and model it on global variables
Fixes rdar://162549960.
2025-10-15 20:44:11 -07:00