Commit Graph

1020 Commits

Author SHA1 Message Date
Andrew Trick
f4c7d4611f Change the algorithm for the AccessEnforcementDom pass.
This adds a mostly flow-insensitive analysis that runs before the
dominator-based transformations. The analysis is simple and efficient
because it only needs to track data flow of currently in-scope
accesses. The original dominator tree walk remains simple, but it now
checks the flow insensitive analysis information to determine general
correctness. This is now correct in the presence of all kinds of nested
static and dynamic nested accesses, call sites, coroutines, etc.

This is a better compromise than:

(a) disabling the pass and taking a major performance loss.

(b) converting the pass itself to full-fledged data flow driven
optimization, which would be more optimal because it could remove
accesses when nesting is involved, but would be much more expensive
and complicated, and there's no indication that it's useful.

The new approach is also simpler than adding more complexity to
independently handle to each of many issues:

- Nested reads followed by a modify without a false conflict.
- Reads nested within a function call without a false conflict.
- Conflicts nested within a function call without dropping enforcement.
- Accesses within a generalized accessor.
- Conservative treatment of invalid storage locations.
- Conservative treatment of unknown apply callee.
- General analysis invalidation.

Some of these issues also needed to be considered in the
LoopDominatingAccess sub-pass. Rather than fix that sub-pass, I just
integrated it into the main pass. This is a simplification, is more
efficient, and also handles nested loops without creating more
redundant accesses. It is also generalized to:
- hoist non-uniquely identified accesses.
- Avoid unnecessarily promoting accesses inside the loop.

With this approach we can remove the scary warnings and caveats in the
comments.

While doing this I also took the opportunity to eliminate quadratic
behavior, make the domtree walk non-recursive, and eliminate cutoff
thresholds.

Note that simple nested dynamic reads to identical storage could very
easily be removed via separate logic, but it does not fit with the
dominator-based algorithm. For example, during the analysis phase, we
could simply mark the "fully nested" read scopes, then convert them to
[static] right after the analysis, removing them from the result
map. I didn't do this because I don't know if it happens in practice.
2019-03-07 12:39:53 -08:00
Slava Pestov
5847e163c1 SIL: Use better type lowering APIs in a couple of spots 2019-03-05 20:59:58 -05:00
Ravi Kandhadai
6c662f7a6c [stdlib][Semantics annotation] Add ".empty" suffix to the semantics attribute of
array.init() and add semantics annotation to the compiler-intrinsic:
Array._allocateUninitializedArray
2019-03-05 17:09:34 -08:00
Andrew Trick
eda86d03eb Merge pull request #22962 from atrick/remove-keypath-attr
Remove references to the unused "keypath.entry" attribute.
2019-03-05 13:15:05 -08:00
Arnold Schwaighofer
6948319f5e Merge pull request #22996 from aschwaighofer/simplify_switch_enum_objc_optionals
SimplifyCFG: Simplify switch_enum on optional classes used by objc method calls
2019-03-04 14:09:19 -08:00
Arnold Schwaighofer
e2a5ddf7a3 Merge pull request #22727 from aschwaighofer/mem2reg_unchecked_addr_cast
SILMem2Reg: Allow uncheck_addr_cast 'projections'
2019-03-04 10:26:54 -08:00
Slava Pestov
7b0d10e2c7 Merge pull request #23004 from slavapestov/sil-resilience-expansion-plumbing
Continue plumbing resilience expansion through SIL type lowering
2019-03-01 07:32:01 -05:00
Slava Pestov
112d1bd561 SILOptimizer: Small cleanups for devirtualizer
Where possible, pass around a ClassDecl or a CanType instead of a
SILType that might wrap a metatype; the unwrapping logic was
repeated in several places.

Also add a FIXME for a bug I found by inspection.
2019-02-28 22:40:54 -05:00
Slava Pestov
c970caedd5 SIL: Optimization remarks can take SILType by value
No need to pass a pointer to SILType; it is a pointer-sized value itself.
2019-02-28 21:28:16 -05:00
Erik Eckstein
4acffab173 SILOptimizer: fix a crash in ArrayElementValuePropagation.
This optimization is doing 2 things: replacing getElement calls and replacing append(contentOf:) calls.
Now if the argument to a append(contentOf:) is a previously replaced getElement call, we ended up in a use-after-free crash.

