Refactor to use RuntimeAvailability

This commit is contained in:
Arnold Schwaighofer
2019-06-14 12:50:13 -07:00
parent f29b77f954
commit eb32194e97
8 changed files with 91 additions and 101 deletions

View File

@@ -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
//===--------------------------------------------------------------------===//

View File

@@ -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<llvm::Type*> retTypes,
llvm::ArrayRef<llvm::Type*> argTypes,
llvm::ArrayRef<llvm::Attribute::AttrKind> attrs);

View File

@@ -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))

View File

@@ -218,6 +218,10 @@ AvailabilityContext AvailabilityInference::inferForType(Type t) {
}
AvailabilityContext ASTContext::getOpaqueTypeAvailability() {
return getSwift51Availability();
}
AvailabilityContext ASTContext::getSwift51Availability() {
auto target = LangOpts.Target;
if (target.isMacOSX()) {

View File

@@ -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();

View File

@@ -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.
//
@@ -565,21 +540,11 @@ namespace RuntimeConstants {
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<llvm::Type*> retTypes,
llvm::ArrayRef<llvm::Type*> argTypes,
ArrayRef<Attribute::AttrKind> 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<llvm::Function>(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); \
}

View File

@@ -1441,7 +1441,6 @@ public:
void emitOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *);
static bool isGetReplacementAvailable(ASTContext &context);
private:
llvm::Constant *
getAddrOfSharedContextDescriptor(LinkEntity entity,

View File

@@ -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"
UnknownObjectRetainN = getRuntimeFn(
getModule(), cache,
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRetain_n"
: "swift_unknownObjectRetain_n",
DefaultCC, false, {ObjectPtrTy}, {ObjectPtrTy, Int32Ty},
{NoUnwind, FirstParamReturned});
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"
UnknownObjectReleaseN = getRuntimeFn(
getModule(), cache,
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRelease_n"
: "swift_unknownObjectRelease_n",
DefaultCC, false,
{VoidTy}, {ObjectPtrTy, Int32Ty}, {NoUnwind});
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,
BridgeRetainN = getRuntimeFn(
getModule(), cache,
isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n"
: "swift_bridgeObjectRetain_n",
DefaultCC, false, {BridgeObjectPtrTy},
{BridgeObjectPtrTy, Int32Ty}, {NoUnwind});
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();
}