Skip to content

Commit 554e1e4

Browse files
authored
Merge pull request #37759 from DougGregor/global-actor-function-mangling
@DougGregor Implement (de-)mangling and type metadata for global actor function types
2 parents 60a09da + b814e22 commit 554e1e4

26 files changed

+273
-78
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ Types
589589
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
590590
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
591591

592-
function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
592+
function-signature ::= params-type params-type async? sendable? throws? differentiable? global-actor? // results and parameters
593593

594594
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
595595
// with optional inout convention, shared convention. parameters don't have labels,
@@ -599,6 +599,7 @@ Types
599599
#if SWIFT_RUNTIME_VERSION >= 5.5
600600
async ::= 'Ya' // 'async' annotation on function types
601601
sendable ::= 'Yb' // @Sendable on function types
602+
global-actor :: = type 'Yc' // Global actor on function type
602603
#endif
603604
throws ::= 'K' // 'throws' annotation on function types
604605
differentiable ::= 'Yjf' // @differentiable(_forward) on function type

include/swift/ABI/Metadata.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,7 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
16651665
bool isDifferentiable() const { return Flags.isDifferentiable(); }
16661666
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
16671667
bool isEscaping() const { return Flags.isEscaping(); }
1668+
bool hasGlobalActor() const { return Flags.hasGlobalActor(); }
16681669

16691670
static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);
16701671

@@ -1702,6 +1703,31 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
17021703
return TargetFunctionMetadataDifferentiabilityKind<StoredSize>
17031704
::NonDifferentiable;
17041705
}
1706+
1707+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *
1708+
getGlobalActorAddr() {
1709+
assert(hasGlobalActor());
1710+
1711+
void *endAddr =
1712+
isDifferentiable()
1713+
? reinterpret_cast<void *>(getDifferentiabilityKindAddress() + 1) :
1714+
hasParameterFlags()
1715+
? reinterpret_cast<void *>(getParameterFlags() + getNumParameters()) :
1716+
reinterpret_cast<void *>(getParameters() + getNumParameters());
1717+
return reinterpret_cast<
1718+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *>(
1719+
llvm::alignAddr(
1720+
endAddr, llvm::Align(alignof(typename Runtime::StoredPointer))));
1721+
}
1722+
1723+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>
1724+
getGlobalActor() const {
1725+
if (!hasGlobalActor())
1726+
return ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>();
1727+
1728+
return *const_cast<TargetFunctionTypeMetadata<Runtime> *>(this)
1729+
->getGlobalActorAddr();
1730+
}
17051731
};
17061732
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
17071733

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,10 @@ class TargetFunctionTypeFlags {
834834
ParamFlagsMask = 0x02000000U,
835835
EscapingMask = 0x04000000U,
836836
DifferentiableMask = 0x08000000U,
837+
GlobalActorMask = 0x10000000U,
837838
AsyncMask = 0x20000000U,
838839
SendableMask = 0x40000000U,
840+
// NOTE: The next bit will need to introduce a separate flags word.
839841
};
840842
int_type Data;
841843

@@ -891,6 +893,12 @@ class TargetFunctionTypeFlags {
891893
(isSendable ? SendableMask : 0));
892894
}
893895

896+
constexpr TargetFunctionTypeFlags<int_type>
897+
withGlobalActor(bool globalActor) const {
898+
return TargetFunctionTypeFlags<int_type>(
899+
(Data & ~GlobalActorMask) | (globalActor ? GlobalActorMask : 0));
900+
}
901+
894902
unsigned getNumParameters() const { return Data & NumParametersMask; }
895903

