Skip to content

Commit 296b9d1

Browse files
authored
Merge pull request #17802 from jckarter/external-component-local-attempt
SIL: Generate external key path references with local candidate components.
2 parents 17724f1 + 849d939 commit 296b9d1

File tree

17 files changed

+194
-516
lines changed

17 files changed

+194
-516
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 48 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,7 +2279,6 @@ class KeyPathPatternComponent {
22792279
StoredProperty,
22802280
GettableProperty,
22812281
SettableProperty,
2282-
External,
22832282
OptionalChain,
22842283
OptionalForce,
22852284
OptionalWrap,
@@ -2298,7 +2297,6 @@ class KeyPathPatternComponent {
22982297
enum PackedKind: unsigned {
22992298
PackedStored,
23002299
PackedComputed,
2301-
PackedExternal,
23022300
Unpacked,
23032301
};
23042302

@@ -2311,8 +2309,6 @@ class KeyPathPatternComponent {
23112309
case Kind::GettableProperty:
23122310
case Kind::SettableProperty:
23132311
return PackedComputed;
2314-
case Kind::External:
2315-
return PackedExternal;
23162312
case Kind::OptionalChain:
23172313
case Kind::OptionalForce:
23182314
case Kind::OptionalWrap:
@@ -2323,23 +2319,18 @@ class KeyPathPatternComponent {
23232319
// Value is the VarDecl* for StoredProperty, the SILFunction* of the
23242320
// Getter for computed properties, or the Kind for other kinds
23252321
llvm::PointerIntPair<void *, KindPackingBits, unsigned> ValueAndKind;
2326-
union {
2327-
// Valid if Kind == GettableProperty || Kind == SettableProperty
2328-
struct {
2329-
llvm::PointerIntPair<SILFunction *, 2,
2330-
ComputedPropertyId::KindType> SetterAndIdKind;
2331-
ComputedPropertyId::ValueType IdValue;
2332-
} Computed;
2333-
// Valid if Kind == External
2334-
SubstitutionMap ExternalSubstitutions;
2335-
};
2322+
llvm::PointerIntPair<SILFunction *, 2,
2323+
ComputedPropertyId::KindType> SetterAndIdKind;
2324+
ComputedPropertyId::ValueType IdValue;
23362325
ArrayRef<Index> Indices;
23372326
struct {
23382327
SILFunction *Equal;
23392328
SILFunction *Hash;
23402329
} IndexEquality;
23412330
CanType ComponentType;
2342-
2331+
AbstractStorageDecl *ExternalStorage;
2332+
SubstitutionMap ExternalSubstitutions;
2333+
23432334
/// Constructor for stored components
23442335
KeyPathPatternComponent(VarDecl *storedProp,
23452336
CanType ComponentType)
@@ -2353,26 +2344,18 @@ class KeyPathPatternComponent {
23532344
ArrayRef<Index> indices,
23542345
SILFunction *indicesEqual,
23552346
SILFunction *indicesHash,
2347+
AbstractStorageDecl *externalStorage,
2348+
SubstitutionMap externalSubstitutions,
23562349
CanType ComponentType)
23572350
: ValueAndKind(getter, PackedComputed),
2358-
Computed{{setter, id.Kind}, {id.Value}},
2351+
SetterAndIdKind{setter, id.Kind},
2352+
IdValue{id.Value},
23592353
Indices(indices),
23602354
IndexEquality{indicesEqual, indicesHash},
2361-
ComponentType(ComponentType) {
2362-
}
2363-
2364-
/// Constructor for external components
2365-
KeyPathPatternComponent(AbstractStorageDecl *externalStorage,
2366-
SubstitutionMap substitutions,
2367-
ArrayRef<Index> indices,
2368-
SILFunction *indicesEqual,
2369-
SILFunction *indicesHash,
2370-
CanType componentType)
2371-
: ValueAndKind(externalStorage, PackedExternal),
2372-
ExternalSubstitutions(substitutions),
2373-
Indices(indices),
2374-
IndexEquality{indicesEqual, indicesHash},
2375-
ComponentType(componentType) {
2355+
ComponentType(ComponentType),
2356+
ExternalStorage(externalStorage),
2357+
ExternalSubstitutions(externalSubstitutions)
2358+
{
23762359
}
23772360

23782361
/// Constructor for optional components.
@@ -2396,10 +2379,8 @@ class KeyPathPatternComponent {
23962379
case PackedStored:
23972380
return Kind::StoredProperty;
23982381
case PackedComputed:
2399-
return Computed.SetterAndIdKind.getPointer()
2382+
return SetterAndIdKind.getPointer()
24002383
? Kind::SettableProperty : Kind::GettableProperty;
2401-
case PackedExternal:
2402-
return Kind::External;
24032384
case Unpacked:
24042385
return (Kind)((uintptr_t)ValueAndKind.getPointer() >> KindPackingBits);
24052386
}
@@ -2418,7 +2399,6 @@ class KeyPathPatternComponent {
24182399
case Kind::OptionalChain:
24192400
case Kind::OptionalForce:
24202401
case Kind::OptionalWrap:
2421-
case Kind::External:
24222402
llvm_unreachable("not a stored property");
24232403
}
24242404
llvm_unreachable("unhandled kind");
@@ -2430,12 +2410,11 @@ class KeyPathPatternComponent {
24302410
case Kind::OptionalChain:
24312411
case Kind::OptionalForce:
24322412
case Kind::OptionalWrap:
2433-
case Kind::External:
24342413
llvm_unreachable("not a computed property");
24352414
case Kind::GettableProperty:
24362415
case Kind::SettableProperty:
2437-
return ComputedPropertyId(Computed.IdValue,
2438-
Computed.SetterAndIdKind.getInt());
2416+
return ComputedPropertyId(IdValue,
2417+
SetterAndIdKind.getInt());
24392418
}
24402419
llvm_unreachable("unhandled kind");
24412420
}
@@ -2446,7 +2425,6 @@ class KeyPathPatternComponent {
24462425
case Kind::OptionalChain:
24472426
case Kind::OptionalForce:
24482427
case Kind::OptionalWrap:
2449-
case Kind::External:
24502428
llvm_unreachable("not a computed property");
24512429
case Kind::GettableProperty:
24522430
case Kind::SettableProperty:
@@ -2462,10 +2440,9 @@ class KeyPathPatternComponent {
24622440
case Kind::OptionalChain:
24632441
case Kind::OptionalForce:
24642442
case Kind::OptionalWrap:
2465-
case Kind::External:
24662443
llvm_unreachable("not a settable computed property");
24672444
case Kind::SettableProperty:
2468-
return Computed.SetterAndIdKind.getPointer();
2445+
return SetterAndIdKind.getPointer();
24692446
}
24702447
llvm_unreachable("unhandled kind");
24712448
}
@@ -2479,7 +2456,6 @@ class KeyPathPatternComponent {
24792456
return {};
24802457
case Kind::GettableProperty:
24812458
case Kind::SettableProperty:
2482-
case Kind::External:
24832459
return Indices;
24842460
}
24852461
}
@@ -2491,7 +2467,6 @@ class KeyPathPatternComponent {
24912467
case Kind::OptionalForce:
24922468
case Kind::OptionalWrap:
24932469
llvm_unreachable("not a computed property");
2494-
case Kind::External:
24952470
case Kind::GettableProperty:
24962471
case Kind::SettableProperty:
24972472
return IndexEquality.Equal;
@@ -2504,7 +2479,6 @@ class KeyPathPatternComponent {
25042479
case Kind::OptionalForce:
25052480
case Kind::OptionalWrap:
25062481
llvm_unreachable("not a computed property");
2507-
case Kind::External:
25082482
case Kind::GettableProperty:
25092483
case Kind::SettableProperty:
25102484
return IndexEquality.Hash;
@@ -2519,15 +2493,29 @@ class KeyPathPatternComponent {
25192493
}
25202494

25212495
AbstractStorageDecl *getExternalDecl() const {
2522-
assert(getKind() == Kind::External
2523-
&& "not an external property");
2524-
return (AbstractStorageDecl*)ValueAndKind.getPointer();
2496+
switch (getKind()) {
2497+
case Kind::StoredProperty:
2498+
case Kind::OptionalChain:
2499+
case Kind::OptionalForce:
2500+
case Kind::OptionalWrap:
2501+
llvm_unreachable("not a computed property");
2502+
case Kind::GettableProperty:
2503+
case Kind::SettableProperty:
2504+
return ExternalStorage;
2505+
}
25252506
}
25262507

25272508
SubstitutionMap getExternalSubstitutions() const {
2528-
assert(getKind() == Kind::External
2529-
&& "not an external property");
2530-
return ExternalSubstitutions;
2509+
switch (getKind()) {
2510+
case Kind::StoredProperty:
2511+
case Kind::OptionalChain:
2512+
case Kind::OptionalForce:
2513+
case Kind::OptionalWrap:
2514+
llvm_unreachable("not a computed property");
2515+
case Kind::GettableProperty:
2516+
case Kind::SettableProperty:
2517+
return ExternalSubstitutions;
2518+
}
25312519
}
25322520

25332521
static KeyPathPatternComponent
@@ -2536,10 +2524,14 @@ class KeyPathPatternComponent {
25362524
ArrayRef<Index> indices,
25372525
SILFunction *indicesEquals,
25382526
SILFunction *indicesHash,
2527+
AbstractStorageDecl *externalDecl,
2528+
SubstitutionMap externalSubs,
25392529
CanType ty) {
25402530
return KeyPathPatternComponent(identifier,
25412531
getter, nullptr, indices,
2542-
indicesEquals, indicesHash, ty);
2532+
indicesEquals, indicesHash,
2533+
externalDecl, externalSubs,
2534+
ty);
25432535
}
25442536

25452537
static KeyPathPatternComponent
@@ -2549,10 +2541,14 @@ class KeyPathPatternComponent {
25492541
ArrayRef<Index> indices,
25502542
SILFunction *indicesEquals,
25512543
SILFunction *indicesHash,
2544+
AbstractStorageDecl *externalDecl,
2545+
SubstitutionMap externalSubs,
25522546
CanType ty) {
25532547
return KeyPathPatternComponent(identifier,
25542548
getter, setter, indices,
2555-
indicesEquals, indicesHash, ty);
2549+
indicesEquals, indicesHash,
2550+
externalDecl, externalSubs,
2551+
ty);
25562552
}
25572553

25582554
static KeyPathPatternComponent
@@ -2568,23 +2564,11 @@ class KeyPathPatternComponent {
25682564
case Kind::StoredProperty:
25692565
case Kind::GettableProperty:
25702566
case Kind::SettableProperty:
2571-
case Kind::External:
25722567
llvm_unreachable("not an optional kind");
25732568
}
25742569
return KeyPathPatternComponent(kind, ty);
25752570
}
25762571

2577-
static KeyPathPatternComponent
2578-
forExternal(AbstractStorageDecl *externalDecl,
2579-
SubstitutionMap substitutions,
2580-
ArrayRef<Index> indices,
2581-
SILFunction *indicesEquals,
2582-
SILFunction *indicesHash,
2583-
CanType ty) {
2584-
return KeyPathPatternComponent(externalDecl, substitutions,
2585-
indices, indicesEquals, indicesHash, ty);
2586-
}
2587-
25882572
void incrementRefCounts() const;
25892573
void decrementRefCounts() const;
25902574

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 425; // Last change: access impls
58+
const uint16_t VERSION_MINOR = 426; // SIL key path external components with local attempts
5959

6060
using DeclIDField = BCFixed<31>;
6161

lib/IRGen/GenKeyPath.cpp

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,7 @@ getInitializerForComputedComponent(IRGenModule &IGM,
623623
// External components don't need to store the key path environment (and
624624
// can't), since they need to already have enough information to function
625625
// independently of any context using the component.
626-
if (genericEnv &&
627-
component.getKind() != KeyPathPatternComponent::Kind::External) {
626+
if (genericEnv) {
628627
auto destGenericEnv = dest;
629628
if (!component.getSubscriptIndices().empty()) {
630629
auto genericEnvAlignMask = llvm::ConstantInt::get(IGM.SizeTy,
@@ -703,28 +702,6 @@ emitMetadataGeneratorForKeyPath(IRGenModule &IGM,
703702
});
704703
};
705704

706-
static llvm::Function *
707-
emitWitnessTableGeneratorForKeyPath(IRGenModule &IGM,
708-
CanType type,
709-
ProtocolConformanceRef conformance,
710-
GenericEnvironment *genericEnv,
711-
ArrayRef<GenericRequirement> requirements) {
712-
// TODO: Use the standard conformance accessor when there are no arguments
713-
// and the conformance accessor is defined.
714-
return emitGeneratorForKeyPath(IGM, "keypath_get_witness_table", type,
715-
IGM.WitnessTablePtrTy,
716-
genericEnv, requirements,
717-
[&](IRGenFunction &IGF, CanType substType) {
718-
if (type->hasTypeParameter())
719-
conformance = conformance.subst(type,
720-
QueryInterfaceTypeSubstitutions(genericEnv),
721-
LookUpConformanceInSignature(*genericEnv->getGenericSignature()));
722-
auto ret = emitWitnessTableRef(IGF, substType, conformance);
723-
IGF.Builder.CreateRet(ret);
724-
});
725-
}
726-
727-
728705
static void
729706
emitKeyPathComponent(IRGenModule &IGM,
730707
ConstantStructBuilder &fields,
@@ -745,75 +722,6 @@ emitKeyPathComponent(IRGenModule &IGM,
745722
loweredBaseTy = IGM.getLoweredType(AbstractionPattern::getOpaque(),
746723
baseTy->getWithoutSpecifierType());
747724
switch (auto kind = component.getKind()) {
748-
case KeyPathPatternComponent::Kind::External: {
749-
fields.addInt32(KeyPathComponentHeader::forExternalComponent().getData());
750-
// Emit accessors for all of the external declaration's necessary
751-
// bindings.
752-
SmallVector<llvm::Constant*, 4> descriptorArgs;
753-
auto componentSig = component.getExternalDecl()->getInnermostDeclContext()
754-
->getGenericSignatureOfContext();
755-
auto subs = component.getExternalSubstitutions();
756-
enumerateGenericSignatureRequirements(
757-
componentSig->getCanonicalSignature(),
758-
[&](GenericRequirement reqt) {
759-
auto substType = reqt.TypeParameter.subst(subs)
760-
->getCanonicalType();
761-
if (!reqt.Protocol) {
762-
// Type requirement.
763-
descriptorArgs.push_back(
764-
emitMetadataGeneratorForKeyPath(IGM, substType,
765-
genericEnv, requirements));
766-
} else {
767-
// Protocol requirement.
768-
auto conformance = subs.lookupConformance(
769-
reqt.TypeParameter->getCanonicalType(), reqt.Protocol);
770-
descriptorArgs.push_back(
771-
emitWitnessTableGeneratorForKeyPath(IGM, substType,
772-
*conformance,
773-
genericEnv, requirements));
774-
}
775-
});
776-
// If instantiable in-place, pad out the argument count here to ensure
777-
// there's room enough to instantiate a settable computed property
778-
// with two captured words in-place. The runtime instantiation of the
779-
// external component will ignore the padding, and this will make in-place
780-
// instantiation more likely to avoid needing an allocation.
781-
unsigned argSize = descriptorArgs.size();
782-
if (isInstantiableInPlace) {
783-
argSize = std::max(argSize, 3u);
784-
}
785-
786-
fields.addInt32(argSize);
787-
fields.add(IGM.getAddrOfPropertyDescriptor(component.getExternalDecl()));
788-
789-
// Add an initializer function that copies generic arguments out of the
790-
// pattern argument buffer into the instantiated object, along with the
791-
// index equality/hash operations we have from our perspective, or null
792-
// if there are no arguments.
793-
if (component.getSubscriptIndices().empty()) {
794-
fields.addInt(IGM.IntPtrTy, 0);
795-
fields.addInt(IGM.IntPtrTy, 0);
796-
fields.addInt(IGM.IntPtrTy, 0);
797-
} else {
798-
fields.add(getInitializerForComputedComponent(IGM, component,
799-
operands,
800-
genericEnv,
801-
requirements));
802-
fields.add(IGM.getAddrOfSILFunction(component.getSubscriptIndexEquals(),
803-
NotForDefinition));
804-
fields.add(IGM.getAddrOfSILFunction(component.getSubscriptIndexHash(),
805-
NotForDefinition));
806-
}
807-
808-
// Add the generic arguments for the external context.
809-
for (auto arg : descriptorArgs)
810-
fields.add(arg);
811-
812-
// Add padding.
813-
for (unsigned i = descriptorArgs.size(); i < argSize; ++i)
814-
fields.addInt(IGM.IntPtrTy, 0);
815-
break;
816-
}
817725
case KeyPathPatternComponent::Kind::StoredProperty: {
818726
auto property = cast<VarDecl>(component.getStoredPropertyDecl());
819727

@@ -1162,7 +1070,6 @@ IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
11621070
switch (component.getKind()) {
11631071
case KeyPathPatternComponent::Kind::GettableProperty:
11641072
case KeyPathPatternComponent::Kind::SettableProperty:
1165-
case KeyPathPatternComponent::Kind::External:
11661073
for (auto &index : component.getSubscriptIndices()) {
11671074
operands[index.Operand].LoweredType = index.LoweredType;
11681075
operands[index.Operand].LastUser = &component;

0 commit comments

Comments
 (0)