Commit Graph

45 Commits

Author SHA1 Message Date
Philip Reames
0e9b7998e6 [LoopPred] Fix a bug in unconditional latch bailout introduced in r362284
This is a really silly bug that even a simple test w/an unconditional latch would have caught.  I tried to guard against the case, but put it in the wrong if check.  Oops.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362727 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-06 18:02:36 +00:00
Philip Reames
8f95d9be11 [LoopPred] Convert a second member function to a static helper [NFC]
(And remember to actually mark the first one static.)



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362415 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-03 16:23:20 +00:00
Philip Reames
1a002c683a [LoopPred] Convert member function to free helper function [NFC]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362411 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-03 16:17:14 +00:00
Richard Trieu
338487191e Inline variable into assert to fix unused variable warning.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362285 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-01 03:32:20 +00:00
Philip Reames
26777bcd97 [LoopPred] Eliminate a redundant/confusing cover function [NFC]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362284 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-01 03:09:28 +00:00
Philip Reames
f9207feee4 [LoopPred] Handle a subset of NE comparison based latches
At the moment, LoopPredication completely bails out if it sees a latch of the form:
%cmp = icmp ne %iv, %N
br i1 %cmp, label %loop, label %exit
OR
%cmp = icmp ne %iv.next, %NPlus1
br i1 %cmp, label %loop, label %exit

This is unfortunate since this is exactly the form that LFTR likes to produce. So, go ahead and recognize simple cases where we can.

For pre-increment loops, we leverage the fact that LFTR likes canonical counters (i.e. those starting at zero) and a (presumed) range fact on RHS to discharge the check trivially.

