Commit Graph

2601 Commits

Author SHA1 Message Date
Arnold Schwaighofer
a793dfb451 Respect resilience when specializing opaque type archetypes 2019-05-01 09:31:07 -07:00
Arnold Schwaighofer
881d9ad2bf Fix assert in type substitution cloner
We might have to replace opaque archetypes to satisfy equality of types
2019-05-01 09:31:07 -07:00
Arnold Schwaighofer
9f83f4b088 Projections should keep the type of the underlying type 2019-05-01 09:31:07 -07:00
Arnold Schwaighofer
fbf09031e4 Add a pass to specialize opaque type archetypes.
Clones functions containing opaque type archetypes replacing the opaque
type by a concrete type.

rdar://46140751
2019-05-01 09:31:07 -07:00
Slava Pestov
16d5716e71 SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:

- Places that call SILType::isAddressOnly()/isLoadable() now call
  the SILFunction overload and not the SILModule one.

- SILFunction's overloads of getTypeLowering() and getLoweredType()
  now pass the function's resilience expansion down, instead of
  hardcoding ResilienceExpansion::Minimal.

- Various other places with '// FIXME: Expansion' now use a better
  resilience expansion.

- A few tests were updated to reflect SILGen's improved code
  generation, and some new tests are added to cover more code paths
  that previously were uncovered and only manifested themselves as
  standard library build failures while I was working on this change.
2019-04-26 22:47:59 -04:00
Slava Pestov
472787bab7 SIL: isNonThrowing parameter of SILBuilder::create{Begin,}Apply() defaults to false
Also remove the overload of createApply() that does not take a SubstitutionMap.
It accomplishes nothing except creating ambiguity.
2019-04-25 22:27:38 -04:00
Erik Eckstein
a402544588 SILOptimizer: support for Dictionary literals generated in the data section.
Actually: generate the array of (key, value) tuples in the data section, which is then passed to Dictionary.init(dictionaryLiteral:)
We already do this for simple arrays, e.g. arrays with trivial element types.
The only change needed for dictionary literals is to support tuple types in the ObjectOutliner.

The effect of this optimization is a significant reduction in code size for dictionary literals - and an increase in data size.
But in most cases there is a considerable net win for code+data size in total.
2019-04-23 09:02:53 -07:00
Michael Gottesman
f7b014b95c [cast-opt] Rename CastOptimizer member vars to match the rest of the CastOptimizer.
Done using Xcode's refactoring engine.
2019-04-12 11:09:29 -07:00
Erik Eckstein
4e9a9cc626 SimplifyCFG: disable some expensive optimizations for huge functions.
Disable constant folding and jump threading for functions with > 10000 blocks.
Those optimizations are not strictly linear with the number of blocks and cause compile time issues if the function is really huge.

SR-10209
rdar://problem/49522869
2019-04-10 10:37:37 -07:00
Slava Pestov
cece98b2ed AST: Generalize ClassDecl::checkObjCAncestry() to ClassDecl::checkAncestry()
This replaces ClassDecl::hasObjCMembers() and some hand-coded walks.
2019-03-26 18:42:59 -04:00
Andrew Trick
7e3f8d99c6 Merge pull request #23473 from atrick/fix-inline-canspecialize
Fix a PerformanceInliner crash caused by a null callee signature.
2019-03-22 09:17:32 -07:00
Andrew Trick
a461faf16b Fix a PerformanceInliner crash caused by a null callee signature.
This is an obvious drive-by fix. It will crash when building
Foundation after I commit changes to the pipeline. My attempts at
creating a unit test were unsuccessful because it depends on some
interaction between inlining and specialization heuristics.
2019-03-21 15:13:12 -07:00
Andrew Trick
219fbe9f15 Fix a comment in AccessEnforcementOpts.
This was supposed to land in the previous commit but was dropped.
2019-03-21 15:07:58 -07:00
Andrew Trick
71b012e8f0 Merge pull request #23190 from atrick/cleanup-accessopts
Cleanup/fix AccessEnforcementOpts
2019-03-20 13:15:55 -07:00
Andrew Trick
462df6cef3 Cleanup/fix the loop access summary in AccessEnforcementOpts.
Reuse AccessStorageAnalysis to summarize accesses.

