Commit Graph

1020 Commits

Author SHA1 Message Date
Joe Shajrawi
a9df5863d0 Merge pull request #19119 from shajrawi/mayrelease
[Exclusivity] Handle mayRelease instructions conservatively in AccessnforcementOpts and LICM
2018-09-04 17:41:17 -07:00
Andrew Trick
423c0625f1 Merge pull request #18902 from atrick/copyprop
CopyPropagation for SILValues with ownership.
2018-09-04 15:47:41 -07:00
Joe Shajrawi
7297b81108 AccessEnforcementOpts: Refactoring
1) use vectors instead of MapVector for in/out of scope local maps
2) record nested conflict without creating a temporary copy
2018-09-04 13:58:37 -07:00
eeckstein
9b62f0defb Merge pull request #19120 from eeckstein/let-property-opt
SILOptimizer: handle copies in LetPropertiesOpt.
2018-09-04 13:49:56 -07:00
Joe Shajrawi
c6a4e2cdd2 [Exclusivity] Handle mayRelease instructions conservatively in AccessEnforcementOpts and LICM 2018-09-04 13:23:22 -07:00
Andrew Trick
098759f070 CopyPropagation for SILValues with ownership.
This is a simple "utility" pass that canonicalizes SSA SILValues with
respect to copies and destroys. It is a self-contained, provably
complete pass that eliminates spurious copy_value instructions from
scalar SSA SILValues. It fundamentally depends on ownership SIL, but
otherwise can be run efficiently after any other pass. It separates
the pure problem of handling scalar SSA values from the more important
and complex problems:

- Promoting variables to SSA form (PredictableMemOps and Mem2Reg
  partially do this).

- Optimizing copies within "SIL borrow" scopes (another mandatory pass
  will be introduced to do this).

- Composing and decomposing aggregates (SROA handles some of this).

- Coalescing phis (A BlockArgumentOptimizer will be introduced as part
  of AddressLowering).

- Removing unnecessary retain/release when nothing within its scope
  may release the same object (ARC Code Motion does some of this).

Note that removing SSA copies was more obviously necessary before the
migration to +0 argument convention.
2018-09-04 13:12:36 -07:00
Erik Eckstein
6d3f74a2a0 SILOptimizer: only do SROA when it has a benefit.
Replacing an alloc_stack of a struct/tuple with multiple alloc_stacks of the struct/tuple elements should only be done if the elements are somehow accessed individually.
If not, e.g. if the whole struct/tuple is just copied, there is no benefit of doing SROA.

Although this change has little impact by its own (some small code size wins), it is important for the improvement of let-property optimization.
2018-09-04 11:21:27 -07:00
Graydon Hoare
3b76f007d6 [SIL] Reallocate temporary SILFunction names to live in SILModule. 2018-09-01 00:05:58 -07:00
Andrew Trick
f764b8b615 Fix a bug in CopyForwarding. Bailout during destoy hoisting.
Once the algorithm has begun hoisting destroys globally, there's no
way to cleanly bailout. The previous attempt to bailout could result
in an assert or lost destroy in release mode.

This is continued fall-out from changes in the previous release to
upstream SILGen or mandatory passes, such as PredictableMemOps, that
no longer preserve natural variable lifetimes.

In this case, we end up with SIL like this before CopyForwarding:

bb(%arg)
%local_addr = alloc_stack
store %arg to %local_addr
%payload = switch_enum(%arg)
retain %arg
store %arg to %some_addr
destroy_addr %local_addr
release_value %arg

We're attempting to hoist the destroy_addr to its last use, but can't
because the lifetimes of the alloc_stack (%local_addr) and the value
being stored on the stack (%arg) have become mixed up by an upstream
pass. We actually detect this situation now in order to bail-out of
destroy hoisting. Sadly, the bailout might only partially recover in
the case of interesting control flow, as happens in the test case's
Graph.init function. This triggers an assert, but in release mode it
simply drops the destroy.

Fixed <rdar://problem/43888666> [SR-8526]: Memory leak after switch in
release configuration.
2018-08-31 18:29:15 -07:00
Andrew Trick
5cb033d802 Merge pull request #19027 from atrick/fix-phi-incoming-value
Fix the SIL incoming phi value API, verify critical edges, fix SIL passes that break verification.
2018-08-30 15:57:01 -07:00
Andrew Trick
1e88e44ce8 Add critical edge verification and fix SIL passes.
SIL passes were violating the existing invariant on non-cond-br
critical edges in several places. I fixed the places that I could
find.  Wherever there was a post-pass to "clean up" critical edges, I
replaced it with a a call to verification that the critical edges
aren't broken in the first place.

