diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 07ab028e4e7..a5554ccb76a 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -590,6 +590,10 @@ public: /// Get the runtime availability of the opaque types language feature for the target platform. AvailabilityContext getOpaqueTypeAvailability(); + /// Get the runtime availability of features introduced in the Swift 5.1 + /// compiler for the target platform. + AvailabilityContext getSwift51Availability(); + //===--------------------------------------------------------------------===// // Diagnostics Helper functions //===--------------------------------------------------------------------===// diff --git a/include/swift/Runtime/RuntimeFnWrappersGen.h b/include/swift/Runtime/RuntimeFnWrappersGen.h index 0ba1116c8f7..9ef178a272e 100644 --- a/include/swift/Runtime/RuntimeFnWrappersGen.h +++ b/include/swift/Runtime/RuntimeFnWrappersGen.h @@ -22,6 +22,13 @@ namespace swift { class AvailabilityContext; +class ASTContext; + +enum class RuntimeAvailability { + AlwaysAvailable, + AvailableByCompatibilityLibrary, + ConditionallyAvailable +}; /// Generate an llvm declaration for a runtime entry with a /// given name, return types, argument types, attributes and @@ -30,7 +37,8 @@ llvm::Constant *getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache, char const *name, llvm::CallingConv::ID cc, - bool isWeakLinked, + RuntimeAvailability availability, + ASTContext *context, llvm::ArrayRef retTypes, llvm::ArrayRef argTypes, llvm::ArrayRef attrs); diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def index 8aa89cadead..291750c02fc 100644 --- a/include/swift/Runtime/RuntimeFunctions.def +++ b/include/swift/Runtime/RuntimeFunctions.def @@ -638,7 +638,7 @@ FUNCTION(GetGenericMetadata, swift_getGenericMetadata, // const OpaqueTypeDescriptor *descriptor, // uintptr_t index); FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata, - SwiftCC, OpaqueTypeAvailability, + SwiftCC, ConditionallyAvailable, RETURNS(TypeMetadataResponseTy), ARGS(SizeTy, Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy), ATTRS(NoUnwind, ReadOnly)) @@ -647,7 +647,7 @@ FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata, // const OpaqueTypeDescriptor *descriptor, // uintptr_t index); FUNCTION(GetOpaqueTypeConformance, swift_getOpaqueTypeConformance, - SwiftCC, OpaqueTypeAvailability, + SwiftCC, ConditionallyAvailable, RETURNS(WitnessTablePtrTy), ARGS(Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy), ATTRS(NoUnwind, ReadOnly)) @@ -1226,25 +1226,13 @@ FUNCTION(EndAccess, swift_endAccess, C_CC, AlwaysAvailable, ATTRS(NoUnwind)) FUNCTION(GetOrigOfReplaceable, swift_getOrigOfReplaceable, C_CC, - GetReplacementAvailability, + AvailableByCompatibilityLibrary, RETURNS(FunctionPtrTy), ARGS(FunctionPtrTy->getPointerTo()), ATTRS(NoUnwind)) FUNCTION(GetReplacement, swift_getFunctionReplacement, C_CC, - GetReplacementAvailability, - RETURNS(FunctionPtrTy), - ARGS(FunctionPtrTy->getPointerTo(), FunctionPtrTy), - ATTRS(NoUnwind)) - -FUNCTION(GetOrigOfReplaceable50, swift_getOrigOfReplaceable50, C_CC, - AlwaysAvailable, - RETURNS(FunctionPtrTy), - ARGS(FunctionPtrTy->getPointerTo()), - ATTRS(NoUnwind)) - -FUNCTION(GetReplacement50, swift_getFunctionReplacement50, C_CC, - AlwaysAvailable, + AvailableByCompatibilityLibrary, RETURNS(FunctionPtrTy), ARGS(FunctionPtrTy->getPointerTo(), FunctionPtrTy), ATTRS(NoUnwind)) diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 6a1ec00c07b..d094532cb52 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -218,6 +218,10 @@ AvailabilityContext AvailabilityInference::inferForType(Type t) { } AvailabilityContext ASTContext::getOpaqueTypeAvailability() { + return getSwift51Availability(); +} + +AvailabilityContext ASTContext::getSwift51Availability() { auto target = LangOpts.Target; if (target.isMacOSX()) { diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 9a4f002abea..0a522fa67bb 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -2239,12 +2239,8 @@ void IRGenModule::createReplaceableProlog(IRGenFunction &IGF, SILFunction *f) { rhs = FnAddr; } else { // Call swift_getFunctionReplacement to check which function to call. - auto *getReplacementFn = IRGenModule::isGetReplacementAvailable(Context) - ? getGetReplacementFn() - : getGetReplacement50Fn(); - auto *callRTFunc = - IGF.Builder.CreateCall(getReplacementFn, {ReplAddr, FnAddr}); + IGF.Builder.CreateCall(getGetReplacementFn(), {ReplAddr, FnAddr}); callRTFunc->setDoesNotThrow(); ReplFn = callRTFunc; rhs = llvm::ConstantExpr::getNullValue(ReplFn->getType()); @@ -2412,10 +2408,8 @@ void IRGenModule::emitDynamicReplacementOriginalFunctionThunk(SILFunction *f) { llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, linkEntry, indices), FunctionPtrTy->getPointerTo()); - auto *getOrigOfReplaceableFn = IRGenModule::isGetReplacementAvailable(Context) - ? getGetOrigOfReplaceableFn() - : getGetOrigOfReplaceable50Fn(); - auto *OrigFn = IGF.Builder.CreateCall(getOrigOfReplaceableFn, {fnPtrAddr}); + auto *OrigFn = + IGF.Builder.CreateCall(getGetOrigOfReplaceableFn(), {fnPtrAddr}); OrigFn->setDoesNotThrow(); diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 50af7a9a896..1c422814a73 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -527,31 +527,6 @@ IRGenModule::~IRGenModule() { static bool isReturnAttribute(llvm::Attribute::AttrKind Attr); -static AvailabilityContext -getGetReplacementAvailability(ASTContext &context) { - auto target = context.LangOpts.Target; - - if (target.isMacOSX()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 15, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(13, 0, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(6, 0, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -bool IRGenModule::isGetReplacementAvailable(ASTContext &Context) { - auto deploymentAvailability = - AvailabilityContext::forDeploymentTarget(Context); - auto featureAvailability = getGetReplacementAvailability(Context); - return deploymentAvailability.isContainedIn(featureAvailability); -} - // Explicitly listing these constants is an unfortunate compromise for // making the database file much more compact. // @@ -564,22 +539,12 @@ namespace RuntimeConstants { const auto NoUnwind = llvm::Attribute::NoUnwind; const auto ZExt = llvm::Attribute::ZExt; const auto FirstParamReturned = llvm::Attribute::Returned; - - bool AlwaysAvailable(ASTContext &Context) { - return false; - } - - bool OpaqueTypeAvailability(ASTContext &Context) { - auto deploymentAvailability = - AvailabilityContext::forDeploymentTarget(Context); - auto featureAvailability = Context.getOpaqueTypeAvailability(); - - return !deploymentAvailability.isContainedIn(featureAvailability); - } - bool GetReplacementAvailability(ASTContext &Context) { - return !IRGenModule::isGetReplacementAvailable(Context); - } + const auto AlwaysAvailable = RuntimeAvailability::AlwaysAvailable; + const auto AvailableByCompatibilityLibrary = + RuntimeAvailability::AvailableByCompatibilityLibrary; + const auto ConditionallyAvailable = + RuntimeAvailability::ConditionallyAvailable; } // namespace RuntimeConstants // We don't use enough attributes to justify generalizing the @@ -623,13 +588,40 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache, const char *name, llvm::CallingConv::ID cc, - bool isWeakLinked, + RuntimeAvailability availability, + ASTContext *context, llvm::ArrayRef retTypes, llvm::ArrayRef argTypes, ArrayRef attrs) { + if (cache) return cache; - + + bool isWeakLinked = false; + std::string functionName(name); + + auto isFeatureAvailable = [&]() -> bool { + auto deploymentAvailability = + AvailabilityContext::forDeploymentTarget(*context); + auto featureAvailability = context->getSwift51Availability(); + return deploymentAvailability.isContainedIn(featureAvailability); + }; + + switch (availability) { + case RuntimeAvailability::AlwaysAvailable: + // Nothing to do. + break; + case RuntimeAvailability::ConditionallyAvailable: { + isWeakLinked = !isFeatureAvailable(); + break; + } + case RuntimeAvailability::AvailableByCompatibilityLibrary: { + if (!isFeatureAvailable()) + functionName.append("50"); + break; + } + } + llvm::Type *retTy; if (retTypes.size() == 1) retTy = *retTypes.begin(); @@ -641,7 +633,7 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module, {argTypes.begin(), argTypes.end()}, /*isVararg*/ false); - cache = Module.getOrInsertFunction(name, fnTy); + cache = Module.getOrInsertFunction(functionName.c_str(), fnTy); // Add any function attributes and set the calling convention. if (auto fn = dyn_cast(cache)) { @@ -696,7 +688,7 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module, llvm::Constant *IRGenModule::get##ID##Fn() { \ using namespace RuntimeConstants; \ return getRuntimeFn(Module, ID##Fn, #NAME, CC, \ - (AVAILABILITY)(this->Context), \ + AVAILABILITY, &this->Context, \ RETURNS, ARGS, ATTRS); \ } diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index c87bac8c2ee..e8084d1f6e4 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -1441,7 +1441,6 @@ public: void emitOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *); - static bool isGetReplacementAvailable(ASTContext &context); private: llvm::Constant * getAddrOfSharedContextDescriptor(LinkEntity entity, diff --git a/lib/LLVMPasses/ARCEntryPointBuilder.h b/lib/LLVMPasses/ARCEntryPointBuilder.h index b4ad5d56156..210096793d7 100644 --- a/lib/LLVMPasses/ARCEntryPointBuilder.h +++ b/lib/LLVMPasses/ARCEntryPointBuilder.h @@ -220,8 +220,8 @@ private: Retain = getRuntimeFn( getModule(), cache, isNonAtomic(OrigI) ? "swift_nonatomic_retain" : "swift_retain", - DefaultCC, false, {ObjectPtrTy}, {ObjectPtrTy}, - {NoUnwind, FirstParamReturned}); + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {ObjectPtrTy}, + {ObjectPtrTy}, {NoUnwind, FirstParamReturned}); return Retain.get(); } @@ -234,10 +234,11 @@ private: auto *VoidTy = Type::getVoidTy(getModule().getContext()); llvm::Constant *cache = nullptr; - Release = getRuntimeFn( - getModule(), cache, - isNonAtomic(OrigI) ? "swift_nonatomic_release" : "swift_release", - DefaultCC, false, {VoidTy}, {ObjectPtrTy}, {NoUnwind}); + Release = getRuntimeFn(getModule(), cache, + isNonAtomic(OrigI) ? "swift_nonatomic_release" + : "swift_release", + DefaultCC, RuntimeAvailability::AlwaysAvailable, + nullptr, {VoidTy}, {ObjectPtrTy}, {NoUnwind}); return Release.get(); } @@ -272,8 +273,8 @@ private: RetainN = getRuntimeFn( getModule(), cache, isNonAtomic(OrigI) ? "swift_nonatomic_retain_n" : "swift_retain_n", - DefaultCC, false, {ObjectPtrTy}, {ObjectPtrTy, Int32Ty}, - {NoUnwind, FirstParamReturned}); + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {ObjectPtrTy}, + {ObjectPtrTy, Int32Ty}, {NoUnwind, FirstParamReturned}); return RetainN.get(); } @@ -290,7 +291,8 @@ private: ReleaseN = getRuntimeFn( getModule(), cache, isNonAtomic(OrigI) ? "swift_nonatomic_release_n" : "swift_release_n", - DefaultCC, false, {VoidTy}, {ObjectPtrTy, Int32Ty}, {NoUnwind}); + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {VoidTy}, + {ObjectPtrTy, Int32Ty}, {NoUnwind}); return ReleaseN.get(); } @@ -304,13 +306,12 @@ private: auto *Int32Ty = Type::getInt32Ty(getModule().getContext()); llvm::Constant *cache = nullptr; - UnknownObjectRetainN = - getRuntimeFn(getModule(), cache, - isNonAtomic(OrigI) - ? "swift_nonatomic_unknownObjectRetain_n" - : "swift_unknownObjectRetain_n", - DefaultCC, false, {ObjectPtrTy}, {ObjectPtrTy, Int32Ty}, - {NoUnwind, FirstParamReturned}); + UnknownObjectRetainN = getRuntimeFn( + getModule(), cache, + isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRetain_n" + : "swift_unknownObjectRetain_n", + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {ObjectPtrTy}, + {ObjectPtrTy, Int32Ty}, {NoUnwind, FirstParamReturned}); return UnknownObjectRetainN.get(); } @@ -324,13 +325,12 @@ private: auto *VoidTy = Type::getVoidTy(getModule().getContext()); llvm::Constant *cache = nullptr; - UnknownObjectReleaseN = - getRuntimeFn(getModule(), cache, - isNonAtomic(OrigI) - ? "swift_nonatomic_unknownObjectRelease_n" - : "swift_unknownObjectRelease_n", - DefaultCC, false, - {VoidTy}, {ObjectPtrTy, Int32Ty}, {NoUnwind}); + UnknownObjectReleaseN = getRuntimeFn( + getModule(), cache, + isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRelease_n" + : "swift_unknownObjectRelease_n", + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {VoidTy}, + {ObjectPtrTy, Int32Ty}, {NoUnwind}); return UnknownObjectReleaseN.get(); } @@ -343,12 +343,12 @@ private: auto *Int32Ty = Type::getInt32Ty(getModule().getContext()); llvm::Constant *cache = nullptr; - BridgeRetainN = - getRuntimeFn(getModule(), cache, - isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n" - : "swift_bridgeObjectRetain_n", - DefaultCC, false, {BridgeObjectPtrTy}, - {BridgeObjectPtrTy, Int32Ty}, {NoUnwind}); + BridgeRetainN = getRuntimeFn( + getModule(), cache, + isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n" + : "swift_bridgeObjectRetain_n", + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, + {BridgeObjectPtrTy}, {BridgeObjectPtrTy, Int32Ty}, {NoUnwind}); return BridgeRetainN.get(); } @@ -366,7 +366,8 @@ private: getModule(), cache, isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRelease_n" : "swift_bridgeObjectRelease_n", - DefaultCC, false, {VoidTy}, {BridgeObjectPtrTy, Int32Ty}, {NoUnwind}); + DefaultCC, RuntimeAvailability::AlwaysAvailable, nullptr, {VoidTy}, + {BridgeObjectPtrTy, Int32Ty}, {NoUnwind}); return BridgeReleaseN.get(); }