Skip to content

Commit 2e0836b

Browse files
committed
Merge branch 'master' into hermetic
2 parents a526f73 + 493b4a8 commit 2e0836b

File tree

105 files changed

+3343
-1886
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+3343
-1886
lines changed

docs/ABI/Mangling.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ Globals
173173

174174
global ::= global 'MK' // instantiation cache associated with global
175175

176+
global ::= global 'MJ' // noncanonical specialized generic type metadata instantiation cache associated with global
177+
global ::= global 'MN' // noncanonical specialized generic type metadata for global
178+
176179
A direct symbol resolves directly to the address of an object. An
177180
indirect symbol resolves to the address of a pointer to the object.
178181
They are distinct manglings to make a certain class of bugs

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ SIMPLE_DECL_ATTR(nonobjc, NonObjC,
244244
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
245245
30)
246246
SIMPLE_DECL_ATTR(_fixed_layout, FixedLayout,
247-
OnVar | OnClass | OnStruct |
247+
OnVar | OnClass | OnStruct | OnProtocol |
248248
UserInaccessible | ABIBreakingToAdd | ABIBreakingToRemove |
249249
APIStableToAdd | APIStableToRemove,
250250
31)

include/swift/AST/AutoDiff.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,29 @@ bool getBuiltinDifferentiableOrLinearFunctionConfig(
649649
bool getBuiltinDifferentiableOrLinearFunctionConfig(
650650
StringRef operationName, unsigned &arity, bool &throws);
651651

652+
/// Returns the SIL differentiability witness generic signature given the
653+
/// original declaration's generic signature and the derivative generic
654+
/// signature.
655+
///
656+
/// In general, the differentiability witness generic signature is equal to the
657+
/// derivative generic signature.
658+
///
659+
/// Edge case, if two conditions are satisfied:
660+
/// 1. The derivative generic signature is equal to the original generic
661+
/// signature.
662+
/// 2. The derivative generic signature has *all concrete* generic parameters
663+
/// (i.e. all generic parameters are bound to concrete types via same-type
664+
/// requirements).
665+
///
666+
/// Then the differentiability witness generic signature is `nullptr`.
667+
///
668+
/// Both the original and derivative declarations are lowered to SIL functions
669+
/// with a fully concrete type and no generic signature, so the
670+
/// differentiability witness should similarly have no generic signature.
671+
GenericSignature
672+
getDifferentiabilityWitnessGenericSignature(GenericSignature origGenSig,
673+
GenericSignature derivativeGenSig);
674+
652675
} // end namespace autodiff
653676

654677
} // end namespace swift

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2795,7 +2795,7 @@ WARNING(differentiable_let_property_implicit_noderivative_fixit,none,
27952795
NOTE(codable_extraneous_codingkey_case_here,none,
27962796
"CodingKey case %0 does not match any stored properties", (Identifier))
27972797
NOTE(codable_non_conforming_property_here,none,
2798-
"cannot automatically synthesize %0 because %1 does not conform to %0", (Type, Type))
2798+
"cannot automatically synthesize %0 because %1 does not conform to %0", (Type, TypeLoc))
27992799
NOTE(codable_non_decoded_property_here,none,
28002800
"cannot automatically synthesize %0 because %1 does not have a matching CodingKey and does not have a default value", (Type, Identifier))
28012801
NOTE(codable_codingkeys_type_is_not_an_enum_here,none,

include/swift/Demangling/DemangleNodes.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,12 @@ NODE(OpaqueTypeDescriptorAccessorVar)
287287
NODE(OpaqueReturnType)
288288
CONTEXT_NODE(OpaqueReturnTypeOf)
289289

290-
// Added in Swift 5.3
290+
// Added in Swift 5.4
291291
NODE(CanonicalSpecializedGenericMetaclass)
292292
NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction)
293-
294-
// Added in Swift 5.4
295293
NODE(MetadataInstantiationCache)
294+
NODE(NoncanonicalSpecializedGenericTypeMetadata)
295+
NODE(NoncanonicalSpecializedGenericTypeMetadataCache)
296296

