Skip to content

Commit cb7982d

Browse files
authored
Merge pull request #67761 from tshortli/ast-unavailable-decl-queries
NFC: Hoist queries for unavailable decl optimizations into the AST library
2 parents 5429100 + ca8bf98 commit cb7982d

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)