IRGen: further generalise runtime function generation

This adjusts the runtime function declaration handling to track the
owning module for the well known functions. This allows us to ensure
that we are able to properly identify if the symbol should be imported
or not when building the shared libraries. This will require a
subsequent tweak to allow for checking for static library linkage to
ensure that we do not mark the symbol as DLLImport when doing static
linking.
This commit is contained in:
Saleem Abdulrasool
2025-01-10 10:35:36 -08:00
parent 73b184df24
commit ec70054c93
9 changed files with 340 additions and 334 deletions

View File

@@ -39,7 +39,8 @@ enum class RuntimeAvailability {
/// given name, return types, argument types, attributes and
/// a calling convention.
llvm::Constant *getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache,
char const *name, llvm::CallingConv::ID cc,
const char *ModuleName, char const *FunctionName,
llvm::CallingConv::ID cc,
RuntimeAvailability availability,
llvm::ArrayRef<llvm::Type *> retTypes,
llvm::ArrayRef<llvm::Type *> argTypes,

File diff suppressed because it is too large Load Diff

View File

@@ -1072,9 +1072,9 @@ llvm::FunctionType *swift::getRuntimeFnType(llvm::Module &Module,
}
llvm::Constant *swift::getRuntimeFn(
llvm::Module &Module, llvm::Constant *&cache, const char *name,
llvm::CallingConv::ID cc, RuntimeAvailability availability,
llvm::ArrayRef<llvm::Type *> retTypes,
llvm::Module &Module, llvm::Constant *&cache, const char *ModuleName,
const char *FunctionName, llvm::CallingConv::ID cc,
RuntimeAvailability availability, llvm::ArrayRef<llvm::Type *> retTypes,
llvm::ArrayRef<llvm::Type *> argTypes, ArrayRef<Attribute::AttrKind> attrs,
ArrayRef<llvm::MemoryEffects> memEffects, IRGenModule *IGM) {
@@ -1082,7 +1082,7 @@ llvm::Constant *swift::getRuntimeFn(
return cache;
bool isWeakLinked = false;
std::string functionName(name);
std::string name(FunctionName);
switch (availability) {
case RuntimeAvailability::AlwaysAvailable:
@@ -1093,7 +1093,7 @@ llvm::Constant *swift::getRuntimeFn(
break;
}
case RuntimeAvailability::AvailableByCompatibilityLibrary: {
functionName.append("50");
name.append("50");
break;
}
}
@@ -1109,7 +1109,7 @@ llvm::Constant *swift::getRuntimeFn(
{argTypes.begin(), argTypes.end()},
/*isVararg*/ false);
auto addr = Module.getOrInsertFunction(functionName.c_str(), fnTy).getCallee();
auto addr = Module.getOrInsertFunction(name.c_str(), fnTy).getCallee();
auto fnptr = addr;
// Strip off any bitcast we might have due to this function being declared of
// a different type previously.
@@ -1126,12 +1126,20 @@ llvm::Constant *swift::getRuntimeFn(
(fn->getLinkage() == llvm::GlobalValue::ExternalLinkage &&
fn->isDeclaration());
if (!isStandardLibrary(Module) && IsExternal &&
::useDllStorage(llvm::Triple(Module.getTargetTriple())))
fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
if (IGM && useDllStorage(IGM->Triple) && IsExternal) {
bool bIsImported = true;
if (IGM->getSwiftModule()->getPublicModuleName(true).str() == ModuleName)
bIsImported = false;
else if (ModuleDecl *MD = IGM->Context.getModuleByName(ModuleName))
bIsImported = !MD->isStaticLibrary();
if (IsExternal && isWeakLinked
&& !::useDllStorage(llvm::Triple(Module.getTargetTriple())))
if (bIsImported)
fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
}
// Windows does not allow multiple definitions of weak symbols.
if (IsExternal && isWeakLinked &&
!llvm::Triple(Module.getTargetTriple()).isOSWindows())
fn->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
llvm::AttrBuilder buildFnAttr(Module.getContext());
@@ -1165,7 +1173,7 @@ llvm::Constant *swift::getRuntimeFn(
// This mismatch of attributes would be issue when lowering to WebAssembly.
// While lowering, LLVM counts how many dummy params are necessary to match
// callee and caller signature. So we need to add them correctly.
if (functionName == "swift_willThrow") {
if (name == "swift_willThrow") {
assert(IGM && "IGM is required for swift_willThrow.");
fn->addParamAttr(0, Attribute::AttrKind::SwiftSelf);
if (IGM->ShouldUseSwiftError) {
@@ -1201,10 +1209,10 @@ void IRGenModule::registerRuntimeEffect(ArrayRef<RuntimeEffect> effect,
#define QUOTE(...) __VA_ARGS__
#define STR(X) #X
#define FUNCTION(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, EFFECT, \
MEMEFFECTS) \
FUNCTION_IMPL(ID, NAME, CC, AVAILABILITY, QUOTE(RETURNS), QUOTE(ARGS), \
QUOTE(ATTRS), QUOTE(EFFECT), QUOTE(MEMEFFECTS))
#define FUNCTION(ID, MODULE, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, \
EFFECT, MEMEFFECTS) \
FUNCTION_IMPL(ID, MODULE, NAME, CC, AVAILABILITY, QUOTE(RETURNS), \
QUOTE(ARGS), QUOTE(ATTRS), QUOTE(EFFECT), QUOTE(MEMEFFECTS))
#define RETURNS(...) { __VA_ARGS__ }
#define ARGS(...) { __VA_ARGS__ }
@@ -1217,12 +1225,12 @@ void IRGenModule::registerRuntimeEffect(ArrayRef<RuntimeEffect> effect,
#define MEMEFFECTS(...) \
{ __VA_ARGS__ }
#define FUNCTION_IMPL(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, \
#define FUNCTION_IMPL(ID, MODULE, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS,\
EFFECT, MEMEFFECTS) \
llvm::Constant *IRGenModule::get##ID##Fn() { \
using namespace RuntimeConstants; \
registerRuntimeEffect(EFFECT, #NAME); \
return getRuntimeFn(Module, ID##Fn, #NAME, CC, \
return getRuntimeFn(Module, ID##Fn, #MODULE, #NAME, CC, \
AVAILABILITY(this->Context), RETURNS, ARGS, ATTRS, \
MEMEFFECTS, this); \
} \
@@ -1289,7 +1297,8 @@ IRGenModule::createStringConstant(StringRef Str, bool willBeRelativelyAddressed,
if (NAME) \
return NAME; \
NAME = Module.getOrInsertGlobal(SYM, FullExistentialTypeMetadataStructTy); \
if (!getSwiftModule()->isStdlibModule()) \
if (!getSwiftModule()->isStdlibModule() || \
!getSwiftModule()->isStaticLibrary()) \
ApplyIRLinkage(IRLinkage::ExternalImport) \
.to(cast<llvm::GlobalVariable>(NAME)); \
return NAME; \

View File

@@ -221,7 +221,7 @@ private:
llvm::Constant *cache = nullptr;
Retain = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_retain" : "swift_retain",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
{ObjectPtrTy}, {NoUnwind, FirstParamReturned}, {});
@@ -237,7 +237,7 @@ private:
auto *VoidTy = Type::getVoidTy(getModule().getContext());
llvm::Constant *cache = nullptr;
Release = getRuntimeFn(getModule(), cache,
Release = getRuntimeFn(getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_release"
: "swift_release",
DefaultCC, RuntimeAvailability::AlwaysAvailable,
@@ -274,7 +274,7 @@ private:
llvm::Constant *cache = nullptr;
RetainN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_retain_n" : "swift_retain_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
{ObjectPtrTy, Int32Ty}, {NoUnwind, FirstParamReturned}, {});
@@ -291,7 +291,7 @@ private:
auto *VoidTy = Type::getVoidTy(getModule().getContext());
llvm::Constant *cache = nullptr;
ReleaseN = getRuntimeFn(getModule(), cache,
ReleaseN = getRuntimeFn(getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_release_n"
: "swift_release_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable,
@@ -310,7 +310,7 @@ private:
llvm::Constant *cache = nullptr;
UnknownObjectRetainN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRetain_n"
: "swift_unknownObjectRetain_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
@@ -329,7 +329,7 @@ private:
llvm::Constant *cache = nullptr;
UnknownObjectReleaseN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRelease_n"
: "swift_unknownObjectRelease_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},
@@ -347,7 +347,7 @@ private:
llvm::Constant *cache = nullptr;
BridgeRetainN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n"
: "swift_bridgeObjectRetain_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {BridgeObjectPtrTy},
@@ -366,7 +366,7 @@ private:
llvm::Constant *cache = nullptr;
BridgeReleaseN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRelease_n"
: "swift_bridgeObjectRelease_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},

View File

@@ -49,10 +49,10 @@ public:
void linkEmbeddedRuntimeFromStdlib() {
using namespace RuntimeConstants;
#define FUNCTION(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, EFFECT, \
MEMORY_EFFECTS) \
#define FUNCTION(ID, MODULE, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, \
EFFECT, MEMORY_EFFECTS) \
linkEmbeddedRuntimeFunctionByName(#NAME, EFFECT); \
if (getModule()->getASTContext().hadError()) \
if (getModule()->getASTContext().hadError()) \
return;
#define RETURNS(...)

View File

@@ -2443,7 +2443,7 @@ static bool canDeclareSymbolName(StringRef symbol, ModuleDecl *fromModule) {
// promote this to an error after a while.
return llvm::StringSwitch<bool>(symbol)
#define FUNCTION(_, Name, ...) \
#define FUNCTION(_, Module, Name, ...) \
.Case(#Name, false) \
.Case("_" #Name, false) \
.Case(#Name "_", false) \

View File

@@ -1,13 +1,9 @@
// RUN: %swift -target thumbv7--windows-itanium -emit-ir -parse-as-library -disable-legacy-type-info -parse-stdlib -module-name dllexport %s -o - | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-OPT
// RUN: %swift -target thumbv7--windows-itanium -O -emit-ir -parse-as-library -disable-legacy-type-info -parse-stdlib -module-name dllexport %s -o - | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
// RUN: %swift -target %host_triple -emit-ir -parse-as-library -disable-legacy-type-info -module-name dllexport %s -o - | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-OPT
// RUN: %swift -target %host_triple -O -emit-ir -parse-as-library -disable-legacy-type-info -module-name dllexport %s -o - | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
// REQUIRES: OS=windows-msvc
// REQUIRES: CODEGENERATOR=ARM
enum Never {}
@_silgen_name("_swift_fatalError")
func fatalError() -> Never
import Swift
public protocol p {
func f()
@@ -25,12 +21,12 @@ open class d {
}
}
// CHECK-DAG: @"$s9dllexport2ciAA1cCvp" = dllexport global ptr null, align 4
// CHECK-DAG: @"$s9dllexport2ciAA1cCvp" = dllexport global ptr null
// CHECK-DAG: @"$s9dllexport1pMp" = dllexport constant
// CHECK-DAG: @"$s9dllexport1cCMn" = dllexport constant
// CHECK-DAG: @"$s9dllexport1cCN" = dllexport alias %swift.type
// CHECK-DAG: @"$s9dllexport1dCN" = dllexport alias %swift.type
// CHECK-DAG-OPT: @"$s9dllexport1dC1m33_C57BA610BA35E21738CC992438E660E9LLyyF" = dllexport alias void (), ptr @_swift_dead_method_stub
// CHECK-DAG-OPT: @"$s9dllexport1dC1m33_C57BA610BA35E21738CC992438E660E9LLs5NeverOyf" = dllexport alias void (), ptr @_swift_dead_method_stub
// CHECK-DAG-OPT: @"$s9dllexport1dCACycfc" = dllexport alias void (), ptr @_swift_dead_method_stub
// CHECK-DAG-OPT: @"$s9dllexport1cCACycfc" = dllexport alias void (), ptr @_swift_dead_method_stub
// CHECK-DAG-OPT: @"$s9dllexport1cCACycfC" = dllexport alias void (), ptr @_swift_dead_method_stub
@@ -38,11 +34,11 @@ open class d {
// CHECK-DAG-NO-OPT: define dllexport swiftcc ptr @"$s9dllexport1cCACycfc"(ptr %0)
// CHECK-DAG-NO-OPT: define dllexport swiftcc ptr @"$s9dllexport1cCACycfC"(ptr %0)
// CHECK-DAG: define dllexport swiftcc {{(noundef )?(nonnull )?}}ptr @"$s9dllexport2ciAA1cCvau"()
// CHECK-DAG-NO-OPT: define dllexport swiftcc void @"$s9dllexport1dC1m33_C57BA610BA35E21738CC992438E660E9LLyyF"(ptr %0)
// CHECK-DAG-NO-OPT: define dllexport swiftcc void @"$s9dllexport1dC1m33_C57BA610BA35E21738CC992438E660E9LLs5NeverOyF"(ptr %0)
// CHECK-DAG-NO-OPT: define dllexport swiftcc void @"$s9dllexport1dCfD"(ptr %0)
// CHECK-DAG: define dllexport swiftcc ptr @"$s9dllexport1dCfd"(ptr{{.*}})
// CHECK-DAG: define dllexport swiftcc %swift.metadata_response @"$s9dllexport1cCMa"(i32 %0)
// CHECK-DAG: define dllexport swiftcc %swift.metadata_response @"$s9dllexport1dCMa"(i32 %0)
// CHECK-DAG: define dllexport swiftcc %swift.metadata_response @"$s9dllexport1cCMa"(i64 %0)
// CHECK-DAG: define dllexport swiftcc %swift.metadata_response @"$s9dllexport1dCMa"(i64 %0)
// CHECK-DAG-NO-OPT: define dllexport swiftcc ptr @"$s9dllexport1dCACycfc"(ptr %0)
// CHECK-DAG-OPT: define dllexport swiftcc void @"$s9dllexport1dCfD"(ptr %0)

View File

@@ -1,7 +1,7 @@
// RUN: %swift -Xllvm -sil-disable-pass=GenericSpecializer -target thumbv7--windows-itanium -emit-ir -parse-as-library -disable-legacy-type-info -parse-stdlib -module-name dllimport %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-OPT
// RUN: %swift -Xllvm -sil-disable-pass=GenericSpecializer -target thumbv7--windows-itanium -O -emit-ir -parse-as-library -disable-legacy-type-info -parse-stdlib -module-name dllimport -primary-file %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
// RUN: %swift -Xllvm -sil-disable-pass=GenericSpecializer -target %host_triple -emit-ir -parse-as-library -disable-legacy-type-info -module-name dllimport %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-OPT
// RUN: %swift -Xllvm -sil-disable-pass=GenericSpecializer -target %host_triple -O -emit-ir -parse-as-library -disable-legacy-type-info -module-name dllimport -primary-file %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
// REQUIRES: CODEGENERATOR=ARM
// REQUIRES: OS=windows-msvc
import dllexport
@@ -36,16 +36,16 @@ public func g() {
blackhole({ () -> () in })
}
// CHECK-NO-OPT-DAG: declare dllimport ptr @swift_allocObject(ptr, i32, i32)
// CHECK-NO-OPT-DAG: declare dllimport ptr @swift_allocObject(ptr, i64, i64)
// CHECK-NO-OPT-DAG: declare dllimport void @swift_release(ptr)
// CHECK-NO-OPT-DAG: declare dllimport ptr @swift_retain(ptr returned)
// CHECK-NO-OPT-DAG: @"$s9dllexport1pMp" = external dllimport global %swift.protocol
// CHECK-NO-OPT-DAG: declare dllimport swiftcc ptr @"$s9dllexport2ciAA1cCvau"()
// CHECK-NO-OPT-DAG: declare dllimport swiftcc ptr @"$s9dllexport1cCfd"(ptr swiftself)
// CHECK-NO-OPT-DAG: declare dllimport void @swift_deallocClassInstance(ptr, i32, i32)
// CHECK-NO-OPT-DAG: declare dllimport void @swift_deallocClassInstance(ptr, i64, i64)
// CHECK-OPT-DAG: declare dllimport ptr @swift_retain(ptr returned) local_unnamed_addr
// CHECK-OPT-DAG: @"\01__imp_{{_?}}$s9dllexport1pMp" = external externally_initialized constant ptr
// CHECK-OPT-DAG: declare dllimport swiftcc ptr @"$s9dllexport2ciAA1cCvau"()
// CHECK-OPT-DAG: declare dllimport void @swift_deallocClassInstance(ptr, i32, i32)
// CHECK-OPT-DAG: declare dllimport void @swift_deallocClassInstance(ptr, i64, i64)
// CHECK-OPT-DAG: declare dllimport swiftcc ptr @"$s9dllexport1cCfd"(ptr swiftself)

View File

@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend %s -disable-type-layout -disable-generic-metadata-prespecialization -gnone -emit-ir -enable-objc-interop | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-objc --check-prefix=CHECK-objc-simulator-%target-is-simulator --check-prefix=CHECK-objc-%target-ptrsize --check-prefix=CHECK-%target-os --check-prefix=CHECK-objc-%target-os
// RUN: %target-swift-frontend %s -disable-type-layout -disable-generic-metadata-prespecialization -gnone -emit-ir -disable-objc-interop | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-native --check-prefix=CHECK-native-%target-ptrsize --check-prefix=CHECK-%target-os --check-prefix=CHECK-native-%target-os
// RUN: %target-swift-frontend %s -Xllvm -type-lowering-disable-verification -disable-type-layout -disable-generic-metadata-prespecialization -gnone -emit-ir -enable-objc-interop | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-objc --check-prefix=CHECK-objc-simulator-%target-is-simulator --check-prefix=CHECK-objc-%target-ptrsize --check-prefix=CHECK-%target-os --check-prefix=CHECK-objc-%target-os
// RUN: %target-swift-frontend %s -Xllvm -type-lowering-disable-verification -disable-type-layout -disable-generic-metadata-prespecialization -gnone -emit-ir -disable-objc-interop | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-native --check-prefix=CHECK-native-%target-ptrsize --check-prefix=CHECK-%target-os --check-prefix=CHECK-native-%target-os
// REQUIRES: CPU=x86_64