For types like `Atomic` and `Mutex`, we want to know that even though they are
technically bitwise-takable, they differ from other bitwise-takable types until
this point because they are not also "bitwise-borrowable"; while borrowed,
they are pinned in memory, so they cannot be passed by value as a borrowed
parameter, unlike copyable bitwise-takable types. Add a bit to the value witness
table flags to record this.
Note that this patch does not include any accompanying runtime support for
propagating the flag into runtime-instantiated type metadata. There isn't yet
any runtime functionality that varies based on this flag, so that can
be implemented separately.
rdar://136396806
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
* [Executors][Distributed] custom executors for distributed actor
* harden ordering guarantees of synthesised fields
* the issue was that a non-default actor must implement the is remote check differently
* NonDefaultDistributedActor to complete support and remote flag handling
* invoke nonDefaultDistributedActorInitialize when necessary in SILGen
* refactor inline assertion into method
* cleanup
* [Executors][Distributed] Update module version for NonDefaultDistributedActor
* Minor docs cleanup
* we solved those fixme's
* add mangling test for non-def-dist-actor
And use the new bit to ensure we don't try to lower move-only types
with common layout value witness surrogates. Take a bit in the runtime
value witness flags to represent types that are not copyable.
Noncopyable types aren't really "POD", but the bit is still useful to track
whether a noncopyable type has a no-op destroy operation, so rename the
existing bit to be more specific within IRGen's implementation.
Don't rename it in the runtime or Builtin names yet, since doing so will
require a naming transition for compatibility.
Since these types have an implicit stored property, this requires
adding an abstraction over fields to IRGen, at least throughout
the class code. In some ways I think this significantly improves
the code, especially in how we approach missing members.
Fixes rdar://72202671.
of adding a property.
This better matches what the actual implementation expects,
and it avoids some possibilities of weird mismatches. However,
it also requires special-case initialization, destruction, and
dynamic-layout support, none of which I've added yet.
In order to get NSObject default actor subclasses to use Swift
refcounting (and thus avoid the need for the default actor runtime
to generally use ObjC refcounting), I've had to introduce a
SwiftNativeNSObject which we substitute as the superclass when
inheriting directly from NSObject. This is something we could
do in all NSObject subclasses; for now, I'm just doing it in
actors, although it's all actors and not just default actors.
We are not yet taking advantage of our special knowledge of this
class anywhere except the reference-counting code.
I went around in circles exploring a number of alternatives for
doing this; at one point I basically had a completely parallel
"ForImplementation" superclass query. That proved to be a lot
of added complexity and created more problems than it solved.
We also don't *really* get any benefit from this subclassing
because there still wouldn't be a consistent superclass for all
actors. So instead it's very ad-hoc.
When the first element in the heap layout was non fixed we would use the
mininum size of the total heap layout for the initial offset. This would
create unneccessary large heap layouts.
rdar://61716736
Wait until we know the full size of the SpareBitVector before we
construct it from the spare bit masks of the individual elements
in the struct. This process mirrors the way we construct the rest
of the struct type.
This should reduce the number of short-lived allocations required
to build small struct types (especially after #25240). It also
provides a convenient place to insert code to handle the
construction of big-endian bit masks on when targeting big-endian
machines, assuming we decide to go down that route.
Field offset vectors are always filled out with either zero or the static layout's offset, depending on the metadata initialization strategy. This change means that the static layout's offset will only be non-zero for properties with a statically-known layout. Existing runtimes doing dynamic class layout assign class properties a zero offset if the field offset vector entry is zero and the property is zero-sized. So this effectively brings the compiler into accord with the runtime (for all newly-compiled Swift code, which will eventually be all Swift code because the current public releases of Swift 5 are not yet considered ABI-stable) and guarantees a zero value for the offset everywhere.
Since the runtime will agree with the compiler about the zero value of the offset, the compiler can continue to emit such offset variables as constant. The exception to this rule is if the class has non-fragile ObjC ancestry, in which case the ObjC runtime (which is not aware of this special rule for empty fields) will attempt to slide it along with everything else.
Fixes rdar://48031465, in which the `FixedClassMetadataBuilder` for a class with a legacy-fixed layout was writing a non-zero offset for an empty field into the field offset vector, causing the runtime to not apply the special case and thus to compute a non-zero offset, which it then attempted to copy into the global field offset variable, which the compiler had emitted as a true-constant zero.
The type info for a class described its layout using a combination of a
StructLayout and ClassLayout, with different information stored in both.
Since we never use a class as a struct, it's simpler to add the relevant
bits to ClassLayout, and not build a StructLayout at all.
Also, drop inherited properties from the ClassLayout -- they're no
longer needed.
Asking isFixedLayout() on the class's StructLayout does not take
missing members or Objective-C sliding into account. Adding a new
bit that carries this information allows removing the hack where
across modules the size of a class was always loaded from metadata.
In practice we hope most classes will be resilient, but its
better to centralize the checking for what resilience means instead
of using different rules in different places.
We would lay out all classes starting with a Swift-style two-word header, even classes that inherit NSObject and therefore don't have Swift refcounting. The ObjC runtime would slide our ivars down for us at realization time, but it's nice to avoid unnecessarily dirtying memory in the not-uncommon case of direct NSObject subclasses.
properties of classes with generic layouts.
Previously we were falling back on accessing them via the field
offset vector even when we knew everything about the type.
As a minor benefit, this allows RemoteAST to also determine offsets
for members of classes with generic layout.
Half of the test changes are IR type-name uniquing; I'm going to
explore mangling these with the full type where possible.
Give empty fields a notional byte offset so we can still use the offset of the first field as an approximation of the instanceStart of a class.
Fixes SR-1055.
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size. This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.
This patch requires an associated LLDB change which is being
submitted in parallel.
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
ClassLayoutBuilder computes a bunch of stuff in addition to the
StructLayout, which is then stashed in ClassTypeInfo. Extract this
into a new ClassLayout type. It probably should not exist at all,
if we only generalized StructLayout a bit.
For example, if a @_fixed_layout struct A contains a resilient struct B
from the same module M, then inside M, A can have a fixed size, but
outside, A has a dynamic size because B is opaque. In this case, A is
not "universally fixed-size". This impacts multi-payload enums, because
if A is placed inside a multi-payload enum E which is lowered inside X,
we would get a fixed layout with spare bits, but lowering E outside of
X would yield a dynamic layout. This is incorrect.
Fix this by plumbing through a new predicate IsAlwaysFixedSize, which
is similar to IsPOD and IsBitwiseTakable, where a compound type inherits
the property if all leaf types exhibit it, and only use spare bits if
the original and substituted types have this property.
This is an internal-only affordance for the numerics team to be able to work on SIMD-compatible types. For now, it can only increase alignment of fixed-layout structs and enums; dynamic layout, classes, and other obvious extensions are left to another day when we can design a proper layout control design.
Swift SVN r27323
Previously some parts of the compiler referred to them as "fields",
and most referred to them as "elements". Use the more generic 'elements'
nomenclature because that's what we refer to other things in the compiler
(e.g. the elements of a bracestmt).
At the same time, make the API better by providing "getElement" consistently
and using it, instead of getElements()[i].
NFC.
Swift SVN r26894
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
This commit repplies r24305 with two fixes:
- It fixes the computation of spare bits for unusual
integer types to use the already-agreed-upon type
size instead of recomputing it. This fixes the
i386 stdlib build. Joe and I agreed that we should
also change the size to use the LLVM alloc size
instead of the next power of 2, but this patch
does not do that yet.
- It changes the spare bits in function types back
to the empty set. I'll be changing this in a
follow-up, but it needs to be tied to runtime
changes. This fixes the regression test failures.
Swift SVN r24324
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
Swift SVN r24305
llvm::Optional lives in "llvm/ADT/Optional.h". Like Clang, we can get
Optional in the 'swift' namespace by including "swift/Basic/LLVM.h".
We're now fully switched over to llvm::Optional!
Swift SVN r22477
In value witness table generation, and probably other places, we're inappropriately assuming that 'initializeWithTake' is equivalent to a memcpy in all cases, which isn't true for types that carry weak references or for potentially other types in the future. Add an 'isBitwiseTakable' property to TypeInfos that can be checked to see whether a type is bitwise-takable.
Swift SVN r16799
When doing struct layout for fixed-layout structs or tuples, combine the spare bit masks of their elements to form the spare bit mask of the aggregate, treating padding between elements as spare bits as well.
For now, disable using these spare bits to form extra inhabitants for structs and tuples; we would need additional runtime work to expose these extra inhabitants for correct generic runtime behavior. This puts us in a weird situation where 'enum { case A(Struct), B, C }' spills a bit but 'enum { case A(Struct), B(Struct), C }' doesn't, but the work to make the former happen isn't immediately critical for String optimization.
Swift SVN r12165
This completes the FileUnit refactoring. A module consists of multiple
FileUnits, which provide decls from various file-like sources. I say
"file-like" because the Builtin module is implemented with a single
BuiltinUnit, and imported Clang modules are just a single FileUnit source
within a module.
Most modules, therefore, contain a single file unit; only the main module
will contain multiple source files (and eventually partial AST files).
The term "translation unit" has been scrubbed from the project. To refer
to the context of declarations outside of any other declarations, use
"top-level" or "module scope". To refer to a .swift file or its DeclContext,
use "source file". To refer to a single unit of compilation, use "module",
since the model is that an entire module will be compiled with a single
driver call. (It will still be possible to compile a single source file
through the direct-to-frontend interface, but only in the context of the
whole module.)
Swift SVN r10837
We need these for dependent-layout generic classes so we know the allocation/deallocation size and alignment. When I figure out ObjC interop with generic subclasses these should move to the rodata so they get handled resiliently by the ObjC runtime, but for generic class bringup this is convenient.
Swift SVN r9249