Commit Graph

49 Commits

Author SHA1 Message Date
Erik Eckstein b058869656 SILOptimizer: replace the recursive CFG walk in the RemoveUnreachable utility with a worklist algorithm.
This avoids deep stack nesting for large CFGs. It also makes the code simpler.
2019-05-08 13:55:00 -07: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 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
Andrew Trick c1164c0bac Add splitCriticalEdgesFrom API. 2018-10-26 23:18:37 -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
Andrew Trick 2ccc089b27 SILGenFunction::mergeCleanupBlocks.
Avoid emitting unnecessary basic block for cleanup chains. This is a
general approach that handles all cases while simplifying SILGen
emission and keeping the CFG in a valid state during SILGen.
2018-10-19 22:22:23 -07:00
Gogul Balakrishnan c3759101f6 Bugfix in dominator patching logic in mergeBasicBlockWithSuccessor. 2018-09-27 00:26:16 -07:00
Michael Gottesman d57a88af0d [gardening] Rename references to SILPHIArgument => SILPhiArgument. 2018-09-25 22:23:34 -07:00
Erik Eckstein a015d9111d SIL optimizer: consider non-branch terminators with a single successor for critical edges.
For example: a switch_enum for a single-case enum. It has only a single successor edge, but needs to be split as well (if the destination block has multiple predecessors).

Fixes a crash in SimplifyCFG.
rdar://problem/44675677
2018-09-24 10:28:25 -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
John McCall e8d80c2d12 Convert if-chain to an exhaustive switch and add the missing case for 'yield'. 2018-08-21 15:15:15 -04:00
John McCall 6a2a2b8324 Modify successors in-place in changeBranchTarget unless dropping args. 2018-08-19 18:22:12 -04:00
John McCall 512e55683e Make it easy to create a SILBasicBlock immediately before a target block.
Also, make "after" requests explicit in the API.
2018-08-18 12:36:36 -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 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 49adf11a00 [cfg] Add back in bool return value, returning a value to it this time. 2017-11-15 21:52:50 -08:00
Slava Pestov 2aa126e680 SILOptimizer: Fix a warning 2017-11-15 20:58:58 -08:00
Michael Gottesman 1c33bc19c4 [cfg] Add Ownership SIL utility method splitAllCondBrCriticalEdgesWithNonTrivialArgs.
Currently, the ownership verifier assumes that all cond_br with critical edges
do not have non-trivial arguments. This utility method fixes any such issues and
should be run /after/ any passes that mess with the CFG in ownership SIL if this
could come up.

Chopping this off of a larger commit.

rdar://31521023
2017-11-14 12:04:58 -08:00
Michael Gottesman 1288bff937 [cfg] Add utility method completeJointPostDominanceSet.
This helper utility given a set of uses/defs determines the set of blocks that
together with the user blocks jointly post-dominate the def blocks. In a sense
this is completing the providing set of user blocks to a joint-post dominating
set. This completion is not unique.

I am adding this method because often times when working with Ownership SIL, one
needs to hoist/sink operations and then compensate to ensure that ownership
properties are still preserved.

I think with a little bit of work I can get the ownership model eliminator to
use this routine (since the condition for ownership to be correct on an @owned
value is an empty joint-post dominating completion. I wrote it b/c I need it in
pred-memopts and I expect it to be a general useful routine for Ownership SIL.

rdar://31521023
2017-11-14 09:46:51 -08:00
John McCall 14d6390352 Add "yield" and "unwind" instructions to SIL. 2017-11-07 03:51:54 -05:00
Joe Shajrawi f4e6bb3725 PGO: add support for checked_cast__br 2017-09-26 11:14:55 -07:00
Joe Shajrawi 64830c2d5e PGO: add support for checked_cast_addr_br 2017-09-26 11:14:31 -07:00
Joe Shajrawi 72c66cab9a Further cond_br support in the Optimizer: SimplifyCFG and Utils' change target 2017-09-26 11:10:51 -07:00
Andrew Trick e272564d63 [sil-opaque-values] Fix UpdateSSA to handle checked_cast_value_br. 2017-09-19 09:09:48 -07:00
Roman Levenstein 45c2c4af0e Re-factoring: Get rid of useless arguments in "create*Apply" functions
Till now createApply, createTryApply, createPartialApply were taking some arguments like SubstCalleeType or ResultType. But these arguments are redundant and can be easily derived from other arguments of these functions. There is no need to put the burden of their computation on the clients of these APIs.

The removal of these redundant parameters simplifies the APIs and reduces the possibility of providing mismatched types by clients, which often happened in the past.
2017-05-10 08:03:37 -07:00
practicalswift 492f5cd35a [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar)
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.

The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).

