Commit Graph

132 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
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
bd28b0ea1b SILCloner and SILInliner rewrite.
Mostly functionally neutral:
- may fix latent bugs.
- may reduce useless basic blocks after inlining.

This rewrite encapsulates the cloner's internal state, providing a
clean API for the CRTP subclasses. The subclasses are rewritten to use
the exposed API and extension points. This makes it much easier to
understand, work with, and extend SIL cloners, which are central to
many optimization passes. Basic SIL invariants are now clearly
expressed and enforced. There is no longer a intricate dance between
multiple levels of subclasses operating on underlying low-level data
structures. All of the logic needed to keep the original SIL in a
consistent state is contained within the SILCloner itself. Subclasses
only need to be responsible for their own modifications.

The immediate motiviation is to make CFG updates self-contained so
that SIL remains in a valid state. This will allow the removal of
critical edge splitting hacks and will allow general SIL utilities to
take advantage of the fact that we don't allow critical edges.

This rewrite establishes a simple principal that should be followed
everywhere: aside from the primitive mutation APIs on SIL data types,
each SIL utility is responsibile for leaving SIL in a valid state and
the logic for doing so should exist in one central location.

This includes, for example:
- Generating a valid CFG, splitting edges if needed.
- Returning a valid instruction iterator if any instructions are removed.
- Updating dominance.
- Updating SSA (block arguments).

(Dominance info and SSA properties are fundamental to SIL verification).

LoopInfo is also somewhat fundamental to SIL, and should generally be
updated, but it isn't required.

This also fixes some latent bugs related to iterator invalidation in
recursivelyDeleteTriviallyDeadInstructions and SILInliner. Note that
the SILModule deletion callback should be avoided. It can be useful as
a simple cache invalidation mechanism, but it is otherwise bug prone,
too limited to be very useful, and basically bad design. Utilities
that mutate should return a valid instruction iterator and provide
their own deletion callbacks.
2018-10-08 19:30:09 -07:00
Graydon Hoare
cc16ddfd13 Revert "[SILOptimizer] Don't diagnose infinite recursion if a branch terminates (#19724)"
This reverts commit e94450e840.

rdar://45080912
2018-10-07 23:54:33 -07:00
Harlan
e94450e840 [SILOptimizer] Don't diagnose infinite recursion if a branch terminates (#19724)
This patch augments the infinite recursion checker to not warn if a
branch terminates, but still warns if a branch calls into something with
`@_semantics("arc.programtermination_point")`. This way, calling `fatalError`
doesn't disqualify you for the diagnostic, but calling `exit` does.

This also removes the warning workaround in the standard library, and
annotates the internal _assertionFailure functions as
`programtermination_point`s, so they get this treatment too.
2018-10-05 19:15:26 -07:00
Michael Gottesman
d57a88af0d [gardening] Rename references to SILPHIArgument => SILPhiArgument. 2018-09-25 22:23:34 -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
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
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
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
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
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
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
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
David Zarzycki
03b7eae9ed [SILOptimizer] NFC: Adopt reference storage type meta-programming macros 2018-06-30 06:44:33 -04:00
Arnold Schwaighofer
73d3b37c94 Move RemoveUnreachable from SimplifyCFG into a utility function
The utility function will be used in a follow-up commit by a different
pass.