We still need to eliminate critical edges entirely before enabling
ownership SIL.
2018-08-30 13:01:39 -07:00
Andrew Trick
9d2af79975 Simplify SILPHIArgument::getIncomingValue.
The client of this interface naturally expects to get back the
incoming phi value. Ignoring dominance and SIL ownership, the incoming
phi value and the block argument should be substitutable.

This method was actually returning the incoming operand for
checked_cast and switch_enum terminators, which is deeply misleading
and has been the source of bugs.

If the client wants to peek though casts, and enums, it should do so
explicitly. getSingleTerminatorOperand[s]() will do just that.
2018-08-30 13:01:39 -07:00
Brent Royal-Gordon
e289f4e586 [SILOptimizer] Fix overflow in inlining
When compiling benchmark/single-source/DictTest.swift, a multiplication can overflow in SILPerformanceInliner::isProfitableToInline(). Notice when the value is large enough to overflow and zero out the value it would have been subtracted from.
2018-08-29 22:53:40 -07:00
Andrew Trick
b3a3220e38 Merge pull request #19020 from atrick/fix-critical-edges
Fix critical edges
2018-08-29 09:51:05 -07:00
Andrew Trick
3a445fee96 Fix the no-swift-assert stdlib build. (#19037)
Partially revert a recent attempt to fix build warnings.

Fixes: <rdar://problem/43824067> Swift CI:
1. OSS - Swift (Tools Opt+No Assert, Stdlib Opt+DebInfo, Test Simulator)
   - OS X (master) - SimplifyCFG crashes at AssertCommon.swift:283:10
2018-08-28 19:59:21 -07:00
Ben Cohen
6567438027 Squash release build warnings (#18986) 2018-08-28 09:56:17 -07:00
Andrew Trick
873affd39a Remove -disable-with-critical-edge flag. 2018-08-27 23:56:52 -07:00
John McCall
6cc5a27c09 begin_apply is not a trivially-duplicable instruction.
The test case here did not actually previously fail, but it
seems worth including.
2018-08-26 01:18:37 -04:00
John McCall
348fda2c2f More optimizer fixes for coroutines. 2018-08-24 15:19:14 -04:00
Erik Eckstein
99a9ed5535 SIL: remove the pinning instructions: strong_pin, strong_unpin, is_unique_or_pinned
They are not used anymore after removing the pinning addressors.
2018-08-23 12:47:56 -07:00
Erik Eckstein
192431b830 SIL optimizer: remove the RemovePin optimization.
Not useful anymore after removing the pinning adressors
2018-08-23 12:47:56 -07:00
Joe Shajrawi
19e5256baf [AccessEnforcementOpts] Fix an iterator invalidation issue
visitSetForConflicts Had a bug wherein we might change the accessSet while iterating over it by recording a conflict. This makes our current iterator invalid.

Work-around this issue by restarting the iteration in case we made any changes to the accessSet

Similarly, we do that for anywhere where in we recorded a conflict
2018-08-21 23:26:57 -07:00
John McCall
94b748a14c Update SIL devirtualization to handle begin_apply instructions.
In order to make this reasonable, I needed to shift responsibilities
around a little; the devirtualization operation is now responsible for
replacing uses of the original apply.  I wanted to remove the
phase-separation completely, but there was optimization-remark code
relying on the old apply site not having been deleted yet.

The begin_apply aspects of this aren't testable independently of
replacing materializeForSet because coroutines are currently never
called indirectly.
2018-08-19 19:50:13 -04:00
Erik Eckstein
1f2629fd88 SIL optimizer: fix two non-deterministic behaviors
The problem was again iterating over pointer sets. This produced non-deterministic use list orderings, which does result in non-deterministic code generation itself.
But somehow debug info generation depends on the use list ordering (which should be investigated why).
And the non-deterministic debug info changes triggered re-running of the llvm pipeline.
2018-08-17 15:47:23 -07:00
Ben Cohen
428c580158 Fix unused variable warnings in release builds. (#18755) 2018-08-16 11:46:45 -06:00
Joe Shajrawi
e68e087462 Merge pull request #18560 from shajrawi/merge_accesses
[AccessEnforcementOpts] Add mergeAccesses analysis + optimization
2018-08-10 00:44:11 -07:00
Joe Shajrawi
7281a76deb [AccessEnforcementOpts] Add mergeAccesses optimization 2018-08-09 16:15:25 -07:00
Joe Shajrawi
62e43a13d7 [AccessEnforcementOpts] Add merge accesses analysis to conflict analysis 2018-08-09 14:09:24 -07:00
Michael Gottesman
f35a2a3cf8 [sil-opt] Only notify the pass manager of newly added functions in SILOptFunctionBuilder.
To do so this commit does a few different things:

1. I changed SILOptFunctionBuilder to notify the pass manager's logging
functionality when new functions are added to the module and to notify analyses
as well. NOTE: This on purpose does not put the new function on the pass manager
worklist since we do not want to by mistake introduce a large amount of
re-optimizations. Such a thing should be explicit.

2. I eliminated SILModuleTransform::notifyAddFunction. This just performed the
operations from 1. Now that SILOptFunctionBuilder performs this operation for
us, it is not needed.

3. I changed SILFunctionTransform::notifyAddFunction to just add the function to
the passmanager worklist. It does not need to notify the pass manager's logging
or analyses that a new function was added to the module since
SILOptFunctionBuilder now performs that operation. Given its reduced
functionality, I changed the name to addFunctionToPassManagerWorklist(...). The
name is a little long/verbose, but this is a feature since one should think
before getting the pass manager to rerun transforms on a function. Also, giving
it a longer name calls out the operation in the code visually, giving this
operation more prominance when reading code. NOTE: I did the rename using
Xcode's refactoring functionality!

rdar://42301529
2018-08-06 18:27:24 -07:00
Michael Gottesman
f500f007f8 [sil] Add a template parameter to TypeSubstCloner so that subclasses can inject a SILFunctionBuilder composition class.
This works around a potential circular dependence issue where TypeSubstCloner
needs access to SILOptFunctionBuilder but is in libswiftSIL.

rdar://42301529
2018-08-06 13:40:25 -07:00
Michael Gottesman
b72304415d [passmanager] Change the optimizer to use SILOptFunctionBuilder.
I am going to add the code in a bit that does the notifications. I tried to pass
down the builder instead of the pass manager. I also tried not to change the
formatting.

rdar://42301529
2018-08-05 21:21:55 -07:00
Andrew Trick
2c74a01215 Generalize AllocBoxToStack pass to handle apply variations.
Remove all the bespoke utilities for handling apply sites.
Use the ApplySite abstraction instead. As a side effect,
we can now properly analyze begin_apply and try_apply.
2018-08-02 11:23:09 -07:00
Andrew Trick
87755a4eb1 Merge pull request #18453 from atrick/revert-unexpected-box-use
Temoprarily revert AllocBoxToStack change to handle general applies.
2018-08-01 14:40:52 -07:00
Andrew Trick
3ab54d5fc9 Temoprarily revert AllocBoxToStack change to handle general applies.
Fixes <rdar://problem/42815224> Swift CI: 2. Swift Source Compatibility Suite (master):
Kitura project fails with compiler crash

This will be properly fixed by rewriting the AllocBoxToStack utilities
in a follow up commit.
2018-08-01 13:18:40 -07:00
Jordan Rose
2dcac4bcb2 Merge pull request #18408 from jrose-apple/default-on-your-futures
[SIL] Don't drop a default when switching on a non-exhaustive enum

rdar://problem/42775178
2018-08-01 10:54:19 -07:00
Jordan Rose
e96886a819 [SIL] Honor @inlinable in resilient modules for enum exhaustivity
Otherwise, we'll generate inlinable code over a supposedly non-frozen
enum that doesn't actually contain a 'default'.
2018-08-01 08:34:57 -07:00
Jordan Rose
ec8aa9f014 Add EnumDecl::isEffectivelyExhaustive, and use it consistently
...rather than copying the same check around all over the place.
2018-07-31 19:01:00 -07:00
Andrew Trick
06d0973ebe Merge pull request #18315 from atrick/fix-argument-convention
Fix several incorrect uses of ApplySite::getArgumentConvention.
2018-07-31 18:09:54 -07:00
Jordan Rose
c5a86e0386 [SIL] Don't drop a default when switching on a non-exhaustive enum
This was undoing the effects of 36eae9d4f, which is supposed to
guarantee trapping behavior on unexpected values. Worse, it put
switches that *actually had defaults* back into
undefined-behavior-land if a case were added.

The verifier changes are in lieu of test changes; this was originally
caught by IRGen/CoreGraphics_test.swift.

rdar://problem/42775178
2018-07-31 11:54:10 -07:00
Michael Gottesman
11b24415c1 [sil-module] Create SILFunctionBuilder and hide creation/erasing functions on SILModule.
This commit does not modify those APIs or their usage. It just:

1. Moves the APIs onto SILFunctionBuilder and makes SILFunctionBuilder a friend
   of SILModule.
2. Hides the APIs on SILModule so all users need to use SILFunctionBuilder to
   create/destroy functions.

I am doing this in order to allow for adding/removing function notifications to
be enforced via the type system in the SILOptimizer. In the process of finishing
off CallerAnalysis for FSO, I discovered that we were not doing this everywhere
we need to. After considering various other options such as:

1. Verifying after all passes that the notifications were sent correctly and
   asserting. Turned out to be expensive.
2. Putting a callback in SILModule. This would add an unnecessary virtual call.

I realized that by using a builder we can:

1. Enforce that users of SILFunctionBuilder can only construct composed function
   builders by making the composed function builder's friends of
   SILFunctionBuilder (notice I did not use the word subclass, I am talking
   about a pure composition).
2. Refactor a huge amount of code in SILOpt/SILGen that involve function
   creation onto a SILGenFunctionBuilder/SILOptFunctionBuilder struct. Many of
   the SILFunction creation code in question are straight up copies of each
   other with small variations. A builder would be a great way to simplify that
   code.
3. Reduce the size of SILModule.cpp by 25% from ~30k -> ~23k making the whole
   file easier to read.

NOTE: In this commit, I do not hide the constructor of SILFunctionBuilder since
I have not created the derived builder structs yet. Once I have created those in
a subsequent commit, I will hide that constructor.

rdar://42301529
2018-07-31 10:04:03 -07:00
Andrew Trick
89ed064808 Fix several incorrect uses of ApplySite::getArgumentConvention.
At least most of these were latent bugs since the code was
unreachable in the PartialApply case. But that's no excuse to misuse
the API.

Also, whenever referring to an integer index, be explicit about
whether it is an applied argument or callee argument.
2018-07-28 00:05:40 -07:00
Michael Gottesman
fac606ebba [arc-codemotion] Eliminate retains that we move next to fatalErrors and unreachables.
The reason to do this is that otherwise, retain code motion can increase the
size of the IR by large amounts as it pushes tons and tons of retains/releases
into these sorts of blocks. One one test case, it increased the amount of raw
instructions by 2-3 orders of magnitude.

We used to implement this in ARCSequenceOpts when it did code motion. When code
motion was stripped out of ARCSequenceOpts and ARCCodeMotion was implemented,
this was not implemented for some reason yielding this regression.

NOTE: If one reads this PR there is "retain" trimming code as well as usage of
ProgramTerminationAnalysis. The reason why I implemented the code in this way is
that tThe program termination analysis allows us to avoid inserting retains at
all into fatal error blocks, but it can not handle cases where a fatal error
block has been merged into another block. The trimmer code handles this case and
potential cases where side-effect code is in the fatal error block. On the other
hand, if we just relied on the retain trimming code, we would be inserting a
huge amount of retains just to free them. That is really wasteful from a
performance standpoint given the amount of retains that we can insert here.

rdar://42347024
2018-07-25 17:28:15 -07:00
John McCall
70e2aea266 Merge pull request #18156 from rjmccall/generalized-accessors
Implement generalized accessors using yield-once coroutines
2018-07-23 22:58:25 -04:00
John McCall
7a4aeed570 Implement generalized accessors using yield-once coroutines.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.

`_read` accessors do not make any effort yet to avoid copying the
value being yielded.  I'll work on it in follow-up patches.

Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.

SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.

rdar://35399664
2018-07-23 18:59:58 -04:00
Bob Wilson
8e330ee344 NFC: Fix indentation around the newly renamed LLVM_DEBUG macro.
Jordan used a sed command to rename DEBUG to LLVM_DEBUG. That caused some
lines to wrap and messed up indentiation for multi-line arguments.
2018-07-21 00:56:18 -07:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
Joe Groff
849d9397d6 SIL: Generate external key path references with local candidate components.
The other side of #17404. Since we don't want to generate up front key path metadata for properties/subscripts with no withheld implementation details, the client should generate a key path component that can be used to represent a key path component based on its public interface.
2018-07-06 14:24:07 -07:00
John McCall
34b0cbc11d Merge pull request #16237 from davezarzycki/metaprogram_ref_storage_types
[AST] NFC: Enable reference storage type meta-programming
2018-07-05 14:45:38 -04:00
Christopher Rogers
dff1d8983d Fix typos/grammar in comments & docs 2018-07-03 14:31:36 +09:00
David Zarzycki
03b7eae9ed [SILOptimizer] NFC: Adopt reference storage type meta-programming macros 2018-06-30 06:44:33 -04:00