297297
#undef CONTEXT_NODE
298298
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,16 @@ class LinkEntity {
393393
/// An access function for prespecialized type metadata.
394394
/// The pointer is a canonical TypeBase*.
395395
CanonicalSpecializedGenericTypeMetadataAccessFunction,
396+
397+
/// Metadata for a specialized generic type which cannot be statically
398+
/// guaranteed to be canonical and so must be canonicalized.
399+
/// The pointer is a canonical TypeBase*.
400+
NoncanonicalSpecializedGenericTypeMetadata,
401+
402+
/// A cache variable for noncanonical specialized type metadata, to be
403+
/// passed to swift_getCanonicalSpecializedMetadata.
404+
/// The pointer is a canonical TypeBase*.
405+
NoncanonicalSpecializedGenericTypeMetadataCacheVariable,
396406
};
397407
friend struct llvm::DenseMapInfo<LinkEntity>;
398408

@@ -1045,6 +1055,24 @@ class LinkEntity {
10451055
return entity;
10461056
}
10471057

1058+
static LinkEntity
1059+
forNoncanonicalSpecializedGenericTypeMetadata(CanType theType) {
1060+
LinkEntity entity;
1061+
entity.setForType(Kind::NoncanonicalSpecializedGenericTypeMetadata,
1062+
theType);
1063+
entity.Data |= LINKENTITY_SET_FIELD(
1064+
MetadataAddress, unsigned(TypeMetadataAddress::FullMetadata));
1065+
return entity;
1066+
}
1067+
1068+
1069+
static LinkEntity
1070+
forNoncanonicalSpecializedGenericTypeMetadataCacheVariable(CanType theType) {
1071+
LinkEntity entity;
1072+
entity.setForType(Kind::NoncanonicalSpecializedGenericTypeMetadataCacheVariable, theType);
1073+
return entity;
1074+
}
1075+
10481076
void mangle(llvm::raw_ostream &out) const;
10491077
void mangle(SmallVectorImpl<char> &buffer) const;
10501078
std::string mangleAsString() const;
@@ -1152,6 +1180,7 @@ class LinkEntity {
11521180
}
11531181
TypeMetadataAddress getMetadataAddress() const {
11541182
assert(getKind() == Kind::TypeMetadata ||
1183+
getKind() == Kind::NoncanonicalSpecializedGenericTypeMetadata ||
11551184
getKind() == Kind::ObjCResilientClassStub);
11561185
return (TypeMetadataAddress)LINKENTITY_GET_FIELD(Data, MetadataAddress);
11571186
}

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ class Parser {
660660
/// \returns true if there is an instance of \c T1 on the current line (this
661661
/// avoids the foot-gun of not considering T1 starting the next line for a
662662
/// plain Tok.is(T1) check).
663-
bool skipUntilTokenOrEndOfLine(tok T1);
663+
bool skipUntilTokenOrEndOfLine(tok T1, tok T2 = tok::NUM_TOKENS);
664664

665665
/// Skip a braced block (e.g. function body). The current token must be '{'.
666666
/// Returns \c true if the parser hit the eof before finding matched '}'.

include/swift/SIL/MemAccessUtils.h

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ namespace swift {
189189
/// the base of a formal access. It may be from a ref_tail_addr, undef, or some
190190
/// recognized memory initialization pattern. Unidentified valid storage cannot
191191
/// represent any arbitrary base address--it must at least been proven not to
192-
/// correspond to any class or global variable access.
192+
/// correspond to any class or global variable access, unless it's nested within
193+
/// another access to the same object. So, Unidentified can overlap with
194+
/// Class/Global access, but it cannot be the only formal access to that memory.
193195
///
194196
/// An *invalid* AccessedStorage object is Unidentified and associated with an
195197
/// invalid SILValue. This signals that analysis has failed to recognize an
@@ -219,6 +221,7 @@ class AccessedStorage {
219221
Stack,
220222
Global,
221223
Class,
224+
Tail,
222225
Argument,
223226
Yield,
224227
Nested,
@@ -228,10 +231,16 @@ class AccessedStorage {
228231

229232
static const char *getKindName(Kind k);
230233

231-
/// Directly create an AccessedStorage for class property access.
234+
// Give object tail storage a fake property index for convenience.
235+
static constexpr unsigned TailIndex = ~0U;
236+
237+
/// Directly create an AccessedStorage for class or tail property access.
232238
static AccessedStorage forClass(SILValue object, unsigned propertyIndex) {
233239
AccessedStorage storage;
234-
storage.initKind(Class, propertyIndex);
240+
if (propertyIndex == TailIndex)
241+
storage.initKind(Tail);
242+
else
243+
storage.initKind(Class, propertyIndex);
235244
storage.value = object;
236245
return storage;
237246
}
@@ -301,7 +310,8 @@ class AccessedStorage {
301310
union {
302311
// For non-class storage, 'value' is the access base. For class storage
303312
// 'value' is the object base, where the access base is the class' stored
304-
// property.
313+
// property. For tail storage 'value' is the object base and there is no
314+
// value for the access base.
305315
SILValue value;
306316
SILGlobalVariable *global;
307317
};
@@ -334,7 +344,7 @@ class AccessedStorage {
334344
}
335345

336346
SILValue getValue() const {
337-
assert(getKind() != Global && getKind() != Class);
347+
assert(getKind() != Global && getKind() != Class && getKind() != Tail);
338348
return value;
339349
}
340350

@@ -354,7 +364,7 @@ class AccessedStorage {
354364
}
355365

356366
SILValue getObject() const {
357-
assert(getKind() == Class);
367+
assert(getKind() == Class || getKind() == Tail);
358368
return value;
359369
}
360370
unsigned getPropertyIndex() const {
@@ -374,6 +384,7 @@ class AccessedStorage {
374384
switch (getKind()) {
375385
case Box:
376386
case Stack:
387+
case Tail:
377388
case Argument:
378389
case Yield:
379390
case Nested:
@@ -396,6 +407,7 @@ class AccessedStorage {
396407
return true;
397408
case Global:
398409
case Class:
410+
case Tail:
399411
case Argument:
400412
case Yield:
401413
case Nested:
@@ -405,6 +417,11 @@ class AccessedStorage {
405417
llvm_unreachable("unhandled kind");
406418
}
407419

420+
/// Return trye if the given access is guaranteed to be within a heap object.
421+
bool isObjectAccess() const {
422+
return getKind() == Class || getKind() == Tail;
423+
}
424+
408425
/// Return true if the given access is on a 'let' lvalue.
409426
bool isLetAccess(SILFunction *F) const;
410427

@@ -420,6 +437,7 @@ class AccessedStorage {
420437
case Global:
421438
return true;
422439
case Class:
440+
case Tail:
423441
case Argument:
424442
case Yield:
425443
case Nested:
@@ -455,20 +473,47 @@ class AccessedStorage {
455473
// Return true if this storage is guaranteed not to overlap with \p other's
456474
// storage.
457475
bool isDistinctFrom(const AccessedStorage &other) const {
458-
if (isUniquelyIdentified() && other.isUniquelyIdentified()) {
459-
return !hasIdenticalBase(other);
476+
if (isUniquelyIdentified()) {
477+
if (other.isUniquelyIdentified() && !hasIdenticalBase(other))
478+
return true;
479+
480+
if (other.isObjectAccess())
481+
return true;
482+
483+
// We currently assume that Unidentified storage may overlap with
484+
// Box/Stack storage.
485+
return false;
460486
}
461-
if (getKind() != Class || other.getKind() != Class)
462-
// At least one side is an Argument or Yield, or is unidentified.
487+
if (other.isUniquelyIdentified())
488+
return other.isDistinctFrom(*this);
489+
490+
// Neither storage is uniquely identified.
491+
if (isObjectAccess()) {
492+
if (other.isObjectAccess()) {
493+
// Property access cannot overlap with Tail access.
494+
if (getKind() != other.getKind())
495+
return true;
496+
497+
// We could also check if the object types are distinct, but that only
498+
// helps if we know the relationships between class types.
499+
return getKind() == Class
500+
&& getPropertyIndex() != other.getPropertyIndex();
501+
}
502+
// Any type of nested/argument address may be within the same object.
503+
//
504+
// We also currently assume Unidentified access may be within an object
505+
// purely to handle KeyPath accesses. The deriviation of the KeyPath
506+
// address must separately appear to be a Class access so that all Class
507+
// accesses are accounted for.
463508
return false;
464-
465-
// Classes are not uniquely identified by their base. However, if the
466-
// underling objects have identical types and distinct property indices then
467-
// they are distinct storage locations.
468-
if (getObject()->getType() == other.getObject()->getType()
469-
&& getPropertyIndex() != other.getPropertyIndex()) {
470-
return true;
471509
}
510+
if (other.isObjectAccess())
511+
return other.isDistinctFrom(*this);
512+
513+
// Neither storage is from a class or tail.
514+
//
515+
// Unidentified values may alias with each other or with any kind of
516+
// nested/argument access.
472517
return false;
473518
}
474519

@@ -530,10 +575,11 @@ template <> struct DenseMapInfo<swift::AccessedStorage> {
530575
return storage.getParamIndex();
531576
case swift::AccessedStorage::Global:
532577
return DenseMapInfo<void *>::getHashValue(storage.getGlobal());
533-
case swift::AccessedStorage::Class: {
578+
case swift::AccessedStorage::Class:
534579
return llvm::hash_combine(storage.getObject(),
535580
storage.getPropertyIndex());
536-
}
581+
case swift::AccessedStorage::Tail:
582+
return DenseMapInfo<swift::SILValue>::getHashValue(storage.getObject());
537583
}
538584
llvm_unreachable("Unhandled AccessedStorageKind");
539585
}
@@ -673,6 +719,9 @@ class AccessUseDefChainVisitor {
673719
Result visitClassAccess(RefElementAddrInst *field) {
674720
return asImpl().visitBase(field, AccessedStorage::Class);
675721
}
722+
Result visitTailAccess(RefTailAddrInst *tail) {
723+
return asImpl().visitBase(tail, AccessedStorage::Tail);
724+
}
676725
Result visitArgumentAccess(SILFunctionArgument *arg) {
677726
return asImpl().visitBase(arg, AccessedStorage::Argument);
678727
}
@@ -808,7 +857,7 @@ Result AccessUseDefChainVisitor<Impl, Result>::visit(SILValue sourceAddr) {
808857
// This is a valid address producer for nested @inout argument
809858
// access, but it is never used for formal access of identified objects.
810859
case ValueKind::RefTailAddrInst:
811-
return asImpl().visitUnidentified(sourceAddr);
860+
return asImpl().visitTailAccess(cast<RefTailAddrInst>(sourceAddr));
812861

813862
// Inductive single-operand cases:
814863
// Look through address casts to find the source address.

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ PASS(CrossModuleSerializationSetup, "cross-module-serialization-setup",
6868
"Setup serialization flags for cross-module optimization")
6969
PASS(AccessSummaryDumper, "access-summary-dump",
7070
"Dump Address Parameter Access Summary")
71+
PASS(AccessedStorageAnalysisDumper, "accessed-storage-analysis-dump",
72+
"Dump Accessed Storage Analysis Summaries")
7173
PASS(AccessedStorageDumper, "accessed-storage-dump",
72-
"Dump Accessed Storage Summary")
74+
"Dump Accessed Storage Information")
7375
PASS(AccessMarkerElimination, "access-marker-elim",
7476
"Access Marker Elimination.")
7577
PASS(AddressLowering, "address-lowering",

lib/AST/AutoDiff.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,23 @@ bool autodiff::getBuiltinDifferentiableOrLinearFunctionConfig(
372372
return operationName.empty();
373373
}
374374

375+
GenericSignature autodiff::getDifferentiabilityWitnessGenericSignature(
376+
GenericSignature origGenSig, GenericSignature derivativeGenSig) {
377+
// If there is no derivative generic signature, return the original generic
378+
// signature.
379+
if (!derivativeGenSig)
380+
return origGenSig;
381+
// If derivative generic signature has all concrete generic parameters and is
382+
// equal to the original generic signature, return `nullptr`.
383+
auto derivativeCanGenSig = derivativeGenSig.getCanonicalSignature();
384+
auto origCanGenSig = origGenSig.getCanonicalSignature();
385+
if (origCanGenSig == derivativeCanGenSig &&
386+
derivativeCanGenSig->areAllParamsConcrete())
387+
return GenericSignature();
388+
// Otherwise, return the derivative generic signature.
389+
return derivativeGenSig;
390+
}
391+
375392
Type TangentSpace::getType() const {
376393
switch (kind) {
377394
case Kind::TangentVector:

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,18 +2065,9 @@ Type EquivalenceClass::getTypeInContext(GenericSignatureBuilder &builder,
20652065
return ErrorType::get(anchor);
20662066

20672067
// Map the parent type into this context.
2068-
Type parentType = parentEquivClass->getTypeInContext(builder, genericEnv);
2069-
2070-
// If the parent is concrete, handle the
2071-
parentArchetype = parentType->getAs<ArchetypeType>();
2072-
if (!parentArchetype) {
2073-
// Resolve the member type.
2074-
Type memberType =
2075-
depMemTy->substBaseType(parentType, builder.getLookupConformanceFn());
2076-
2077-
return genericEnv->mapTypeIntoContext(memberType,
2078-
builder.getLookupConformanceFn());
2079-
}
2068+
parentArchetype =
2069+
parentEquivClass->getTypeInContext(builder, genericEnv)
2070+
->castTo<ArchetypeType>();
20802071

20812072
// If we already have a nested type with this name, return it.
20822073
assocType = depMemTy->getAssocType();

0 commit comments

Comments
 (0)