896904
FunctionMetadataConvention getConvention() const {
@@ -915,6 +923,10 @@ class TargetFunctionTypeFlags {
915923
return bool (Data & DifferentiableMask);
916924
}
917925

926+
bool hasGlobalActor() const {
927+
return bool (Data & GlobalActorMask);
928+
}
929+
918930
int_type getIntValue() const {
919931
return Data;
920932
}

include/swift/AST/ASTDemangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class ASTBuilder {
9898
Type createFunctionType(
9999
ArrayRef<Demangle::FunctionParam<Type>> params,
100100
Type output, FunctionTypeFlags flags,
101-
FunctionMetadataDifferentiabilityKind diffKind);
101+
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor);
102102

103103
Type createImplFunctionType(
104104
Demangle::ImplParameterConvention calleeConvention,

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ NODE(ErrorType)
8282
NODE(EscapingAutoClosureType)
8383
NODE(NoEscapeFunctionType)
8484
NODE(ConcurrentFunctionType)
85+
NODE(GlobalActorFunctionType)
8586
NODE(DifferentiableFunctionType)
8687
NODE(ExistentialMetatype)
8788
CONTEXT_NODE(ExplicitClosure)

include/swift/Demangling/TypeDecoder.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,23 @@ class TypeDecoder {
738738
++firstChildIdx;
739739
}
740740

741+
BuiltType globalActorType = BuiltType();
742+
if (Node->getChild(firstChildIdx)->getKind() ==
743+
NodeKind::GlobalActorFunctionType) {
744+
auto child = Node->getChild(firstChildIdx);
745+
if (child->getNumChildren() < 1) {
746+
return MAKE_NODE_TYPE_ERROR0(child,
747+
"Global actor node is missing child");
748+
}
749+
750+
auto globalActorResult = decodeMangledType(child->getChild(0));
751+
if (globalActorResult.isError())
752+
return globalActorResult;
753+
754+
globalActorType = globalActorResult.getType();
755+
++firstChildIdx;
756+
}
757+
741758
FunctionMetadataDifferentiabilityKind diffKind;
742759
if (Node->getChild(firstChildIdx)->getKind() ==
743760
NodeKind::DifferentiableFunctionType) {
@@ -811,7 +828,7 @@ class TypeDecoder {
811828
if (result.isError())
812829
return result;
813830
return Builder.createFunctionType(
814-
parameters, result.getType(), flags, diffKind);
831+
parameters, result.getType(), flags, diffKind, globalActorType);
815832
}
816833
case NodeKind::ImplFunctionType: {
817834
auto calleeConvention = ImplParameterConvention::Direct_Unowned;

include/swift/Reflection/TypeRef.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,12 @@ class FunctionTypeRef final : public TypeRef {
462462
const TypeRef *Result;
463463
FunctionTypeFlags Flags;
464464
FunctionMetadataDifferentiabilityKind DifferentiabilityKind;
465+
const TypeRef *GlobalActor;
465466

466467
static TypeRefID Profile(const std::vector<Param> &Parameters,
467468
const TypeRef *Result, FunctionTypeFlags Flags,
468-
FunctionMetadataDifferentiabilityKind DiffKind) {
469+
FunctionMetadataDifferentiabilityKind DiffKind,
470+
const TypeRef *GlobalActor) {
469471
TypeRefID ID;
470472
for (const auto &Param : Parameters) {
471473
ID.addString(Param.getLabel().str());
@@ -475,21 +477,27 @@ class FunctionTypeRef final : public TypeRef {
475477
ID.addPointer(Result);
476478
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));
477479
ID.addInteger(static_cast<uint64_t>(DiffKind.getIntValue()));
480+
ID.addPointer(GlobalActor);
481+
478482
return ID;
479483
}
480484

481485
public:
482486
FunctionTypeRef(std::vector<Param> Params, const TypeRef *Result,
483487
FunctionTypeFlags Flags,
484-
FunctionMetadataDifferentiabilityKind DiffKind)
488+
FunctionMetadataDifferentiabilityKind DiffKind,
489+
const TypeRef *GlobalActor)
485490
: TypeRef(TypeRefKind::Function), Parameters(Params), Result(Result),
486-
Flags(Flags), DifferentiabilityKind(DiffKind) {}
491+
Flags(Flags), DifferentiabilityKind(DiffKind),
492+
GlobalActor(GlobalActor) {}
487493

488494
template <typename Allocator>
489495
static const FunctionTypeRef *create(
490496
Allocator &A, std::vector<Param> Params, const TypeRef *Result,
491-
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind) {
492-
FIND_OR_CREATE_TYPEREF(A, FunctionTypeRef, Params, Result, Flags, DiffKind);
497+
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind,
498+
const TypeRef *GlobalActor) {
499+
FIND_OR_CREATE_TYPEREF(
500+
A, FunctionTypeRef, Params, Result, Flags, DiffKind, GlobalActor);
493501
}
494502

495503
const std::vector<Param> &getParameters() const { return Parameters; };
@@ -506,6 +514,10 @@ class FunctionTypeRef final : public TypeRef {
506514
return DifferentiabilityKind;
507515
}
508516

517+
const TypeRef *getGlobalActor() const {
518+
return GlobalActor;
519+
}
520+
509521
static bool classof(const TypeRef *TR) {
510522
return TR->getKind() == TypeRefKind::Function;
511523
}

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,10 @@ class TypeRefBuilder {
415415
const FunctionTypeRef *createFunctionType(
416416
llvm::ArrayRef<remote::FunctionParam<const TypeRef *>> params,
417417
const TypeRef *result, FunctionTypeFlags flags,
418-
FunctionMetadataDifferentiabilityKind diffKind) {
419-
return FunctionTypeRef::create(*this, params, result, flags, diffKind);
418+
FunctionMetadataDifferentiabilityKind diffKind,
419+
const TypeRef *globalActor) {
420+
return FunctionTypeRef::create(
421+
*this, params, result, flags, diffKind, globalActor);
420422
}
421423

422424
const FunctionTypeRef *createImplFunctionType(
@@ -472,7 +474,8 @@ class TypeRefBuilder {
472474
}
473475

474476
auto result = createTupleType({}, "");
475-
return FunctionTypeRef::create(*this, {}, result, funcFlags, diffKind);
477+
return FunctionTypeRef::create(
478+
*this, {}, result, funcFlags, diffKind, nullptr);
476479
}
477480

478481
const ProtocolCompositionTypeRef *

include/swift/Remote/MetadataReader.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,13 @@ class MetadataReader {
811811
.withEscaping(Function->isEscaping())
812812
.withDifferentiable(Function->isDifferentiable());
813813

814+
BuiltType globalActor = BuiltType();
815+
if (Function->hasGlobalActor()) {
816+
globalActor = readTypeFromMetadata(Function->getGlobalActor());
817+
if (globalActor)
818+
flags = flags.withGlobalActor(true);
819+
}
820+
814821
FunctionMetadataDifferentiabilityKind diffKind;
815822
switch (Function->getDifferentiabilityKind().Value) {
816823
#define CASE(X) \
@@ -827,7 +834,7 @@ class MetadataReader {
827834
}
828835

829836
auto BuiltFunction = Builder.createFunctionType(
830-
Parameters, Result, flags, diffKind);
837+
Parameters, Result, flags, diffKind, globalActor);
831838
TypeCache[MetadataAddress] = BuiltFunction;
832839
return BuiltFunction;
833840
}

include/swift/Runtime/Metadata.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,13 @@ swift_getFunctionTypeMetadataDifferentiable(
499499
const Metadata *const *parameters, const uint32_t *parameterFlags,
500500
const Metadata *result);
501501

502+
SWIFT_RUNTIME_EXPORT
503+
const FunctionTypeMetadata *
504+
swift_getFunctionTypeMetadataGlobalActor(
505+
FunctionTypeFlags flags, FunctionMetadataDifferentiabilityKind diffKind,
506+
const Metadata *const *parameters, const uint32_t *parameterFlags,
507+
const Metadata *result, const Metadata *globalActor);
508+
502509
SWIFT_RUNTIME_EXPORT
503510
const FunctionTypeMetadata *
504511
swift_getFunctionTypeMetadata0(FunctionTypeFlags flags,

lib/AST/ASTDemangler.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ Type ASTBuilder::createTupleType(ArrayRef<Type> eltTypes, StringRef labels) {
344344
Type ASTBuilder::createFunctionType(
345345
ArrayRef<Demangle::FunctionParam<Type>> params,
346346
Type output, FunctionTypeFlags flags,
347-
FunctionMetadataDifferentiabilityKind diffKind) {
347+
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor) {
348348
// The result type must be materializable.
349349
if (!output->isMaterializable()) return Type();
350350

@@ -407,14 +407,12 @@ Type ASTBuilder::createFunctionType(
407407
clangFunctionType = Ctx.getClangFunctionType(funcParams, output,
408408
representation);
409409

410-
Type globalActor;
411-
// FIXME: Demangle global actors.
412-
413410
auto einfo =
414411
FunctionType::ExtInfoBuilder(representation, noescape, flags.isThrowing(),
415412
resultDiffKind, clangFunctionType,
416413
globalActor)
417414
.withAsync(flags.isAsync())
415+
.withConcurrent(flags.isSendable())
418416
.build();
419417

420418
return FunctionType::get(funcParams, output, einfo);

lib/AST/ASTMangler.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,6 +2477,11 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
24772477
appendOperator("Yjl");
24782478
break;
24792479
}
2480+
2481+
if (Type globalActor = fn->getGlobalActor()) {
2482+
appendType(globalActor);
2483+
appendOperator("Yc");
2484+
}
24802485
}
24812486

24822487
void ASTMangler::appendFunctionInputType(
@@ -2876,18 +2881,6 @@ CanType ASTMangler::getDeclTypeForMangling(
28762881

28772882
Type ty = decl->getInterfaceType()->getReferenceStorageReferent();
28782883

2879-
// Strip the global actor out of the mangling.
2880-
ty = ty.transform([](Type type) {
2881-
if (auto fnType = type->getAs<AnyFunctionType>()) {
2882-
if (fnType->getGlobalActor()) {
2883-
return Type(fnType->withExtInfo(
2884-
fnType->getExtInfo().withGlobalActor(Type())));
2885-
}
2886-
}
2887-
2888-
return type;
2889-
});
2890-
28912884
auto canTy = ty->getCanonicalType();
28922885

28932886
if (auto gft = dyn_cast<GenericFunctionType>(canTy)) {

lib/Demangling/Demangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,9 @@ NodePointer Demangler::demangleTypeAnnotation() {
736736
return createNode(Node::Kind::AsyncAnnotation);
737737
case 'b':
738738
return createNode(Node::Kind::ConcurrentFunctionType);
739+
case 'c':
740+
return createWithChild(
741+
Node::Kind::GlobalActorFunctionType, popTypeAndGetChild());
739742
case 'j':
740743
return demangleDifferentiableFunctionType();
741744
case 'k':
@@ -1280,6 +1283,7 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
12801283
ClangType = demangleClangType();
12811284
}
12821285
addChild(FuncType, ClangType);
1286+
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
12831287
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
12841288
addChild(FuncType, popNode(Node::Kind::ThrowsAnnotation));
12851289
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
@@ -1316,6 +1320,9 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
13161320
return nullptr;
13171321

13181322
unsigned FirstChildIdx = 0;
1323+
if (FuncType->getChild(FirstChildIdx)->getKind()
1324+
== Node::Kind::GlobalActorFunctionType)
1325+
++FirstChildIdx;
13191326
if (FuncType->getChild(FirstChildIdx)->getKind()
13201327
== Node::Kind::DifferentiableFunctionType)
13211328
++FirstChildIdx;

lib/Demangling/NodePrinter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ class NodePrinter {
517517
case Node::Kind::GenericTypeParamDecl:
518518
case Node::Kind::ConcurrentFunctionType:
519519
case Node::Kind::DifferentiableFunctionType:
520+
case Node::Kind::GlobalActorFunctionType:
520521
case Node::Kind::AsyncAnnotation:
521522
case Node::Kind::ThrowsAnnotation:
522523
case Node::Kind::EmptyList:
@@ -810,6 +811,11 @@ class NodePrinter {
810811
unsigned startIndex = 0;
811812
bool isSendable = false, isAsync = false, isThrows = false;
812813
auto diffKind = MangledDifferentiabilityKind::NonDifferentiable;
814+
if (node->getChild(startIndex)->getKind() ==
815+
Node::Kind::GlobalActorFunctionType) {
816+
print(node->getChild(startIndex));
817+
++startIndex;
818+
}
813819
if (node->getChild(startIndex)->getKind() ==
814820
Node::Kind::DifferentiableFunctionType) {
815821
diffKind =
@@ -2585,6 +2591,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
25852591
Printer << ' ';
25862592
return nullptr;
25872593
}
2594+
case Node::Kind::GlobalActorFunctionType: {
2595+
if (Node->getNumChildren() > 0) {
2596+
Printer << '@';
2597+
print(Node->getChild(0));
2598+
Printer << ' ';
2599+
}
2600+
return nullptr;
2601+
}
25882602
case Node::Kind::AsyncAnnotation:
25892603
Printer << " async ";
25902604
return nullptr;

0 commit comments

Comments
 (0)