Skip to content

Commit c16eadb

Browse files
authored
Merge pull request #61193 from gottesmm/moveonly-deinits
[move-only] Implement support for move only deinits
2 parents 4c4acf1 + b1d6768 commit c16eadb

40 files changed

+1384
-77
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,14 @@ ERROR(sil_vtable_bad_entry_kind,none,
720720
ERROR(sil_vtable_expect_rsquare,none,
721721
"expected ']' after vtable entry kind", ())
722722

723+
// SIL MoveOnlyDeinit
724+
ERROR(expected_sil_moveonlydeinit_colon,none,
725+
"expected ':' in a MoveOnlyDeinit entry", ())
726+
ERROR(sil_moveonlydeinit_func_not_found,none,
727+
"sil function not found %0", (Identifier))
728+
ERROR(sil_moveonlydeinit_nominal_not_found,none,
729+
"sil nominal decl not found %0", (Identifier))
730+
723731
// SIL Global
724732
ERROR(sil_global_variable_not_found,none,
725733
"sil global not found %0", (Identifier))

include/swift/Parse/ParseSILSupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace swift {
2929
virtual bool parseDeclSIL(Parser &P) = 0;
3030
virtual bool parseDeclSILStage(Parser &P) = 0;
3131
virtual bool parseSILVTable(Parser &P) = 0;
32+
virtual bool parseSILMoveOnlyDeinit(Parser &P) = 0;
3233
virtual bool parseSILGlobal(Parser &P) = 0;
3334
virtual bool parseSILWitnessTable(Parser &P) = 0;
3435
virtual bool parseSILDefaultWitnessTable(Parser &P) = 0;

include/swift/Parse/Parser.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -976,13 +976,12 @@ class Parser {
976976
PD_AllowTopLevel = 1 << 1,
977977
PD_HasContainerType = 1 << 2,
978978
PD_DisallowInit = 1 << 3,
979-
PD_AllowDestructor = 1 << 4,
980-
PD_AllowEnumElement = 1 << 5,
981-
PD_InProtocol = 1 << 6,
982-
PD_InClass = 1 << 7,
983-
PD_InExtension = 1 << 8,
984-
PD_InStruct = 1 << 9,
985-
PD_InEnum = 1 << 10,
979+
PD_AllowEnumElement = 1 << 4,
980+
PD_InProtocol = 1 << 5,
981+
PD_InClass = 1 << 6,
982+
PD_InExtension = 1 << 7,
983+
PD_InStruct = 1 << 8,
984+
PD_InEnum = 1 << 9,
986985
};
987986

988987
/// Options that control the parsing of declarations.

include/swift/SIL/Notifications.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/Basic/LLVM.h"
1717
#include "swift/Basic/STLExtras.h"
18+
#include "swift/SIL/SILMoveOnlyDeinit.h"
1819
#include "llvm/ADT/PointerUnion.h"
1920
#include "llvm/ADT/SmallVector.h"
2021
#include "llvm/ADT/StringRef.h"
@@ -68,6 +69,9 @@ class DeserializationNotificationHandlerBase {
6869
virtual void didDeserialize(ModuleDecl *mod,
6970
SILDefaultWitnessTable *wtable) = 0;
7071

72+
/// Observe that we deserialized a move only deinit declaration.
73+
virtual void didDeserialize(ModuleDecl *mod, SILMoveOnlyDeinit *deinit) = 0;
74+
7175
virtual ~DeserializationNotificationHandlerBase() = default;
7276
};
7377

@@ -109,6 +113,10 @@ class DeserializationNotificationHandler
109113
virtual void didDeserialize(ModuleDecl *mod,
110114
SILDefaultWitnessTable *wtable) override {}
111115

116+
/// Observe that we deserialized a move only deinit declaration.
117+
virtual void didDeserialize(ModuleDecl *mod,
118+
SILMoveOnlyDeinit *deinit) override {}
119+
112120
virtual StringRef getName() const = 0;
113121

114122
virtual ~DeserializationNotificationHandler() = default;
@@ -239,6 +247,7 @@ class DeserializationNotificationHandlerSet final
239247
void didDeserialize(ModuleDecl *mod, SILWitnessTable *wtable) override;
240248
void didDeserialize(ModuleDecl *mod,
241249
SILDefaultWitnessTable *wtable) override;
250+
void didDeserialize(ModuleDecl *mod, SILMoveOnlyDeinit *deinit) override;
242251
};
243252
} // namespace swift
244253

