Skip to content

Commit ca8bf98

Browse files
committed
NFC: Hoist queries for unavailable decl optimizations into the AST library.
Moving the query implementation up to the AST library from SIL will allow conveniences to be written on specific AST element classes. For instance, this will allow `EnumDecl` to expose a convenience that enumerates element decls that are available during lowering. Also, improve naming and documentation for these queries.
1 parent 469f7b4 commit ca8bf98

18 files changed

+71
-68
lines changed

include/swift/AST/Decl.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,18 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
12341234
llvm::Optional<std::pair<const AvailableAttr *, const Decl *>>
12351235
getSemanticUnavailableAttr() const;
12361236

1237+
/// Returns true if this declaration should be considered available during
1238+
/// SIL/IR lowering. A declaration would not be available during lowering if,
1239+
/// for example, it is annotated as unavailable with \c @available and
1240+
/// optimization settings require that it be omitted.
1241+
bool isAvailableDuringLowering() const;
1242+
1243+
/// Returns true if ABI compatibility stubs must be emitted for the given
1244+
/// declaration. Decls marked unavailable with \c @available require these
1245+
/// stubs if the compiler flags have enabled unavailable declaration ABI
1246+
/// compatibility mode.
1247+
bool requiresUnavailableDeclABICompatibilityStubs() const;
1248+
12371249
// List the SPI groups declared with @_spi or inherited by this decl.
12381250
//
12391251
// SPI groups are inherited from the parent contexts only if the local decl

include/swift/SIL/SILModule.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,23 +1078,14 @@ namespace Lowering {
10781078
/// Determine whether the given class will be allocated/deallocated using the
10791079
/// Objective-C runtime, i.e., +alloc and -dealloc.
10801080
LLVM_LIBRARY_VISIBILITY bool usesObjCAllocator(ClassDecl *theClass);
1081-
1082-
/// Returns true if SIL/IR lowering for the given declaration should be skipped.
1083-
/// A declaration may not require lowering if, for example, it is annotated as
1084-
/// unavailable and optimization settings allow it to be omitted.
1085-
LLVM_LIBRARY_VISIBILITY bool shouldSkipLowering(const Decl *D);
1086-
1087-
/// Returns true if SIL/IR lowering for the given declaration should produce
1088-
/// a stub that traps at runtime because the code ought to be unreachable.
1089-
LLVM_LIBRARY_VISIBILITY bool shouldLowerToUnavailableCodeStub(const Decl *D);
10901081
} // namespace Lowering
10911082

10921083
/// Apply the given function to each ABI member of \c D skipping the members
10931084
/// that should be skipped according to \c shouldSkipLowering()
10941085
template <typename F>
10951086
void forEachMemberToLower(IterableDeclContext *D, F &&f) {
10961087
for (auto *member : D->getABIMembers()) {
1097-
if (!Lowering::shouldSkipLowering(member))
1088+
if (member->isAvailableDuringLowering())
10981089
f(member);
10991090
}
11001091
}

lib/AST/Availability.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,33 @@ llvm::Optional<AvailableAttrDeclPair> Decl::getSemanticUnavailableAttr() const {
298298
llvm::None);
299299
}
300300

