1858 Commits

Author SHA1 Message Date
Nikita Popov
4d97a914d7 [SCEV] Use umin_seq for symbolic max BE count
We were using umin_seq when computing the exact BE count, but not
when computing the symbolic max BE count.
2022-12-07 15:32:49 +01:00
Max Kazantsev
07de5d18c9 [SCEV] Remember blocks for which we know symbolic exit count but not exact
The old code didn't bother to memoize blocks for which exact exit count is not
known. As result, in situation when exact isn't known but symbolic is known, this
info was lost. This patch fixes the situation: now we memoize when symbolic is
known (exact always implies symbolic, so this is a strict superset of what was before).

Differential Revision: https://reviews.llvm.org/D139515
Reviewed By: nikic
2022-12-07 17:51:30 +07:00
Max Kazantsev
49e928bee8 [SCEV][NFC] Sink initialization of SymbolicMaxNotTaken from ExitLimit constructor to its callers
Preserves current behavior (always select Exact if known, otherwise select Constant Max).
This is the final preparation step before letting each particular computation way to decide
how exactly it should be computed. Functional improvement is coming shortly as follow-up.

Differential Revision: https://reviews.llvm.org/D139402
Reviewed By: nikic, fhahn
2022-12-07 15:33:03 +07:00
Kazu Hirata
1f421b6d7e [llvm] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-06 22:45:17 -08:00
Roman Lebedev
46db90cc71
[SCEV] MatchBinaryOp(): try to recognize or as add-in-disguise (w/ no common bits set)
LLVM *loves* to convert `add` of operands with no common bits
into an `or`. But SCEV really doesn't deal with `or` that well,
so try extra hard to recognize this `or` as an `add`.

I believe, previously this wasn't being done because of the recursive
of this, but now that the `createSCEV()` is not recursive,
this should be fine. Unless this is *too* costly compile-time wise...

https://alive2.llvm.org/ce/z/EfapCo
2022-12-06 20:26:53 +03:00
Max Kazantsev
0c7910eab9 [NFC] Rename variable MaxBECount -> ConstantMaxBECount
Just to distinguish it from symbolic max which we plan to compute
here as well.
2022-12-05 17:48:36 +07:00
Kazu Hirata
3c09ed006a [llvm] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04 17:12:44 -08:00
Benjamin Kramer
856f7937c7 Compress a few pairs using PointerIntPairs
Use the uniform structured bindings interface where possible. NFCI.
2022-12-04 16:55:16 +01:00
Kazu Hirata
19aff0f37d [Analysis] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 19:43:04 -08:00
Jan Svoboda
abf0c6c0c0 Use CTAD on llvm::SaveAndRestore
Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D139229
2022-12-02 15:36:12 -08:00
Max Kazantsev
0b74cb4231 [SCEV] Introduce field for storing SymbolicMaxNotTaken. NFCI
ritht is initialized with either exact (if available) or
with constant max exit count. In the future, this can be improved.

Hypothetically this is not an NFC (it is possible that exact is not
known and max is known for a particular exit), but for how we use
it now it seems be an NFC (or at least I could not find an example
where it differs). constant max exit count. In the future, this can
be improved.

