Previously it was testing for opened existentials specifically.
We should really teach outlining to handle local archetypes properly.
We'd have to build a generic signature for the lowered type, and that
probably means also adding requirements that are relevant to value
operations, but it would mean outlining would benefit all types, and
it would let us avoid bundling in unnecessary information from the
enclosing generic environment.
A minor side-effect of this is that we no longer bind names to
opened element type values. The names were things like \tau_1_0,
which is not very useful, especially in LLVM IR where \tau is
printed with two UTF-8 escapes.
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.
rdar://105837040
* WIP: Store layout string in type metadata
* WIP: More cases working
* WIP: Layout strings almost working
* Add layout string pointer to struct metadata
* Fetch bytecode layout strings from metadata in runtime
* More efficient bytecode layout
* Add support for interpreted generics in layout strings
* Layout string instantiation, take and more
* Remove duplicate information from layout strings
* Include size of previous object in next objects offset to reduce number of increments at runtime
* Add support for existentials
* Build type layout strings with StructBuilder to support target sizes and metadata pointers
* Add support for resilient types
* Properly cache layout strings in compiler
* Generic resilient types working
* Non-generic resilient types working
* Instantiate resilient type in layout when possible
* Fix a few issues around alignment and signing
* Disable generics, fix static alignment
* Fix MultiPayloadEnum size when no extra tag is necessary
* Fixes after rebase
* Cleanup
* Fix most tests
* Fix objcImplementattion and non-Darwin builds
* Fix BytecodeLayouts on non-Darwin
* Fix Linux build
* Fix sizes in linux tests
* Sign layout string pointers
* Use nullptr instead of debug value
The `deinit` takes full responsibility for destroying the value, using the
user-defined deinit body and implicitly destroying any remaining resources
not consumed during the deinit.
Remaining to do after this patch:
- Run the deinit for enums
- Pass generic arguments for generic move-only types
- Handle deinits that take their parameter indirectly
- Teach value witness layout about when types are move-only and/or have
deinits, so that we don't attempt to give move-only types standard
value witness tables or share box metadata with copyable payloads
* Introduce TypeLayout Strings
Layout strings encode the structure of a type into a byte string that can be
interpreted by a runtime function to achieve a destroy or copy. Rather than
generating ir for a destroy/assignWithCopy/etc, we instead generate a layout
string which encodes enough information for a called runtime function to
perform the operation for us. Value witness functions tend to be quite large,
so this allows us to replace them with a single call instead. This gives us the
option of making a codesize/runtime cost trade off.
* Added Attribute @_GenerateLayoutBytecode
This marks a type definition that should use generic bytecode based
value witnesses rather than generating the standard suite of
value witness functions. This should reduce the codesize of the binary
for a runtime interpretation of the bytecode cost.
* Statically link in implementation
Summary:
This creates a library to store the runtime functions in to deploy to
runtimes that do not implement bytecode layouts. Right now, that is
everything. Once these are added to the runtime itself, it can be used
to deploy to old runtimes.
* Implement Destroy at Runtime Using LayoutStrings
If GenerateLayoutBytecode is enabled, Create a layout string and use it
to call swift_generic_destroy
* Add Resilient type and Archetype Support for BytecodeLayouts
Add Resilient type and Archetype Support to Bytecode Layouts
* Implement Bytecode assign/init with copy/take
Implements swift_generic_initialize and swift_generic_assign to allow copying
types using bytecode based witnesses.
* Add EnumTag Support
* Add IRGen Bytecode Layouts Test
Added a test to ensure layouts are correct and getting generated
* Implement BytecodeLayouts ObjC retain/release
* Fix for Non static alignments in aligned groups
* Disable MultiEnums
MultiEnums currently have some correctness issues with non fixed multienum
types. Disabling them for now then going to attempt a correct implementation in
a follow up patch
* Fixes after merge
* More fixes
* Possible fix for native unowned
* Use TypeInfoeBasedTypeLayoutEntry for all scalars when ForceStructTypeLayouts is disabled
* Remove @_GenerateBytecodeLayout attribute
* Fix typelayout_based_value_witness.swift
Co-authored-by: Gwen Mittertreiner <gwenm@fb.com>
Co-authored-by: Gwen Mittertreiner <gwen.mittertreiner@gmail.com>
`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
* [IRGen] Generate proper TypeLayout for singleton enums
rdar://101587387
Instead of creating a proper TypeLayout, we returned the layout for the singleton case, which caused the tags for the nested cases cases to be returned, instead of the expected `0` for singleton enums.
* Forward destroy, copy calls
* Add some missing forwarding cases
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`.
`PointerType::getElementType` has been removed entirely as part of the
opaque pointers migration. Update to `getPointerElementType` for now
until we've also migrated.
This reverts commit d27e6e1e46, reversing
changes made to f2e85a2b1f.
It causes an execution time failure in
`Interpreter/struct_extra_inhabitants.swift` with
```
ninja -C swift-macosx-x86_64 check-swift-optimize
```
rdar://86054209
The functions in llvm-project `AttributeList` have been
renamed/refactored to help remove uses of `AttributeList::*Index`.
Update to use these new functions where possible. There's one use of
`AttrIndex` remaining as `replaceAttributeTypeAtIndex` still takes the
index and there is no `param` equivalent. We could add one locally, but
presumably that will be added eventually.
This reverts commit 5ebb1b2fc6, reversing
changes made to 76260c2235.
This commit causes compiler crashes when using protocol composition
types involving objc.
Repo:
```
import Foundation
public class SomeObject : NSObject {}
public protocol ProtoA{}
public protocol SomeProtoType { }
public typealias Composition = SomeObject & SomeProtoType
public struct Thing<T: ProtoA> {
let a: Composition
let b: T
init(a: Composition,
b: T
) {
self.a = a
self.b = b
}
}
$ swiftc -c Repo.swift -O
```
While looking at this issue I noticed that it is not correct to use a
ScalarEntry of ObjCReference (or other ScalarKind::XXXReference) for
`AddressOnly##Name##ClassExistentialTypeInfo` types. These should be
calling the IGF.emit##Name##Destroy(addr, Refcounting); functions not
objc_release.
It is probably best to use the macro facilities in a similar fashion like
lib/IRGen/GenExistential.cpp does.
rdar://85269025
Summary:
As part of SR-14273, the type layout infrastructure needs to be able to be able
to differentiate between types of scalars so it knows how to release/retain
appropriately. Right now, for example, to destroy a scalar, it blindly calls
into typeInfo's irgen functions which means it's not able to generate any of
the needed information for itself.
This patch adds a field to ScalarTypeLayout to allow them to know what kind of
reference they are and strings through the machinery to provide the information
to set it.
This also moves ScalarTypeLayout::destroy to use the new information.
Test Plan: ninja check-swift
Reviewers: mren, #pika_compiler
Reviewed By: mren
Subscribers: apl, phabricatorlinter
Differential Revision: https://phabricator.intern.facebook.com/D30983093
Tasks: T100580959
Tags: swift-adoption
Signature: 30983093:1632340205:3bdd3218ae86ad6b3d199cc1b504a625e3650ec0
Augment the `isSingleRetainablePointer` check that allows IRGen to avoid adding branching around retain/release operations on enums that use the null pointer extra inhabitant with a more general "can value witness extra inhabitants" method on TypeInfo, which says whether a type's retain/release operations are safe to invoke on some or all of its extra inhabitants. This lets us generalize the optimization to include things like `String?` or `ClassProtocol?` which are common types with a nullable pointer in them.
In order to remove the enum raw value check request in validateDecl,
IRGen must now tolerate recieving an invalid raw value expression.
Switch the assert to instead check for this condition and emit an
invalid negative discriminator.
Make getRawValueExpr() return a checked value.
This entails a strange kind of request that effectively acts like
a cache warmer. In order to properly check the raw value expression for
a single case, we actually need all the other cases for the
autoincrementing synthesis logic. The strategy is therefore to have the
request act at the level of the parent EnumDecl and check all the values
at once. We also cache at the level of the EnumDecl so the cache
"warms" for all enum elements simultaneously.
The request also abuses TypeResolutionStage to act as an indicator for
how much information to compute. In the minimal case, we will return
a complete accounting of (auto-incremented) raw values. In the maximal
case we will also check and record types and emit diagnostics. The
minimal case is uncached to support repeated evaluation.
Note that computing the interface type of an @objc enum decl *must*
force this request. The enum's raw values are part of the ABI, and we
should not get all the way to IRGen before discovering that we cannot
possibly lay out the enum. In the future, we might want to consider
moving this check earlier or have IRGen tolerate broken cases but for
now we will maintain the status quo and not have IRGen emit
diagnostics.
First, remove the AvailabilityContext parameter; it was confusing because
we actually always want to use the deployment target here.
Then, split this method up into three methods:
- isAlwaysWeakImported(): simply checks for a @_weakLinked attribute, either
on the declaration itself or one of its parent contexts.
- getAvailabilityForLinkage(): returns the OS version availability when
this declaration was introduced, or if the declaration does not have
explicit availability, check it's storage (if its an accessor), or its
parent contexts.
- isWeakImported(ModuleDecl *fromModule): combines these two checks to
determine if the declaration should be weak linked when referenced from
the given module, or if it might be weak referenced from some module
(if the module parameter is null).
This is a regression from recent changes to make finalizeDecl() do
less work. All these resolveDeclSignature() calls will hopefully go
away soon, once validateDecl() is refactored into a getInterfaceType()
request.
This change modifies spare bit masks so that they are arranged in
the byte order of the target platform. It also modifies and
consolidates the code that gathers and scatters bits into enum
values.
All enum-related validation tests are now passing on IBM Z (s390x)
which is a big-endian platform.
When a c++ namespace IRGens for reflection, it triggers a path that
expects the namespace to have a particular form. Because it is always
empty, we can treat it just like an empty swift enum.
Instead of adding a resolveDeclSignature() call here, I'm going to live
dangerously and try to only get the enum element type in the case where
SIL type lowering has already computed it, that is, if the enum is not
indirect.
Soon this will become moot anyway because getInterfaceType() will be a
request.