301+
static bool isUnconditionallyUnavailable(const Decl *D) {
302+
if (auto unavailableAttrAndDecl = D->getSemanticUnavailableAttr())
303+
return unavailableAttrAndDecl->first->isUnconditionallyUnavailable();
304+
305+
return false;
306+
}
307+
308+
bool Decl::isAvailableDuringLowering() const {
309+
// Unconditionally unavailable declarations should be skipped during lowering
310+
// when -unavailable-decl-optimization=complete is specified.
311+
if (getASTContext().LangOpts.UnavailableDeclOptimizationMode !=
312+
UnavailableDeclOptimization::Complete)
313+
return true;
314+
315+
return !isUnconditionallyUnavailable(this);
316+
}
317+
318+
bool Decl::requiresUnavailableDeclABICompatibilityStubs() const {
319+
// Code associated with unavailable declarations should trap at runtime if
320+
// -unavailable-decl-optimization=stub is specified.
321+
if (getASTContext().LangOpts.UnavailableDeclOptimizationMode !=
322+
UnavailableDeclOptimization::Stub)
323+
return false;
324+
325+
return isUnconditionallyUnavailable(this);
326+
}
327+
301328
bool UnavailabilityReason::requiresDeploymentTargetOrEarlier(
302329
ASTContext &Ctx) const {
303330
return RequiredDeploymentRange.getLowerEndpoint() <=

lib/IRGen/GenClass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,7 @@ namespace {
18411841

18421842
void buildMethod(ConstantArrayBuilder &descriptors,
18431843
AbstractFunctionDecl *method) {
1844-
if (Lowering::shouldSkipLowering(method))
1844+
if (!method->isAvailableDuringLowering())
18451845
return;
18461846

18471847
auto accessor = dyn_cast<AccessorDecl>(method);

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,7 @@ void IRGenerator::noteUseOfTypeGlobals(NominalTypeDecl *type,
15631563
if (!type)
15641564
return;
15651565

1566-
assert(!Lowering::shouldSkipLowering(type));
1566+
assert(type->isAvailableDuringLowering());
15671567

15681568
// Force emission of ObjC protocol descriptors used by type refs.
15691569
if (auto proto = dyn_cast<ProtocolDecl>(type)) {
@@ -2473,7 +2473,7 @@ void swift::irgen::disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariabl
24732473

24742474
/// Emit a global declaration.
24752475
void IRGenModule::emitGlobalDecl(Decl *D) {
2476-
if (Lowering::shouldSkipLowering(D))
2476+
if (!D->isAvailableDuringLowering())
24772477
return;
24782478

24792479
D->visitAuxiliaryDecls([&](Decl *decl) {
@@ -5550,7 +5550,7 @@ static Address getAddrOfSimpleVariable(IRGenModule &IGM,
55505550
/// The result is always a GlobalValue.
55515551
Address IRGenModule::getAddrOfFieldOffset(VarDecl *var,
55525552
ForDefinition_t forDefinition) {
5553-
assert(!Lowering::shouldSkipLowering(var));
5553+
assert(var->isAvailableDuringLowering());
55545554

55555555
LinkEntity entity = LinkEntity::forFieldOffset(var);
55565556
return getAddrOfSimpleVariable(*this, GlobalVars, entity,
@@ -5559,7 +5559,7 @@ Address IRGenModule::getAddrOfFieldOffset(VarDecl *var,
55595559

55605560
Address IRGenModule::getAddrOfEnumCase(EnumElementDecl *Case,
55615561
ForDefinition_t forDefinition) {
5562-
assert(!Lowering::shouldSkipLowering(Case));
5562+
assert(Case->isAvailableDuringLowering());
55635563

55645564
LinkEntity entity = LinkEntity::forEnumCase(Case);
55655565
auto addr = getAddrOfSimpleVariable(*this, GlobalVars, entity, forDefinition);
@@ -5572,7 +5572,7 @@ Address IRGenModule::getAddrOfEnumCase(EnumElementDecl *Case,
55725572

55735573
void IRGenModule::emitNestedTypeDecls(DeclRange members) {
55745574
for (Decl *member : members) {
5575-
if (Lowering::shouldSkipLowering(member))
5575+
if (!member->isAvailableDuringLowering())
55765576
continue;
55775577

55785578
member->visitAuxiliaryDecls([&](Decl *decl) {

lib/IRGen/GenEnum.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ EnumImplStrategy::getTagIndex(EnumElementDecl *Case) const {
263263
static void emitResilientTagIndex(IRGenModule &IGM,
264264
const EnumImplStrategy *strategy,
265265
EnumElementDecl *Case) {
266-
if (Lowering::shouldSkipLowering(Case))
266+
if (!Case->isAvailableDuringLowering())
267267
return;
268268

269269
auto resilientIdx = strategy->getTagIndex(Case);
@@ -6175,7 +6175,7 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
61756175

61766176
// For the purposes of memory layout, treat unavailable cases as if they do
61776177
// not have a payload.
6178-
if (Lowering::shouldSkipLowering(elt)) {
6178+
if (!elt->isAvailableDuringLowering()) {
61796179
elementsWithNoPayload.push_back({elt, nullptr, nullptr});
61806180
continue;
61816181
}

lib/IRGen/GenReflection.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,9 +853,9 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
853853
if (hasPayload && (decl->isIndirect() || enumDecl->isIndirect()))
854854
flags.setIsIndirectCase();
855855

856-
Type interfaceType = Lowering::shouldSkipLowering(decl)
857-
? nullptr
858-
: decl->getArgumentInterfaceType();
856+
Type interfaceType = decl->isAvailableDuringLowering()
857+
? decl->getArgumentInterfaceType()
858+
: nullptr;
859859

860860
addField(flags, interfaceType, decl->getBaseIdentifier().str());
861861
}

lib/IRGen/GenStruct.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ void IRGenModule::emitStructDecl(StructDecl *st) {
15781578
}
15791579

15801580
void IRGenModule::maybeEmitOpaqueTypeDecl(OpaqueTypeDecl *opaque) {
1581-
if (Lowering::shouldSkipLowering(opaque))
1581+
if (!opaque->isAvailableDuringLowering())
15821582
return;
15831583

15841584
if (IRGen.Opts.EnableAnonymousContextMangledNames) {

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ class IRGenerator {
456456
}
457457

458458
void noteLazyReemissionOfNominalTypeDescriptor(NominalTypeDecl *decl) {
459-
assert(!Lowering::shouldSkipLowering(decl));
459+
assert(decl->isAvailableDuringLowering());
460460
LazilyReemittedTypeContextDescriptors.insert(decl);
461461
}
462462

@@ -466,7 +466,7 @@ class IRGenerator {
466466
}
467467

468468
void noteUseOfMetadataAccessor(NominalTypeDecl *decl) {
469-
assert(!Lowering::shouldSkipLowering(decl));
469+
assert(decl->isAvailableDuringLowering());
470470
if (LazyMetadataAccessors.count(decl) == 0) {
471471
LazyMetadataAccessors.insert(decl);
472472
}

lib/IRGen/TBDGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ void TBDGenVisitor::addSymbol(StringRef name, SymbolSource source,
414414
}
415415

416416
bool TBDGenVisitor::willVisitDecl(Decl *D) {
417-
if (Lowering::shouldSkipLowering(D))
417+
if (!D->isAvailableDuringLowering())
418418
return false;
419419

420420
// A @_silgen_name("...") function without a body only exists to

lib/SIL/IR/SILModule.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -953,30 +953,3 @@ bool Lowering::usesObjCAllocator(ClassDecl *theClass) {
953953
// allocation methods because they may have been overridden.
954954
return theClass->getObjectModel() == ReferenceCounting::ObjC;
955955
}
956-
957-
static bool isUnconditionallyUnavailable(const Decl *D) {
958-
if (auto unavailableAttrAndDecl = D->getSemanticUnavailableAttr())
959-
return unavailableAttrAndDecl->first->isUnconditionallyUnavailable();
960-
961-
return false;
962-
}
963-
964-
bool Lowering::shouldSkipLowering(const Decl *D) {
965-
if (D->getASTContext().LangOpts.UnavailableDeclOptimizationMode !=
966-
UnavailableDeclOptimization::Complete)
967-
return false;
968-
969-
// Unavailable declarations should be skipped if
970-
// -unavailable-decl-optimization=complete is specified.
971-
return isUnconditionallyUnavailable(D);
972-
}
973-
974-
bool Lowering::shouldLowerToUnavailableCodeStub(const Decl *D) {
975-
if (D->getASTContext().LangOpts.UnavailableDeclOptimizationMode !=
976-
UnavailableDeclOptimization::Stub)
977-
return false;
978-
979-
// Unavailable declarations should trap at runtime if
980-
// -unavailable-decl-optimization=stub is specified.
981-
return isUnconditionallyUnavailable(D);
982-
}

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ bool SILGenModule::hasFunction(SILDeclRef constant) {
763763
}
764764

765765
void SILGenModule::visit(Decl *D) {
766-
if (Lowering::shouldSkipLowering(D))
766+
if (!D->isAvailableDuringLowering())
767767
return;
768768

769769
ASTVisitor::visit(D);

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
15531553
SILDeclRef native = thunk.asForeign(false);
15541554

15551555
if (thunk.hasDecl()) {
1556-
if (shouldLowerToUnavailableCodeStub(thunk.getDecl()))
1556+
if (thunk.getDecl()->requiresUnavailableDeclABICompatibilityStubs())
15571557
emitApplyOfUnavailableCodeReached();
15581558
}
15591559

@@ -2068,7 +2068,7 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
20682068
auto nativeFnTy = F.getLoweredFunctionType();
20692069
assert(nativeFnTy == nativeCI.SILFnType);
20702070

2071-
if (shouldLowerToUnavailableCodeStub(fd))
2071+
if (fd->requiresUnavailableDeclABICompatibilityStubs())
20722072
emitApplyOfUnavailableCodeReached();
20732073

20742074
// Use the same generic environment as the native entry point.

lib/SILGen/SILGenConstructor.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
333333
RegularLocation Loc(ctor);
334334
Loc.markAutoGenerated();
335335

336-
if (shouldLowerToUnavailableCodeStub(ctor))
336+
if (ctor->requiresUnavailableDeclABICompatibilityStubs())
337337
SGF.emitApplyOfUnavailableCodeReached();
338338

339339
AssertingManualScope functionLevelScope(SGF.Cleanups,
@@ -612,7 +612,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
612612
bool isDelegating = ctor->getDelegatingOrChainedInitKind().initKind ==
613613
BodyInitKind::Delegating;
614614

615-
if (shouldLowerToUnavailableCodeStub(ctor))
615+
if (ctor->requiresUnavailableDeclABICompatibilityStubs())
616616
emitApplyOfUnavailableCodeReached();
617617

618618
// Get the 'self' decl and type.
@@ -839,7 +839,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
839839
auto &enumTI =
840840
SGM.Types.getTypeLowering(enumTy, TypeExpansionContext::minimal());
841841

842-
if (shouldLowerToUnavailableCodeStub(element))
842+
if (element->requiresUnavailableDeclABICompatibilityStubs())
843843
emitApplyOfUnavailableCodeReached();
844844

845845
RegularLocation Loc(element);
@@ -918,7 +918,7 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
918918
SmallVector<SILValue, 8> args;
919919
bindParametersForForwarding(ctor->getParameters(), args);
920920

921-
if (shouldLowerToUnavailableCodeStub(ctor))
921+
if (ctor->requiresUnavailableDeclABICompatibilityStubs())
922922
emitApplyOfUnavailableCodeReached();
923923

924924
SILValue selfMetaValue = emitConstructorMetatypeArg(*this, ctor);
@@ -1036,7 +1036,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
10361036

10371037
assert(ctor->getTypecheckedBody() && "Class constructor without a body?");
10381038

1039-
if (shouldLowerToUnavailableCodeStub(ctor))
1039+
if (ctor->requiresUnavailableDeclABICompatibilityStubs())
10401040
emitApplyOfUnavailableCodeReached();
10411041

10421042
// True if this constructor delegates to a peer constructor with self.init().

lib/SILGen/SILGenDestructor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
3535
if (dd->isImplicit())
3636
Loc.markAutoGenerated();
3737

38-
if (shouldLowerToUnavailableCodeStub(dd))
38+
if (dd->requiresUnavailableDeclABICompatibilityStubs())
3939
emitApplyOfUnavailableCodeReached();
4040

4141
auto cd = cast<ClassDecl>(dd->getDeclContext()->getSelfNominalTypeDecl());
@@ -181,7 +181,7 @@ void SILGenFunction::emitDeallocatingClassDestructor(DestructorDecl *dd) {
181181
RegularLocation loc(dd);
182182
loc.markAutoGenerated();
183183

184-
if (shouldLowerToUnavailableCodeStub(dd))
184+
if (dd->requiresUnavailableDeclABICompatibilityStubs())
185185
emitApplyOfUnavailableCodeReached();
186186

187187
// Emit the prolog.
@@ -239,7 +239,7 @@ void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) {
239239
if (dd->isImplicit())
240240
loc.markAutoGenerated();
241241

242-
if (shouldLowerToUnavailableCodeStub(dd))
242+
if (dd->requiresUnavailableDeclABICompatibilityStubs())
243243
emitApplyOfUnavailableCodeReached();
244244

245245
// Emit the prolog.
@@ -561,7 +561,7 @@ void SILGenFunction::emitObjCDestructor(SILDeclRef dtor) {
561561
if (dd->isImplicit())
562562
loc.markAutoGenerated();
563563

564-
if (shouldLowerToUnavailableCodeStub(dd))
564+
if (dd->requiresUnavailableDeclABICompatibilityStubs())
565565
emitApplyOfUnavailableCodeReached();
566566

567567
SILValue selfValue = emitSelfDeclForDestructor(dd->getImplicitSelfDecl());

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
10171017
prepareEpilog(fd->getResultInterfaceType(),
10181018
fd->hasThrows(), CleanupLocation(fd));
10191019

1020-
if (shouldLowerToUnavailableCodeStub(fd))
1020+
if (fd->requiresUnavailableDeclABICompatibilityStubs())
10211021
emitApplyOfUnavailableCodeReached();
10221022

10231023
emitProfilerIncrement(fd->getTypecheckedBody());

lib/SILGen/SILGenGlobalVariable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ void SILGenFunction::emitLazyGlobalInitializer(PatternBindingDecl *binding,
250250
// Add unused context pointer argument required to pass to `Builtin.once`
251251
SILBasicBlock &entry = *F.begin();
252252

253-
if (shouldLowerToUnavailableCodeStub(binding))
253+
if (binding->requiresUnavailableDeclABICompatibilityStubs())
254254
emitApplyOfUnavailableCodeReached();
255255

256256
SILType rawPointerSILTy =
@@ -292,7 +292,7 @@ static void emitOnceCall(SILGenFunction &SGF, VarDecl *global,
292292
void SILGenFunction::emitGlobalAccessor(VarDecl *global,
293293
SILGlobalVariable *onceToken,
294294
SILFunction *onceFunc) {
295-
if (shouldLowerToUnavailableCodeStub(global))
295+
if (global->requiresUnavailableDeclABICompatibilityStubs())
296296
emitApplyOfUnavailableCodeReached();
297297

298298
emitOnceCall(*this, global, onceToken, onceFunc);

lib/SILGen/SILGenPoly.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6025,7 +6025,7 @@ void SILGenFunction::emitProtocolWitness(
60256025
SmallVector<ManagedValue, 8> origParams;
60266026
collectThunkParams(loc, origParams);
60276027

6028-
if (shouldLowerToUnavailableCodeStub(witness.getDecl()))
6028+
if (witness.getDecl()->requiresUnavailableDeclABICompatibilityStubs())
60296029
emitApplyOfUnavailableCodeReached();
60306030

60316031
if (enterIsolation) {

0 commit comments

Comments
 (0)