Skip to content

Commit 229398c

Browse files
authored
Merge pull request #69141 from tshortli/silgen-lazy-typecheck
SILGen: Introduce option to skip non-exportable declarations
2 parents 0ada2e2 + b8bddb5 commit 229398c

File tree

14 files changed

+129
-27
lines changed

14 files changed

+129
-27
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
957957
unsigned getAttachedMacroDiscriminator(DeclBaseName macroName, MacroRole role,
958958
const CustomAttr *attr) const;
959959

960+
/// Determines if this declaration is exposed to clients of the module it is
961+
/// defined in. For example, `public` declarations are exposed to clients.
962+
bool isExposedToClients() const;
963+
960964
/// Returns the innermost enclosing decl with an availability annotation.
961965
const Decl *getInnermostDeclWithAvailability() const;
962966

include/swift/AST/DeclContext.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -877,15 +877,6 @@ class IterableDeclContext {
877877
/// The resulting list of members will be stable across translation units.
878878
ArrayRef<Decl *> getABIMembers() const;
879879

880-
using DeclsForLowering =
881-
OptionalTransformRange<ArrayRef<Decl *>,
882-
AvailableDuringLoweringDeclFilter<Decl>>;
883-
884-
/// Get all of the members within this context that should be included when
885-
/// lowering to SIL/IR, including any implicitly-synthesized members. The
886-
/// decls returned by \c getABIMembers() are a superset of these decls.
887-
DeclsForLowering getMembersForLowering() const;
888-
889880
/// Get all of the members within this context, including any
890881
/// implicitly-synthesized members.
891882
///

include/swift/SIL/SILVTableVisitor.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ template <class T> class SILVTableVisitor {
105105
}
106106

107107
void maybeAddMember(Decl *member) {
108+
if (!member->isAvailableDuringLowering())
109+
return;
110+
108111
if (isa<AccessorDecl>(member))
109112
/* handled as part of its storage */;
110113
else if (auto *fd = dyn_cast<FuncDecl>(member))
@@ -141,7 +144,7 @@ template <class T> class SILVTableVisitor {
141144
if (!theClass->hasKnownSwiftImplementation())
142145
return;
143146

144-
for (Decl *member : theClass->getMembersForLowering()) {
147+
for (Decl *member : theClass->getABIMembers()) {
145148
maybeAddMember(member);
146149
}
147150
}

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/AccessScope.h"
2424
#include "swift/AST/Attr.h"
2525
#include "swift/AST/CaptureInfo.h"
26+
#include "swift/AST/DeclExportabilityVisitor.h"
2627
#include "swift/AST/DiagnosticEngine.h"
2728
#include "swift/AST/DiagnosticsSema.h"
2829
#include "swift/AST/ExistentialLayout.h"
@@ -492,6 +493,10 @@ unsigned Decl::getAttachedMacroDiscriminator(DeclBaseName macroName,
492493
macroName);
493494
}
494495

496+
bool Decl::isExposedToClients() const {
497+
return DeclExportabilityVisitor().visit(this);
498+
}
499+
495500
const Decl *Decl::getInnermostDeclWithAvailability() const {
496501
if (getAttrs().hasAttribute<AvailableAttr>())
497502
return this;

lib/AST/DeclContext.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -914,12 +914,6 @@ ArrayRef<Decl *> IterableDeclContext::getABIMembers() const {
914914
ArrayRef<Decl *>());
915915
}
916916

917-
IterableDeclContext::DeclsForLowering
918-
IterableDeclContext::getMembersForLowering() const {
919-
return DeclsForLowering(getABIMembers(),
920-
AvailableDuringLoweringDeclFilter<Decl>());
921-
}
922-
923917
ArrayRef<Decl *> IterableDeclContext::getAllMembers() const {
924918
ASTContext &ctx = getASTContext();
925919
return evaluateOrDefault(

lib/Frontend/Frontend.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,11 +1425,6 @@ bool CompilerInstance::performParseAndResolveImportsOnly() {
14251425
void CompilerInstance::performSema() {
14261426
performParseAndResolveImportsOnly();
14271427

1428-
// Skip eager type checking. Instead, let later stages of compilation drive
1429-
// type checking as needed through request evaluation.
1430-
if (getASTContext().TypeCheckerOpts.EnableLazyTypecheck)
1431-
return;
1432-
14331428
FrontendStatsTracer tracer(getStatsReporter(), "perform-sema");
14341429

14351430
forEachFileToTypeCheck([&](SourceFile &SF) {

lib/SILGen/SILGen.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,19 @@ bool SILGenModule::hasFunction(SILDeclRef constant) {
797797
return emittedFunctions.count(constant);
798798
}
799799

800-
void SILGenModule::visit(Decl *D) {
800+
bool SILGenModule::shouldSkipDecl(Decl *D) {
801801
if (!D->isAvailableDuringLowering())
802+
return true;
803+
804+
if (getASTContext().SILOpts.SkipNonExportableDecls &&
805+
!D->isExposedToClients())
806+
return true;
807+
808+
return false;
809+
}
810+
811+
void SILGenModule::visit(Decl *D) {
812+
if (shouldSkipDecl(D))
802813
return;
803814

804815
ASTVisitor::visit(D);
@@ -1412,6 +1423,8 @@ void SILGenModule::emitAbstractFuncDecl(AbstractFunctionDecl *AFD) {
14121423
}
14131424

14141425
void SILGenModule::emitFunction(FuncDecl *fd) {
1426+
assert(!shouldSkipDecl(fd));
1427+
14151428
Types.setCaptureTypeExpansionContext(SILDeclRef(fd), M);
14161429

14171430
SILDeclRef::Loc decl = fd;

lib/SILGen/SILGen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
264264
// Visitors for top-level forms
265265
//===--------------------------------------------------------------------===//
266266

267+
/// Returns true if SILGen should be skipped for the given decl.
268+
bool shouldSkipDecl(Decl *d);
269+
267270
void visit(Decl *D);
268271

269272
// These are either not allowed at global scope or don't require

lib/SILGen/SILGenTopLevel.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,18 @@ void SILGenTopLevel::visitTopLevelCodeDecl(TopLevelCodeDecl *TD) {
294294
SILGenTopLevel::TypeVisitor::TypeVisitor(SILGenFunction &SGF) : SGF(SGF) {}
295295

296296
void SILGenTopLevel::TypeVisitor::emit(IterableDeclContext *Ctx) {
297-
for (auto *Member : Ctx->getMembersForLowering()) {
297+
for (auto *Member : Ctx->getABIMembers()) {
298298
visit(Member);
299299
}
300300
}
301301

302+
void SILGenTopLevel::TypeVisitor::visit(Decl *D) {
303+
if (SGF.SGM.shouldSkipDecl(D))
304+
return;
305+
306+
TypeMemberVisitor::visit(D);
307+
}
308+
302309
void SILGenTopLevel::TypeVisitor::visitPatternBindingDecl(
303310
PatternBindingDecl *PD) {
304311
for (auto i : range(PD->getNumPatternEntries())) {

lib/SILGen/SILGenTopLevel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class SILGenTopLevel : public ASTVisitor<SILGenTopLevel> {
4949
/// Emit `mark_function_escape` SIL instructions into `SGF` for encountered
5050
/// escape points.
5151
TypeVisitor(SILGenFunction &SGF);
52+
void visit(Decl *D);
5253
void visitDecl(Decl *D) {}
5354
void emit(IterableDeclContext *Ctx);
5455
virtual void visitPatternBindingDecl(PatternBindingDecl *PD);

lib/SILGen/SILGenType.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ SILGenModule::emitVTableMethod(ClassDecl *theClass, SILDeclRef derived,
4747
auto *baseDecl = cast<AbstractFunctionDecl>(base.getDecl());
4848
auto *derivedDecl = cast<AbstractFunctionDecl>(derived.getDecl());
4949

50+
if (shouldSkipDecl(baseDecl))
51+
return llvm::None;
52+
5053
// Note: We intentionally don't support extension members here.
5154
//
5255
// Once extensions can override or introduce new vtable entries, this will
@@ -1098,7 +1101,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
10981101
void emitType() {
10991102
SGM.emitLazyConformancesForType(theType);
11001103

1101-
for (Decl *member : theType->getMembersForLowering()) {
1104+
for (Decl *member : theType->getABIMembers()) {
11021105
visit(member);
11031106
}
11041107

@@ -1141,6 +1144,13 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11411144
//===--------------------------------------------------------------------===//
11421145
// Visitors for subdeclarations
11431146
//===--------------------------------------------------------------------===//
1147+
void visit(Decl *D) {
1148+
if (SGM.shouldSkipDecl(D))
1149+
return;
1150+
1151+
TypeMemberVisitor::visit(D);
1152+
}
1153+
11441154
void visitTypeAliasDecl(TypeAliasDecl *tad) {}
11451155
void visitOpaqueTypeDecl(OpaqueTypeDecl *otd) {}
11461156
void visitGenericTypeParamDecl(GenericTypeParamDecl *d) {}
@@ -1273,7 +1283,7 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
12731283
// @_objcImplementation extension, but we don't actually need to do any of
12741284
// the stuff that it currently does.
12751285

1276-
for (Decl *member : e->getMembersForLowering()) {
1286+
for (Decl *member : e->getABIMembers()) {
12771287
visit(member);
12781288
}
12791289

@@ -1300,6 +1310,13 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
13001310
//===--------------------------------------------------------------------===//
13011311
// Visitors for subdeclarations
13021312
//===--------------------------------------------------------------------===//
1313+
void visit(Decl *D) {
1314+
if (SGM.shouldSkipDecl(D))
1315+
return;
1316+
1317+
TypeMemberVisitor::visit(D);
1318+
}
1319+
13031320
void visitTypeAliasDecl(TypeAliasDecl *tad) {}
13041321
void visitOpaqueTypeDecl(OpaqueTypeDecl *tad) {}
13051322
void visitGenericTypeParamDecl(GenericTypeParamDecl *d) {}

lib/Sema/TypeChecker.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ void swift::bindExtensions(ModuleDecl &mod) {
242242
}
243243

244244
void swift::performTypeChecking(SourceFile &SF) {
245+
if (SF.getASTContext().TypeCheckerOpts.EnableLazyTypecheck) {
246+
// Skip eager type checking. Instead, let later stages of compilation drive
247+
// type checking as needed through request evaluation.
248+
return;
249+
}
250+
245251
return (void)evaluateOrDefault(SF.getASTContext().evaluator,
246252
TypeCheckSourceFileRequest{&SF}, {});
247253
}

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "swift/AST/ASTMangler.h"
1818
#include "swift/AST/ASTVisitor.h"
1919
#include "swift/AST/AutoDiff.h"
20-
#include "swift/AST/DeclExportabilityVisitor.h"
2120
#include "swift/AST/DiagnosticsCommon.h"
2221
#include "swift/AST/Expr.h"
2322
#include "swift/AST/FileSystem.h"
@@ -3319,7 +3318,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
33193318
/// it, but at the same time keep the safety checks precise to avoid
33203319
/// XRef errors and such.
33213320
static bool isDeserializationSafe(const Decl *decl) {
3322-
return DeclExportabilityVisitor().visit(decl);
3321+
return decl->isExposedToClients();
33233322
}
33243323

33253324
private:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-SKIP
3+
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test -experimental-skip-non-exportable-decls | %FileCheck %s --check-prefixes=CHECK,CHECK-SKIP
4+
5+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF : $@convention(thin) () -> () {
6+
// CHECK-SKIP-NOT: s4Test11privateFunc33_E3F0E1C7B46D05C8067CB98677DE566CLLyyF
7+
private func privateFunc() {}
8+
9+
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test12internalFuncyyF : $@convention(thin) () -> () {
10+
// CHECK-SKIP-NOT: s4Test12internalFuncyyF
11+
internal func internalFunc() {}
12+
13+
// CHECK: sil{{.*}} @$s4Test10publicFuncyyF : $@convention(thin) () -> () {
14+
public func publicFunc() {}
15+
16+
private class PrivateClass {
17+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd : $@convention(method) (@guaranteed PrivateClass) -> @owned Builtin.NativeObject {
18+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfd
19+
20+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD : $@convention(method) (@owned PrivateClass) -> () {
21+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCfD
22+
23+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC : $@convention(method) (@thick PrivateClass.Type) -> @owned PrivateClass {
24+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfC
25+
26+
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc : $@convention(method) (@owned PrivateClass) -> @owned PrivateClass {
27+
// CHECK-SKIP-NOT: s4Test12PrivateClass33_E3F0E1C7B46D05C8067CB98677DE566CLLCADycfc
28+
}
29+
30+
public class PublicClass {
31+
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassC14internalMethodyyF : $@convention(method) (@guaranteed PublicClass) -> () {
32+
// CHECK-SKIP-NOT: s4Test11PublicClassC14internalMethodyyF
33+
internal func internalMethod() {}
34+
35+
// CHECK: sil{{.*}} @$s4Test11PublicClassCfd : $@convention(method) (@guaranteed PublicClass) -> @owned Builtin.NativeObject {
36+
37+
// CHECK: sil{{.*}} @$s4Test11PublicClassCfD : $@convention(method) (@owned PublicClass) -> () {
38+
39+
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassCACycfC : $@convention(method) (@thick PublicClass.Type) -> @owned PublicClass {
40+
// CHECK-SKIP-NOT: s4Test11PublicClassCACycfC
41+
42+
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassCACycfc : $@convention(method) (@owned PublicClass) -> @owned PublicClass {
43+
// CHECK-SKIP-NOT: s4Test11PublicClassCACycfc
44+
}
45+
46+
extension PublicClass {
47+
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassC25internalMethodInExtensionyyF : $@convention(method) (@guaranteed PublicClass) -> () {
48+
// CHECK-SKIP-NOT: s4Test11PublicClassC25internalMethodInExtensionyyF
49+
internal func internalMethodInExtension() {}
50+
}
51+
52+
// CHECK-NO-SKIP-LABEL: sil_vtable PrivateClass {
53+
// CHECK-NO-SKIP-NEXT: #PrivateClass.init!allocator
54+
// CHECK-NO-SKIP-NEXT: #PrivateClass.deinit!deallocator
55+
// CHECK-NO-SKIP-NEXT: }
56+
// CHECK-SKIP-NOT: sil_vtable PrivateClass
57+
58+
// CHECK-LABEL: sil_vtable [serialized] PublicClass {
59+
// CHECK-NO-SKIP-NEXT: #PublicClass.internalMethod
60+
// CHECK-SKIP-NOT: #PublicClass.internalMethod
61+
// CHECK-NO-SKIP-NEXT: #PublicClass.init!allocator
62+
// CHECK-SKIP-NOT: #PublicClass.init!allocator
63+
// CHECK-NEXT: #PublicClass.deinit!deallocator
64+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)