rdar://41139395
2018-06-15 13:52:17 -07:00
Doug Gregor
d457f1c752 [IRGen/SIL] More widespread use of SubstitutionMap. 2018-05-11 13:18:06 -07:00
Doug Gregor
4b5abbddbc [SIL] Teach *ApplyInst to traffic in SubstitutionMap.
Push SubstitutionMaps through most of SILGen and the SIL optimizers
that involve the various *ApplyInsts.
2018-05-11 13:18:06 -07:00
Michael Gottesman
8a7e0fb743 [gardening] Change 3x SmallPtrSet in comments to be SmallPtrSetImpl while I am in the neighborhood. 2018-04-30 15:43:19 -07:00
Michael Gottesman
7b7c3ec9b5 [perf] Change a pass by value of a SmallPtrSet<Ptr, 8> to by ref.
Just noticed on inspection.
2018-04-30 15:43:19 -07:00
Davide Italiano
b4d563802b [SILInstruction] Introduce isDebugInstruction().
This is a property of an instruction and should be a member
function of `SILInstruction` and not a free function in
`DebugUtils`. Discussed with Adrian.
2018-04-11 10:14:21 -07:00
Andrew Trick
9703d56e03 [exclusivity] Remove dead access markers after optimization.
Generalized to handle scope markers which will become common with future
ownership and lifetime dependence markers.
2018-03-11 23:13:30 -07:00
Arnold Schwaighofer
89e972f5a8 SILGen: Implement withoutActuallyEscaping verification
Check that an ``withoutActuallyEscaping(noescape_closure) { // scope}`` closure
has not escaped in the scope using the ``is_escaping_closure %closure``
instruction.

rdar://35525730
2018-03-07 09:00:12 -08:00
Andrew Trick
a4c78dcf72 [NFC] Split up SimplifyCFG and JumpThreadSimplifyCFG transform.
A couple of lines of boilerplate simplies life. It's always nice when the
Transform class matches the formal pass definition. This way, the back trace
doesn't point you to the wrong transform.

There's no good reason to share Transform classes that I know of.
2018-02-22 20:16:44 -08:00
Arnold Schwaighofer
d490c22bb4 SimplifyCFG: Skip convert_escape_to_noescape in try_apply -> apply optimization 2018-02-13 09:38:02 -08:00
Erik Eckstein
4f8cccff68 SimplifyCFG: do constant folding also in SimplifyCFG.
This enables to optimize chains of constant-foldable terminal instructions, for which we would have needed multiple ConstantPropagaion-SimplifyCFG pass pairs in the pipeline otherwise.
See the test file for an example.
2018-01-19 11:32:33 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
485463b8f7 SimplifyCFG: do constant folding also in SimplifyCFG.
This enables to optimize chains of constant-foldable terminal instructions, for which we would have needed multiple ConstantPropagaion-SimplifyCFG pass pairs in the pipeline otherwise.
See the test file for an example.
2018-01-18 18:27:17 -08:00
Michael Gottesman
dfd40e4443 [cast-optimizer] Move the cast optimizer into its own .cpp file.
Local.cpp was ~3k lines of which 1.5k (i.e. 1/2) was the cast optimizer. This
commit extracts the cast optimizer into its own .cpp and .h file. It is large
enough to stand on its own and allows for Local.cpp to return to being a small
group of helper functions.

I am making some changes in this area due to the change in certain function
conventions caused by the +0-normal-arg work. I am just trying to leave the area
a little cleaner than before.
2018-01-13 18:26:22 -08:00
David Zarzycki
68c696dbc1 [SIL] NFC: Replace boilerplate projection with swift::ArrayRefView 2017-12-28 09:51:29 -05:00
Slava Pestov
1f79af7504 SIL: Use objc_method instruction for Objective-C protocol method calls
Fixes <rdar://problem/15933365>.
2017-11-29 16:26:43 -08:00
Arnold Schwaighofer
ea9907ae15 Revert "SIL: Use objc_method instruction for Objective-C protocol method calls" 2017-11-29 11:19:46 -08:00
Slava Pestov
1ee0970934 SIL: Use objc_method instruction for Objective-C protocol method calls
Fixes <rdar://problem/15933365>.
2017-11-29 01:22:05 -08:00
John McCall
14d6390352 Add "yield" and "unwind" instructions to SIL. 2017-11-07 03:51:54 -05:00
Joe Shajrawi
72c66cab9a Further cond_br support in the Optimizer: SimplifyCFG and Utils' change target 2017-09-26 11:10:51 -07:00