This is an archive of the discontinued LLVM Phabricator instance.

[IndVars] Apply more optimistic SkipLastIter for AND/OR conditions
ClosedPublic

Authored by mkazantsev on Dec 13 2022, 7:14 AM.

Details

Summary

When exit by condition C1 dominates exit by condition C2, and
max symbolic exit count for C1 matches those for loop, we will
apply more optimistic logic to C2 by setting SkipLastIter for it,
meaning that it will do 1 iteration less because the dominating branch
must exit on the last loop iteration.

But when we have a single exit by condition C1 & C2, we cannot
apply the same logic, because there is no dominating condition.

However, if we can prove that the symbolic max exit count of C1 & C2
matches those of C1, it means that for C2 we can assume that it
doesn't matter on the last iteration (because the whole thing is false
because C1 must be false). Therefore, in this situation, we can handle
C2 as if it had SkipLastIter.

This is potentiallty CT-consuming operation, so I've limited it with reasonably
small amount of conditions to deal with.

Diff Detail

Event Timeline

mkazantsev created this revision.Dec 13 2022, 7:14 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 13 2022, 7:14 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
mkazantsev requested review of this revision.Dec 13 2022, 7:14 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 13 2022, 7:14 AM
mkazantsev planned changes to this revision.Dec 26 2022, 9:11 PM

Rebase needed

mkazantsev retitled this revision from [IndVars] Apply more optimistic SkipLastIter for AND conditions to [IndVars] Apply more optimistic SkipLastIter for AND/OR conditions.
mkazantsev updated this revision to Diff 487319.Jan 9 2023, 1:02 AM

Simple rebase.

mkazantsev updated this revision to Diff 487371.Jan 9 2023, 3:31 AM

Rebase2

llvm/include/llvm/Analysis/ScalarEvolution.h
1740 ↗(On Diff #487371)

Note that this is supposed to be moved to public block, it's just to show that nothing else changes here.

Rebased:

  • Split off SCEV access change into NFC
  • Introduced option to control max amount of icmps to analyze.

Rebased on top of test var renaming.

nikic added inline comments.Jan 17 2023, 4:15 AM
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1499

I don't really get why we need this quadratic-complexity code. It doesn't look like anything inside here depends on the outer i?

mkazantsev added inline comments.Jan 17 2023, 4:55 AM
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1499

OldCond depends on outer i. The logic here is following: we have n conditions joined through AND. Currenly we are handing i'th condition. If any other condition gives exact same exit count as the whole aggregate, it means that the current condition can be handled w/o last iteration. Scanning these other conditions takes linear time (I guess we could cache something if it's a problem, but they can be rewritten, so it's safer not to).

nikic added inline comments.Jan 17 2023, 5:21 AM
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1499

It should be sufficient to go through all the conditions once, and just remember which ones match the maximum. Then it should be possible to use skip last iter if either a) there is more than one such condition or b) the one such condition is not the one currently processed. Probably, for all practical purposes it's fine to just ignore a) and only store a single index for the condition that matches the max exit count.

1499

And if we do that, then I don't think we need the MaxJoinedICmpsToAnalyze limit either, because the complexity is linear.

mkazantsev planned changes to this revision.Jan 17 2023, 9:56 PM
mkazantsev added inline comments.
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1499

I was thinking about something like this actually. The fact that stopped me is that, after rewriting, the property of "exits on last iteration" will disappear. Imagine A & B & C, all three exiting on last iteration. We could replace A basing on B, B basing on C and C basing on A. The simplistic approach I am currently using prevents that, however if we sustain a set of all conditions exiting on last iter, that should work. Let me try it out.

mkazantsev marked 2 inline comments as done.

Removed quadratic compexity, now it's linear.

nikic accepted this revision.Jan 23 2023, 2:00 AM

LGTM

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1489

Would just WideExitMax == WideMaxIter be sufficient? Don't think we usually use isKnownPredicate for equality comparisons and rely on canonicalization instead.

This revision is now accepted and ready to land.Jan 23 2023, 2:00 AM
nikic added a comment.Jan 23 2023, 2:00 AM

(patch description needs an update, last paragraph can be dropped)

mkazantsev added inline comments.Jan 23 2023, 4:39 AM
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
1489

I think it should be, in any practical sense.

This revision was landed with ongoing or failed builds.Jan 23 2023, 9:45 PM
This revision was automatically updated to reflect the committed changes.