Skip to content

Commit 1e06448

Browse files
committed
[IRGen] Distributed: Remove a requirement that accessible function should be backed by SILFunction
Distributed protocol requirements don't have associated SILFunction, let's introduce a more flexible way to define it that collects only the information necessary for the function to become accessible.
1 parent c6820a5 commit 1e06448

File tree

4 files changed

+96
-39
lines changed

4 files changed

+96
-39
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,8 +4423,34 @@ void IRGenModule::addProtocolConformance(ConformanceDescription &&record) {
44234423
}
44244424
}
44254425

4426-
void IRGenModule::addAccessibleFunction(SILFunction *func) {
4427-
AccessibleFunctions.push_back(func);
4426+
AccessibleFunction AccessibleFunction::forSILFunction(IRGenModule &IGM,
4427+
SILFunction *func) {
4428+
assert(!func->isDistributed() && "use forDistributed(...) instead");
4429+
4430+
llvm::Constant *funcAddr = nullptr;
4431+
if (func->isAsync()) {
4432+
funcAddr = IGM.getAddrOfAsyncFunctionPointer(func);
4433+
} else {
4434+
funcAddr = IGM.getAddrOfSILFunction(func, NotForDefinition);
4435+
}
4436+
4437+
return AccessibleFunction(
4438+
/*recordName=*/LinkEntity::forAccessibleFunctionRecord(func)
4439+
.mangleAsString(),
4440+
/*funcName=*/LinkEntity::forSILFunction(func).mangleAsString(),
4441+
/*isDistributed=*/false, func->getLoweredFunctionType(), funcAddr);
4442+
}
4443+
4444+
AccessibleFunction AccessibleFunction::forDistributed(std::string recordName,
4445+
std::string accessorName,
4446+
CanSILFunctionType type,
4447+
llvm::Constant *address) {
4448+
return AccessibleFunction(recordName, accessorName,
4449+
/*isDistributed=*/true, type, address);
4450+
}
4451+
4452+
void IRGenModule::addAccessibleFunction(AccessibleFunction func) {
4453+
AccessibleFunctions.push_back(std::move(func));
44284454
}
44294455

44304456
/// Emit the protocol conformance list and return it (if asContiguousArray is
@@ -4648,17 +4674,12 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords(bool asContiguousArray) {
46484674
return nullptr;
46494675
}
46504676

4651-
void IRGenModule::emitAccessibleFunction(
4652-
StringRef sectionName, SILFunction* func) {
4653-
std::string mangledRecordName =
4654-
LinkEntity::forAccessibleFunctionRecord(func).mangleAsString();
4655-
std::string mangledFunctionName =
4656-
LinkEntity::forSILFunction(func).mangleAsString();
4657-
4677+
void IRGenModule::emitAccessibleFunction(StringRef sectionName,
4678+
const AccessibleFunction &func) {
46584679
auto var = new llvm::GlobalVariable(
46594680
Module, AccessibleFunctionRecordTy, /*isConstant=*/true,
46604681
llvm::GlobalValue::PrivateLinkage, /*initializer=*/nullptr,
4661-
mangledRecordName);
4682+
func.getRecordName());
46624683

46634684
ConstantInitBuilder builder(*this);
46644685

@@ -4669,47 +4690,36 @@ void IRGenModule::emitAccessibleFunction(
46694690
// -- Field: Name (record name)
46704691
{
46714692
llvm::Constant *name =
4672-
getAddrOfGlobalString(mangledFunctionName,
4693+
getAddrOfGlobalString(func.getFunctionName(),
46734694
/*willBeRelativelyAddressed=*/true);
46744695
fields.addRelativeAddress(name);
46754696
}
46764697

46774698
// -- Field: GenericEnvironment
46784699
llvm::Constant *genericEnvironment = nullptr;
46794700

4680-
GenericSignature signature;
4681-
if (auto *env = func->getGenericEnvironment()) {
4701+
GenericSignature signature = func.getType()->getInvocationGenericSignature();
4702+
if (signature) {
46824703
// Drop all the marker protocols because they are effect-less
46834704
// at runtime.
4684-
signature = env->getGenericSignature().withoutMarkerProtocols();
4705+
signature = signature.withoutMarkerProtocols();
46854706

46864707
genericEnvironment =
46874708
getAddrOfGenericEnvironment(signature.getCanonicalSignature());
46884709
}
46894710
fields.addRelativeAddressOrNull(genericEnvironment);
46904711

46914712
// -- Field: FunctionType
4692-
llvm::Constant *type = getTypeRef(func->getLoweredFunctionType(), signature,
4693-
MangledTypeRefRole::Metadata)
4694-
.first;
4713+
llvm::Constant *type =
4714+
getTypeRef(func.getType(), signature, MangledTypeRefRole::Metadata).first;
46954715
fields.addRelativeAddress(type);
46964716

46974717
// -- Field: Function
4698-
llvm::Constant *funcAddr = nullptr;
4699-
if (func->isDistributed()) {
4700-
funcAddr = getAddrOfAsyncFunctionPointer(
4701-
LinkEntity::forDistributedTargetAccessor(func));
4702-
} else if (func->isAsync()) {
4703-
funcAddr = getAddrOfAsyncFunctionPointer(func);
4704-
} else {
4705-
funcAddr = getAddrOfSILFunction(func, NotForDefinition);
4706-
}
4707-
4708-
fields.addRelativeAddress(funcAddr);
4718+
fields.addRelativeAddress(func.getAddress());
47094719

47104720
// -- Field: Flags
47114721
AccessibleFunctionFlags flags;
4712-
flags.setDistributed(func->isDistributed());
4722+
flags.setDistributed(func.isDistributed());
47134723
fields.addInt32(flags.getOpaqueValue());
47144724

47154725
// ---- End of 'TargetAccessibleFunctionRecord' fields
@@ -4746,7 +4756,7 @@ void IRGenModule::emitAccessibleFunctions() {
47464756
break;
47474757
}
47484758

4749-
for (auto *func : AccessibleFunctions) {
4759+
for (const auto &func : AccessibleFunctions) {
47504760
emitAccessibleFunction(fnsSectionName, func);
47514761
}
47524762
}

lib/IRGen/GenDistributed.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "GenType.h"
3131
#include "IRGenDebugInfo.h"
3232
#include "IRGenFunction.h"
33+
#include "IRGenMangler.h"
3334
#include "IRGenModule.h"
3435
#include "LoadableTypeInfo.h"
3536
#include "ScalarPairTypeInfo.h"
@@ -206,6 +207,8 @@ class DistributedAccessor {
206207
DistributedAccessor(IRGenFunction &IGF, ThunkOrRequirement target,
207208
CanSILFunctionType accessorTy);
208209

210+
CanSILFunctionType getTargetType() const { return Target.getType(); }
211+
209212
void emit();
210213

211214
private:
@@ -357,14 +360,26 @@ IRGenModule::getAddrOfDistributedTargetAccessor(LinkEntity accessor,
357360
}
358361

359362
void IRGenModule::emitDistributedTargetAccessor(ThunkOrRequirement target) {
360-
auto *f = getAddrOfDistributedTargetAccessor(getAccessorLinking(target),
363+
LinkEntity accessorRef = getAccessorLinking(target);
364+
auto *f = getAddrOfDistributedTargetAccessor(accessorRef,
361365
ForDefinition);
362366

363367
if (!f->isDeclaration())
364368
return;
365369

366370
IRGenFunction IGF(*this, f);
367-
DistributedAccessor(IGF, target, getAccessorType(*this)).emit();
371+
auto accessor = DistributedAccessor(IGF, target, getAccessorType(*this));
372+
accessor.emit();
373+
374+
auto targetDecl = cast<AbstractFunctionDecl>(accessorRef.getDecl());
375+
376+
IRGenMangler mangler;
377+
378+
addAccessibleFunction(AccessibleFunction::forDistributed(
379+
mangler.mangleDistributedThunkRecord(targetDecl),
380+
mangler.mangleDistributedThunk(targetDecl),
381+
accessor.getTargetType(),
382+
getAddrOfAsyncFunctionPointer(accessorRef)));
368383
}
369384

370385
DistributedAccessor::DistributedAccessor(IRGenFunction &IGF,

lib/IRGen/IRGenModule.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,40 @@ enum class MangledTypeRefRole {
609609
FlatUnique,
610610
};
611611

612+
613+
struct AccessibleFunction {
614+
private:
615+
std::string RecordName;
616+
std::string FunctionName;
617+
618+
bool IsDistributed: 1;
619+
620+
CanSILFunctionType Type;
621+
llvm::Constant *Address;
622+
623+
explicit AccessibleFunction(std::string recordName, std::string funcName,
624+
bool isDistributed, CanSILFunctionType type,
625+
llvm::Constant *addr)
626+
: RecordName(recordName), FunctionName(funcName),
627+
IsDistributed(isDistributed), Type(type), Address(addr) {}
628+
629+
public:
630+
StringRef getRecordName() const { return RecordName; }
631+
StringRef getFunctionName() const { return FunctionName; }
632+
633+
bool isDistributed() const { return IsDistributed; }
634+
635+
CanSILFunctionType getType() const { return Type; }
636+
637+
llvm::Constant *getAddress() const { return Address; }
638+
639+
static AccessibleFunction forSILFunction(IRGenModule &IGM, SILFunction *func);
640+
static AccessibleFunction forDistributed(std::string recordName,
641+
std::string accessorName,
642+
CanSILFunctionType type,
643+
llvm::Constant *address);
644+
};
645+
612646
/// IRGenModule - Primary class for emitting IR for global declarations.
613647
///
614648
class IRGenModule {
@@ -1148,15 +1182,15 @@ class IRGenModule {
11481182
void addObjCClass(llvm::Constant *addr, bool nonlazy);
11491183
void addObjCClassStub(llvm::Constant *addr);
11501184
void addProtocolConformance(ConformanceDescription &&conformance);
1151-
void addAccessibleFunction(SILFunction *func);
1185+
void addAccessibleFunction(AccessibleFunction func);
11521186

11531187
llvm::Constant *emitSwiftProtocols(bool asContiguousArray);
11541188
llvm::Constant *emitProtocolConformances(bool asContiguousArray);
11551189
llvm::Constant *emitTypeMetadataRecords(bool asContiguousArray);
11561190

11571191
void emitAccessibleFunctions();
11581192
void emitAccessibleFunction(StringRef sectionName,
1159-
SILFunction *func);
1193+
const AccessibleFunction &func);
11601194

11611195
llvm::Constant *getConstantSignedFunctionPointer(llvm::Constant *fn,
11621196
CanSILFunctionType fnType);
@@ -1304,7 +1338,7 @@ class IRGenModule {
13041338

13051339
/// List of all of the functions, which can be lookup by name
13061340
/// up at runtime.
1307-
SmallVector<SILFunction *, 4> AccessibleFunctions;
1341+
SmallVector<AccessibleFunction, 4> AccessibleFunctions;
13081342

13091343
/// Map of Objective-C protocols and protocol references, bitcast to i8*.
13101344
/// The interesting global variables relating to an ObjC protocol.

lib/IRGen/IRGenSIL.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,15 +2468,13 @@ void IRGenSILFunction::emitSILFunction() {
24682468
}
24692469

24702470
if (CurSILFn->isRuntimeAccessible())
2471-
IGM.addAccessibleFunction(CurSILFn);
2471+
IGM.addAccessibleFunction(
2472+
AccessibleFunction::forSILFunction(IGM, CurSILFn));
24722473

24732474
// Emit distributed accessor, and mark the thunk as accessible
24742475
// by name at runtime through it.
24752476
if (CurSILFn->isDistributed() && CurSILFn->isThunk() == IsThunk) {
24762477
IGM.emitDistributedTargetAccessor(CurSILFn);
2477-
IGM.addAccessibleFunction(CurSILFn);
2478-
2479-
// TODO(distributed): for protocols emit a special accessor
24802478
}
24812479

24822480
// Configure the dominance resolver.

0 commit comments

Comments
 (0)