Skip to content

Commit 9f6a375

Browse files
Merge pull request #4765 from swiftwasm/main
[pull] swiftwasm from main
2 parents 3b5f884 + 72cef81 commit 9f6a375

File tree

102 files changed

+1609
-444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1609
-444
lines changed

docs/SIL.rst

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2762,6 +2762,32 @@ sil-opt, one will see that we actually have an ownership violation due to the
27622762
two uses of "value", one for initializing value2 and the other for the return
27632763
value.
27642764

2765+
Move Only Types
2766+
---------------
2767+
2768+
NOTE: This is experimental and is just an attempt to describe where the design
2769+
is currently for others reading SIL today. It should not be interpreted as
2770+
final.
2771+
2772+
Currently there are two kinds of "move only types" in SIL: pure move only types
2773+
that are always move only and move only wrapped types that are move only
2774+
versions of copyable types. The invariant that values of Move Only type obey is
2775+
that they can only be copied (e.x.: operand to a `copy_value`_, ``copy_addr [init]``) during the
2776+
guaranteed passes when we are in Raw SIL. Once we are in non-Raw SIL though
2777+
(i.e. Canonical and later SIL stages), a program is ill formed if one copies a
2778+
move only type.
2779+
2780+
The reason why we have this special rule for move only types is that this allows
2781+
for SIL code generators to insert copies and then have a later guaranteed
2782+
checker optimization pass recover the underlying move only semantics by
2783+
reconstructing needed copies and removing unneeded copies using Ownership
2784+
SSA. If any such copies are actually needed according to Ownership SSA, the
2785+
checker pass emits a diagnostic stating that move semantics have been
2786+
violated. If such a diagnostic is emitted then the checker pass transforms all
2787+
copies on move only types to their explicit copy forms to ensure that once we
2788+
leave the diagnostic passes and enter canonical SIL, our "copy" invariant is
2789+
maintained.
2790+
27652791
Runtime Failure
27662792
---------------
27672793

@@ -4219,6 +4245,25 @@ operations::
42194245
If ``T`` is a trivial type, then ``copy_addr`` is always equivalent to its
42204246
take-initialization form.
42214247

4248+
It is illegal in non-Raw SIL to apply ``copy_addr [init]`` to a value that is
4249+
move only.
4250+
4251+
explicit_copy_addr
4252+
``````````````````
4253+
::
4254+
4255+
sil-instruction ::= 'explicit_copy_addr' '[take]'? sil-value
4256+
'to' '[initialization]'? sil-operand
4257+
4258+
explicit_copy_addr [take] %0 to [initialization] %1 : $*T
4259+
// %0 and %1 must be of the same $*T address type
4260+
4261+
This instruction is exactly the same as `copy_addr`_ except that it has special
4262+
behavior for move only types. Specifically, an `explicit_copy_addr`_ is viewed
4263+
as a copy_addr that is allowed on values that are move only. This is only used
4264+
by a move checker after it has emitted an error diagnostic to preserve the
4265+
general ``copy_addr [init]`` ban in Canonical SIL on move only types.
4266+
42224267
destroy_addr
42234268
````````````
42244269
::
@@ -5557,6 +5602,8 @@ independent of the operand. In terms of specific types:
55575602
In ownership qualified functions, a ``copy_value`` produces a +1 value that must
55585603
be consumed at most once along any path through the program.
55595604