The main change here is to do the transformations immediately after gathering the data (and that means: separately) and not collecting all the data and do both transformation afterwards
The pass does not use any Analysis (where invalidation could be a problem). Also iterator invalidation is not a problem here.

SR-10003
rdar://problem/48445856
2019-02-28 14:38:45 -08:00
Arnold Schwaighofer
5298f81249 SimplifyCFG: Simplify switch_enum on optional classes used by objc method calls
In the statement

  optional1?.objc_setter = optional2?.objc_getter?.objc_getter

we can eliminate all optional switches expect for the first switch on
optional1. We must only execute the setter if optional1 has some value.

We can simplify the following switch_enum with a branch as long all
sideffecting instructions in someBB are objc_method calls on the
optional payload or on another objc_method call that transitively uses
the payload.

 switch_enum %optionalValue, case #Optional.some!enumelt.1: someBB,
                             case #Optional.none: noneBB

 someBB(%optionalPayload):
    %1 = objc_method %optionalPayload
    %2 = apply %1(..., %optionalPayload) // self position
    br mergeBB(%2)

 noneBB:
    %4 = enum #Optional.none
    br mergeBB(%4)

rdar://48007302
2019-02-28 13:39:25 -08:00
Andrew Trick
1256f82c4c Remove references to the unused "keypath.entry" attribute. 2019-02-27 13:40:55 -08:00
Joe Groff
bb67cf815c Merge pull request #21355 from technicated/tuple-keypaths-2
Tuple KeyPaths
2019-02-25 12:56:05 -08:00
Joe Shajrawi
dbbac8dca7 Merge pull request #22838 from shajrawi/access_dom_nested
DominatedAccessRemoval: fix a bug wherein we incorrectly removes nested conflicting accesses
2019-02-23 00:41:50 -08:00
Joe Shajrawi
a4f7d01c38 AccessEnforcementOpts: Fix a bug that caused a compiler assert when dealing with nested scopes
radar rdar://problem/48318054
2019-02-22 17:29:32 -08:00
Joe Shajrawi
97b85018ce DominatedAccessRemoval: fix a bug wherein we incorrectly removes nested conflicting accesses
radar rdar://problem/48323041
2019-02-22 16:49:52 -08:00
Andrew Trick
30994389f2 Disable merging of read/modify exclusivity access markers.
When two access scopes have different access types, it is not safe to
merge them into one access. Doing so will introduce false conflicts
which manifest as crashes in user code.

To do this optimization, we would need additional data flow information
about *potential* read conflicts before converting a read to a modify
access.

Fixes rdar://48239213: Fatal access conflict detected.
2019-02-21 13:05:20 -08:00
Arnold Schwaighofer
c15f489d75 SILMem2Reg: Allow uncheck_addr_cast 'projections' 2019-02-19 15:01:30 -08:00
Andrea Tomarelli
aab138dcea Barebone implementation of TupleElement in SIL 2019-02-18 09:04:42 +01:00
Michael Gottesman
d0ca07b444 [perf-inliner] Do not inline non-ossa funcs into ossa transparent funcs.
This is a temporary restriction for this round of ownership work until I update
the perf pipeline for ownership.
2019-02-11 14:42:46 -08:00
swift-ci
3f54a46bfe Merge pull request #22506 from gottesmm/pr-1976b9749f89a8476a3c2744d1c8e2a758c40fdf 2019-02-11 12:37:08 -08:00
Michael Gottesman
89a447a3de [ownership] When splitting destructures, simplify the instruction if possible.
I noticed that this is needed at -Onone to maintain the same codegen output.
2019-02-11 11:52:52 -08:00
Michael Gottesman
cec2b989c1 [ownership] When transforming destructures => projections, only create projections for used results.
This is not technically necessary, but it eliminates some differences in the
tests at -Onone.
2019-02-10 22:46:25 -08:00
Michael Gottesman
5d94489094 [ownership] Disable SILCodeMotion on ossa SIL.
I missed this during my first go through of the SILOptimizer passes.
2019-02-10 22:02:33 -08:00
Joe Shajrawi
6236fd5ffd Fix typo in PerformanceInliner 2019-02-05 14:51:26 -08:00
Michael Gottesman
21e51edfad [cast-opt] Allow users to pass in a SILBuilderContext to the CastOptimizer.
NOTE: I changed all places that the CastOptimizer is created to just pass in
nullptr for now so this is NFC.