See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
2017-05-05 09:45:53 +02:00
Joe Shajrawi 1f626304f1 Add support for conditional checked cast instruction for opaque value types + SILGen support for it 2017-03-06 16:35:27 -08:00
Michael Gottesman ea1f804207 [semantic-sil] Eliminate ValueOwnershipKind::Any from SILPHIArguments in Semantic SIL.
Most of this involved sprinkling ValueOwnershipKind::Owned in many places. In
some of these places, I am sure I was too cavalier and I expect some of them to
be trivial. The verifier will help me to track those down.

On the other hand, I do expect there to be some places where we are willing to
accept guaranteed+trivial or owned+trivial. In those cases, I am going to
provide an aggregate ValueOwnershipKind that will then tell SILArgument that it
should disambiguate using the type. This will eliminate the ackwardness from
such code.

I am going to use a verifier to fix such cases.

This commit also begins the serialization of ValueOwnershipKind of arguments,
but does not implement parsing of value ownership kinds. That and undef are the
last places that we still use ValueOwnershipKind::Any.

rdar://29791263
2017-01-10 20:05:23 -08:00
practicalswift 6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Michael Gottesman 4e8ff35df5 [semantic-sil] Add ValueOwnershipKind field to SILPHIArgument and split Argument creation methods into one for SILPHIArgument and another for SILFunctionArgument.
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.

Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.

In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.

rdar://29671437
2016-12-18 14:48:35 -08:00
Michael Gottesman 38ec08f45f [gardening] Standardize SILBasicBlock successor/predecessor methods that deal with blocks rather than the full successor data structure to have the suffix 'Block'.
This was already done for getSuccessorBlocks() to distinguish getting successor
blocks from getting the full list of SILSuccessors via getSuccessors(). This
commit just makes all of the successor/predecessor code follow that naming
convention.

Some examples:

getSingleSuccessor() => getSingleSuccessorBlock().
isSuccessor() => isSuccessorBlock().
getPreds() => getPredecessorBlocks().

Really, IMO, we should consider renaming SILSuccessor to a more verbose name so
that it is clear that it is more of an internal detail of SILBasicBlock's
implementation rather than something that one should consider as apart of one's
mental model of the IR when one really wants to be thinking about predecessor
and successor blocks. But that is not what this commit is trying to change, it
is just trying to eliminate a bit of technical debt by making the naming
conventions here consistent.
2016-11-27 12:32:51 -08:00
Michael Gottesman 96837babda Merge pull request #5920 from gottesmm/vacation_gardening
Vacation gardening
2016-11-25 09:17:21 -06:00
Michael Gottesman a998d98924 [gardening] SILBasicBlock::splitBasicBlock() => *::split().
The BasicBlock suffix is redundant.
2016-11-25 01:14:43 -06:00
Michael Gottesman bf6920650c [gardening] Drop BB from all argument related code in SILBasicBlock.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.

Some examples:

getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
2016-11-25 01:14:36 -06:00
Michael Gottesman e42bf07af4 [gardening] Always create SILBasicBlocks via SILFunction::createBasicBlock.
This eliminates all inline creation of SILBasicBlock via placement new.

There are a few reasons to do this:

1. A SILBasicBlock is always created with a parent function. This commit
formalizes this into the SILBasicBlock API by only allowing for SILFunctions to
create SILBasicBlocks. This is implemented via the type system by making all
SILBasicBlock constructors private. Since SILFunction is a friend of
SILBasicBlock, SILFunction can still create a SILBasicBlock without issue.

2. Since all SILBasicBlocks will be created in only a few functions, it becomes
very easy to determine using instruments the amount of memory being allocated
for SILBasicBlocks by simply inverting the call tree in Allocations.

