Skip to content

Commit ff24437

Browse files
committed
[IRGen] Emit calls to swift_getFunctionTypeMetadataGlobalActor as appropriate
1 parent 554e1e4 commit ff24437

File tree

5 files changed

+103
-31
lines changed

5 files changed

+103
-31
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,26 @@ FUNCTION(GetFunctionMetadataDifferentiable,
591591
TypeMetadataPtrTy),
592592
ATTRS(NoUnwind, ReadOnly))
593593

594+
// Metadata *
595+
// swift_getFunctionTypeMetadataGlobalActor(unsigned long flags,
596+
// unsigned long diffKind,
597+
// const Metadata **parameters,
598+
// const uint32_t *parameterFlags,
599+
// const Metadata *result,
600+
// const Metadata *globalActor);
601+
FUNCTION(GetFunctionMetadataGlobalActor,
602+
swift_getFunctionTypeMetadataGlobalActor,
603+
C_CC, AlwaysAvailable,
604+
RETURNS(TypeMetadataPtrTy),
605+
ARGS(SizeTy,
606+
SizeTy,
607+
TypeMetadataPtrTy->getPointerTo(0),
608+
Int32Ty->getPointerTo(0),
609+
TypeMetadataPtrTy,
610+
TypeMetadataPtrTy),
611+
ATTRS(NoUnwind, ReadOnly))
612+
613+
594614
// Metadata *swift_getFunctionTypeMetadata0(unsigned long flags,
595615
// const Metadata *resultMetadata);
596616
FUNCTION(GetFunctionMetadata0, swift_getFunctionTypeMetadata0,

lib/IRGen/MetadataRequest.cpp

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,15 +1445,21 @@ namespace {
14451445
.withThrows(type->isThrowing())
14461446
.withParameterFlags(hasParameterFlags)
14471447
.withEscaping(isEscaping)
1448-
.withDifferentiable(type->isDifferentiable());
1448+
.withDifferentiable(type->isDifferentiable())
1449+
.withGlobalActor(!type->getGlobalActor().isNull());
14491450

14501451
auto flagsVal = llvm::ConstantInt::get(IGF.IGM.SizeTy,
14511452
flags.getIntValue());
14521453
llvm::Value *diffKindVal = nullptr;
14531454
if (type->isDifferentiable()) {
14541455
assert(metadataDifferentiabilityKind.isDifferentiable());
1456+
// FIXME: Shouldn't this use metadataDifferentiabilityKind?
14551457
diffKindVal = llvm::ConstantInt::get(IGF.IGM.SizeTy,
14561458
flags.getIntValue());
1459+
} else if (type->getGlobalActor()) {
1460+
diffKindVal = llvm::ConstantInt::get(
1461+
IGF.IGM.SizeTy,
1462+
FunctionMetadataDifferentiabilityKind::NonDifferentiable);
14571463
}
14581464

14591465
auto collectParameters =
@@ -1507,56 +1513,65 @@ namespace {
15071513
case 1:
15081514
case 2:
15091515
case 3: {
1510-
if (!hasParameterFlags && !type->isDifferentiable()) {
1516+
if (!hasParameterFlags && !type->isDifferentiable() &&
1517+
!type->getGlobalActor()) {
15111518
llvm::SmallVector<llvm::Value *, 8> arguments;
15121519
auto *metadataFn = constructSimpleCall(arguments);
15131520
auto *call = IGF.Builder.CreateCall(metadataFn, arguments);
15141521
call->setDoesNotThrow();
15151522
return setLocal(CanType(type), MetadataResponse::forComplete(call));
15161523
}
15171524

1518-
// If function type has parameter flags or is differentiable, let's emit
1519-
// the most general function to retrieve them.
1525+
// If function type has parameter flags or is differentiable or has a
1526+
// global actor, emit the most general function to retrieve them.
15201527
LLVM_FALLTHROUGH;
15211528
}
15221529

15231530
default:
1524-
assert(!params.empty() || type->isDifferentiable() &&
1531+
assert((!params.empty() || type->isDifferentiable() ||
1532+
type->getGlobalActor()) &&
15251533
"0 parameter case should be specialized unless it is a "
1526-
"differentiable function");
1534+
"differentiable function or has a global actor");
15271535

15281536
auto *const Int32Ptr = IGF.IGM.Int32Ty->getPointerTo();
15291537
llvm::SmallVector<llvm::Value *, 8> arguments;
15301538

15311539
arguments.push_back(flagsVal);
15321540

1533-
if (type->isDifferentiable()) {
1534-
assert(diffKindVal);
1541+
if (diffKindVal) {
15351542
arguments.push_back(diffKindVal);
15361543
}
15371544

15381545
ConstantInitBuilder paramFlags(IGF.IGM);
15391546
auto flagsArr = paramFlags.beginArray();
15401547

1541-
auto arrayTy =
1542-
llvm::ArrayType::get(IGF.IGM.TypeMetadataPtrTy, numParams);
1543-
Address parameters = IGF.createAlloca(
1544-
arrayTy, IGF.IGM.getTypeMetadataAlignment(), "function-parameters");
1545-
1546-
IGF.Builder.CreateLifetimeStart(parameters,
1547-
IGF.IGM.getPointerSize() * numParams);
1548-
1549-
collectParameters([&](unsigned i, llvm::Value *typeRef,
1550-
ParameterFlags flags) {
1551-
auto argPtr = IGF.Builder.CreateStructGEP(parameters, i,
1552-
IGF.IGM.getPointerSize());
1553-
IGF.Builder.CreateStore(typeRef, argPtr);
1554-
if (i == 0)
1555-
arguments.push_back(argPtr.getAddress());
1556-
1557-
if (hasParameterFlags)
1558-
flagsArr.addInt32(flags.getIntValue());
1559-
});
1548+
Address parameters;
1549+
if (!params.empty()) {
1550+
auto arrayTy =
1551+
llvm::ArrayType::get(IGF.IGM.TypeMetadataPtrTy, numParams);
1552+
parameters = IGF.createAlloca(
1553+
arrayTy, IGF.IGM.getTypeMetadataAlignment(), "function-parameters");
1554+
1555+
IGF.Builder.CreateLifetimeStart(parameters,
1556+
IGF.IGM.getPointerSize() * numParams);
1557+
1558+
collectParameters([&](unsigned i, llvm::Value *typeRef,
1559+
ParameterFlags flags) {
1560+
auto argPtr = IGF.Builder.CreateStructGEP(parameters, i,
1561+
IGF.IGM.getPointerSize());
1562+
IGF.Builder.CreateStore(typeRef, argPtr);
1563+
if (i == 0)
1564+
arguments.push_back(argPtr.getAddress());
1565+
1566+
if (hasParameterFlags)
1567+
flagsArr.addInt32(flags.getIntValue());
1568+
});
1569+
} else {
1570+
auto parametersPtr =
1571+
llvm::ConstantPointerNull::get(
1572+
IGF.IGM.TypeMetadataPtrTy->getPointerTo());
1573+
arguments.push_back(parametersPtr);
1574+
}
15601575

15611576
if (hasParameterFlags) {
15621577
auto *flagsVar = flagsArr.finishAndCreateGlobal(
@@ -1570,9 +1585,16 @@ namespace {
15701585

15711586
arguments.push_back(result);
15721587

1573-
auto *getMetadataFn = type->isDifferentiable()
1574-
? IGF.IGM.getGetFunctionMetadataDifferentiableFn()
1575-
: IGF.IGM.getGetFunctionMetadataFn();
1588+
if (Type globalActor = type->getGlobalActor()) {
1589+
arguments.push_back(
1590+
IGF.emitAbstractTypeMetadataRef(globalActor->getCanonicalType()));
1591+
}
1592+
1593+
auto *getMetadataFn = type->getGlobalActor()
1594+
? IGF.IGM.getGetFunctionMetadataGlobalActorFn()
1595+
: type->isDifferentiable()
1596+
? IGF.IGM.getGetFunctionMetadataDifferentiableFn()
1597+
: IGF.IGM.getGetFunctionMetadataFn();
15761598

15771599
auto call = IGF.Builder.CreateCall(getMetadataFn, arguments);
15781600
call->setDoesNotThrow();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix CHECK --check-prefix CHECK-%target-cpu
2+
// REQUIRES: concurrency
3+
4+
import Swift
5+
import _Concurrency
6+
7+
func globalActorMetatype<T>(_: T.Type) -> Any.Type {
8+
typealias Fn = @MainActor () -> T
9+
return Fn.self
10+
}
11+
12+
// CHECK-LABEL: define swiftcc %swift.type* @"$s4test19globalActorMetatypeyypXpxmlF"
13+
// CHECK: [[MAIN_ACTOR_RESPONSE:%[0-9]+]] = call swiftcc %swift.metadata_response @"$sScMMa"(i{{32|64}} 255)
14+
// CHECK-NEXT: [[MAIN_ACTOR_METADATA:%[0-9]+]] = extractvalue %swift.metadata_response [[MAIN_ACTOR_RESPONSE]], 0
15+
// CHECK: call %swift.type* @swift_getFunctionTypeMetadataGlobalActor(i{{32|64}} 335544320, i{{32|64}} 0, %swift.type** null, i32* null, %swift.type* %T, %swift.type* [[MAIN_ACTOR_METADATA]])
16+
sil [ossa] @$s4test19globalActorMetatypeyypXpxmlF : $@convention(thin) <T> (@thick T.Type) -> @thick Any.Type {
17+
bb0(%0 : $@thick T.Type):
18+
%2 = metatype $@thin (@MainActor () -> T).Type
19+
%3 = metatype $@thick (@MainActor () -> T).Type
20+
%4 = init_existential_metatype %3 : $@thick (@MainActor () -> T).Type, $@thick Any.Type
21+
return %4 : $@thick Any.Type
22+
}

test/Runtime/demangleToMetadata.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ func f1_autoclosure(_: @autoclosure () -> Float) { }
5555
func f1_escaping_autoclosure(_: @autoclosure @escaping () -> Float) { }
5656
func f1_mainactor(_: @MainActor () -> Float) { }
5757

58+
func globalActorMetatypeFn<T>(_: T.Type) -> Any.Type {
59+
typealias Fn = @MainActor () -> T
60+
return Fn.self
61+
}
62+
5863
DemangleToMetadataTests.test("function types") {
5964
// Conventions
6065
expectEqual(type(of: f0), _typeByName("yyc")!)
@@ -106,6 +111,9 @@ DemangleToMetadataTests.test("function types") {
106111
expectEqual(
107112
"(@MainActor () -> Float) -> ()",
108113
String(describing: _typeByName("ySfyScMYcXEc")!))
114+
typealias MainActorFn = @MainActor () -> Float
115+
expectEqual(MainActorFn.self, _typeByName("SfyScMYcc")!)
116+
expectEqual(MainActorFn.self, globalActorMetatypeFn(Float.self))
109117
}
110118

111119
DemangleToMetadataTests.test("metatype types") {

test/SILGen/global_actor_function_mangling.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency | %FileCheck %s
1+
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 | %FileCheck %s
22
// REQUIRES: concurrency
33

44
// Declarations don't mangle global actor types.

0 commit comments

Comments
 (0)