Commit Graph

681 Commits

Author SHA1 Message Date
Ravi Kandhadai
9be4fef53a [SIL Optimization] Add a mandatory optimization pass for optimizing
the new os log APIs based on string interpolation.
2019-05-14 18:08:59 -07:00
swift-ci
7ef557e7c8 Merge pull request #24780 from ravikandhadai/constexpr-refactoring 2019-05-14 16:34:48 -07:00
ravikandhadai
f563212f03 Revert "[SIL Optimization] Add a mandatory pass for optimizing the new os log APIs based on string interpolation." 2019-05-14 15:11:05 -07:00
Ravi Kandhadai
8b217afcaf [Const Evaluator] Fix a minor bug in the copy constructor deletion of
`ConstExprStepEvaluator`.
2019-05-14 12:09:57 -07:00
Ravi Kandhadai
b7b46622aa [SIL Optimization] Add a mandatory optimization pass for optimizing
the new os log APIs based on string interpolation.
2019-05-13 19:40:39 -07:00
Andrew Trick
aa6347c832 Merge pull request #24153 from atrick/fix-let-exclusivity
Add a SILGenCleanup pass and CanonicalizeInstruction utility.
2019-05-06 22:51:19 -07:00
Andrew Trick
ece096d91e Fix eraseFromParentWithdebugInsts to call a callback.
The recursivelyDeleteTriviallyDeadInstructions utility takes a
callBack to be called for every deleted instruction. However, it
wasn't passing this callBack to eraseFromParentWithdebugInsts. The
callback was used to update an iterator in some cases, so not calling
it resulted in iterator invalidation.

Doing this also cleans up the both APIs:
recursivelyDeleteTriviallyDeadInstructions and eraseFromParentWithdebugInsts.
2019-05-06 17:23:08 -07:00
ravikandhadai
a282b4513d Merge pull request #24488 from ravikandhadai/inliner-refactoring
[SIL Inlining] Extract out a reusable code snippet in PerformanceInliner into a utility function in SILInliner.
2019-05-06 15:13:23 -07:00
Andrew Trick
301ff8c9f0 Add a SILGenCleanup pass.
The SILGenCleanup pass runs before diagnostics to perform any
canonicalization required by diagnostics.
2019-05-06 09:36:08 -07:00
Andrew Trick
9aa2523393 Add a CanonicalizeInstruction utility.
CanonicalizeInstruction will be a superset of
simplifyInstruction (once all the transforms are fixed for ownership
SIL). Additionally, it will also include simple SSA-based
canonicalization that requires new instruction creation. It may not
perform any optimization that interferes with diagnostics or increases
compile time.

Canonicalization replaces simplifyInstruction in SILCombine so we can
easily factor some existing SILCombine transforms into canonicalization.
2019-05-06 09:36:07 -07:00
Andrew Trick
e400b66897 Cleanup replaceAllUsesAndErase, return an iterator, allow erase handlers.
This will make the forthcoming CanonicalizeInstruction interface more
clear.

This is generally the better approach to utilities that mutate the
instruction stream. It avoids the temptation to assume that only a
single instruction will be deleted or that only instructions before
the current iterator will be deleted. This often happens to work but
eventually fails in the presense of debug and end-of-scope
instructions.

A function returning an iterator has a more clear contract than one
accepting some iterator reference of unknown
providence. Unfortunately, it doesn't work at the lowest level of
utilities, such as recursivelyDeleteTriviallyDeadInstructions, where
we want to handle instruction batches.
2019-05-06 08:36:56 -07:00
Ravi Kandhadai
bed34d65ad [SIL Inlining] Extract out a reusable code snippet in PerformanceInliner
into a utility function in SILInliner.
2019-05-03 15:00:41 -07:00
Arnold Schwaighofer
a5036a97df Fix generic specialization that can result in noreturn apply without unreachable
rdar://50393169
2019-05-02 16:12:21 -07:00
ravikandhadai
d912e3312e Merge pull request #24113 from ravikandhadai/constexpr-skip
[Const evaluator] Add support to "skip" instructions in step-wise evaluation
2019-05-02 15:52:05 -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
Ravi Kandhadai
b0e56f70f9 [Const evaluator] Enable stepwise constant evaluator to skip
instructions without evaluating them while conservatively accounting
for the effects of the skipped instructions on the interpreter state.
2019-04-30 15:36:29 -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
Ravi Kandhadai
55e82004a2 [const evaluator] Expose the step-wise constant evaluation mode
(also referred to as flow-sensitive mode) so that the evaluator
can be used by clients to constant evaluate instructions in a
SILFunction body one by one following the flow of control.
2019-04-17 18:12:17 -07:00
swift-ci
c6f7f97ba1 Merge pull request #23981 from gottesmm/pr-d8251fee09379fbd0cee5696f7b97a85ca886cb2 2019-04-12 12:17:36 -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
ravikandhadai
28efe03fab Merge pull request #23456 from ravikandhadai/constexpr-local-allocation
[const evaluator] Parameterize allocation of symbolic values in the constant interpreter.
2019-04-11 15:14:09 -07:00
Erik Eckstein
8f47439148 PerformanceInliner: disable shortest-path-analysis for huge functions.
As the complexity of the analysis is more than linear with the number of blocks, disable it for functions with > 2000 basic blocks.
In this case inlining will be less aggressive.