For post-increment forms, the key insight is in remembering that LFTR had to insert a (N+1) for the RHS. CVP can hopefully prove that add nsw/nuw (if there's appropriate range on N to start with). This leaves us both with the post-inc IV and the RHS involving an nsw/nuw add, and SCEV can discharge that with no problem.

This does still need to be extended to handle non-one steps, or other harder patterns of variable (but range restricted) starting values. That'll come later.

Differential Revision: https://reviews.llvm.org/D62748



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362282 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-01 00:31:58 +00:00
Philip Reames
382ffde1a1 [LoopPred] Fix a blatantly obvious bug in r358684
The bug is that I didn't check whether the operand of the invariant_loads were themselves invariant.  I don't know how this got missed in the patch and review.  I even had an unreduced test case locally, and I remember handling this case, but I must have lost it in one of the rebases.  Oops.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358688 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-18 17:01:19 +00:00
Philip Reames
131a1e538e [LoopPredication] Allow predication of loop invariant computations (within the loop)
The purpose of this patch is to eliminate a pass ordering dependence between LoopPredication and LICM. To understand the purpose, consider the following snippet of code inside some loop 'L' with IV 'i'
A = _a.length;
guard (i < A)
a = _a[i]
B = _b.length;
guard (i < B);
b = _b[i];
...
Z = _z.length;
guard (i < Z)
z = _z[i]
accum += a + b + ... + z;

Today, we need LICM to hoist the length loads, LoopPredication to make the guards loop invariant, and TrivialUnswitch to eliminate the loop invariant guard to establish must execute for the next length load. Today, if we can't prove speculation safety, we'd have to iterate these three passes 26 times to reduce this example down to the minimal form.

Using the fact that the array lengths are known to be invariant, we can short circuit this iteration. By forming the loop invariant form of all the guards at once, we remove the need for LoopPredication from the iterative cycle. At the moment, we'd still have to iterate LICM and TrivialUnswitch; we'll leave that part for later.

As a secondary benefit, this allows LoopPred to expose peeling oppurtunities in a much more obvious manner.  See the udiv test changes as an example.  If the udiv was not hoistable (i.e. we couldn't prove speculation safety) this would be an example where peeling becomes obviously profitable whereas it wasn't before.

A couple of subtleties in the implementation:
- SCEV's isSafeToExpand guarantees speculation safety (i.e. let's us expand at a new point).  It is not a precondition for expansion if we know the SCEV corresponds to a Value which dominates the requested expansion point.
- SCEV's isLoopInvariant returns true for expressions which compute the same value across all iterations executed, regardless of where the original Value is located.  (i.e. it can be in the loop)  This implies we have a speculation burden to prove before expanding them outside loops.
- invariant_loads and AA->pointsToConstantMemory are two cases that SCEV currently does not handle, but meets the SCEV definition of invariance.  I plan to sink this part into SCEV once this has baked for a bit.

Differential Revision: https://reviews.llvm.org/D60093



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358684 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-18 16:33:17 +00:00
Philip Reames
a1378078d8 [LoopPred] Stop passing around builders [NFC]
This is a preparatory patch for D60093. This patch itself is NFC, but while preparing this I noticed and committed a small hoisting change in rL358419.

The basic structure of the new scheme is that we pass around the guard ("the using instruction"), and select an optimal insert point by examining operands at each construction point. This seems conceptually a bit cleaner to start with as it isolates the knowledge about insertion safety at the actual insertion point.

Note that the non-hoisting path is not actually used at the moment. That's not exercised until D60093 is rebased on this one.

Differential Revision: https://reviews.llvm.org/D60718



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358434 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-15 18:15:08 +00:00
Philip Reames
7fe3ccfcdc [LoopPred] Hoist and of predicated checks where legal
If we have multiple range checks which can be predicated, hoist the and of the results outside the loop.  This minorly cleans up the resulting IR, but the main motivation is as a building block for D60093.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358419 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-15 15:53:25 +00:00
Philip Reames
2f2c88671c [LoopPredication] Simplify widenable condition handling [NFC]
The code doesn't actually need any of the information about the widenable condition at this level.  The only thing we need is to ensure the WC call is the last thing anded in, and even that is a quirk we should really look to remove.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357448 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-02 02:42:57 +00:00
Philip Reames
4513bbfe09 [LoopPred] Rename a variable to simply a future patch [NFC]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357433 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-01 22:39:54 +00:00
Philip Reames
a3d1fd2535 [LoopPred] Be uniform about proving generated conditions
We'd been optimizing the case where the predicate was obviously true, do the same for the false case.  Mostly just for completeness sake, but also may improve compile time in loops which will exit through the guard.  Such loops are presumed rare in fastpath code, but may be present down untaken paths, so optimizing for them is still useful.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357408 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-01 16:26:08 +00:00
Philip Reames
071b5c0eb5 [LoopPred] Delete the old condition expressions if unused
LoopPredication was replacing the original condition, but leaving the instructions to compute the old conditions around.  This would get cleaned up by other passes of course, but we might as well do it eagerly.  That also makes the test output less confusing.  



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357406 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-01 16:05:15 +00:00
Philip Reames
7bbe85d367 [LoopPredication] Remove stale TODO
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357331 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-29 23:10:01 +00:00
Philip Reames
0871289fd9 [LoopPredication] Use the builder's insertion point everywhere [NFC]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357330 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-29 23:06:57 +00:00
Max Kazantsev
5b032bb140 [LoopPredication] Support guards expressed as branches by widenable condition
This patch adds support of guards expressed as branches by widenable
conditions in Loop Predication.

Differential Revision: https://reviews.llvm.org/D56081
Reviewed By: reames


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351805 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-22 11:49:06 +00:00
Max Kazantsev
99ddd77ed3 [NFC] Factor out some reusable logic
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351794 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-22 10:13:36 +00:00
Chandler Carruth
6b547686c5 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-19 08:50:56 +00:00
Max Kazantsev
08ef2bb50e [NFC] Use utility function for guards detection
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350064 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-26 08:22:25 +00:00
Fedor Sergeev
edcfeaeb8e [LoopPredication] add some simple stats
Just adding some useful statistics to LoopPredication pass
which was lacking any of these.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344681 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-17 09:02:54 +00:00
Fangrui Song
af7b1832a0 Remove trailing space
sed -Ei 's/[[:space:]]+$//' include/**/*.{def,h,td} lib/**/*.{cpp,h}

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338293 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-30 19:41:25 +00:00
Nicola Zaghen
0818e789cb Rename DEBUG macro to LLVM_DEBUG.
The DEBUG() macro is very generic so it might clash with other projects.
The renaming was done as follows:
- git grep -l 'DEBUG' | xargs sed -i 's/\bDEBUG\s\?(/LLVM_DEBUG(/g'
- git diff -U0 master | ../clang/tools/clang-format/clang-format-diff.py -i -p1 -style LLVM
- Manual change to APInt
- Manually chage DOCS as regex doesn't match it.

In the transition period the DEBUG() macro is still present and aliased
to the LLVM_DEBUG() one.

Differential Revision: https://reviews.llvm.org/D43624



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332240 91177308-0d34-0410-b5e6-96231b3b80d8
2018-05-14 12:53:11 +00:00
Anna Thomas
ded959f9f4 [LoopPredication] Add profitability check based on BPI
Summary:
LoopPredication is not profitable when the loop is known to always exit
through some block other than the latch block.
A coarse grained latch check can cause loop predication to predicate the
loop, and unconditionally deoptimize.

However, without predicating the loop, the guard may never fail within the
loop during the dynamic execution because the non-latch loop termination
condition exits the loop before the latch condition causes the loop to
exit.
We teach LP about this using BranchProfileInfo pass.

Reviewers: apilipenko, skatkov, mkazantsev, reames

Reviewed by: skatkov

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D44667

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328210 91177308-0d34-0410-b5e6-96231b3b80d8
2018-03-22 16:03:59 +00:00
Serguei Katkov
5e12a214f6 Rename and move utility function getLatchPredicateForGuard. NFC.
Rename getLatchPredicateForGuard to more common name
getFlippedStrictnessPredicate and move it to ICmpInst class.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324717 91177308-0d34-0410-b5e6-96231b3b80d8
2018-02-09 07:59:07 +00:00
Serguei Katkov
91a90a2587 [Loop Predication] Teach LP about reverse loops with uge and sge latch conditions
Add support of uge and sge latch condition to Loop Prediction for
reverse loops.

Reviewers: apilipenko, mkazantsev, sanjoy, anna
Reviewed By: anna
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D42837


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324589 91177308-0d34-0410-b5e6-96231b3b80d8
2018-02-08 10:34:08 +00:00
Serguei Katkov
40a9bb2b06 [LoopPrediction] Introduce utility function getLatchPredicateForGuard. NFC.
Factor out getting the predicate for latch condition in a guard to
utility function getLatchPredicateForGuard.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324450 91177308-0d34-0410-b5e6-96231b3b80d8
2018-02-07 06:53:37 +00:00
Hiroshi Inoue
8040eab589 [NFC] fix trivial typos in comments and documents
"in in" -> "in", "on on" -> "on" etc.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323508 91177308-0d34-0410-b5e6-96231b3b80d8
2018-01-26 08:15:29 +00:00
Anna Thomas
7c3eddc7d6 [Loop Predication] Teach LP about reverse loops
Summary:
Currently, we only support predication for forward loops with step
of 1.  This patch enables loop predication for reverse or
countdownLoops, which satisfy the following conditions:
   1. The step of the IV is -1.
   2. The loop has a singe latch as B(X) = X <pred>
latchLimit with pred as s> or u>
   3. The IV of the guard is the decrement
IV of the latch condition (Guard is: G(X) = X-1 u< guardLimit).

This patch was downstream for a while and is the last series of patches
that's from our LP implementation downstream.

Reviewers: apilipenko, mkazantsev, sanjoy

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D40353

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319659 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-04 15:11:48 +00:00
Anna Thomas
c9ed638d21 [LoopPredication] NFC: Refactored code to separate out functions being reused
Summary:
Refactored the code to separate out common functions that are being
reused.
This is to reduce the changes for changes coming up wrt loop
predication with reverse loops.

This refactoring is what we have in our downstream code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317324 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-03 14:25:39 +00:00
Anna Thomas
b69a2a9ae3 [LoopPredication] Enable predication when latchCheckIV is wider than rangeCheck
Summary:
This patch allows us to predicate range checks that have a type narrower than
the latch check type. We leverage SCEV analysis to identify a truncate for the
latchLimit and latchStart.
There is also safety checks in place which requires the start and limit to be
known at compile time. We require this to make sure that the SCEV truncate expr
for the IV corresponding to the latch does not cause us to lose information
about the IV range.
Added tests show the loop predication over range checks that are of various
types and are narrower than the latch type.
This enhancement has been in our downstream tree for a while.

Reviewers: apilipenko, sanjoy, mkazantsev

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D39500

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317269 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-02 21:21:02 +00:00
Artur Pilipenko
c35c11558b [LoopPredication] Handle the case when the guard and the latch IV have different offsets
This is a follow up change for D37569.

Currently the transformation is limited to the case when:
 * The loop has a single latch with the condition of the form: ++i <pred> latchLimit, where <pred> is u<, u<=, s<, or s<=.
 * The step of the IV used in the latch condition is 1.
 * The IV of the latch condition is the same as the post increment IV of the guard condition.
 * The guard condition is of the form i u< guardLimit.

This patch enables the transform in the case when the latch is

 latchStart + i <pred> latchLimit, where <pred> is u<, u<=, s<, or s<=.

And the guard is

 guardStart + i u< guardLimit

Reviewed By: anna

Differential Revision: https://reviews.llvm.org/D39097


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316768 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-27 14:46:17 +00:00
Artur Pilipenko
2a079134ab [LoopPredication] Check whether the loop is already guarded by the first iteration check condition
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315623 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-12 21:21:17 +00:00
Artur Pilipenko
946dd32421 [LoopPredication] Support ule, sle latch predicates
This is a follow up for the loop predication change 313981 to support ule, sle latch predicates.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D38177

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315616 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-12 20:40:27 +00:00
Artur Pilipenko
cbb0a9e68e Rework loop predication pass
We've found a serious issue with the current implementation of loop predication.
The current implementation relies on SCEV and this turned out to be problematic.
To fix the problem we had to rework the pass substantially. We have had the
reworked implementation in our downstream tree for a while. This is the initial
patch of the series of changes to upstream the new implementation.

For now the transformation is limited to the following case:
  * The loop has a single latch with either ult or slt icmp condition.
  * The step of the IV used in the latch condition is 1.
  * The IV of the latch condition is the same as the post increment IV of the guard condition.
  * The guard condition is ult.

See the review or the LoopPredication.cpp header for the details about the
problem and the new implementation.

Reviewed By: sanjoy, mkazantsev

Differential Revision: https://reviews.llvm.org/D37569


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313981 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-22 13:13:57 +00:00
Chandler Carruth
e3e43d9d57 Sort the remaining #include lines in include/... and lib/....
I did this a long time ago with a janky python script, but now
clang-format has built-in support for this. I fed clang-format every
line with a #include and let it re-sort things according to the precise
LLVM rules for include ordering baked into clang-format these days.

I've reverted a number of files where the results of sorting includes
isn't healthy. Either places where we have legacy code relying on
particular include ordering (where possible, I'll fix these separately)
or where we have particular formatting around #include lines that
I didn't want to disturb in this patch.

This patch is *entirely* mechanical. If you get merge conflicts or
anything, just ignore the changes in this patch and run clang-format
over your #include lines in the files.

Sorry for any noise here, but it is important to keep these things
stable. I was seeing an increasing number of patches with irrelevant
re-ordering of #include lines because clang-format was used. This patch
at least isolates that churn, makes it easy to skip when resolving
conflicts, and gets us to a clean baseline (again).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304787 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-06 11:49:48 +00:00
Artur Pilipenko
63e5aa71e0 [LoopPredication] NFC. Add extra debug output in case we fail to parse the range check
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303544 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-22 12:06:57 +00:00
Artur Pilipenko
73576b5741 [LoopPredication] NFC. Move a nested struct declaration before the fields, clang-format a bit
This will simplify the diff for an upcoming review.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303543 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-22 12:01:32 +00:00
Artur Pilipenko
285ad946f7 [LoopPredication] NFC. Extract LoopICmp struct and parseLoopICmp helper
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303427 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-19 14:02:46 +00:00
Artur Pilipenko
481df100e8 [LoopPredication] NFC. Extract LoopPredication::expandCheck helper
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303426 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-19 14:00:58 +00:00
Artur Pilipenko
f7a732400a [LoopPredication] NFC. Extract CanExpand helper lambda
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303425 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-19 14:00:04 +00:00
Artur Pilipenko
92e33060a2 [LoopPredication] NFC. Add an early exit if there is no guards in the loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303424 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-19 13:59:34 +00:00
Artur Pilipenko
7e587ddfd9 Loop predication expand both sides of the widened condition
This is a fix for a loop predication bug which resulted in malformed IR generation.

Loop invariant side of the widened condition is not guaranteed to be available in the preheader as is, so we need to expand it as well. See added unsigned_loop_0_to_n_hoist_length test for example.

Reviewed By: sanjoy, mkazantsev

Differential Revision: https://reviews.llvm.org/D30099


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296345 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-27 15:44:49 +00:00
Artur Pilipenko
38847f25fe [LoopPredication] Add a new line to debug output in LoopPredication pass
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293762 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-01 12:25:38 +00:00
Artur Pilipenko
1dd101bfef [Guards] Introduce loop-predication pass
This patch introduces guard based loop predication optimization. The new LoopPredication pass tries to convert loop variant range checks to loop invariant by widening checks across loop iterations. For example, it will convert

  for (i = 0; i < n; i++) {
    guard(i < len);
    ...
  }

to

  for (i = 0; i < n; i++) {
    guard(n - 1 < len);
    ...
  }

After this transformation the condition of the guard is loop invariant, so loop-unswitch can later unswitch the loop by this condition which basically predicates the loop by the widened condition:

  if (n - 1 < len)
    for (i = 0; i < n; i++) {
      ...
    } 
  else
    deoptimize

This patch relies on an NFC change to make ScalarEvolution::isMonotonicPredicate public (revision 293062).

Reviewed By: sanjoy

Differential Revision: https://reviews.llvm.org/D29034


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293064 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-25 16:00:44 +00:00