5605+
It is illegal in non-Raw SIL to `copy_value`_ a value that is "move only".
5606+
55605607
explicit_copy_value
55615608
```````````````````
55625609

@@ -5566,27 +5613,18 @@ explicit_copy_value
55665613

55675614
%1 = explicit_copy_value %0 : $A
55685615

5569-
Performs a copy of a loadable value as if by the value's type lowering and
5570-
returns the copy. The returned copy semantically is a value that is completely
5571-
independent of the operand. In terms of specific types:
5572-
5573-
1. For trivial types, this is equivalent to just propagating through the trivial
5574-
value.
5575-
2. For reference types, this is equivalent to performing a ``strong_retain``
5576-
operation and returning the reference.
5577-
3. For ``@unowned`` types, this is equivalent to performing an
5578-
``unowned_retain`` and returning the operand.
5579-
4. For aggregate types, this is equivalent to recursively performing a
5580-
``copy_value`` on its components, forming a new aggregate from the copied
5581-
components, and then returning the new aggregate.
5582-
5583-
In ownership qualified functions, a ``explicit_copy_value`` produces a +1 value
5584-
that must be consumed at most once along any path through the program.
5585-
5586-
When move only variable checking is performed, ``explicit_copy_value`` is
5616+
This is exactly the same instruction semantically as `copy_value`_ with the
5617+
exception that when move only checking is performed, `explicit_copy_value`_ is
55875618
treated as an explicit copy asked for by the user that should not be rewritten
55885619
and should be treated as a non-consuming use.
55895620

5621+
This is used for two things:
5622+
5623+
1. Implementing a copy builtin for no implicit copy types.
5624+
2. To enable the move checker, once it has emitted an error diagnostic, to still
5625+
produce valid Ownership SSA SIL at the end of the guaranteed optimization
5626+
pipeline when we enter the Canonical SIL stage.
5627+
55905628
move_value
55915629
``````````
55925630

include/swift/AST/ASTContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,8 +1343,8 @@ class ASTContext final {
13431343
/// particular, the opened archetype signature does not have requirements for
13441344
/// conformances inherited from superclass constraints while existential
13451345
/// values do.
1346-
CanGenericSignature getOpenedArchetypeSignature(Type type,
1347-
GenericSignature parentSig);
1346+
CanGenericSignature getOpenedExistentialSignature(Type type,
1347+
GenericSignature parentSig);
13481348

13491349
GenericSignature getOverrideGenericSignature(const ValueDecl *base,
13501350
const ValueDecl *derived);

include/swift/AST/Attr.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,8 @@ DECL_ATTR(_clangImporterSynthesizedType, ClangImporterSynthesizedType,
456456
74)
457457
SIMPLE_DECL_ATTR(_weakLinked, WeakLinked,
458458
OnNominalType | OnAssociatedType | OnFunc | OnAccessor | OnVar |
459-
OnSubscript | OnConstructor | OnEnumElement | OnExtension | UserInaccessible |
459+
OnSubscript | OnConstructor | OnEnumElement | OnExtension | OnImport |
460+
UserInaccessible |
460461
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
461462
75)
462463
SIMPLE_DECL_ATTR(frozen, Frozen,

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,6 +2508,10 @@ ERROR(recursive_generic_signature,none,
25082508
"%0 %1 has self-referential generic requirements", (DescriptiveDeclKind, DeclBaseName))
25092509
ERROR(recursive_generic_signature_extension,none,
25102510
"extension of %0 %1 has self-referential generic requirements", (DescriptiveDeclKind, DeclBaseName))
2511+
ERROR(recursive_same_type_constraint,none,
2512+
"same-type constraint %0 == %1 is recursive", (Type, Type))
2513+
ERROR(recursive_superclass_constraint,none,
2514+
"superclass constraint %0 : %1 is recursive", (Type, Type))
25112515
ERROR(requires_same_concrete_type,none,
25122516
"generic signature requires types %0 and %1 to be the same", (Type, Type))
25132517
WARNING(redundant_conformance_constraint,none,

include/swift/AST/FileUnit.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
123123
const ModuleDecl *importedModule,
124124
SmallSetVector<Identifier, 4> &spiGroups) const {};
125125

126+
/// Checks whether this file imports \c module as \c @_weakLinked.
127+
virtual bool importsModuleAsWeakLinked(const ModuleDecl *module) const {
128+
// For source files, this should be overridden to inspect the import
129+
// declarations in the file. Other kinds of file units, like serialized
130+
// modules, can just use this default implementation since the @_weakLinked
131+
// attribute is not transitive. If module C is imported @_weakLinked by
132+
// module B, that does not imply that module A imports module C @_weakLinked
133+
// if it imports module B.
134+
return false;
135+
}
136+
126137
virtual Optional<Fingerprint>
127138
loadFingerprint(const IterableDeclContext *IDC) const { return None; }
128139

include/swift/AST/Import.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ enum class ImportFlags {
8484
/// concurrency.
8585
Preconcurrency = 0x20,
8686

87+
/// The module's symbols are linked weakly.
88+
WeakLinked = 0x40,
89+
8790
/// Used for DenseMap.
8891
Reserved = 0x80
8992
};

include/swift/AST/Module.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,11 @@ class ModuleDecl
414414
/// present overlays as if they were part of their underlying module.
415415
std::pair<ModuleDecl *, Identifier> getDeclaringModuleAndBystander();
416416

417+
public:
417418
/// If this is a traditional (non-cross-import) overlay, get its underlying
418419
/// module if one exists.
419420
ModuleDecl *getUnderlyingModuleIfOverlay() const;
420421

421-
public:
422-
423422
/// Returns true if this module is an underscored cross import overlay
424423
/// declared by \p other or its underlying clang module, either directly or
425424
/// transitively (via intermediate cross-import overlays - for cross-imports
@@ -686,6 +685,10 @@ class ModuleDecl
686685
// Is \p spiGroup accessible as an explicitly imported SPI from this module?
687686
bool isImportedAsSPI(Identifier spiGroup, const ModuleDecl *fromModule) const;
688687

688+
/// Is \p targetDecl from a module that is imported as \c @_weakLinked from
689+
/// this module?
690+
bool isImportedAsWeakLinked(const Decl *targetDecl) const;
691+
689692
/// \sa getImportedModules
690693
enum class ImportFilterKind {
691694
/// Include imports declared with `@_exported`.

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ class SourceFile final : public FileUnit {
356356
const ModuleDecl *importedModule,
357357
llvm::SmallSetVector<Identifier, 4> &spiGroups) const override;
358358

359+
/// Is \p module imported as \c @_weakLinked by this file?
360+
bool importsModuleAsWeakLinked(const ModuleDecl *module) const override;
361+
359362
// Is \p targetDecl accessible as an explicitly imported SPI from this file?
360363
bool isImportedAsSPI(const ValueDecl *targetDecl) const;
361364

include/swift/AST/Type.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,11 @@ class Type {
282282
/// Transform the given type by recursively applying the user-provided
283283
/// function to each node.
284284
///
285-
/// If the function returns \c None, the transform operation will
286-
///
287285
/// \param fn A function object which accepts a type pointer and returns a
288286
/// transformed type, a null type (which will propagate out the null type),
289287
/// or None (to indicate that the transform operation should recursively
290288
/// transform the children). The function object should use \c dyn_cast rather
291-
/// than \c getAs when the transform is intended to preserve sugar
289+
/// than \c getAs when the transform is intended to preserve sugar.
292290
///
293291
/// \returns the result of transforming the type.
294292
Type transformRec(llvm::function_ref<Optional<Type>(TypeBase *)> fn) const;

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,15 @@ class IRABIDetailsProvider {
105105
/// access function.
106106
FunctionABISignature getTypeMetadataAccessFunctionSignature();
107107

108+
struct EnumElementInfo {
109+
unsigned tag;
110+
StringRef globalVariableName;
111+
};
112+
108113
/// Returns EnumElementDecls (enum cases) in their declaration order with
109114
/// their tag indices from the given EnumDecl
110-
llvm::MapVector<EnumElementDecl *, unsigned> getEnumTagMapping(EnumDecl *ED);
115+
llvm::MapVector<EnumElementDecl *, EnumElementInfo>
116+
getEnumTagMapping(const EnumDecl *ED);
111117

112118
/// Returns the additional params if they exist after lowering the function.
113119
SmallVector<ABIAdditionalParam, 1>

0 commit comments

Comments
 (0)