Differential Revision: https://reviews.llvm.org/D138699
Reviewed By: lebedev.ri
2022-11-28 17:07:33 +07:00
Kazu Hirata
ee8959d098 [Analysis] Use std::optional in ScalarEvolution.cpp (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-25 11:25:45 -08:00
Max Kazantsev
eb95ab5745 Revert "[Test] Add couple more tests where we can compute symbolic max exit count"
This reverts commit 7e3373c9e174eff6edb1214efb3e67d7b7ad447d.

Some changes that were not supposed to be commited came with it.
2022-11-25 13:37:24 +07:00
Max Kazantsev
7e3373c9e1 [Test] Add couple more tests where we can compute symbolic max exit count 2022-11-25 13:35:16 +07:00
Max Kazantsev
98307381d4 [SCEV][NFC] Rename constructor parameter to match its field name 2022-11-25 12:59:05 +07:00
Max Kazantsev
04b9a70fec [SCEV][NFC] Get rid of redundant constructor, replace with default parameter 2022-11-25 12:07:41 +07:00
Max Kazantsev
4496d553bd [SCEV] Fix misplaced \n in printout of max symbolic exit counts 2022-11-25 11:41:36 +07:00
Max Kazantsev
e5fa7eb120 [SCEV] Add printout of symbolic max backedge-taken and block exit count
We do compute it and use in optimizations, but never print it out. We need
to do it in order to be able to track improvements in its computation.
2022-11-24 19:29:58 +07:00
Max Kazantsev
fc986e38d2 [SCEV][NFC] Call getConstantMaxBackedgeTakenCount once in printout 2022-11-24 18:48:30 +07:00
Max Kazantsev
211d941188 [SCEV] Rename max backedge-taken count -> constant max backedge taken-count in printout
This is a preparatory step for introducing symbolic max backedge-taken count.
2022-11-24 18:43:42 +07:00
Max Kazantsev
24c1d36bb5 [SCEV][NFC] Rename MaxNotTaken -> ConstantMaxNotTaken
We are going to introduce SymbolicMaxNotTaken, avoid mixing
things up.

Differential Revision: https://reviews.llvm.org/D138568
Reviewed By: lebedev.ri
2022-11-24 17:26:37 +07:00
Max Kazantsev
f5eeda037f [SCEV][NFC] Fix typo in comment 2022-11-23 14:38:24 +07:00
Max Kazantsev
f285be6214 [SCEV][NFC] Introduce API for getting basic block's symbolic max exit count
Currently, it just returns exact exit count. This is a refectoring step
before it is actually implemented.
2022-11-22 16:02:58 +07:00
Max Kazantsev
b803957bce [SCEV][NFC] Call getExitCount with SymbolicMaximum when computing loop symbolic max
Currently this is NFC, because SymbolicMaximum for BB is not implemented and just
reuses exact result. However, from code purity perspective, it's a necessary step
to do. Plans to implement symbolic max for blocks are underway.
2022-11-22 15:27:14 +07:00
Florian Hahn
5dad4c6788
[SCEV] Iteratively compute ranges for deeply nested expressions.
At the moment, getRangeRef may overflow the stack for very deeply nested
expressions.

This patch introduces a new getRangeRefIter function, which first builds
a worklist of N-ary expressions and phi nodes, followed by their
operands iteratively.

getRangeRef has been extended to also take a Depth argument and it
switches to use getRangeRefIter once the depth reaches a certain
threshold.

This ensures compile-time is not impacted in general. Note that
the iterative algorithm may lead to a slightly different evaluation
order, which could result in slightly worse ranges for cyclic phis.

https://llvm-compile-time-tracker.com/compare.php?from=23c3eb7cdf3478c9db86f6cb5115821a8f0f5f40&to=e0e09fa338e77e53242bfc846e1484350ad79773&stat=instructions

Fixes #49579.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D130728
2022-11-21 21:56:14 +00:00
Florian Hahn
1625224fbb
[SCEV] Replace assert with returning CouldNotComp in computeMaxBECountForLT.
This patch removes the bail out for signed predicates and non-positive
strides in howManyLessThans and updates computeMaxBECountForLT to return
SCEVCouldNotCompute for signed predicates with negative strides.

AFAICT bail-out was only added because computeMaxBECountForLT may not
handle negative signed strides correctly. Instead of not calling
computeMaxBECountForLT at all because we bail out earlier, we can
instead return SCEVCouldNotCompute in computeMaxBECountForLT.

The max backedge taken count will be computed as the max value of the
symbolic backedge taken count.

This improves precision in cases where we can compute symbolic backedge
taken counts and also fixes a crash.

Fixes #57818.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D135667
2022-10-19 11:24:10 +01:00
Florian Hahn
a8e9742bd4
[IndVarSimplify] Clear block and loop dispositions after moving instr.
Moving an instruction can invalidate the cached block dispositions of
the corresponding SCEV. Invalidate the cached dispositions.

Also fixes a copy-paste error in forgetBlockAndLoopDispositions where
the start expression S was removed from BlockDispositions in the loop
but not the current values. This was also exposed by the new test case.

Fixes #58439.
2022-10-18 16:18:14 +01:00
Florian Hahn
4b599fa1ee
[SCEV] Verify block disposition cache.
This extends the existing SCEV verification to catch cache invalidation
issues as in #57837.

The validation logic is similar to the recently added loop disposition
cache validation in bb68b2402daa9.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D134531
2022-10-10 20:42:19 +01:00
Florian Hahn
19ad1cd5ce
Recommit "[SCEV] Support clearing Block/LoopDispositions for a single value."
This reverts commit 92f698f01fa0bb8967233a6391ada2d51849fa68.

The updated version of the patch includes handling for non-SCEVable
types. A test case has been added in ec86e9a99bca802.
2022-10-07 20:15:44 +01:00
Florian Hahn
92f698f01f
Revert "[SCEV] Support clearing Block/LoopDispositions for a single value."
This reverts commit 9e931439ddb9b6b8f655940b9d8ed6db50c2a7e2.

This commit causes a crash when TSan, e.g. with
https://lab.llvm.org/buildbot/#/builders/70/builds/28309/steps/10/logs/stdio

Reverting while I extract a reproducer and submit a fix.
2022-10-07 17:58:54 +01:00
Florian Hahn
9e931439dd
[SCEV] Support clearing Block/LoopDispositions for a single value.
Extend forgetBlockAndLoopDisposition to allow clearing information for a
single value. This can be useful when only a single value is changed,
e.g. because the instruction is moved.

We also need to clear the cached values for all SCEV users, because they
may depend on the starting value's disposition.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D134614
2022-10-07 16:07:17 +01:00
Florian Hahn
8ae0d9aa07
[LoopDeletion] Clear block & loop dispo cache after breaking backedge.
breakLoopBackedge may remove blocks and loops. Also clear block &
loop disposition to avoid the cache containing invalid blocks and loops.

The coverage for the change is provided when using an ASAN build of opt
to run the LoopDeletion unit tests; without the fix, pointers to invalid
objects would be used.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D134663
2022-09-30 11:21:58 +01:00
Florian Hahn
275bee32ad
[LoopUnroll] Forget block and loop dispositions during unrolling.
After unrolling a loop, the block and loop dispositions need to be
cleared. As we don't know which SCEVs in the loop/blocks may be
impacted, completely clear the cache. This should also fix some cases
where deleted loops remained in the LoopDispositions cache.

This fixes a verification failure surfaced by D134531.

I am planning on reviewing/updating the existing uses of
forgetLoopDispositions to check if they should be replaced by
forgetBlockAndLoopDispositions.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D134612
2022-09-27 08:49:04 +01:00
Nikita Popov
36f325413e [SCEV] Don't verify dispositions of invalid loops
This should fix the expensive checks build. Ideally we would not
have invalid loops in LoopDispositions.
2022-09-19 15:07:44 +02:00
Max Kazantsev
bb68b2402d [SCEV] Verify contents of loop disposition cache
It seems that it is sometimes broken. Initial motivation for this was
investigation of https://github.com/llvm/llvm-project/issues/56260, but
it also seems that we have found an unrelated bug in LoopFusion that leaves
broken caches.

Differential Revision: https://reviews.llvm.org/D134158
Reviewed By: nikic
2022-09-19 17:43:00 +07:00
Max Kazantsev
818b1ab84e [SCEV][NFC] Remove unused parameter from forgetLoopDispositions
Let's be honest about it, we don't drop loop dispositions for
particular loops. Remove the parameter that misleadingly makes
it apparent that we do.
2022-09-19 14:06:42 +07:00
Kazu Hirata
20d764aff0 [llvm] Don't including SetVector.h (NFC)
llvm/lib/ProfileData/RawMemProfReader.cpp uses SetVector without
including SetVector.h, so this patch adds an appropriate #include
there.
2022-09-17 12:36:43 -07:00
Kazu Hirata
7a617fdf39 Use std::gcd (NFC)
This patch replaces calls to GreatestCommonDivisor64 with std::gcd
where both arguments are known to be of unsigned types no larger than
64 bits in size.
2022-08-27 21:20:59 -07:00
Max Kazantsev
e587199a50 [SCEV] Prove condition invariance via context, try 2
Initial implementation had too weak requirements to positive/negative
range crossings. Not crossing zero with nuw is not enough for two reasons:

- If ArLHS has negative step, it may turn from positive to negative
  without crossing 0 boundary from left to right (and crossing right to
  left doesn't count for unsigned);
- If ArLHS crosses SINT_MAX boundary, it still turns from positive to
  negative;

In fact we require that ArLHS always stays non-negative or negative,
which an be enforced by the following set of preconditions:

- both nuw and nsw;
- positive step (looks liftable);

Because of positive step, boundary crossing is only possible from left
part to the right part. And because of no-wrap flags, it is guaranteed
to never happen.
2022-08-22 14:31:19 +07:00
Kazu Hirata
258531b7ac Remove redundant initialization of Optional (NFC) 2022-08-20 21:18:28 -07:00
Max Kazantsev
f798c042f4 Revert "[SCEV] Prove condition invariance via context"
This reverts commit a3d1fb3b59b473e4f262a05f187de6474b7721e7.

Reverting until investigation of https://github.com/llvm/llvm-project/issues/57247
has concluded.
2022-08-19 21:02:06 +07:00
Max Kazantsev
ebabd6bf18 Return "[SCEV] Use context to strengthen flags of BinOps"
This reverts commit 354fa0b48008eca701a110badd6974bf449df257.

Returning as is. The patch was reverted due to a miscompile, but
this patch is not causing it. This patch made it possible to infer
some nuw flags in code guarded by `false` condition, and then someone
else to managed to propagate the flag from dead code outside.

Returning the patch to be able to reproduce the issue.
2022-08-16 14:12:36 +07:00
Max Kazantsev
354fa0b480 Revert "[SCEV] Use context to strengthen flags of BinOps"
This reverts commit 34ae308c73e4d76dbdab25a6206d3fbc5ebafdf5.

Our internal testing found a miscompile. Not sure if it's caused by
this patch or it revealed something else. Reverting while investigating.
2022-08-15 18:51:59 +07:00
Max Kazantsev
a3d1fb3b59 [SCEV] Prove condition invariance via context
Contextual knowledge may be used to prove invariance of some conditions.
For example, in this case:
```
  ; %len >= 0
  guard(%iv = {start,+,1}<nuw> <s %len)
  guard(%iv = {start,+,1}<nuw> <u %len)
```
the 2nd check always fails if `start` is negative and always passes otherwise.

It looks like there are more opportunities of this kind that are still to be
implemented in the future.

Differential Revision: https://reviews.llvm.org/D129753
Reviewed By: apilipenko
2022-08-12 14:23:35 +07:00
Fangrui Song
de9d80c1c5 [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-08 11:24:15 -07:00
Johannes Reifferscheid
3e9e43b48e Fix compiler error: init-statements in if/switch.
Reviewed By: pifon2a

Differential Revision: https://reviews.llvm.org/D131061
2022-08-03 11:36:41 +02:00
Johannes Reifferscheid
7ae5d00afa Fix a stack overflow in ScalarEvolution.
Unfortunately, this overflow is extremely hard to reproduce reliably (in fact, I was unable to do so). The issue is that:

- getOperandsToCreate sometimes skips creating an SCEV for the LHS
- then, createSCEV is called for the BinaryOp
- ... which calls getNoWrapFlagsFromUB
- ... which under certain circumstances calls isSCEVExprNeverPoison
- ... which under certain circumstances requires the SCEVs of all operands

For certain deep dependency trees, this causes a stack overflow.

Reviewed By: bkramer, fhahn

Differential Revision: https://reviews.llvm.org/D129745
2022-08-03 11:08:01 +02:00
Max Kazantsev
34ae308c73 [SCEV] Use context to strengthen flags of BinOps
Sometimes SCEV cannot infer nuw/nsw from something as simple as
```
  len in [0, MAX_INT]
...
  iv = phi(0, iv.next)
  guard(iv <s len)
  guard(iv <u len)
  iv.next = iv + 1
```
just because flag strenthening only relies on definition and does not use local facts.
This patch adds support for the simplest case: inference of flags of `add(x, constant)`
if we can contextually prove that `x <= max_int - constant`.

In case if it has negative CT impact, we can add an option to switch it off. I woudln't
expect that though.

Differential Revision: https://reviews.llvm.org/D129643
Reviewed By: apilipenko
2022-08-03 14:08:57 +07:00
Florian Hahn
214e2d8fe5
[SCEV] Avoid repeated proveNoSignedWrapViaInduction calls.
At the moment, proveNoSignedWrapViaInduction may be called for the
same AddRec a large number of times via getSignExtendExpr. This can have
a severe compile-time impact for very loop-heavy code.

If proveNoSignedWrapViaInduction failed to prove NSW the first time,
it is unlikely to succeed on subsequent tries and the cost doesn't seem
to be justified.

This is the signed version of 8daa338297d533d / D130648.

This can drastically improve compile-time in some excessive cases and
also has a slightly positive compile-time impact on CTMark:

NewPM-O3: -0.06%
NewPM-ReleaseThinLTO: -0.04%
NewPM-ReleaseLTO-g: -0.04%

https://llvm-compile-time-tracker.com/compare.php?from=8daa338297d533db4d1ae8d3770613eb25c29688&to=aed126a196e7a5a9803543d9b4d6bdb233d0009c&stat=instructions

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D130694
2022-07-29 09:15:03 +01:00
Florian Hahn
8daa338297
[SCEV] Avoid repeated proveNoUnsignedWrapViaInduction calls.
At the moment, proveNoUnsignedWrapViaInduction may be called for the
same AddRec a large number of times via getZeroExtendExpr. This can have
a severe compile-time impact for very loop-heavy code. One one
particular workload, LSR takes ~51s without this patch, almost
exlusively in proveNoUnsignedWrapViaInduction. With this patch, the time
in LSR drops to ~0.4s.

If proveNoUnsignedWrapViaInduction failed to prove NUW the first time,
it is unlikely to succeed on subsequent tries and the cost doesn't seem
to be justified.

Besides drastically improving compile-time in some excessive cases, this
also has a slightly positive compile-time impact on CTMark:

NewPM-O3: -0.07%
NewPM-ReleaseThinLTO: -0.08%
NewPM-ReleaseLTO-g: -0.06

https://llvm-compile-time-tracker.com/compare.php?from=b435da027d7774c24cdb8c88d09f6b771e07fb14&to=f2729e33e8284b502f6c35a43345272252f35d12&stat=instructions

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D130648
2022-07-28 10:02:19 +01:00