Commit Graph

882 Commits

Author SHA1 Message Date
swift-ci
3ae2e04c28 Merge pull request #31445 from zoecarver/fix/escape-state-public 2020-04-30 18:10:38 -07:00
zoecarver
c733ca1419 [NFC] Make EscapeState a public member of EscapeAnalysis.
Makes EscapeAnalysis::EscapeState public. This allows EscapeAnalysis::getEscapeState to be used outside of EscapeAnalysis.
2020-04-30 10:36:10 -07:00
Meghana Gupta
013387eceb Update Devirtualizer's analysis invalidation (#31284)
* Update Devirtualizer's analysis invalidation

castValueToABICompatibleType can change CFG, Devirtualizer uses this api but doesn't check if it modified the cfg
2020-04-27 18:30:33 -07:00
Saleem Abdulrasool
618ced846b Merge pull request #31310 from compnerd/unreachable
sprinkle some `llvm_unreachable` for MSVC (NFC)
2020-04-25 09:44:39 -07:00
Saleem Abdulrasool
fa46f7131c sprinkle some llvm_unreachable for MSVC (NFC)
MSVC does not realize that the switch is exhaustive and requires that
the path is explicitly marked as unreachable.  This silences the C4715
warning ("not all control paths return a value").
2020-04-24 18:59:07 -07:00
swift-ci
0f892b671f Merge pull request #31274 from meg-gupta/cherrypickflag 2020-04-24 12:33:50 -07:00
Michael Gottesman
46703b4ba1 Merge pull request #31261 from gottesmm/pr-f32ad796de54eea8dcf9d5c8440c50b4be632251
[sil-combine] Refactor rewriteApplyCallee -> cloneFullApplySiteReplacingCallee and move into InstOptUtils.h.
2020-04-24 11:43:57 -07:00
Meghana Gupta
6c3857b6d6 Add forced precomputation and verification of analysis (#31251)
-sil-verify-all flag will verify analyses before and after a pass to
confirm correct invalidations. But if an analysis was never
constructed or invalidated as per current pass order,
it may never detect insufficient invalidations.

-sil-verify-force-analysis will force construct an analysis so that we
can better check for insufficient invalidations.
It is also terribly slow compared to -sil-verify-all.
2020-04-24 10:55:45 -07:00
Erik Eckstein
53f6fdadc6 SILOptimizer: reorganize the optimization-prepare passpipeline
Don't create a separate pass manager for those passes, just let them run at the beginning of the performance pipeline.
Regarding generated code this is a NFC.

This change fixes a problem with pass-bisecting (for debugging). Having two instances of the pass manager can cause troubles with bisecting, because -sil-opt-pass-count affects both pass managers at the same time.
2020-04-24 15:48:48 +02:00
Michael Gottesman
c3fb485c7d [sil-combine] Refactor rewriteApplyCallee -> cloneFullApplySiteReplacingCallee and move into InstOptUtils.h.
I am going to use this in mandatory combine, and it seems like a generally
useful transformation.

I also updated the routine to construct its own SILBuilder that injects a user
passed in SILBuilderContext eliminating the bad pattern of passing in
SILBuilders.

This should be an NFC change.
2020-04-23 20:33:14 -07:00
ematejska
4cd68edf8c [Autodiff upstream] Add DifferentiabilityWitnessDevirtualizer SILOptimizer pass (#30984)
Add DifferentiabilityWitnessDevirtualizer: an optimization pass that
devirtualizes `differentiability_witness_function` instructions into
`function_ref` instructions.

Co-authored-by: Dan Zheng <danielzheng@google.com>
2020-04-23 02:13:05 -07:00
Erik Eckstein
fd6c26e948 EscapeAnalysis: don't compute the connection graph for very large functions
For functions which results in > 10000 nodes, just bail and don't compute the connection graph.
The node merging algorithm is quadratic and can result in significant compile times for very large functions.

rdar://problem/56268570
2020-04-10 20:10:24 +02:00
Erik Eckstein
f33c2ade1d EscapeAnalysis: remove an unused parameter from canOptimizeArrayUninitializedCall
NFC
2020-04-10 20:10:24 +02:00
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
bb6d4ebd9f [AutoDiff upstream] Add differentiable activity analysis.
Differentiable activity analysis is a dataflow analysis which marks values in
a function as varied, useful, or active (both varied and useful).

Only active values need a derivative.
2020-04-05 20:35:30 -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
Erik Eckstein
93a0dfc578 SILOptimizer: a new small optimization pass to remove redundant basic block arguments.
RedundantPhiElimination eliminates block phi-arguments which have the same value as other arguments of the same block.
This also works with cycles, like two equivalent loop induction variables. Such patterns are generated e.g. when using stdlib's enumerated() on Array.

   preheader:
     br bb1(%initval, %initval)
   header(%phi1, %phi2):
     %next1 = builtin "add" (%phi1, %one)
     %next2 = builtin "add" (%phi2, %one)
     cond_br %loopcond, header(%next1, %next2), exit
   exit:

is replaced with

   preheader:
     br bb1(%initval)
   header(%phi1):
     %next1 = builtin "add" (%phi1, %one)
     %next2 = builtin "add" (%phi1, %one) // dead: will be cleaned-up later
     cond_br %loopcond, header(%next1), exit
   exit:

Any remaining dead or "trivially" equivalent instructions will then be cleaned-up by DCE and CSE, respectively.

rdar://problem/33438123
2020-03-26 19:30:01 +01:00
Andrew Trick
991a8dc31b Add getArraySemanticsKind API.
So that it's possible to determine the kind of Array semantic function
from its SILFunction decl only.
2020-03-18 18:19:10 -07: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
Hamish Knight
e9a7427712 [SILOptimizer] Add pipeline execution request (#29552)
[SILOptimizer] Add pipeline execution request
2020-03-03 20:24:28 -08:00
Andrew Trick
badc5658bb Fix SIL MemBehavior queries with access markers.
This is in prepration for other bug fixes.

Clarify the SIL utilities that return canonical address values for
formal access given the address used by some memory operation:

- stripAccessMarkers
- getAddressAccess
- getAccessedAddress

These are closely related to the code in MemAccessUtils.

Make sure passes use these utilities consistently so that
optimizations aren't defeated by normal variations in SIL patterns.

Create an isLetAddress() utility alongside these basic utilities to
make sure it is used consistently with the address corresponding to
formal access. When this query is used inconsistently, it defeats
optimization. It can also cause correctness bugs because some
optimizations assume that 'let' initialization is only performed on a
unique address value.

Functional changes to Memory Behavior:

- An instruction with side effects now conservatively still has side
  effects even when the queried value is a 'let'. Let values are
  certainly sensitive to side effects, such as the parent object being
  deallocated.

- Return the correct MemBehavior for begin/end_access markers.
2020-03-03 09:24:18 -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
Hamish Knight
13217b600c [SILOptimizer] Add pipeline execution request
Add ExecuteSILPipelineRequest which executes a
pipeline plan on a given SIL (and possibly IRGen)
module. This serves as a top-level request for
the SILOptimizer that we'll be able to hang
dependencies off.
2020-02-14 09:58:32 -08:00
Hamish Knight
54629e1538 [SILOptimizer] Remove Stage param from SILPassManager
The value of this parameter doesn't appear to be
used for anything, as it gets immediately
overwritten by the pipeline stage name.
2020-02-14 09:57:27 -08:00
Hamish Knight
13bfac1820 Register IRGen SIL passes with the ASTContext
Rather than registering individual IRGen passes
when we want to execute them, store function
pointers to all the pass constructors on the
ASTContext. This will make it easier to requestify
the execution of pass pipelines.
2020-02-14 09:57:27 -08:00