SR-10209
rdar://problem/49522869
2019-04-10 10:37:37 -07:00
Ravi Kandhadai
bb7363da2e [const evaluator] Parameterize allocation of symbolic values in the
constant interpreter. Based on this, change to a short-lived bump
allocator for storing symbolic values in the pass that checks #assert.
2019-04-09 13:56:21 -07:00
Slava Pestov
9ac0dc3d6c SILOptimizer: Re-implement escaping capture diagnostics
The new pass is based on existing asserts in DiagnoseStaticExclusivity.
They were compiled out in release builds and only checked for captures of
inout parameters. This patch converts the assertions into diagnostics and
adds checks for captures of non-escaping function values.

Unlike the Sema-based checks that this replaces, the new code handles
transitive captures from recursive local functions, which means certain
invalid code that used to compile will now be rejected with an error.

The new analysis also looks at the ultimate usages of a local function
instead of just assuming all local functions are escaping, which fixes
issues where the compiler would reject valid code.

Fixes a bunch of related issues, including:

- <rdar://problem/29403178>
- <https://bugs.swift.org/browse/SR-8546> / <rdar://problem/43355341>
- <https://bugs.swift.org/browse/SR-9043> / <rdar://problem/45511834>
2019-04-09 15:02:14 -04:00
Michael Gottesman
db13769ea8 [ownership] Change OwnershipDumper to also dump ownership kind map per operand. 2019-04-01 19:02:58 -07:00
Erik Eckstein
00599eeb3c Check for completeness of the SwiftOnoneSupport library
When compiling SwiftOnoneSupport, issue errors for missing functions which are expected in the module.
This ensures ABI compatibility.

rdar://problem/48924409
2019-03-25 14:57:03 -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
72a9190258 Expose AccessedStorageAnalysis as a utility.
The previous design was customized to perfoming IPO with
GenericSideEffectAnalysis. Expose the underlying logic as a utility so
that AccessEnforcementOpts can use it to summarize loops (in addition
to call sites).
2019-03-18 12:42:53 -07:00
Slava Pestov
e9bd15f7fc SILOptimizer: More generic specializer plumbing for using the right resilience expansion
Also NFC for now.
2019-03-13 02:21:53 -04:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Slava Pestov
00b4662ab9 SILOptimizer: Clean up the generic specializer a bit 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
Michael Gottesman
ee02174f71 [cast-opt] Change optimize{Swift,ObjC}to{ObjC,Swift} to use SILDynamicCastInst.
I also debrided dead variables that resulted from eliminating the trampoline
argument code in optimizeBridgedCasts().
2019-03-04 10:48:13 -08:00
Michael Gottesman
fa4c38bf0c [cast-opt] Now that all users of optimizeBridgedCasts use the SILDynamicCastInst entrypoint, delete the old entrypoint and inline its body into the new entrypoint. 2019-03-03 16:33:12 -08:00
Slava Pestov
c5cf5c2c4b SILOptimizer: Remove isSimpleType()
This was checking if the type is a trivial type that is not a
class. However this was redundant because class types are not
trivial anyway.
2019-02-28 22:56:03 -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
Michael Gottesman
98ed241ce5 [cast-optimizer] Add an "ApplySite" like data structure "SILDynamicCastInst" that abstracts over all dynamic cast instructions.
I am going to use this to refactor a bunch of the goop in the cast optimizer. At
a high level, we are really just performing a giant switch over the casts to
grab different state. We then take that state and we pass it into the bridge
cast optimizer.

To make such code more compact/easier to understand, I am adding in this commit
a type erased dynamic cast instruction type called "SILDynamicCastInst". In
subsequent commits, I wire up each of the individual instructions to it one at a
time.

As an additional advantage it will enable us to take advantage of covered
switches when ever in the future we introduce new casts.
2019-02-26 13:23:54 -08:00
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