Skip to content

Commit 49a1f21

Browse files
author
Dave Abrahams
committed
Merge branch 'master' of github.com:apple/swift into tensorflow-stage
* 'master' of github.com:apple/swift: [docs] Fix broken links in the documentation index (#33829) [Profiler] Increment closure body count prior to the prolog (#33946) ARCSequenceOpts: Add LoopSummary verifier (#33810) [build-script] Cleanup source directory layout help Address review comment. ABI checker: when invoking via build system, explicitly mention ABI breakge in diagnostics stdlib: Remove unused, unsafe helper function _withUninitializedString (#33704) test: Replace _silgen_name w/ _cdecl in CommandLineStressTest [AutoDiff] [Docs] Clarify 'Differentiable' derived conformances conditions. Revert "build-script: remove dead CMake options for Swift"
2 parents ea78066 + 0c6129d commit 49a1f21

File tree

14 files changed

+268
-80
lines changed

14 files changed

+268
-80
lines changed

docs/DifferentiableProgramming.md

Lines changed: 117 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,53 +1219,73 @@ network layers and models are formed from smaller components stored as
12191219
properties in structure types and class types. In order to use these types for
12201220
differentiation, one must extend these types to conform to the `Differentiable`
12211221
protocol. Luckily, this need not be done manually in most cases—the compiler
1222-
automatically synthesizes conformances when a memberwise `Differentiable`
1223-
conformance is declared.
1222+
automatically synthesizes conformances when a `Differentiable` conformance is
1223+
declared.
12241224

12251225
##### Synthesis conditions
12261226

12271227
The compiler automatically synthesizes implementations of `Differentiable`
1228-
protocol requirements for struct and class types. Here are the conditions for
1229-
synthesis: The type must declare a conformance to `Differentiable` with a
1230-
`@memberwise` attribute before the protocol name, either on the type declaration
1231-
or on an extension in the same file. All stored properties of the conforming
1232-
type must either be a `var` that conforms to `Differentiable` or be marked with
1233-
the `@noDerivative` attribute. If a non-`Differentiable` or a `let` stored
1234-
property is not marked with `@noDerivative`, then it is treated as if it has
1235-
`@noDerivative` and the compiler emits a warning (with a fix-it in IDEs) asking
1236-
the user to make the attribute explicit.
1228+
protocol requirements for struct and class types. For a type, conditions for the
1229+
synthesis are:
1230+
1231+
1. There is a conformance to `Differentiable` declared for the type, either in
1232+
the original type declaration or in an extension.
1233+
1234+
2. There is a `@memberwise` attribute in the conformance clause before the
1235+
protocol name.
1236+
1237+
3. The conformance must be declared in the same file.
1238+
1239+
Here is an example where the synthesis conditions are satisfied.
1240+
1241+
```swift
1242+
struct Model: @memberwise Differentiable {
1243+
var weight: SIMD4<Double>
1244+
var bias: Double
1245+
let metadata1: Float
1246+
let metadata2: Float
1247+
let usesBias: Bool
1248+
}
1249+
```
12371250

12381251
##### Default synthesis
12391252

1240-
By default, the compiler synthesizes a nested `TangentVector` structure type
1241-
that contains the `TangentVector`s of all stored properties that are not marked
1242-
with `@noDerivative`. In other words, `@noDerivative` makes a stored property
1243-
not be included in a type's tangent vectors.
1253+
The compiler synthesizes a nested `TangentVector` structure type that contains
1254+
the `TangentVector`s of all stored properties (terms and conditions apply) that
1255+
conform to `Differentiable`, which we call **differentiable variables**.
1256+
1257+
Mathematically, the synthesized implementation treats the data structure as a
1258+
product manifold of the manifolds each differentiable variable's type
1259+
represents. Differentiable variables' types are required to conform to
1260+
`Differentiable` because the synthesized implementation needs to access each
1261+
differentiable variable's type's `TangentVector` associated type and invoke each
1262+
differentiable variable's implementation of `move(along:)` and
1263+
`zeroTangentVectorInitializer`. Because the synthesized implementation needs to
1264+
invoke `move(along:)` on each differentiable variable, the differentiable
1265+
variables must have a `move(along:)` which satisfies the protocol requirement
1266+
and can be invoked on the property. That is, the property must be either a
1267+
variable (`var`) or a constant (`let`) with a non-`mutating` implementation of
1268+
the `move(along:)` protocol requirement.
12441269

12451270
The synthesized `TangentVector` has the same effective access level as the
12461271
original type declaration. Properties in the synthesized `TangentVector` have
12471272
the same effective access level as their corresponding original properties.
12481273

1249-
A `move(along:)` method is synthesized with a body that calls `move(along:)` for
1250-
each pair of the original property and its corresponding property in
1251-
`TangentVector`.
1274+
The synthesized `move(along:)` method calls `move(along:)` for each pair of a
1275+
differentiable variable and its corresponding property in `TangentVector`.
12521276

1253-
Similarly, when memberwise derivation is possible,
1254-
`zeroTangentVectorInitializer` is synthesized to return a closure that captures
1255-
and calls each stored property's `zeroTangentVectorInitializer` closure.
1256-
When memberwise derivation is not possible (e.g. for custom user-defined
1257-
`TangentVector` types), `zeroTangentVectorInitializer` is synthesized as a
1258-
`{ TangentVector.zero }` closure.
1259-
1260-
Here's an example:
1277+
The synthesized `zeroTangentVectorInitializer` property returns a closure that
1278+
captures and calls each stored property's `zeroTangentVectorInitializer`
1279+
closure. When memberwise derivation is not possible (e.g. for custom
1280+
user-defined `TangentVector` types), `zeroTangentVectorInitializer` is
1281+
synthesized as a `{ TangentVector.zero }` closure.
12611282

12621283
```swift
12631284
struct Foo<T: Differentiable, U: Differentiable>: @memberwise Differentiable {
1264-
// `x` and `y` are the "differentiation properties".
1285+
// `x` and `y` are the "differentiable variables".
12651286
var x: T
12661287
var y: U
1267-
@noDerivative var customFlag: Bool
1268-
@noDerivative let helperVariable: T
1288+
let customFlag: Bool
12691289

12701290
// The compiler synthesizes:
12711291
//
@@ -1279,7 +1299,6 @@ struct Foo<T: Differentiable, U: Differentiable>: @memberwise Differentiable {
12791299
// y.move(along: direction.y)
12801300
// }
12811301
//
1282-
// @noDerivative
12831302
// var zeroTangentVectorInitializer: () -> TangentVector {
12841303
// { [xTanInit = x.zeroTangentVectorInitializer,
12851304
// yTanInit = y.zeroTangentVectorInitializer] in
@@ -1289,6 +1308,74 @@ struct Foo<T: Differentiable, U: Differentiable>: @memberwise Differentiable {
12891308
}
12901309
```
12911310

1311+
###### Opt out of synthesis for a stored property
1312+
1313+
The synthesized implementation of `Differentiable` protocol requirements already
1314+
excludes stored properties that are not differentiable variables, such as stored
1315+
properties that do not conform to `Differentiable` and `let`
1316+
properties that do not have a non-mutating `move(along:)`. In addition to this
1317+
behavior, we also introduce a `@noDerivative` declaration attribute, which can
1318+
be attached to properties that the programmer does not wish to include in the
1319+
synthesized `Differentiable` protocol requirement implementation.
1320+
1321+
When a stored property is marked with `@noDerivative` in a type that declares a
1322+
conformance to `Differentiable`, it will not be treated as a differentiable
1323+
variable regardless of whether it conforms to `Differentiable`. That is, the
1324+
synthesized implementation of protocol requirements will not include this
1325+
property.
1326+
1327+
```swift
1328+
struct Foo<T: Differentiable, U: Differentiable>: @memberwise Differentiable {
1329+
// `x` and `y` are the "differentiable variables".
1330+
var x: T
1331+
var y: U
1332+
@noDerivative var customFlag: Bool
1333+
@noDerivative let helperVariable: T
1334+
}
1335+
```
1336+
1337+
For clarity as to which stored properties are to be included for
1338+
differentiation, the compiler will recommend that all stored properties that
1339+
cannot be included as differentiable variables (due to either lacking a
1340+
conformance to `Differentiable` or being a non-`class`-bound `let` property) be
1341+
marked with `@noDerivative`. When a property is not included as a differentiable
1342+
variable and is not marked with `@noDerivative`, the compiler produces a warning
1343+
asking the user to make the exclusion explicit along with fix-it suggestions in
1344+
IDEs.
1345+
1346+
```swift
1347+
struct Foo<T: Differentiable, U: Differentiable>: @memberwise Differentiable {
1348+
// `x` and `y` are the "differentiable variables".
1349+
var x: T
1350+
var y: U
1351+
var customFlag: Bool
1352+
let helperVariable: T
1353+
}
1354+
```
1355+
1356+
```console
1357+
test.swift:5:4: warning: stored property 'customFlag' has no derivative because 'Bool' does not conform to 'Differentiable'
1358+
var customFlag: Bool
1359+
1360+
test.swift:5:4: note: add a '@noDerivative' attribute to make it explicit
1361+
var customFlag: Bool
1362+
^
1363+
@noDerivative
1364+
1365+
test.swift:6:4: warning: synthesis of the 'Differentiable.move(along:)' requirement for 'Foo' requires all stored properties not marked with `@noDerivative` to be mutable
1366+
let helperVariable: T
1367+
1368+
test.swift:6:4: note: change 'let' to 'var' to make it mutable
1369+
let helperVariable: T
1370+
^~~
1371+
var
1372+
1373+
test.swift:6:4: note: add a '@noDerivative' attribute to make it explicit
1374+
let helperVariable: T
1375+
^
1376+
@noDerivative
1377+
```
1378+
12921379
##### Shortcut synthesis
12931380

12941381
In certain cases, it is not ideal to keep `Self` and `TangentVector` as separate

docs/README.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ documentation, please create a thread on the Swift forums under the
7777
How to build Swift on Windows using Visual Studio.
7878
- [WindowsCrossCompile.md](/docs/WindowsCrossCompile.md):
7979
How to cross compile Swift for Windows on a non-Windows host OS.
80-
- [RunningIncludeWhatYouUse.md](/docs/RunningIncludeWhatYouUse.md):
80+
- [RunningIncludeWhatYouUse.md](/docs/HowToGuides/RunningIncludeWhatYouUse.md):
8181
Describes how to run [include-what-you-use](https://include-what-you-use.org)
8282
on the Swift project.
8383

@@ -86,6 +86,8 @@ documentation, please create a thread on the Swift forums under the
8686
- [ByteTree.md](/docs/ByteTree.md):
8787
Describes the ByteTree binary format used for serializing syntax trees
8888
in `libSyntax`.
89+
- [WebAssembly.md](/docs/WebAssembly.md):
90+
Explains some decisions that were made while implementing the WebAssembly target.
8991

9092
### Compiler and Runtime Subsystems
9193

@@ -138,10 +140,11 @@ documentation, please create a thread on the Swift forums under the
138140
### Language subsystems
139141

140142
- Swift's Object Model
141-
- [LogicalObjects.md]():
143+
- [LogicalObjects.md](/docs/LogicalObjects.md):
142144
Describes the differences between logical and physical objects and
143145
introduces materialization and writeback.
144-
- [MutationModel.rst]() <!--: NOTE: Outdated -->
146+
- [MutationModel.rst](/docs/MutationModel.rst): Outdated.
147+
<!-- NOTE: Outdated -->
145148
- [DocumentationComments.md](/docs/DocumentationComments.md):
146149
Describes the format of Swift's documentation markup, including
147150
specially-recognized sections.
@@ -174,6 +177,29 @@ documentation, please create a thread on the Swift forums under the
174177
<!-- NOTE: Outdated -->
175178
- [Lexicon.md](/docs/Lexicon.md):
176179
Canonical reference for terminology used throughout the project.
180+
181+
### ABI
182+
183+
- [GenericSignature.md](/docs/ABI/GenericSignature.md):
184+
Describes what generic signatures are and how they are used in the ABI,
185+
including the algorithms for minimization and canonicalization.
186+
- [KeyPaths.md](/docs/ABI/KeyPaths.md):
187+
Describes the layout of key path objects (instantiated by the runtime,
188+
and therefore not strictly ABI). \
189+
**TODO:** The layout of key path patterns (emitted by the compiler,
190+
to represent key path literals) isn't documented yet.
191+
- [Mangling.rst](/docs/ABI/Mangling.rst):
192+
Describes the stable mangling scheme, which produces unique symbols for
193+
ABI-public declarations.
194+
- [RegisterUsage.md](/docs/ABI/RegisterUsage.md):
195+
Summarizes the register allocation for ARM64 and x86_64 calling conventions,
196+
including the context register (self) and error return register.
197+
- [TypeLayout.rst](/docs/ABI/TypeLayout.rst):
198+
Describes the algorithms/strategies for fragile struct and tuple layout;
199+
class layout; fragile enum layout; and existential container layout.
200+
- [TypeMetadata.rst](/docs/ABI/TypeMetadata.rst):
201+
Describes the fields, values, and layout of metadata records, which can be
202+
used (by reflection and debugger tools) to discover information about types.
177203

178204
## Recommended Practices
179205

@@ -188,7 +214,7 @@ documentation, please create a thread on the Swift forums under the
188214
- [StdlibAPIGuidelines.rst](/docs/StdlibAPIGuidelines.rst):
189215
Provides guidelines for designing stdlib APIs.
190216
<!-- NOTE: Outdated -->
191-
- [StandardLibraryProgrammersManual](/docs/StandardLibraryProgrammersManual.md):
217+
- [StandardLibraryProgrammersManual.md](/docs/StandardLibraryProgrammersManual.md):
192218
Provides guidelines for working code in the stdlib.
193219
- [OptimizationTips.rst](/docs/OptimizationTips.rst):
194220
Provides guidelines for writing high-performance Swift code.
@@ -199,7 +225,7 @@ documentation, please create a thread on the Swift forums under the
199225

200226
- [Branches.md](/docs/Branches.md):
201227
Describes how different branches are setup and what the automerger does.
202-
- [ContinuousIntegration.md](ContinuousIntegration.md):
228+
- [ContinuousIntegration.md](/docs/ContinuousIntegration.md):
203229
Describes the continuous integration setup, including the `@swift_ci` bot.
204230

205231
## Evolution Documents
@@ -211,9 +237,9 @@ documentation, please create a thread on the Swift forums under the
211237
Describes the goals and design for ABI stability.
212238
- [LibraryEvolutionManifesto.md](/docs/LibraryEvolutionManifesto.md):
213239
Describes the goals and design for Library Evolution.
214-
- [BuildManifesto.md](BuildManifesto.md):
240+
- [BuildManifesto.md](/docs/BuildManifesto.md):
215241
Provides an outline for modularizing the build system for the Swift toolchain.
216-
- [CppInteroperabilityManifesto.md](CppInteroperabilityManifesto.md):
242+
- [CppInteroperabilityManifesto.md](/docs/CppInteroperabilityManifesto.md):
217243
Describes the motivation and design for first-class Swift-C++ interoperability.
218244
- [DifferentiableProgramming.md](/docs/DifferentiableProgramming.md):
219245
Outlines a vision and design for first-class differentiable programming in Swift.
@@ -232,10 +258,13 @@ More recent proposals are located in the [apple/swift-evolution][] repository.
232258
You can see the status of different proposals at
233259
<https://apple.github.io/swift-evolution/>.
234260

235-
[swift-evolution]: https://github.com/apple/swift-evolution
261+
[apple/swift-evolution]: https://github.com/apple/swift-evolution
236262

237263
### Surveys
238264

265+
- [CallingConvention.rst](/docs/ABI/CallingConvention.rst):
266+
This whitepaper discusses the Swift calling convention (high-level semantics;
267+
ownership transfer; physical representation; function signature lowering).
239268
- [ErrorHandlingRationale.rst](/docs/ErrorHandlingRationale.rst):
240269
Surveys error-handling in a variety of languages, and describes the rationale
241270
behind the design of error handling in Swift.
@@ -247,10 +276,10 @@ You can see the status of different proposals at
247276
### Archive
248277

249278
These documents are known to be out-of-date and are superseded by other
250-
documentation, primarily [The Swift Programming Language (TSPL)][].
279+
documentation, primarily [The Swift Programming Language][] (TSPL).
251280
They are preserved mostly for historical interest.
252281

253-
- [AccessControl.rst](/docs/AccessControl.swift)
282+
- [AccessControl.rst](/docs/AccessControl.rst)
254283
- [Arrays.rst](/docs/Arrays.rst)
255284
<!-- Has additional notes on bridging that may be of general interest? -->
256285
- [Generics.rst](/docs/Generics.rst)
@@ -262,7 +291,7 @@ They are preserved mostly for historical interest.
262291

263292
## External Resources
264293

265-
External resources are listed in [docs/ExternalResources.md](ExternalResources.md).
294+
External resources are listed in [ExternalResources.md](/docs/ExternalResources.md).
266295
These cover a variety of topics,
267296
such as the design of different aspects of the Swift compiler and runtime
268297
and contributing to the project more effectively.
@@ -323,9 +352,9 @@ provide greater clarity to contributors wanting to add new documentation.
323352
`@_hasMissingDesignatedInitializers`. Some of this is covered in
324353
[TSPL's initialization section][] but that doesn't include newly added
325354
attributes.
326-
- [Modules.rst](/docs/Module.rst): for Swift pre-1.0.
355+
- [Modules.rst](/docs/Modules.rst): for Swift pre-1.0.
327356
- [Swift3Compatibility.md](/docs/Swift3Compatibility.md):
328357
Discusses the Swift 3 -> Swift 4 migration.
329-
- [StoredAndComputedVariables.rst](): for Swift pre-1.0.
358+
- [StoredAndComputedVariables.rst](/docs/StoredAndComputedVariables.rst): for Swift pre-1.0.
330359

331360
[TSPL's initialization section]: https://docs.swift.org/swift-book/LanguageGuide/Initialization.html

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,10 @@ void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
524524
auto resultIfaceTy = ace->getResultType()->mapTypeOutOfContext();
525525
auto captureInfo = SGM.M.Types.getLoweredLocalCaptures(
526526
SILDeclRef(ace));
527+
emitProfilerIncrement(ace);
527528
emitProlog(captureInfo, ace->getParameters(), /*selfParam=*/nullptr,
528529
ace, resultIfaceTy, ace->isBodyThrowing(), ace->getLoc());
529530
prepareEpilog(true, ace->isBodyThrowing(), CleanupLocation(ace));
530-
emitProfilerIncrement(ace);
531531
if (auto *ce = dyn_cast<ClosureExpr>(ace)) {
532532
emitStmt(ce->getBody());
533533
} else {

lib/SILOptimizer/ARC/ARCRegionState.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h"
1919
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
2020
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
21+
#include "llvm/Support/CommandLine.h"
2122
#include "llvm/Support/Debug.h"
2223

2324
using namespace swift;
2425

26+
llvm::cl::opt<bool> verifyARCLoopSummary(
27+
"verify-arc-loop-summary", llvm::cl::init(false),
28+
llvm::cl::desc("Verify if loop summary is correct in ARCLoopsOpts"));
29+
2530
//===----------------------------------------------------------------------===//
2631
// ARCRegionState
2732
//===----------------------------------------------------------------------===//
@@ -282,6 +287,18 @@ bool ARCRegionState::processLoopBottomUp(
282287
OtherState->second.checkAndResetKnownSafety(
283288
I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
284289
}
290+
#ifndef NDEBUG
291+
// Verify updateForDifferentLoopInst is conservative enough that the flow
292+
// sensitive native of the loop summarized instructions does not matter.
293+
if (verifyARCLoopSummary) {
294+
auto NewRefCountState = OtherState->second;
295+
for (auto *I : State->getSummarizedInterestingInsts()) {
296+
NewRefCountState.updateForDifferentLoopInst(I, AA);
297+
}
298+
assert(NewRefCountState.getLatticeState() ==
299+
OtherState->second.getLatticeState());
300+
}
301+
#endif
285302
}
286303

287304
return false;
@@ -420,6 +437,18 @@ bool ARCRegionState::processLoopTopDown(
420437
OtherState->second.checkAndResetKnownSafety(
421438
I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
422439
}
440+
#ifndef NDEBUG
441+
// Verify updateForDifferentLoopInst is conservative enough that the flow
442+
// sensitive native of the loop summarized instructions does not matter.
443+
if (verifyARCLoopSummary) {
444+
auto NewRefCountState = OtherState->second;
445+
for (auto *I : State->getSummarizedInterestingInsts()) {
446+
NewRefCountState.updateForDifferentLoopInst(I, AA);
447+
}
448+
assert(NewRefCountState.getLatticeState() ==
449+
OtherState->second.getLatticeState());
450+
}
451+
#endif
423452
}
424453

425454
return false;

0 commit comments

Comments
 (0)