Skip to content

Commit 4be9673

Browse files
authored
Merge pull request #2782 from swiftwasm/main
[pull] swiftwasm from main
2 parents 8c204f7 + b7f7221 commit 4be9673

39 files changed

+1246
-630
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4316,24 +4316,45 @@ WARNING(non_concurrent_property_type,none,
43164316
"cannot use %0 %1 with a non-concurrent-value type %2 "
43174317
"%select{across actors|from concurrently-executed code}3",
43184318
(DescriptiveDeclKind, DeclName, Type, bool))
4319+
WARNING(non_concurrent_keypath_capture,none,
4320+
"cannot form key path that captures non-concurrent-value type %0",
4321+
(Type))
43194322
ERROR(non_concurrent_type_member,none,
43204323
"%select{stored property %1|associated value %1}0 of "
43214324
"'ConcurrentValue'-conforming %2 %3 has non-concurrent-value type %4",
43224325
(bool, DeclName, DescriptiveDeclKind, DeclName, Type))
4326+
WARNING(non_concurrent_type_member_warn,none,
4327+
"%select{stored property %1|associated value %1}0 of "
4328+
"'ConcurrentValue'-conforming %2 %3 has non-concurrent-value type %4",
4329+
(bool, DeclName, DescriptiveDeclKind, DeclName, Type))
43234330
ERROR(concurrent_value_class_mutable_property,none,
43244331
"stored property %0 of 'ConcurrentValue'-conforming %1 %2 is mutable",
43254332
(DeclName, DescriptiveDeclKind, DeclName))
4333+
WARNING(concurrent_value_class_mutable_property_warn,none,
4334+
"stored property %0 of 'ConcurrentValue'-conforming %1 %2 is mutable",
4335+
(DeclName, DescriptiveDeclKind, DeclName))
43264336
ERROR(concurrent_value_outside_source_file,none,
4327-
"conformance 'ConcurrentValue' must occur in the same source file as "
4337+
"conformance to 'ConcurrentValue' must occur in the same source file as "
4338+
"%0 %1; use 'UnsafeConcurrentValue' for retroactive conformance",
4339+
(DescriptiveDeclKind, DeclName))
4340+
WARNING(concurrent_value_outside_source_file_warn,none,
4341+
"conformance to 'ConcurrentValue' must occur in the same source file as "
43284342
"%0 %1; use 'UnsafeConcurrentValue' for retroactive conformance",
43294343
(DescriptiveDeclKind, DeclName))
43304344
ERROR(concurrent_value_open_class,none,
43314345
"open class %0 cannot conform to `ConcurrentValue`; "
43324346
"use `UnsafeConcurrentValue`", (DeclName))
4347+
WARNING(concurrent_value_open_class_warn,none,
4348+
"open class %0 cannot conform to `ConcurrentValue`; "
4349+
"use `UnsafeConcurrentValue`", (DeclName))
43334350
ERROR(concurrent_value_inherit,none,
43344351
"`ConcurrentValue` class %1 cannot inherit from another class"
43354352
"%select{| other than 'NSObject'}0",
43364353
(bool, DeclName))
4354+
WARNING(concurrent_value_inherit_warn,none,
4355+
"`ConcurrentValue` class %1 cannot inherit from another class"
4356+
"%select{| other than 'NSObject'}0",
4357+
(bool, DeclName))
43374358