Don't ignore call sites in loops.

Don't consider a read access in a loop to conflict with a read
outside.

Use the unidentified access flag from the analysis.

Remove extraneous code, some of which was unreachable.

General cleanup.
2019-03-19 15:29:59 -07:00
Michael Gottesman
30accb058d [temp-immut-rv-forward] Handle open_existential_addr immutable_access.
Now we handle this case:

  %stack = alloc_stack $Protocol
  copy_addr %var to [initialization] %stack
  open_existential_addr immutable_access %stack
  ...
  destroy_addr %stack
  dealloc_stack %stack

We only do this if we have immutable_access. To be conservative I still only let
the normal whitelist of other instructions through.

I am adding this optimization since I am going to be eliminating a SILGen
peephole so I can enable SIL ownership verification everywhere.
2019-03-18 22:13:06 -07:00
Andrew Trick
dfc2d47f3b Redo the data flow part of AccessEnforcementOpts.
Directly implement the data flow. Eliminate the extraneous work.
Remove cubic behavior. Do a single iteration of the data flow state at
each program point only performing the necessary set operations. At
unidentified access, clear the sets for simplicity and efficiency.

This cleanup results in significant functional changes:

- Allowing scopes to merge even if they are enclosed.

- Handling unidentified access conservatively.

Note that most of the added lines of code are comments.

Somehow this cleanup incidentally fixes:
<rdar://problem/48514339> swift compiler hangs building project

(I expected the subsequent loop summary cleanup to fix that problem.)
2019-03-18 12:42:53 -07:00
Andrew Trick
c516a1ca0e Retain the [no_nested_conflict] flag when merging.
The optimization already proves that there are no potential conflicts
between the two merged scopes, so merging them can't introduce a new
nested conflict.
2019-03-18 12:42:53 -07:00
Andrew Trick
4887d17dbd Remove RegionState::AccessSummary and rewrite mergePredAccesses.
AccessSummary was storing unnecessary state in every per-block entry in the
global map. It was also making most of the code in this pass very hard to read.

Rewriting mergePredAccesses allows AccessSummary to be removed. The
new implementation also avoids unnecessary DenseMap lookups.

There is also a functional change. mergePredAccesses was clearing the
state of predecessor blocks. This isn't logical and had no explanation.
2019-03-18 12:42:53 -07:00
Andrew Trick
d882b09c88 Avoid unnecessarily copying the worklist for the entire CFG. 2019-03-18 12:42:53 -07:00
Andrew Trick
25f24da779 Cleanup the recordConflict API.
And remove cubic behavior.
2019-03-18 12:42:53 -07:00
Andrew Trick
5183929d35 Cleanup the mergeAccessSummary API. 2019-03-18 12:42:53 -07:00
Andrew Trick
c2d4642bcb Rename RegionInfo to RegionState.
Most of the API's operate on the data flow state (RegionState) with
respect to the information for a given access (AccessInfo). Calling
them both "info" made the code completely indecipherable.
2019-03-18 12:42:53 -07:00
Andrew Trick
ac846cb146 Clarify AccessEnforcementOptsInfo comments. 2019-03-18 12:42:53 -07:00
Slava Pestov
5c72a3691c SILOptimizer: Add some FIXMEs and a cleanup 2019-03-13 02:12:29 -04:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Slava Pestov
c791c4a137 SIL: SILUndef must be aware of the resilience expansion
The ownership kind is Any for trivial types, or Owned otherwise, but
whether a type is trivial or not will soon depend on the resilience
expansion.

This means that a SILModule now uniques two SILUndefs per type instead
of one, and serialization uses two distinct sentinel IDs for this
purpose as well.

For now, the resilience expansion is not actually used here, so this
change is NFC, other than changing the module format.
2019-03-12 00:30:35 -04:00
Andrew Trick
404cf73ca6 Merge pull request #23111 from atrick/dominating-access-algo
Change the algorithm for the AccessEnforcementDom pass.
2019-03-07 16:51:18 -08:00
swift-ci
74d1322a72 Merge pull request #23119 from ravikandhadai/array-init-semantics 2019-03-07 14:17:34 -08:00
Andrew Trick
3da2cc9e06 Clarify comments. 2019-03-07 13:48:41 -08:00
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