----

Right now the interface of the CastOptimizer is muddled and confused. Sometimes
it is returning a value that should be used by the caller, other times it is
returning an instruction that is meant to be reprocessed by the caller.

This series of patches is attempting to clean this up by switching to the
following model:

1. If we are optimizing a cast of a value, we return a SILValue. If the cast
fails, we return an empty SILValue().

2. If we are optimizing a cast of an address, we return a boolean value to show
success/failure and require the user to use the SILBuilderContext to get the
cast if they need to.
2019-02-04 12:59:44 -08:00
Michael Gottesman
a5b47e127d [cast-opt] Add a new callback: ReplaceValueUsesAction.
This is the first in a series of patches to update the cast optimizer for
ownership and multiple value instructions.

This specific patch is NFC.
2019-02-04 11:26:46 -08:00
Andrew Trick
7176aaf8ea Add a comment to TempRValue optimization.
A recent fix added some code that is inconsistent with the design of
the pass, creates an implicit coupling between separate parts of the
optimization, and relies on incredibly subtle reasoning to ensure
correctness.

This sort of thing needs a big fat comment.
2019-02-03 14:16:31 -08:00
Erik Eckstein
767ad5e70a Inliner: fix a stack nesting problem when inlining coroutines
Beside fixing the compiler crash, this change also improves the stack-nesting correction mechanisms in the inliners:

* Instead of trying to correct the nesting after each inlining of a callee, correct the nesting once when inlining is finished for a caller function.
This fixes a potential compile time problem, because StackNesting iterates over the whole function.
In worst case this can lead to quadratic behavior in case many begin_apply instructions with overlapping stack locations are inlined.

* Because we are doing it only once for a caller, we can remove the complex logic for checking if it is necessary.
We can just do it unconditionally in case any coroutine gets inlined.
The inliners iterate over all instruction of a function anyway, so this does not increase the computational complexity (StackNesting is roughly linear with the number of instructions).

rdar://problem/47615442
2019-02-01 08:32:19 -08:00
Michael Gottesman
85ef0b2340 [ownership] Once we strip ownership ignoring transparent functions from our module, strip ownership as we serialize. 2019-01-31 15:45:38 -08:00
Michael Gottesman
aa4d406d57 Merge pull request #22264 from gottesmm/pr-1eb3e90eae662c1a6cff4fe226e620212a0497b9
[ownership] Add a specialized version of ome that skips transparent f…
2019-01-31 14:49:32 -08:00
Michael Gottesman
d78e83c010 [ownership] Do some preliminary work for moving OME out of the diagnostics pipeline.
This disables a bunch of passes when ownership is enabled. This will allow me to
keep transparent functions in ossa and skip most of the performance pipeline without
being touched by passes that have not been updated for ownership.