43384359
ERROR(actorindependent_let,none,
43394360
"'@actorIndependent' is meaningless on 'let' declarations because "
@@ -5624,6 +5645,10 @@ ERROR(marker_protocol_inherit_nonmarker, none,
56245645
(DeclName, DeclName))
56255646
ERROR(marker_protocol_cast,none,
56265647
"marker protocol %0 cannot be used in a conditional cast", (DeclName))
5648+
ERROR(marker_protocol_conditional_conformance,none,
5649+
"conditional conformance to non-marker protocol %0 cannot depend on "
5650+
"conformance of %1 to non-marker protocol %2",
5651+
(Identifier, Type, Identifier))
56275652

56285653
//------------------------------------------------------------------------------
56295654
// MARK: differentiable programming diagnostics

include/swift/SILOptimizer/Analysis/EscapeAnalysis.h

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -989,8 +989,13 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
989989
/// The allocator for the connection graphs in Function2ConGraph.
990990
llvm::SpecificBumpPtrAllocator<FunctionInfo> Allocator;
991991

992+
// TODO: Use per-function caches, at least for Resilient types, to use Maximal
993+
// expansion.
994+
992995
/// Cache for isPointer().
993996
PointerKindCache pointerKindCache;
997+
/// Cache for checking the aggregate pointerness of class properties.
998+
PointerKindCache classPropertiesKindCache;
994999

9951000
SILModule *M;
9961001

@@ -1014,6 +1019,12 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
10141019

10151020
PointerKind findCachedPointerKind(SILType Ty, const SILFunction &F) const;
10161021

1022+
PointerKind findClassPropertiesPointerKind(SILType Ty,
1023+
const SILFunction &F) const;
1024+
1025+
PointerKind findCachedClassPropertiesKind(SILType Ty,
1026+
const SILFunction &F) const;
1027+
10171028
// Returns true if the type \p Ty must be a reference or must transitively
10181029
// contain a reference and no other pointer or address type.
10191030
bool hasReferenceOnly(SILType Ty, const SILFunction &F) const {
@@ -1114,6 +1125,10 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
11141125
bool canEscapeToUsePoint(SILValue value, SILInstruction *usePoint,
11151126
ConnectionGraph *conGraph);
11161127

1128+
/// Common implementation for mayReleaseReferenceContent and
1129+
/// mayReleaseAddressContent.
1130+
bool mayReleaseContent(SILValue releasedPtr, SILValue liveAddress);
1131+
11171132
friend struct ::CGForDotView;
11181133

11191134
public:
@@ -1163,8 +1178,38 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
11631178
bool canEscapeTo(SILValue V, DestroyValueInst *DVI);
11641179

11651180
/// Return true if \p releasedReference deinitialization may release memory
1166-
/// pointed to by \p accessedAddress.
1167-
bool mayReleaseContent(SILValue releasedReference, SILValue accessedAddress);
1181+
/// pointed to by \p liveAddress.
1182+
///
1183+
/// This determines whether a direct release of \p releasedReference, such as
1184+
/// destroy_value or strong_release may release memory pointed to by \p
1185+
/// liveAddress. It can also be used to determine whether passing a
1186+
/// reference-type call argument may release \p liveAddress.
1187+
///
1188+
/// This does not distinguish between a call that releases \p
1189+
/// releasedReference directly, vs. a call that releases one of indirect
1190+
/// references.The side effects of releasing any object reachable from \p
1191+
/// releasedReference are a strict subset of the side effects of directly
1192+
/// releasing the parent reference.
1193+
bool mayReleaseReferenceContent(SILValue releasedReference,
1194+
SILValue liveAddress) {
1195+
assert(!releasedReference->getType().isAddress() &&
1196+
"expected a potentially nontrivial value, not an address");
1197+
return mayReleaseContent(releasedReference, liveAddress);
1198+
}
1199+
1200+
/// Return true if accessing memory at \p accessedAddress may release memory
1201+
/// pointed to by \p liveAddress.
1202+
///
1203+
/// This makes sense for determining whether accessing indirect call argument
1204+
/// \p accessedAddress may release memory pointed to by \p liveAddress.
1205+
///
1206+
/// "Access" to the memory can be any release of a reference pointed to by \p
1207+
/// accessedAddress, so '@in' and '@inout' are handled the same.
1208+
bool mayReleaseAddressContent(SILValue accessedAddress,
1209+
SILValue liveAddress) {
1210+
assert(accessedAddress->getType().isAddress() && "expected an address");
1211+
return mayReleaseContent(accessedAddress, liveAddress);
1212+
}
11681213

11691214
/// Returns true if the pointers \p V1 and \p V2 can possibly point to the
11701215
/// same memory.

include/swift/SILOptimizer/Differentiation/ADContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ class ADContext {
115115
mutable FuncDecl *cachedPlusFn = nullptr;
116116
/// `AdditiveArithmetic.+=` declaration.
117117
mutable FuncDecl *cachedPlusEqualFn = nullptr;
118+
/// `AdditiveArithmetic.zero` declaration.
119+
mutable AccessorDecl *cachedZeroGetter = nullptr;
118120

119121
public:
120122
/// Construct an ADContext for the given module.
@@ -201,6 +203,7 @@ class ADContext {
201203

202204
FuncDecl *getPlusDecl() const;
203205
FuncDecl *getPlusEqualDecl() const;
206+
AccessorDecl *getAdditiveArithmeticZeroGetter() const;
204207

205208
/// Cleans up all the internal state.
206209
void cleanUp();
@@ -269,6 +272,10 @@ class ADContext {
269272
Diag<T...> diag, U &&... args);
270273
};
271274

275+
raw_ostream &getADDebugStream();
276+
SILLocation getValidLocation(SILValue v);
277+
SILLocation getValidLocation(SILInstruction *inst);
278+
272279
template <typename... T, typename... U>
273280
InFlightDiagnostic
274281
ADContext::emitNondifferentiabilityError(SILValue value,

include/swift/SILOptimizer/Differentiation/AdjointValue.h

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,45 @@ class AdjointValueBase {
5151
/// The type of this value as if it were materialized as a SIL value.
5252
SILType type;
5353

54+
using DebugInfo = std::pair<SILDebugLocation, SILDebugVariable>;
55+
56+
/// The debug location and variable info associated with the original value.
57+
Optional<DebugInfo> debugInfo;
58+
5459
/// The underlying value.
5560
union Value {
56-
llvm::ArrayRef<AdjointValue> aggregate;
61+
unsigned numAggregateElements;
5762
SILValue concrete;
58-
Value(llvm::ArrayRef<AdjointValue> v) : aggregate(v) {}
63+
Value(unsigned numAggregateElements)
64+
: numAggregateElements(numAggregateElements) {}
5965
Value(SILValue v) : concrete(v) {}
6066
Value() {}
6167
} value;
6268

69+
// Begins tail-allocated aggregate elements, if
70+
// `kind == AdjointValueKind::Aggregate`.
71+
6372
explicit AdjointValueBase(SILType type,
64-
llvm::ArrayRef<AdjointValue> aggregate)
65-
: kind(AdjointValueKind::Aggregate), type(type), value(aggregate) {}
73+
llvm::ArrayRef<AdjointValue> aggregate,
74+
Optional<DebugInfo> debugInfo)
75+
: kind(AdjointValueKind::Aggregate), type(type), debugInfo(debugInfo),
76+
value(aggregate.size()) {
77+
MutableArrayRef<AdjointValue> tailElements(
78+
reinterpret_cast<AdjointValue *>(this + 1), aggregate.size());
79+
std::uninitialized_copy(
80+
aggregate.begin(), aggregate.end(), tailElements.begin());
81+
}
6682

67-
explicit AdjointValueBase(SILValue v)
68-
: kind(AdjointValueKind::Concrete), type(v->getType()), value(v) {}
83+
explicit AdjointValueBase(SILValue v, Optional<DebugInfo> debugInfo)
84+
: kind(AdjointValueKind::Concrete), type(v->getType()),
85+
debugInfo(debugInfo), value(v) {}
6986

70-
explicit AdjointValueBase(SILType type)
71-
: kind(AdjointValueKind::Zero), type(type) {}
87+
explicit AdjointValueBase(SILType type, Optional<DebugInfo> debugInfo)
88+
: kind(AdjointValueKind::Zero), type(type), debugInfo(debugInfo) {}
7289
};
7390

74-
/// A symbolic adjoint value that is capable of representing zero value 0 and
75-
/// 1, in addition to a materialized SILValue. This is expected to be passed
76-
/// around by value in most cases, as it's two words long.
91+
/// A symbolic adjoint value that wraps a `SILValue`, a zero, or an aggregate
92+
/// thereof.
7793
class AdjointValue final {
7894

7995
private:
@@ -85,26 +101,37 @@ class AdjointValue final {
85101
AdjointValueBase *operator->() const { return base; }
86102
AdjointValueBase &operator*() const { return *base; }
87103

88-
static AdjointValue createConcrete(llvm::BumpPtrAllocator &allocator,
89-
SILValue value) {
90-
return new (allocator.Allocate<AdjointValueBase>()) AdjointValueBase(value);
104+
using DebugInfo = AdjointValueBase::DebugInfo;
105+
106+
static AdjointValue createConcrete(
107+
llvm::BumpPtrAllocator &allocator, SILValue value,
108+
Optional<DebugInfo> debugInfo = None) {
109+
auto *buf = allocator.Allocate<AdjointValueBase>();
110+
return new (buf) AdjointValueBase(value, debugInfo);
91111
}
92112

93-
static AdjointValue createZero(llvm::BumpPtrAllocator &allocator,
94-
SILType type) {
95-
return new (allocator.Allocate<AdjointValueBase>()) AdjointValueBase(type);
113+
static AdjointValue createZero(
114+
llvm::BumpPtrAllocator &allocator, SILType type,
115+
Optional<DebugInfo> debugInfo = None) {
116+
auto *buf = allocator.Allocate<AdjointValueBase>();
117+
return new (buf) AdjointValueBase(type, debugInfo);
96118
}
97119

98-
static AdjointValue createAggregate(llvm::BumpPtrAllocator &allocator,
99-
SILType type,
100-
llvm::ArrayRef<AdjointValue> aggregate) {
101-
return new (allocator.Allocate<AdjointValueBase>())
102-
AdjointValueBase(type, aggregate);
120+
static AdjointValue createAggregate(
121+
llvm::BumpPtrAllocator &allocator, SILType type,
122+
ArrayRef<AdjointValue> elements,
123+
Optional<DebugInfo> debugInfo = None) {
124+
AdjointValue *buf = reinterpret_cast<AdjointValue *>(allocator.Allocate(
125+
sizeof(AdjointValueBase) + elements.size() * sizeof(AdjointValue),
126+
alignof(AdjointValueBase)));
127+
return new (buf) AdjointValueBase(type, elements, debugInfo);
103128
}
104129

105130
AdjointValueKind getKind() const { return base->kind; }
106131
SILType getType() const { return base->type; }
107132
CanType getSwiftType() const { return getType().getASTType(); }
133+
Optional<DebugInfo> getDebugInfo() const { return base->debugInfo; }
134+
void setDebugInfo(DebugInfo debugInfo) const { base->debugInfo = debugInfo; }
108135

109136
NominalTypeDecl *getAnyNominal() const {
110137
return getSwiftType()->getAnyNominal();
@@ -116,16 +143,18 @@ class AdjointValue final {
116143

117144
unsigned getNumAggregateElements() const {
118145
assert(isAggregate());
119-
return base->value.aggregate.size();
146+
return base->value.numAggregateElements;
120147
}
121148

122149
AdjointValue getAggregateElement(unsigned i) const {
123-
assert(isAggregate());
124-
return base->value.aggregate[i];
150+
return getAggregateElements()[i];
125151
}
126152

127153
llvm::ArrayRef<AdjointValue> getAggregateElements() const {
128-
return base->value.aggregate;
154+
assert(isAggregate());
155+
return {
156+
reinterpret_cast<const AdjointValue *>(base + 1),
157+
getNumAggregateElements()};
129158
}
130159

131160
SILValue getConcreteValue() const {
@@ -143,15 +172,15 @@ class AdjointValue final {
143172
if (auto *decl =
144173
getType().getASTType()->getStructOrBoundGenericStruct()) {
145174
interleave(
146-
llvm::zip(decl->getStoredProperties(), base->value.aggregate),
175+
llvm::zip(decl->getStoredProperties(), getAggregateElements()),
147176
[&s](std::tuple<VarDecl *, const AdjointValue &> elt) {
148177
s << std::get<0>(elt)->getName() << ": ";
149178
std::get<1>(elt).print(s);
150179
},
151180
[&s] { s << ", "; });
152181
} else if (getType().is<TupleType>()) {
153182
interleave(
154-
base->value.aggregate,
183+
getAggregateElements(),
155184
[&s](const AdjointValue &elt) { elt.print(s); },
156185
[&s] { s << ", "; });
157186
} else {

include/swift/SILOptimizer/Differentiation/Common.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
#include "swift/SIL/TypeSubstCloner.h"
2828
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
2929
#include "swift/SILOptimizer/Analysis/DifferentiableActivityAnalysis.h"
30+
#include "swift/SILOptimizer/Differentiation/ADContext.h"
3031
#include "swift/SILOptimizer/Differentiation/DifferentiationInvoker.h"
32+
#include "swift/SILOptimizer/Differentiation/TangentBuilder.h"
3133

3234
namespace swift {
3335

@@ -142,6 +144,9 @@ template <class Inst> Inst *peerThroughFunctionConversions(SILValue value) {
142144
return nullptr;
143145
}
144146

147+
Optional<std::pair<SILDebugLocation, SILDebugVariable>>
148+
findDebugLocationAndVariable(SILValue originalValue);
149+
145150
//===----------------------------------------------------------------------===//
146151
// Diagnostic utilities
147152
//===----------------------------------------------------------------------===//
@@ -190,12 +195,6 @@ SILValue joinElements(ArrayRef<SILValue> elements, SILBuilder &builder,
190195
void extractAllElements(SILValue value, SILBuilder &builder,
191196
SmallVectorImpl<SILValue> &results);
192197

193-
/// Emit a zero value into the given buffer access by calling
194-
/// `AdditiveArithmetic.zero`. The given type must conform to
195-
/// `AdditiveArithmetic`.
196-
void emitZeroIntoBuffer(SILBuilder &builder, CanType type,
197-
SILValue bufferAccess, SILLocation loc);
198-
199198
/// Emit a `Builtin.Word` value that represents the given type's memory layout
200199
/// size.
201200
SILValue emitMemoryLayoutSize(

0 commit comments

Comments
 (0)