Commit Graph

370 Commits

Author SHA1 Message Date
Dan Zheng
165af547f3 Fix SynthesizedFileUnit serialization and TBDGen issues.
Make `SynthesizedFileUnit` attached to a `SourceFile`. This seemed like the
least ad-hoc approach to avoid doing unnecessary work for other `FileUnit`s.

TBDGen: when visiting a `SourceFile`, also visit its `SynthesizedFileUnit` if
it exists.

Serialization: do not treat `SynthesizedFileUnit` declarations as xrefs when
serializing the companion `SourceFile`.

Resolves TF-1239: AutoDiff test failures.
2020-04-08 21:19:56 -07:00
Dan Zheng
2eb460de4d [AutoDiff upstream] Add forward-mode differentiation. (#30878)
JVP functions are forward-mode derivative functions. They take original
arguments and return original results and a differential function. Differential
functions take derivatives wrt arguments and return derivatives wrt results.

`JVPEmitter` is a cloner that emits JVP and differential functions at the same
time. In JVP functions, function applications are replaced with JVP function
applications. In differential functions, function applications are replaced
with differential function applications.

In JVP functions, each basic block takes a differential struct containing callee
differentials. These structs are consumed by differential functions.
2020-04-08 11:29:21 -07:00
Dan Zheng
a282ee622b [AutoDiff] NFC: silence unused variable warnings. 2020-04-08 00:10:12 -07:00
Dan Zheng
de4deb5867 [AutoDiff] Lazily create synthesized file during differentiation.
Make `ADContext` lazily create a `SynthesizedFileUnit` instead of creating one
during `ADContext` construction. This avoids always creating a
`SynthesizedFileUnit` in every module, since differentiation is a mandatory
transform that always runs.

It was nonetheless useful to test always creating a `SynthesizedFileUnit` for
testing purposes.
2020-04-07 18:45:41 -07:00
Dan Zheng
f7a9eed4de [AutoDiff] Add generated implicit declarations to SynthesizedFileUnit.
Add implicit declarations generated by the differentiation transform to a
`SynthesizedFileUnit` instead of an ad-hoc pre-existing `SourceFile`.

Resolves TF-1232: type reconstruction for AutoDiff-generated declarations.

Previously, type reconstruction failed because retroactively adding declarations
to a `SourceFile` did not update name lookup caches.
2020-04-07 18:29:34 -07:00
Dan Zheng
fe20afb917 [AutoDiff] NFC: gardening.
Remove `SILAutoDiffIndices` argument from `LinearMapInfo` methods.
Use the `SILAutoDiffIndices` stored in `LinearMapInfo` instead.
2020-04-07 11:01:00 -07:00
Dan Zheng
d93a818a37 [AutoDiff upstream] Add PullbackEmitter.
`PullbackEmitter` is a visitor that emits pullback functions. It implements
reverse-mode automatic differentiation, along with `VJPEmitter`.

Pullback functions take derivatives with respect to outputs and return
derivatives with respect to inputs. Every active value/address in an original
function has a corresponding adjoint value/buffer in the pullback function.

Pullback functions consume pullback structs and predecessor enums constructed
by VJP functions.
2020-04-05 20:35:35 -07:00
Dan Zheng
1775e8ae16 [AutoDiff upstream] Add VJPEmitter.
`VJPEmitter` is a cloner that emits VJP functions. It implements reverse-mode
automatic differentiation, along with `PullbackEmitter`.

`VJPEmitter` clones an original function, replacing function applications with
VJP function applications. In VJP functions, each basic block takes a pullback
struct (containing callee pullbacks) and produces a predecessor enum: these data
structures are consumed by pullback functions.
2020-04-05 20:35:35 -07:00
Dan Zheng
fa405e69c4 [AutoDiff upstream] Add LinearMapInfo.
`LinearMapInfo` contains information about linear map structs and branching
trace enums, which are auxiliary data structures created by the differentiation
transform.

These data structures are constructed in JVP/VJP functions and consumed in
differential/pullback functions.
2020-04-05 20:35:35 -07:00
Dan Zheng
9e28e0a8c4 [AutoDiff upstream] Add AdjointValue.
Add `AdjointValue`: a symbolic representation for adjoint values enabling
efficient differentiation by avoiding zero materialization.
2020-04-05 20:35:35 -07:00
Dan Zheng
55ac2c0e46 [AutoDiff upstream] Add common differentiation thunking utilities. 2020-04-05 20:35:35 -07:00
Dan Zheng
8081482b57 [AutoDiff upstream] Add common SIL differentiation utilities. 2020-04-05 20:35:35 -07:00
Dan Zheng
146c11ec80 [AutoDiff upstream] Add differentiable_function canonicalization. (#30818)
Canonicalizes `differentiable_function` instructions by filling in missing
derivative function operands.

Derivative function emission rules, based on the original function value:

- `function_ref`: look up differentiability witness with the exact or a minimal
  superset derivative configuration. Emit a `differentiability_witness_function`
  for the derivative function.
- `witness_method`: emit a `witness_method` with the minimal superset derivative
  configuration for the derivative function.
- `class_method`: emit a `class_method` with the minimal superset derivative
  configuration for the derivative function.

If an *actual* emitted derivative function has a superset derivative
configuration versus the *desired* derivative configuration, create a "subset
parameters thunk" to thunk the actual derivative to the desired type.

For `differentiable_function` instructions formed from curry thunk applications:
clone the curry thunk (with type `(Self) -> (T, ...) -> U`) and create a new
version with type `(Self) -> @differentiable (T, ...) -> U`.

Progress towards TF-1211.
2020-04-05 20:19:10 -07:00
Dan Zheng
aa66cce808 [AutoDiff upstream] Add differentiation transform.
The differentiation transform does the following:
- Canonicalizes differentiability witnesses by filling in missing derivative
  function entries.
- Canonicalizes `differentiable_function` instructions by filling in missing
  derivative function operands.
- If necessary, performs automatic differentiation: generating derivative
  functions for original functions.
  - When encountering non-differentiability code, produces a diagnostic and
    errors out.

Partially resolves TF-1211: add the main canonicalization loop.

To incrementally stage changes, derivative functions are currently created
with empty bodies that fatal error with a nice message.

Derivative emitters will be upstreamed separately.
2020-04-02 15:43:57 -07:00
Suyash Srijan
f724d1ff85 [SE-0280] Enum cases as protocol witnesses (#28916)
* [Typechecker] Allow enum cases without payload to witness a static get-only property with Self type protocol requirement

* [SIL] Add support for payload cases as well

* [SILGen] Clean up comment

* [Typechecker] Re-enable some previously disabled witness matching code

Also properly handle the matching in some cases

* [Test] Update typechecker tests with payload enum test cases

* [Test] Update SILGen test

* [SIL] Add two FIXME's to address soon

* [SIL] Emit the enum case constructor unconditionally when an enum case is used as a witness

Also, tweak SILDeclRef::getLinkage to update the 'limit' to 'OnDemand' if we have an enum declaration

* [SILGen] Properly handle a enum witness in addMethodImplementation

Also remove a FIXME and code added to workaround the original bug

* [TBDGen] Handle enum case witness

* [Typechecker] Fix conflicts

* [Test] Fix tests

* [AST] Fix indentation in diagnostics def file
2020-03-28 10:44:01 +00:00
Andrew Trick
70678ab856 SILOptimizer: Fix analysis invalidation after devirtualization.
Devirtualizing try_apply modified the CFG, but passes that run
devirtualization were not invalidating any CFG analyses, such as the
domtree.

This could hypothetically have caused miscompilation, but will be
caught by running with -sil-verify-all.
2020-03-18 10:21:35 -07:00
Andrew Trick
ca686a58ec Merge pull request #30414 from atrick/fix-escape-unreachable
Fix EscapeAnalysis verification assert at unreachable blocks
2020-03-14 17:53:09 -07:00
Andrew Trick
bebbe370e8 Fix EscapeAnalysis verification assert at unreachable blocks
If EscapeAnalysis verification runs on unreachable code, it asserts
with "Missing escape connection graph mapping" because the connection
graph builder only runs on reachable blocks.

Add a ReachableBlocks utility and use it during verification.

Fixes <rdar://problem/60373501> EscapeAnalysis crashes with CFG with
unreachable blocks
2020-03-14 14:31:41 -07:00
Meghana Gupta
8e800e49bf Recommit #29812 with fixes (#30342) 2020-03-13 19:34:16 -07:00
Michael Gottesman
e3f2bb74d2 [inliner] Add a new Inliner that only inlines AlwaysInline functions (but do not put it in the pass pipeline).
We need this anyways for -Onone and I want to do some experiments with running
this very early so I can expose more of the stdlib (modulo inlining) to the new
ownership optimizing passes.

I also changed how the inliner handles inlining around OSSA by changing it to
check early that if the caller is in ossa, then we only inline if all of the
callees that the caller calls are in ossa. The intention is to hopefully avoid
weird swings in code-size/perf due to the inliner heuristic's calculation being
artificially manipulated due to some callees not being available to inline (due
to this difference) when others are already available.
2020-03-10 19:53:18 -07:00
Michael Gottesman
621573e839 [semantic-arc-opts] Refactor out convert to guarantee code into a method on LiveRange.
Should be NFC.

I am doing this since when I am eliminating phi webs, I need this exact
functionality.
2020-03-05 11:49:36 -08:00
eeckstein
7b2c8f1c87 Merge pull request #30074 from eeckstein/globalopt
GlobalOpt: improvements for constant folding global variables
2020-02-27 08:30:12 +01:00
Erik Eckstein
43e8b07e3f GlobalOpt: improvements for constant folding global variables
* Simplified the logic for creating static initializers and constant folding for global variables: instead of creating a getter function, directly inline the constant value into the use-sites.
* Wired up the constant folder in GlobalOpt, so that a chains for global variables can be propagated, e.g.

  let a = 1
  let b = a + 10
  let c = b + 5

* Fixed a problem where we didn't create a static initializer if a global is not used in the same module. E.g. a public let variable.
* Simplified the code in general.

rdar://problem/31515927
2020-02-26 17:35:05 +01:00
Jonathan Keller
620fba6a1f [SILOptimizer] fix KeyPathProjector memory management
I was inconsistently providing initialized or uninitialized memory
to the callback when projecting a settable address, depending on
component type. We should always provide an uninitialized address.
2020-02-21 15:34:17 -08:00
Jonathan Keller
44d211fa17 [SILOptimizer] Generalize optimization of static keypaths
We have an optimization in SILCombiner that "inlines" the use of compile-time constant key paths by performing the property access directly instead of calling a runtime function (leading to huge performance gains e.g. for heavy use of @dynamicMemberLookup). However, this optimization previously only supported key paths which solely access stored properties, so computed properties, optional chaining, etc. still had to call a runtime function. This commit generalizes the optimization to support all types of key paths.
2020-02-21 15:34:17 -08:00
Joe Groff
f353c40ce9 Revert "[SILOptimizer] Generalize optimization of static keypaths" 2020-02-19 19:58:15 -08:00
Joe Groff
14cda1a472 Merge pull request #28799 from NobodyNada/master
[SILOptimizer] Generalize optimization of static keypaths
2020-02-18 13:28:05 -08:00
Michael Gottesman
b44fbaeb87 [sil] Use FrozenMultiMap in PredictableMemOpts instead of implementing the data structure by hand. 2020-02-17 17:07:33 -08:00
Jonathan Keller
1feead804b [SILOptimizer] fix KeyPathProjector memory management
I was inconsistently providing initialized or uninitialized memory
to the callback when projecting a settable address, depending on
component type. We should always provide an uninitialized address.
2020-02-15 15:10:25 -08:00
Erik Eckstein
40e5955193 SILOptimizer: rename needUpdateStackNesting (and similar) -> invalidatedStackNesting
NFC
2020-02-11 18:26:04 +01:00
Erik Eckstein
85789367a3 SILOptimizer: restructure the apply(partial_apply) peephole and the dead partial_apply elimination optimizations
Changes:

* Allow optimizing partial_apply capturing opened existential: we didn't do this originally because it was complicated to insert the required alloc/dealloc_stack instructions at the right places. Now we have the StackNesting utility, which makes this easier.

* Support indirect-in parameters. Not super important, but why not? It's also easy to do with the StackNesting utility.

* Share code between dead closure elimination and the apply(partial_apply) optimization. It's a bit of refactoring and allowed to eliminate some code which is not used anymore.

* Fix an ownership problem: We inserted copies of partial_apply arguments _after_ the partial_apply (which consumes the arguments).

* When replacing an apply(partial_apply) -> apply and the partial_apply becomes dead, avoid inserting copies of the arguments twice.

These changes don't have any immediate effect on our current benchmarks, but will allow eliminating curry thunks for existentials.
2020-02-11 12:48:39 +01:00
swift-ci
e7e6d27ac9 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-02-08 10:24:29 -08:00
Ravi Kandhadai
ec9844b2d9 [SIL Optimization] Add a new mandatory pass for unrolling forEach
calls over arrays created from array literals. This enables optimizing
further the output of the OSLogOptimization pass, and results in
highly-compact and optimized IR for calls to the new os log API.

<rdar://58928427>
2020-02-07 20:06:29 -08:00
swift-ci
afad2f3018 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-01-24 23:44:18 -08:00
Ravi Kandhadai
a12fe9ae3b [SIL Optimization] Fix a bug in the identification of dead constant
evaluable calls. The fix makes the check more conservative and
assumes that calls with generic arguments are not dead, as generic
functions with arbitrary side-effects can be invoked through them.

Also, add a few helper functions to the InstructionDeleter utility
that will enable deleting an instruction along with its users.
2020-01-24 19:00:16 -08:00
swift_jenkins
47af5bcec0 Merge remote-tracking branch 'origin/master' into master-next 2019-12-18 17:39:43 -08:00
Ravi Kandhadai
935686460c [SIL Optimization] Create a new utility InstructionDeleter to delete instructions
and eliminate dead code. This is meant to be a replacement for the utility:
recursivelyDeleteTriviallyDeadInstructions. The new utility performs more aggresive
dead-code elimination for ownership SIL.

This patch also migrates most non-force-delete uses of
recursivelyDeleteTriviallyDeadInstructions to the new utility.
and migrates one force-delete use of recursivelyDeleteTriviallyDeadInstructions
(in IRGenPrepare) to use the new utility.
2019-12-18 13:17:17 -08:00
Jonathan Keller
e1ceb4f437 [SILOptimizer] Generalize optimization of static keypaths
We have an optimization in SILCombiner that "inlines" the use of compile-time constant key paths by performing the property access directly instead of calling a runtime function (leading to huge performance gains e.g. for heavy use of @dynamicMemberLookup). However, this optimization previously only supported key paths which solely access stored properties, so computed properties, optional chaining, etc. still had to call a runtime function. This commit generalizes the optimization to support all types of key paths.
2019-12-15 14:10:00 -08:00
swift_jenkins
f048d4cd19 Merge remote-tracking branch 'origin/master' into master-next 2019-12-13 04:40:04 -08:00
Erik Eckstein
4017570de7 Generic Specializer: Use getResilienceExpansion() throughout ReabstractionInfo
It must be consistent, otherwise the specialized function types may not match for calls in functions with different resilience expansions.

Fixes an assertion crash in the generic specializer.

rdar://problem/57844964
2019-12-13 11:15:38 +01:00
swift_jenkins
1fba729d62 Merge remote-tracking branch 'origin/master' into master-next 2019-12-11 18:40:34 -08:00
Michael Gottesman
113c22a680 [sil] Move partial apply combiner code from SILCombiner into InstOptUtils.h/SILCombinerApplyVisitor.cpp.
This is in preparation for moving this into the mandatory combiner.
2019-12-11 14:48:19 -08:00
Joe Groff
fb34044408 Merge remote-tracking branch 'origin/master' into master-next 2019-12-10 12:46:41 -08:00
Erik Eckstein
402e228b39 SIL: add a table in SILModule to mark method declarations as externally visible.
This is needed for cross-module-optimization: CMO marks functions as inlinable. If a private or internal method is referenced from such an inlinable function, it must not be eliminated by dead function elimination after serialization (a method is basically an AbstractFunctionDecl).
For SILFunctions we can do this by simply setting the linkage, but for methods we need another mechanism.
2019-12-03 14:37:01 +01:00
Jonas Devlieghere
027b8659f2 Add missing include for llvm::cl::opt
Include  "llvm/Support/CommandLine.h" for cl::opt.
2019-11-18 09:57:03 -08:00
Andrew Trick
38c29e231e Generalize and fix SinkAddressProjections.
Fixes a potential real bug in the case that SinkAddressProjections moves
projections without notifying SimplifyCFG of the change. This could
fail to update Analyses (probably won't break anything in practice).

Introduce SILInstruction::isPure. Among other things, this can tell
you if it's safe to duplicate instructions at their
uses. SinkAddressProjections should check this before sinking uses. I
couldn't find a way to expose this as a real bug, but it is a
theoretical bug.

Add the SinkAddressProjections functionality to the BasicBlockCloner
utility. Enable address projection sinking for all BasicBlockCloner
clients (the four different kinds of jump-threading that use it). This
brings the compiler much closer to banning all address phis.

The "bugs" were originally introduced a week ago here:

commit f22371bf0b (fork/fix-address-phi, fix-address-phi)
Author: Andrew Trick <atrick@apple.com>
Date:   Tue Sep 17 16:45:51 2019

    Add SIL SinkAddressProjections utility to avoid address phis.

    Enable this utility during jump-threading in SimplifyCFG.

    Ultimately, the SIL verifier should prevent all address-phis and we'll
    need to use this utility in a few more places.

    Fixes <rdar://problem/55320867> SIL verification failed: Unknown
    formal access pattern: storage
2019-11-14 16:11:00 -08:00
Arnold Schwaighofer
8aaa7b4dc1 SILOptimizer: Pipe through TypeExpansionContext 2019-11-11 14:21:52 -08:00
Robert Widmann
5f3b1da22a Merge pull request #27949 from CodaFi/protoplasmic-supine-jellies
[NFC] Fold The Tri-State In Optional<ProtocolConformanceRef>
2019-10-30 07:47:17 -07:00
Ravi Kandhadai
861c0aaca9 [OSLogOptimization][stdlib/private] Make string interpolation methods
of OSLogMessage constant evaluable and remove @_transparent annotation
from the methods. Also, improve diagnostics in the OSLogOptimization
pass as now it rely on seeing the appendInterpolation/Literal calls.
2019-10-29 19:35:37 -07:00
Robert Widmann
3e1a61f425 [NFC] Fold The Tri-State In Optional<ProtocolConformanceRef>
ProtocolConformanceRef already has an invalid state.  Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it.  Mechanically
translate all of the callers and callsites to use this new
representation.
2019-10-29 16:55:56 -07:00