With LTO+PGO, normal inlining can occur if profitable so there shouldn't be
overhead that we care about in shipping compilers.
2016-11-25 01:12:49 -06:00
practicalswift 797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
Xin Tong be793d26eb Remove last bit of retain release code motion in SILCodeMotion. All these code are
replaced by retain release code motion. This code has been disabled for sometime now.

This should bring the retain release code motion into a close. The retain release
code motion pipeline looks like this. There could be some minor cleanups after this though.

1. We perform a global data flow for retain release code motion in RRCM (RetainReleaseCodeMotion)
2. We perform a local form of retain release code motion in SILCodeMotion. This is more
for cases which can not be handled in RRCM. e.g. sinking into a switch is more efficiently
done in a local form, the retain is not needed on the None block. Release on SILArgument needs
to be split to incoming values, this can not be done in RRCM and other cases.
3. We do not perform code motion in ASO, only elimination which are very important.

Some modifications to test cases, they look different, but functionally the same.
RRCM has this canonicalization effect, i.e. it uses the rc root, instead of
the SSA value the retain/release is currently using. As a result some test cases need
to be modified.

I also removed some test cases that do not make sense anymore and lot of duplicate test
cases between earlycodemotion.sil and latecodemotion.sil. These tests cases only have retains
and should be used to test early code motion.
2016-06-08 10:49:33 -07:00
Erik Eckstein 8e624a655b remove unneeded allocation in swift::splitAllCriticalEdges 2016-03-27 10:59:29 -07:00
Erik Eckstein 6e00d8a9e1 add asserts in replaceBranchTarget() and use casts instead of dyn_casts 2016-02-02 17:46:32 -08:00
Erik Eckstein 74d44b74e7 SIL: remove SILValue::getDef and add a cast operator to ValueBase * as a repelacement. NFC. 2016-01-25 15:00:49 -08:00
practicalswift 8efa5f587e [gardening] Remove "-*- C++ -*-" tag from .cpp files
Emacs assumes .h files are C files by default which is why the
tag "-*- C++ -*-" is needed.

.cpp files do not have this problem.
2016-01-23 12:09:32 +01:00
Erik Eckstein ec172cde5b Remove SILValue::replaceAllUsesWith.
It's not needed anymore because we can use ValueBase::replaceAllUses
2016-01-21 16:04:30 -08:00
Erik Eckstein 2db6f3d213 SIL: remove multiple result values from SILValue
As there are no instructions left which produce multiple result values, this is a NFC regarding the generated SIL and generated code.
Although this commit is large, most changes are straightforward adoptions to the changes in the ValueBase and SILValue classes.
2016-01-21 10:30:31 -08:00
Michael Gottesman 5b1ebe12a9 Remove the case 'Invalid' from the TermKind enum and just use an unreachable in the ValueKind -> TermKind switch instead.
In all of the cases where this is being used, we already immediately perform an
unreachable if we find a TermKind::Invalid. So simplify the code and move it
into the conversion switch itself.
2016-01-11 15:44:05 -08:00
Michael Gottesman a7bbdd0846 Remove nullptr access. NewBr here is always nullptr.
Found with clang static analyzer.
2016-01-08 19:28:43 -08:00
Zach Panzarino e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Michael Gottesman 3eca15623b Change 6 non-exhaustive switches on ValueKind to be exhaustive switches on TermKind. NFC.
This exposed the first interesting bug found by using TermKind, in DCE we were
not properly handling switch_enum_addr and checked_cast_addr_br.

SR-335
rdar://23980060
2015-12-21 17:12:06 -06:00
practicalswift 8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00
Andrew Trick 739b0e9c56 Reorganize SILOptimizer directories for better discoverability.
(libraries now)

It has been generally agreed that we need to do this reorg, and now
seems like the perfect time. Some major pass reorganization is in the
works.

This does not have to be the final word on the matter. The consensus
among those working on the code is that it's much better than what we
had and a better starting point for future bike shedding.

Note that the previous organization was designed to allow separate
analysis and optimization libraries. It turns out this is an
artificial distinction and not an important goal.
2015-12-11 15:14:23 -08:00