Commit Graph

644 Commits

Author SHA1 Message Date
Slava Pestov
23f7c4f6ee SILOptimizer: Fix potential crashes with uses of replaceLoadSequence()
This utility is generally a horrible idea but even worse the
callers were not doing anything to ensure the required
invariants actually held.

Add a new canReplaceLoadSequence() method and chek it in the
right places.
2019-02-21 23:06:21 -05:00
Ravi Kandhadai
a9b0ebe542 [SIL Diagnostics] Create a mandatory pass to check correct usage of
yields in generalized accessors: _read and _modify, which are
yield-once corountines. This pass is based on the existing SIL verifier
checks but diagnoses only those errors that can be introduced by programmers
when using yields.

<rdar://43578476>
2019-02-19 18:25:47 -08:00
Michael Gottesman
0cdc2d6a35 [sil] Teach constant folding how to handle destructures and multiple value instructions.
I also ported the constant_propagation.sil tests over for ownership and updated
a few parts of the cast optimizer so that those tests pass with and without
ownership. I purposely only updated the parts of the cast optimizer that crashed
with ownership in the relevant test so that I can add new sil code coverage for
those uncovered code paths.
2019-02-12 20:15:02 -08:00
Michael Gottesman
0c7f5b3064 [cast-opt] Change optimizeMetatypeConversion to return a value and use the new
replace value uses action to make sure that we properly notify passes that we
made the change.

This fixes a latent bug where we were not notifying SILCombine about this
replacement.

Specifically:

-  auto replaceCast = [&](SingleValueInstruction *NewCast) {
-    assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
-           == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
-    MCI->replaceAllUsesWith(NewCast);
-    EraseInstAction(MCI);
-    return NewCast;
+  auto replaceCast = [&](SILValue newValue) -> SILValue {
+    assert(ty.getAs<AnyMetatypeType>()->getRepresentation() ==
+           newValue->getType().getAs<AnyMetatypeType>()->getRepresentation());
+    ReplaceValueUsesAction(mci, newValue);
+    EraseInstAction(mci);
+    return newValue;
   };

Notice how we use MCI->replaceAllUsesWith instead of one of our replace call
backs. SILCombine hooks these to know if it should re-run users.
2019-02-04 16:13:07 -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
Michael Gottesman
fccd75e5ce [sil-passmanager] Stash a SILOptions reference in SILPassPipeline.
This normalizes the creation of pass pipelines by ensuring that all pass
pipelines take a SILOption instead of only some. It also makes it so that we do
not need to propagate options through various pipeline creation helpers.
2019-02-02 22:57:05 -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
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
787c35f165 SILOptimizer: correctly handle unreachable blocks in StackNesting.
Instead of some special treatment of unreachable blocks, model unreachable as implicitly deallocating all alive stack locations at that point.
This requires an additional forward-dataflow pass. But it now correctly models the problem and fixes a compiler crash.

rdar://problem/47402694
2019-01-25 11:29:21 -08:00
Michael Gottesman
671033ac7d [ssa-updater] Allow a user to set the InsertedPHIs list after construction.
I need this API so that I can conditionally handle the inserted phis.
2019-01-22 01:29:45 -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
Michael Gottesman
ac1f956ac0 Split predictable mem opts into two different passes, one that runs before diagnostics and one that runs after diagnostics.
I discovered while updating PMO for ownership that for ~5 years there has been a
bug where we were treating copy_addr of trivial values like an "Assign" (in PMO
terminology) of a non-trivial value and thus stopping allocation
elimination. When I fixed this I discovered that this caused us to no longer
emit diagnostics in a predictable way. Specifically, consider the following
swift snippet:

  var _: UInt = (-1) >> 0

Today, we emit a diagnostic that -1 can not be put into a UInt. This occurs
since even though the underlying allocation is only stored into, the copy_addr
assign keeps it alive, causing the diagnostics pass to see the conversion. With
my fix though, we see that we are only storing into the allocation, causing the
allocation to be eliminated before the constant propagation diagnostic pass
runs, causing the diagnostic to no longer be emitted.

We should truly not be performing this type of DCE before we emit such
diagnostics. So in this commit, I split the pass into two parts:

1. A load promotion pass that performs the SSA formation needed for SSA based
diagnostics to actually work.

2. An allocation elimination passes that run /after/ SSA based diagnostics.

This should be NFC since the constant propagation SSA based diagnostics do not
create memory operations so the output should be the same.
2019-01-17 14:48:03 -08:00
Arnold Schwaighofer
84c17372c0 Add insertDestroyOfCapturedArguments to Local.h 2019-01-15 11:31:57 -08:00
Arnold Schwaighofer
df1eb708fb Fix StackNesting to work with partial_apply [stack] 2019-01-15 11:20:33 -08:00
Andrew Trick
bc884d4ba8 Merge pull request #20977 from rajbarik/raj-extend-existential2generic
Perform ExistentialSpecializer when SoleConformingType is known
2019-01-14 18:23:19 -08:00
Erik Eckstein
1072bb6bc6 SILCombine: fix a miscompile caused by dead-apply elimination
SILCombine ended up moving a strong_release past a dealloc_ref.
fixes https://bugs.swift.org/browse/SR-9627
rdar://problem/47153896
2019-01-14 09:00:00 -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
Raj Barik
0070730e5a Perform ExistentialSpecializer when SoleConformingType is known 2019-01-07 14:47:39 -08:00
Andrew Trick
118a725d96 Generalize and cleanup code for existential specialization.
Generalizes the ConcreteExistentialInfo abstraction so it can be used
both by the ExistentialSpecializer and SILCombine, allowing redundant
code in ExistentialSpecializer.cpp to be deleted.

Splits OpenedArchetypeInfo from ConcreteExistentialInfo. Adds a
ConcreteOpenedArchetypeInfo convenience wrapper around them both, for
use wherever we were originally using ConcreteExistentialInfo.

Splits getAddressOfStackInit into getStackInitInst, This is cleaner and
allows both the ExistentialSpecializer and SILCombine to handle more
interesting cases in the future, like unconditional_checked_cast.

Creates utilities, initializeSubstitutionMap, and
initializeConcreteTypeDef to simplify an generalize
ConcreteExistentialInfo.

While rewriting ExistentialSpecializer to use the new
abstraction, I fixed a latent bug in which is was using a SIL
argument index as a function type parameter index (this would
have broken up if/when we decide to enable calls with indirect
results).
2019-01-02 08:44:37 -08:00
Andrew Trick
83950babc9 Merge pull request #21490 from atrick/fix-getobjc-after-free
Fix SILCombine metatype cast optimization to avoid extending lifetimes.
2018-12-21 11:22:19 -08:00
Andrew Trick
65c95dd840 Fix SILCombine metatype cast optimization to avoid extending lifetimes.
This cannot be correctly done as a SILCombine because it must create
new instructions at a previous location. Move the optimization into
CastOptimizer. Insert the new metatype instructions in the correct
spot. And manually do the replaceAllUsesWith and eraseInstruction
steps.

Fixes <rdar://problem/46746188> crash in swift_getObjCClassFromObject.
2018-12-21 09:52:38 -08:00
Ravi Kandhadai
92260f9a93 [Devirtualizer] Make the getWitnessMethodSubstitutions function of
Devirtualizer.cpp available to other passes.

This will enable the compile-time interpreter to use this functionality.
2018-12-20 12:27:19 -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
Andrew Trick
984bd99b40 Fix SILCombine to devirtualize existentials wrapped in enum.
This allows Swift code to implement a fast path via a protocol type
check as follows:

  if let existentialVal = genericVal as? SomeProtocol {
    // do something fast.
  }

Fixes <rdar://problem/46322928> Failure to devirtualize a protocol
method applied to an opened existential blocks implemention of
DataProtocol.

Note: the approach of devirtualization via backward pattern matching
is fundamentally wrong and will never be fully general. It should be a
forward type propagation.
2018-12-02 00:39:55 -08:00
swift-ci
2ef35ac80e Merge pull request #19655 from apple/marcrasi-const-evaluator-part-1 2018-11-29 19:25:14 -08:00
Michael Gottesman
c65c540d71 Merge pull request #20819 from gottesmm/pr-f46c6ad2fee1ea70f7b25a8f6a89ab7af28c1404
[ownership] Ban ValueOwnershipKind::Any in preparation for eliminated ValueOwnershipKind::Trivial
2018-11-28 13:55:10 -08:00
Michael Gottesman
c9bb5161a1 [ownership] Change SILUndef to return Any ownership for trivial values and owned for non-trivial values.
This is in preparation for verifying that when ownership verification is enabled
that only enums and trivial values can have any ownership. I am doing this in
preparation for eliminating ValueOwnershipKind::Trivial.

rdar://46294760
2018-11-27 17:31:08 -08:00
Marc Rasi
44d7cdd4e6 constant interpreter: basic integer operations
Implements a constant interpreter that can deal with basic integer operations.

Summary of the features that it includes:
* builtin integer values, and builtin integer insts
* struct and tuple values, and insts that construct and extract them (necessary to use stdlib integers)
* function referencing and application (necessary to call stdlib integer functions)
* error handling data structures and logic, for telling you why your value is not evaluatable
* metatype values (not necessary for integers, but it's only a few extra lines, so I thought it would be more trouble than it's worth to put them in a separate PR)
* conditional branches (ditto)
2018-11-26 14:27:10 -08:00
Andrew Trick
702981f775 Fix MandatoryInlining to not be quadratic.
Inlining has always been quadratic for no good reason. There was a
special hack for single-block callees that allowed linear inlining.

Instead, the now iterates over blocks and instructions in reverse,
splitting blocks as it inlines. There no longer needs to be special
case for single block callees, and the inliner is linear for all kinds
of callees.

This further simplifies and cleans up the code. There are just a few
basic invariants that the common inliner needs to provide about how
blocks are split and laid out. We can do this if we don't add hacks
for special cases within the inliner. Those invariants allow the
inliner clients to be much simpler and more efficient.

PerformanceInliner still needs to be fixed.

Fixes SR-9223: Inliner exhibits slow compilation time with a large
static array.
2018-11-26 09:41:28 -08:00
Andrew Trick
9c46b2a053 Fix block merging after inlining to help avoid quadratic inlining.
A recent SILCloner rewrite removed a special case hack for single
basic block callee functions:

commit c6865c0dff
Merge: 76e6c4157e 9e440d13a6
Author: Andrew Trick <atrick@apple.com>
Date:   Thu Oct 11 14:23:32 2018

    Merge pull request #19786 from atrick/silcloner-cleanup

    SILCloner and SILInliner rewrite.

Instead, the new inliner simply merges trivial unconditional branches
after inlining the return block. This way, the CFG is always in
canonical state after inlining. This is more robust, and avoids
interfering with subsequent SIL passes when non-single-block callees
are inlined.

The problem is that inlining a series of calls within a large block
could result in interleaved block splitting and merging operations,
which is quadratic in the block size. This showed up when inlining the
tens of thousands of array subscript calls emitted for a large array
initialization.

The first half of the fix is to simply defer block merging until all
calls are inlined. We can't expect SimplifyCFG to run immediately
after inlining, nor would we want to do that, *especially* for
mandatory inlining. This fix instead exposes block merging as a
trivial utility.

Note: by eliminating some unconditional branches, this change could
reduce the number of debug locations emitted. This does not
fundamentally change any debug information guarantee, and I was unable
to observe any behavior difference in the debugger.
2018-11-26 09:41:28 -08:00
Arnold Schwaighofer
44b3a47e56 Merge pull request #20333 from aschwaighofer/dynamic_function_replacement
Dynamic function replacement
2018-11-07 13:08:46 -08:00
Andrew Trick
5983aae176 Fix AccessEnforcementReleaseSinking. Check for illegal cases.
In the included, test case, the optimization was sinking
releases past is_escaping_closure.

Rewrite the isBarrier logic to be conservative and define the
mayCheckRefCount property in SIL/InstructionUtils. Properties that may
need to be updated when SIL changes belong there.

Note that it is particularly bad behavior if the presence of access
markers in the code cause miscompiles unrelated to access enforcement.

Fixes <rdar://problem/45846920> TestFoundation, TestProcess, closure
argument passed as @noescape to Objective-C has escaped.
2018-11-06 13:52:03 -08:00
Arnold Schwaighofer
7e32c68e1d Add new SIL instruction for calling dynamically_replaceable funtions
%0 = dynamic_function_ref @dynamically_replaceable_function
  apply %0()
  Calls a [dynamically_replaceable] function.

  %0 = prev_dynamic_function_ref @dynamic_replacement_function
  apply %0
  Calls the previous implementation that dynamic_replacement_function
  replaced.
2018-11-06 09:53:22 -08:00
John McCall
18a8ed6090 Fix a stack-discipline bug with inlining coroutines. 2018-11-05 17:14:29 -05:00
Joe Shajrawi
e3cd69b926 Merge pull request #20201 from shajrawi/release-sink
[Exclusivity] Sink may release release instructions out of access scopes
2018-10-31 19:14:25 -07:00
Joe Shajrawi
32da4f9f45 [Exclusivity] Sink may release release instructions out of access scopes
General case:
begin_access A
...
strong_release / release_value / destroy
end_access

The release instruction can be sunk below the end_access instruction,
This extends the lifetime of the released value, but, might allow us to
Mark the access scope as no nested conflict.
2018-10-31 15:48:08 -07:00
Andrew Trick
063bbfcf7d Merge pull request #20136 from atrick/silcloner-cleanup
[NFC] SILCloner rewrite stage 2: "threading" cloners.
2018-10-30 16:33:50 -07:00
Andrew Trick
1446952521 Merge pull request #20111 from atrick/critedge-util
NFC: SILBasicBlock utilties for handling critical edges.
2018-10-29 15:42:07 -07:00
Andrew Trick
903a9821ab SILCloner rewrite stage 2: "threading" cloners.
Rewrite the SILCLoners used in SimplifyCFG. For convenience, there is
now simply a BasicBlockCloner and a SILFunctionCloner. It's pretty
obvious what they do and almost impossible to use incorrectly.

This is worthwhile on its own just to make the usage clear, but the
real reason is that after this cleanup, it will be possible to remove
many extraneous calls to global critical edge splitting related to
cloning.
2018-10-29 08:57:19 -07:00
Andrew Trick
2aa8427dc6 SILCloner: rename 'remapValue' to 'getMappedValue' to avoid confusion.
A follow up commit adds an API for SILCloner clients to set mapped
values. Calling the map lookup "remap" would be unacceptably misleading.
2018-10-27 16:30:37 -07:00
Andrew Trick
c1164c0bac Add splitCriticalEdgesFrom API. 2018-10-26 23:18:37 -07:00
Joe Shajrawi
22d411c4ae Merge pull request #20053 from shajrawi/enforce_dom
[Exclusivity] Remove dominated access checks with no nested conflict.
2018-10-26 13:22:37 -07:00
Joe Shajrawi
63b50f65a4 [Exclusivity] Remove dominated access checks with no nested conflict.
General case:

—
begin_access A (may or may not have no_nested_conflict)
load/store
end_access

apply // may have a scoped access that conflicts with A

begin_access A [no_nested_conflict]
load/store
end_access A
—

The second access scope does not need to be emitted.

NOTE: KeyPath access must be identified at the top-level, non-inlinable stdlib entry point.
As such, The sodlib entry pointed is annotated by a new @_semantics that is equivalent to inline(never)
2018-10-25 15:21:06 -07:00
Saleem Abdulrasool
813f712ad5 adjust declarations of DenseMapInfo for GCC
Remove the extra qualification and place explicitly in the LLVM
namespace.  This fixes some build issues with GCC 8.2.
2018-10-23 08:29:13 -07:00
Andrew Trick
12bb49f57a Expose SIL/BasicBlockUtils for critical edge splitting.
The primary interfaces for CFG manipulation belong in SIL. This is
just what's necessary to fix SILCloner.
2018-10-22 08:34:57 -07:00
Erik Eckstein
15b01ab792 SIL: Remove array.owner semantic function
Also remove the getOwner functions from ArraySlide.
These functions are not needed anymore with accessors.

rdar://problem/44184810
2018-10-15 09:44:52 -07:00
Erik Eckstein
7b16f7f196 SILOptimizer: fix a phase ordering problem, which prevented array optimizations to work in some cases
Introduce an "early redundant load elimination", which does not optimize loads from arrays.
Later array optimizations, like ABCOpt, get confused if an array load in a loop is converted to a pattern with a phi argument.

This problem was introduced with accessors.

rdar://problem/44184763
2018-10-12 09:32:50 -07:00
Andrew Trick
9e440d13a6 Rename SILCloner doPostProcess and foldValue to recordClonedInstruction and recordFoldedValue. 2018-10-10 18:01:12 -07:00
Andrew Trick
c781d78782 Fix #includes. Arnold's review. 2018-10-09 22:36:33 -07:00