Skip to content

IRGen: further generalise runtime function generation #78553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/swift/Runtime/RuntimeFnWrappersGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
562 changes: 281 additions & 281 deletions include/swift/Runtime/RuntimeFunctions.def

Large diffs are not rendered by default.

47 changes: 28 additions & 19 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,17 +1072,17 @@ 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) {

if (cache)
return cache;

bool isWeakLinked = false;
std::string functionName(name);
std::string name(FunctionName);

switch (availability) {
case RuntimeAvailability::AlwaysAvailable:
Expand All @@ -1093,7 +1093,7 @@ llvm::Constant *swift::getRuntimeFn(
break;
}
case RuntimeAvailability::AvailableByCompatibilityLibrary: {
functionName.append("50");
name.append("50");
break;
}
}
Expand All @@ -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.
Expand All @@ -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());
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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__ }
Expand All @@ -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); \
} \
Expand Down Expand Up @@ -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; \
Expand Down
16 changes: 8 additions & 8 deletions lib/LLVMPasses/ARCEntryPointBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class ARCEntryPointBuilder {

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}, {});
Expand All @@ -237,7 +237,7 @@ class ARCEntryPointBuilder {
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,
Expand Down Expand Up @@ -274,7 +274,7 @@ class ARCEntryPointBuilder {

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}, {});
Expand All @@ -291,7 +291,7 @@ class ARCEntryPointBuilder {
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,
Expand All @@ -310,7 +310,7 @@ class ARCEntryPointBuilder {

llvm::Constant *cache = nullptr;
UnknownObjectRetainN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRetain_n"
: "swift_unknownObjectRetain_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
Expand All @@ -329,7 +329,7 @@ class ARCEntryPointBuilder {

llvm::Constant *cache = nullptr;
UnknownObjectReleaseN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRelease_n"
: "swift_unknownObjectRelease_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},
Expand All @@ -347,7 +347,7 @@ class ARCEntryPointBuilder {

llvm::Constant *cache = nullptr;
BridgeRetainN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n"
: "swift_bridgeObjectRetain_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {BridgeObjectPtrTy},
Expand All @@ -366,7 +366,7 @@ class ARCEntryPointBuilder {

llvm::Constant *cache = nullptr;
BridgeReleaseN = getRuntimeFn(
getModule(), cache,
getModule(), cache, "Swift",
isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRelease_n"
: "swift_bridgeObjectRelease_n",
DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},
Expand Down
6 changes: 3 additions & 3 deletions lib/SILOptimizer/UtilityPasses/Link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class SILLinker : public SILModuleTransform {

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(...)
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
22 changes: 9 additions & 13 deletions test/IRGen/dllexport.swift
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -25,24 +21,24 @@ 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
// CHECK-DAG: define dllexport swiftcc ptr @"$s9dllexport1cCfd"(ptr{{.*}})
// 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)

12 changes: 6 additions & 6 deletions test/IRGen/dllimport.swift
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)
4 changes: 2 additions & 2 deletions test/IRGen/enum_value_semantics.sil
Original file line number Diff line number Diff line change
@@ -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

Expand Down