Use the inliner's heuristic to decide which instructions are 'free' (constants,
etc).
We were not jumpthreading a block because it had four instruction in it - two of
them integer_literals.
rdar://18594600
Swift SVN r22712
Unwrap the argument to select_enum to determine if it is the same
condition as is used in the terminator we are looking to optimize.
This particular code has become a bit unwieldy and needs larger
generalization and refactoring, but this restores the previous
optimization for now.
Resolves rdar://problem/18592542.
Swift SVN r22655
Simplify binary switches to select_enum instead of enum_is_tag, and make a first attempt at changing passes over to recognize limited forms of select_enum instead of enum_is_tag. There is one case in test/SILPasses/simplify_cfg.sil I wasn't able to figure out, and there are a lot more general passes we could define in terms of select_enum.
Swift SVN r22615
I also extracted out an additional method clearBlockBody() from the body
of removeDeadBlocks() since I need that functionality exposed in
Function Signature Opts.
Swift SVN r22560
This pattern occurs a lot in the following benchmark:
let loopcount = 1000000000
let arraysize = 100000
let range = 100..<200
let prtrange = (range.startIndex-2)..<(range.startIndex+2)
var vector = [Double]( count: 5000, repeatedValue: 0.0 )
let alfa = 1.0
for var i=0;i<loopcount;i++ {
vector[range] = vector[range].map() { $0 + alfa }
}
Swift SVN r22273
This will hopefully make it clearer as we onboard people that
SimplifyInstruction should not add instructions to the IR by making it clearer
that it is an analysis, not a pass.
Swift SVN r21752
This matches the name for SwitchEnumInst::getCaseDestination() and includes the word
'unique' so that the name self documents.
I also removed a local function doing the same work in SimplifyCFG and changed
its user to use getUniqueCaseForDestination instead.
Swift SVN r21339
I noticed this while reviewing some code. It's possible to have a single
conditional branch where both the true and false destination are the
same block. The argument simplification code would crash in that case
due to removeArgumentFromTerminator assuming this couldn't happen, and
because the loop over blocks would attempt to visit the same terminator
twice, with the first visit invalidating the iterator over
SILSuccessors.
Swift SVN r21245
I hit this building with another change that I have.
In cases where we have a switch_enum that is dominated by another
switch_enum, where the dominating switch_enum branches to a block with
no block argument, but the dominated switch_enum branches to a block
with a block argument, we need to synthesize the block argument to pass
by using unchecked_enum_data.
Swift SVN r21167
simplifyInstruction conciously does not create constants (AFAIK) so we need to
run instruction combine after simplify-cfg to enable more cfg simplification
exposed by jumpthreading. We can revisit this decision in a follow-up commit if
necessary (I believe it to be useful for simplifyInstruction to be able to
create constants and for simplifycfg to use simplifyInstruction on the branch
condition).
O:
benchmark , baserun0 , optrun0 , delta, speedup
Fibonacci , 1473.00 , 1317.00 , 75.00 , 5.8%
Histogram , 407.00 , 390.00 , 23.00 , 6.1%
InsertionSort , 1273.00 , 1200.00 , 79.00 , 6.7%
Life , 74.00 , 69.00 , 4.00 , 5.8%
NestedLoop , 937.00 , 883.00 , 56.00 , 6.4%
R17315246 , 8.00 , 801.00 , 793.00 , -99.0%
SelectionSort , 1150.00 , 921.00 , 226.00 , 24.5%
Ounchecked:
Histogram , 394.00 , 342.00 , 51.00 , 15.0%
InsertionSort , 1122.00 , 1024.00 , 85.00 , 8.3%
Life , 57.00 , 44.00 , 9.00 , 20.9%
SelectionSort , 1312.00 , 1060.00 , 246.00 , 23.3%
The R17315246 regression is somewhat bad. We dependent on a loop form such that
LLVM transforms the loop into an inner loop that just iterates from x to y and
this is unrolled (good version) the slow version has a loop with cond_fail
control flow and is not unrolled. The loop does nothing more than count up.
I have not being able to narrow this down further.
rdar://16821595
Swift SVN r21124
As we do for conditional branches, try to optimized checked_cast_br to
branch when we have an identical dominating checked_cast_br.
<rdar://problem/17346767>
Swift SVN r19558
hierarchy. I still need to figure out a reliable way to write testcases
for this. For now it's ensured via an assertion in SILCloner::postprocess.
Swift SVN r18917
Instead of erasing instructions immediately, keep track of them until
we've found all the ones we'll erase, and then erase them.
It's not clear to me why the code was hitting an assert as it was
written, but this works around the problem.
Fixes <rdar://problem/16805316>.
Swift SVN r17372
In cases where there is only one successor to a switch_enum that does
not end with "unreachable", replace the switch_enum with an
unchecked_enum_data extracting the data for that one valid successor.
Swift SVN r17312
We do not necessarily want to grab the BB arg that we will use in the
branch we are creating from the same block that the switch_enum we are
eliminating is in.
There is still a latent bug here for the case where the block we are
creating a branch to expects an argument but the block we would grab the
argument from doesn't have an argument. This will be fixed when I land
changes that enforce that payload producing ops like switch_enum target
branches that always have a BB arg.
Swift SVN r17239
I am planning on doing a larger change to ensure that blocks
consistently have a BB arg if they are targeted by a conditional branch
that has a payload (e.g. a switch_enum) so that we do not have to
special case like this.
Fix <rdar://problem/16761996>.
Swift SVN r17238
If we reach a switch_enum_inst via the default case of another
switch_enum_inst that is switching on the same value, we should keep
looking up the dominator tree rather than asserting.
Fixes <rdar://problem/16744848>.
Swift SVN r17020
This updates the CFG optimization pass to use the dominator tree to
eliminate redundant switch_enum instructions. It can be enhanced at a
later time to handle other conditional branching instructions.
Because jump threading can expose opportunitites for this, we run a pass
of CFG simplifications prior to running this, and since this exposes
more opportunities for those CFG simplifications, we run them again
after. Despite this, there is no measurable compile-time impact building
the stdlib with a release build of the compiler.
This in concert with the two commits that precede it reduce the runtime
of the string sort benchmark by 9%, RC4 by around 2-3%, and now the
generated SIL for optionals look slightly more sane.
Swift SVN r16510
If we have BB args that are only used in a struct/tuple extract, and
that are generated in each predecessor with a struct/tuple instruction,
retype the BB arg and replace the argument with what would have been the
extracted value.
This provides more opportunties for jump threading to kick in.
Swift SVN r16509
Add a simple pass to remove blocks that are not reachable from the entry
of the function. Run it once before simplifying blocks, and then if any
blocks are simplified run it again in case those simplifications
resulted in an unreachable loop.
Swift SVN r16364
When merging a two blocks, where the source block has a single successor
and the sink block a single predecessor, do not attempt the merge if the
two blocks are the same, i.e. a self-loop.
<rdar://problem/16605102>
Swift SVN r16335
The optimization that was simplifying:
%e = enum $T, #T.E, %payload
switch_enum %e : $T, case #T.E: bb1
to an unconditional branch was not including the payload as a block
argument.
Fixes <rdar://problem/16509020>.
Swift SVN r15860