@@ -1445,15 +1445,20 @@ 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 ());
1455- diffKindVal = llvm::ConstantInt::get (IGF.IGM .SizeTy ,
1456- flags.getIntValue ());
1456+ diffKindVal = llvm::ConstantInt::get (
1457+ IGF.IGM .SizeTy , metadataDifferentiabilityKind.getIntValue ());
1458+ } else if (type->getGlobalActor ()) {
1459+ diffKindVal = llvm::ConstantInt::get (
1460+ IGF.IGM .SizeTy ,
1461+ FunctionMetadataDifferentiabilityKind::NonDifferentiable);
14571462 }
14581463
14591464 auto collectParameters =
@@ -1507,56 +1512,65 @@ namespace {
15071512 case 1 :
15081513 case 2 :
15091514 case 3 : {
1510- if (!hasParameterFlags && !type->isDifferentiable ()) {
1515+ if (!hasParameterFlags && !type->isDifferentiable () &&
1516+ !type->getGlobalActor ()) {
15111517 llvm::SmallVector<llvm::Value *, 8 > arguments;
15121518 auto *metadataFn = constructSimpleCall (arguments);
15131519 auto *call = IGF.Builder .CreateCall (metadataFn, arguments);
15141520 call->setDoesNotThrow ();
15151521 return setLocal (CanType (type), MetadataResponse::forComplete (call));
15161522 }
15171523
1518- // If function type has parameter flags or is differentiable, let's emit
1519- // the most general function to retrieve them.
1524+ // If function type has parameter flags or is differentiable or has a
1525+ // global actor, emit the most general function to retrieve them.
15201526 LLVM_FALLTHROUGH;
15211527 }
15221528
15231529 default :
1524- assert (!params.empty () || type->isDifferentiable () &&
1530+ assert ((!params.empty () || type->isDifferentiable () ||
1531+ type->getGlobalActor ()) &&
15251532 " 0 parameter case should be specialized unless it is a "
1526- " differentiable function" );
1533+ " differentiable function or has a global actor " );
15271534
15281535 auto *const Int32Ptr = IGF.IGM .Int32Ty ->getPointerTo ();
15291536 llvm::SmallVector<llvm::Value *, 8 > arguments;
15301537
15311538 arguments.push_back (flagsVal);
15321539
1533- if (type->isDifferentiable ()) {
1534- assert (diffKindVal);
1540+ if (diffKindVal) {
15351541 arguments.push_back (diffKindVal);
15361542 }
15371543
15381544 ConstantInitBuilder paramFlags (IGF.IGM );
15391545 auto flagsArr = paramFlags.beginArray ();
15401546
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- });
1547+ Address parameters;
1548+ if (!params.empty ()) {
1549+ auto arrayTy =
1550+ llvm::ArrayType::get (IGF.IGM .TypeMetadataPtrTy , numParams);
1551+ parameters = IGF.createAlloca (
1552+ arrayTy, IGF.IGM .getTypeMetadataAlignment (), " function-parameters" );
1553+
1554+ IGF.Builder .CreateLifetimeStart (parameters,
1555+ IGF.IGM .getPointerSize () * numParams);
1556+
1557+ collectParameters ([&](unsigned i, llvm::Value *typeRef,
1558+ ParameterFlags flags) {
1559+ auto argPtr = IGF.Builder .CreateStructGEP (parameters, i,
1560+ IGF.IGM .getPointerSize ());
1561+ IGF.Builder .CreateStore (typeRef, argPtr);
1562+ if (i == 0 )
1563+ arguments.push_back (argPtr.getAddress ());
1564+
1565+ if (hasParameterFlags)
1566+ flagsArr.addInt32 (flags.getIntValue ());
1567+ });
1568+ } else {
1569+ auto parametersPtr =
1570+ llvm::ConstantPointerNull::get (
1571+ IGF.IGM .TypeMetadataPtrTy ->getPointerTo ());
1572+ arguments.push_back (parametersPtr);
1573+ }
15601574
15611575 if (hasParameterFlags) {
15621576 auto *flagsVar = flagsArr.finishAndCreateGlobal (
@@ -1570,9 +1584,16 @@ namespace {
15701584
15711585 arguments.push_back (result);
15721586
1573- auto *getMetadataFn = type->isDifferentiable ()
1574- ? IGF.IGM .getGetFunctionMetadataDifferentiableFn ()
1575- : IGF.IGM .getGetFunctionMetadataFn ();
1587+ if (Type globalActor = type->getGlobalActor ()) {
1588+ arguments.push_back (
1589+ IGF.emitAbstractTypeMetadataRef (globalActor->getCanonicalType ()));
1590+ }
1591+
1592+ auto *getMetadataFn = type->getGlobalActor ()
1593+ ? IGF.IGM .getGetFunctionMetadataGlobalActorFn ()
1594+ : type->isDifferentiable ()
1595+ ? IGF.IGM .getGetFunctionMetadataDifferentiableFn ()
1596+ : IGF.IGM .getGetFunctionMetadataFn ();
15761597
15771598 auto call = IGF.Builder .CreateCall (getMetadataFn, arguments);
15781599 call->setDoesNotThrow ();
0 commit comments