This is important so that we can in -Onone code import transparent functions and
inline them into other ossa functions (you can't inline from ossa => non-ossa).
2019-01-31 13:38:05 -08:00
Michael Gottesman
1375dd0a62 [ownership] Add a specialized version of ome that skips transparent functions.
This will let me strip ownership from non-transparent functions at the beginning
of the perf pipeline. Then after we serialize, I will run OME on the transparent
functions. Otherwise, we can not perform mandatory inlining successfully since
we can not inline ossa into non-ossa functions.
2019-01-31 00:27:08 -08:00
Erik Eckstein
f0eed8c409 SILOptimizer: fix a bug in the TempRValue optimization which causes a miscompile.
The problematic scenario is that a function receives an @in_guaranteed and @inout parameter where one is a copy of the other value. For example, when appending a container to itself.
In this case the optimization removed the copy_addr, resulting in passing the same stack location to both parameters.

rdar://problem/47632890
2019-01-30 12:38:10 -08:00
Michael Gottesman
f386dd0b6d [ome] Run even on deserialized functions.
This is needed since we are going to start eliminating ownership after SIL is
serialized. So we need to make sure that we strip those as well.

In terms of compile time, this shouldn't have much of an effect since we already
skip functions that already have ownership stripped.
2019-01-29 08:46:01 -08:00
Arnold Schwaighofer
ccbf25b0a2 Merge pull request #21933 from aschwaighofer/partial_apply_stack
Use stack allocation for Swift closures
2019-01-18 10:35:46 -08:00
Arnold Schwaighofer
b6f91292bf We can only eliminate dealloc_stack in an unreachable block if we can eliminate all dealloc_stack instructions in the block 2019-01-17 15:30:07 -08:00
Arnold Schwaighofer
a0b67c622d SimplifyCFG: It is okay to ignore dealloc_stack to simplify an unreachable block 2019-01-16 14:01:42 -08:00
Joe Shajrawi
18e9256e94 [PerformanceInliner] Reduce the code size impact of the exclusivity heuristic 2019-01-15 16:19:31 -08:00
Andrew Trick
5b424694c5 Reduce compile time for large strongly connected call graphs.
Improves SwiftSyntax release build speed by 4x.

Limit the size of the sets tracked by inter procedural
AccessedStorageAnalysis. There is a lot of leeway in this limit since
"normal" code doesn't come close to hitting it and SwiftSyntax compile
time isn't noticeably affected until 10x this limit.

This change also avoids reanalyzing function bodies once results have
bottomed out and avoids copying sets in the common case.

Fixes <rdar://problem/46905624> Release build time regression, a lot of time spent on AccessEnforcementOpts::run().

This is just a band aid. The fundamental problem is really:
<rdar://problem/47195282> Recomputing BottomUpIPAnalysis takes most of
the SwiftSyntax compile time.

SwiftSyntax compile time is still at least an order of magnitude
longer than it should be.
2019-01-10 16:31:08 -08:00
swift-ci
7708e25429 Merge pull request #21710 from aschwaighofer/outliner_fix_open_existential 2019-01-08 14:17:37 -08:00
Michael Gottesman
5d157c55e9 [ome] Make sure to skip functions that do not have ownership.
This is not an actual bug since given where OME is in the pipeline today it will
only process ossa functions. But philosophically this is the right thing to do.
2019-01-08 12:45:12 -08:00
Arnold Schwaighofer
50cac1d081 Outliner: We don't support calls with opened existentials
rdar://47099026
2019-01-08 11:41:50 -08:00
Joe Shajrawi
5195e792e9 [Exclusivity] Change the exclusivity checks inline heuristic threshold 2019-01-04 14:05:23 -08:00
Michael Gottesman
23378cc16f [sil] Rename QualifiedOwnership => Ownership.
Done using Xcode's refactoring engine.
2018-12-16 15:21:52 -08:00
Erik Eckstein
36d3311c9a DeadObjectElimination: enable removal of dead alloc_stack locations which contain a non-payload resilient enum case
If the enum does not have a payload, i.e. there is no init_enum_data_addr involved, we can remove the alloc_stack (if there is no read from it).
2018-12-10 16:14:15 -08:00
Michael Gottesman
f38b782145 [ome] Add an option sil-dump-before-ome-to-path to dump the current module to a path before stripping ownership.
This will simplify analyzing SIL as we move the ownership model eliminator back
through the pipeline.
2018-12-05 16:39:18 -08:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -08:00
Carl Peto
db24809cc1 Remove apparently obsolete builtin functions (#20947)
* Remove apparently obsolete builtin functions.

- Remove s_to_u_checked_conversion and u_to_s_checked_conversion functions from builtin AST parsing, SIL/IR generation and from SIL optimisations.

* Remove apparently obsolete builtin functions - unit tests.

- Remove unit tests for SIL transformations relating to s_to_u_checked_conversion and u_to_s_checked_conversion builtin functions.
2018-12-03 23:44:27 -08:00
Stephen Canon
a5c38d099c Revert "Remove apparently obsolete builtin functions (#20947)" (#20975)
This reverts commit b914464712, which passed the public CI bots, but broke some tests on watchOS.
2018-12-03 17:48:24 -05:00