include/swift/SIL/SILModule.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/AST/ASTContext.h"
2121
#include "swift/AST/Builtins.h"
22+
#include "swift/AST/Decl.h"
2223
#include "swift/AST/SILLayout.h"
2324
#include "swift/AST/SILOptions.h"
2425
#include "swift/Basic/IndexTrie.h"
@@ -32,6 +33,7 @@
3233
#include "swift/SIL/SILDifferentiabilityWitness.h"
3334
#include "swift/SIL/SILFunction.h"
3435
#include "swift/SIL/SILGlobalVariable.h"
36+
#include "swift/SIL/SILMoveOnlyDeinit.h"
3537
#include "swift/SIL/SILPrintContext.h"
3638
#include "swift/SIL/SILProperty.h"
3739
#include "swift/SIL/SILType.h"
@@ -161,6 +163,7 @@ class SILModule {
161163
using DefaultWitnessTableListType = llvm::ilist<SILDefaultWitnessTable>;
162164
using DifferentiabilityWitnessListType =
163165
llvm::ilist<SILDifferentiabilityWitness>;
166+
using SILMoveOnlyDeinitListType = llvm::ArrayRef<SILMoveOnlyDeinit *>;
164167
using CoverageMapCollectionType =
165168
llvm::MapVector<StringRef, SILCoverageMap *>;
166169
using BasicBlockNameMapType =
@@ -191,6 +194,7 @@ class SILModule {
191194
friend SILProperty;
192195
friend SILUndef;
193196
friend SILWitnessTable;
197+
friend SILMoveOnlyDeinit;
194198
friend Lowering::SILGenModule;
195199
friend Lowering::TypeConverter;
196200
class SerializationCallback;
@@ -271,6 +275,13 @@ class SILModule {
271275
/// The list of SILDifferentiabilityWitnesses in the module.
272276
DifferentiabilityWitnessListType differentiabilityWitnesses;
273277

278+
/// Lookup table for SIL vtables from class decls.
279+
llvm::DenseMap<const NominalTypeDecl *, SILMoveOnlyDeinit *>
280+
MoveOnlyDeinitMap;
281+
282+
/// The list of SILVTables in the module.
283+
std::vector<SILMoveOnlyDeinit *> moveOnlyDeinits;
284+
274285
/// Declarations which are externally visible.
275286
///
276287
/// These are method declarations which are referenced from inlinable
@@ -614,6 +625,25 @@ class SILModule {
614625
vtable_const_iterator vtable_begin() const { return getVTables().begin(); }
615626
vtable_const_iterator vtable_end() const { return getVTables().end(); }
616627

628+
ArrayRef<SILMoveOnlyDeinit *> getMoveOnlyDeinits() const {
629+
return ArrayRef<SILMoveOnlyDeinit *>(moveOnlyDeinits);
630+
}
631+
using moveonlydeinit_iterator = SILMoveOnlyDeinitListType::iterator;
632+
using moveonlydeinit_const_iterator =
633+
SILMoveOnlyDeinitListType::const_iterator;
634+
moveonlydeinit_iterator moveonlydeinit_begin() {
635+
return getMoveOnlyDeinits().begin();
636+
}
637+
moveonlydeinit_iterator moveonlydeinit_end() {
638+
return getMoveOnlyDeinits().end();
639+
}
640+
moveonlydeinit_const_iterator moveonlydeinit_begin() const {
641+
return getMoveOnlyDeinits().begin();
642+
}
643+
moveonlydeinit_const_iterator moveonlydeinit_end() const {
644+
return getMoveOnlyDeinits().end();
645+
}
646+
617647
using witness_table_iterator = WitnessTableListType::iterator;
618648
using witness_table_const_iterator = WitnessTableListType::const_iterator;
619649
WitnessTableListType &getWitnessTableList() { return witnessTables; }
@@ -799,6 +829,15 @@ class SILModule {
799829
/// hierarchy of \p Class.
800830
SILFunction *lookUpFunctionInVTable(ClassDecl *Class, SILDeclRef Member);
801831

832+
/// Look up the deinit mapped to the given move only nominal type decl.
833+
/// Returns null on failure.
834+
SILMoveOnlyDeinit *lookUpMoveOnlyDeinit(const NominalTypeDecl *nomDecl,
835+
bool deserializeLazily = true);
836+
837+
/// Look up the function mapped to the given move only nominal type decl.
838+
/// Returns null on failure.
839+
SILFunction *lookUpMoveOnlyDeinitFunction(const NominalTypeDecl *nomDecl);
840+
802841
/// Look up the differentiability witness with the given name.
803842
SILDifferentiabilityWitness *lookUpDifferentiabilityWitness(StringRef name);
804843

include/swift/SIL/SILMoveOnlyDeinit.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===--- SILMoveOnlyDeinit.h ----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// \file
14+
///
15+
/// This file defines the SILMoveOnlyDeinit class which is used to map a
16+
/// non-class move only nominal type to the concrete implementation of its
17+
/// deinit. This function is called in the destroy witness by IRGen and is
18+
/// called directly by the move checker for concrete classes.
19+
///
20+
//===----------------------------------------------------------------------===//
21+
22+
#ifndef SWIFT_SIL_SILMOVEONLYDEINIT_H
23+
#define SWIFT_SIL_SILMOVEONLYDEINIT_H
24+
25+
#include "swift/AST/Decl.h"
26+
#include "swift/SIL/SILAllocated.h"
27+
#include "swift/SIL/SILDeclRef.h"
28+
#include "swift/SIL/SILFunction.h"
29+
30+
namespace swift {
31+
32+
enum IsSerialized_t : unsigned char;
33+
class SILFunction;
34+
class SILModule;
35+
36+
class SILMoveOnlyDeinit final : public SILAllocated<SILMoveOnlyDeinit> {
37+
friend SILModule;
38+
39+
/// The nominal decl that is mapped to this move only deinit table.
40+
NominalTypeDecl *nominalDecl;
41+
42+
/// The SILFunction that implements this deinit.
43+
SILFunction *funcImpl;
44+
45+
/// Whether or not this deinit table is serialized. If a deinit is not
46+
/// serialized, then other modules can not consume directly a move only type
47+
/// since the deinit can not be called directly.
48+
bool serialized : 1;
49+
50+
SILMoveOnlyDeinit()
51+
: nominalDecl(nullptr), funcImpl(nullptr), serialized(false) {}
52+
53+
SILMoveOnlyDeinit(NominalTypeDecl *nominaldecl, SILFunction *implementation,
54+
bool serialized);
55+
~SILMoveOnlyDeinit();
56+
57+
public:
58+
static SILMoveOnlyDeinit *create(SILModule &mod, NominalTypeDecl *nominalDecl,
59+
IsSerialized_t serialized,
60+
SILFunction *funcImpl);
61+
62+
NominalTypeDecl *getNominalDecl() const { return nominalDecl; }
63+
64+
SILFunction *getImplementation() const { return funcImpl; }
65+
66+
bool isSerialized() const { return serialized; }
67+
68+
void print(llvm::raw_ostream &os, bool verbose) const;
69+
void dump() const;
70+
71+
bool operator==(const SILMoveOnlyDeinit &e) const {
72+
return funcImpl == e.funcImpl && serialized == e.serialized &&
73+
nominalDecl == e.nominalDecl;
74+
}
75+
76+
bool operator!=(const SILMoveOnlyDeinit &e) const { return !(*this == e); }
77+
};
78+
79+
} // namespace swift
80+
81+
#endif

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ class SILType {
622622
/// wrapped type.
623623
bool isMoveOnly() const;
624624

625+
/// Returns true if and only if this type is a first class move only
626+
/// type. NOTE: Returns false if the type is a move only wrapped type.
627+
bool isMoveOnlyType() const;
628+
625629
/// Returns true if this SILType is a move only wrapper type.
626630
///
627631
/// Canonical way to check if a SILType is move only. Using is/getAs/castTo

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ PASS(PartialApplySimplification, "partial-apply-simplification",
474474
"Transform partial_apply instructions into explicit closure box constructions")
475475
PASS(MovedAsyncVarDebugInfoPropagator, "sil-moved-async-var-dbginfo-propagator",
476476
"Propagate debug info from moved async vars after coroutine funclet boundaries")
477+
PASS(MoveOnlyDeinitInsertion, "sil-move-only-deinit-insertion",
478+
"After running move only checking, convert last destroy_values to deinit calls")
477479
PASS(PruneVTables, "prune-vtables",
478480
"Mark class methods that do not require vtable dispatch")
479481
PASS_RANGE(AllPasses, AADumper, PruneVTables)

include/swift/Serialization/SerializedSILLoader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/SIL/Notifications.h"
2020
#include "swift/SIL/SILDeclRef.h"
2121
#include "swift/SIL/SILLinkage.h"
22+
#include "swift/SIL/SILMoveOnlyDeinit.h"
2223
#include <memory>
2324
#include <vector>
2425

@@ -63,6 +64,7 @@ class SerializedSILLoader {
6364
SILFunction *lookupSILFunction(StringRef Name, Optional<SILLinkage> linkage);
6465
bool hasSILFunction(StringRef Name, Optional<SILLinkage> linkage = None);
6566
SILVTable *lookupVTable(const ClassDecl *C);
67+
SILMoveOnlyDeinit *lookupMoveOnlyDeinit(const NominalTypeDecl *nomDecl);
6668
SILWitnessTable *lookupWitnessTable(SILWitnessTable *C);
6769
SILDefaultWitnessTable *lookupDefaultWitnessTable(SILDefaultWitnessTable *C);
6870
SILDifferentiabilityWitness *

include/swift/Syntax/TokenKinds.def.gyb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ SIL_KEYWORD(sil)
162162
SIL_KEYWORD(sil_stage)
163163
SIL_KEYWORD(sil_property)
164164
SIL_KEYWORD(sil_vtable)
165+
SIL_KEYWORD(sil_moveonlydeinit)
165166
SIL_KEYWORD(sil_global)
166167
SIL_KEYWORD(sil_witness_table)
167168
SIL_KEYWORD(sil_default_witness_table)

0 commit comments

Comments
 (0)