This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyIndVar] Replace IVUsers with loop invariant if possible
ClosedPublic

Authored by etherzhhb on Sep 29 2017, 10:22 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

etherzhhb created this revision.Sep 29 2017, 10:22 AM
efriedma added inline comments.
lib/Transforms/Utils/SimplifyIndVar.cpp
551 ↗(On Diff #117177)

Could you use SCEVExpander rather than writing out the cast logic here? I'm not sure this covers all the relevant cases.

557 ↗(On Diff #117177)

Does it actually matter whether the value here is a Constant?

etherzhhb added inline comments.Sep 29 2017, 12:40 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
551 ↗(On Diff #117177)

Ok, will do

557 ↗(On Diff #117177)

You means we gain something if we can "simplify" the IV user from a SCEVAddRec to a SCEVUnknown?*

SE->getSCEV(I); may directly return an SCEUnknown, so we need to compare the new LLVM Value and the original one.
We are not going to do the replace if they are the same

efriedma added inline comments.Sep 29 2017, 12:57 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
557 ↗(On Diff #117177)

Rather than try to check for equality, you can just check whether the SCEVUnknown is loop-invariant.

etherzhhb added inline comments.Sep 29 2017, 1:20 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
557 ↗(On Diff #117177)

This sounds great

etherzhhb updated this revision to Diff 117260.Sep 30 2017, 9:15 AM
etherzhhb retitled this revision from [SimplifyIndVar] Correctly extract constant LLVM value from SCEV during constant folding to [SimplifyIndVar] Replace IVUsers with loop invariant if possible.
etherzhhb edited the summary of this revision. (Show Details)

Address reviewer's comments

etherzhhb added inline comments.Sep 30 2017, 9:17 AM
lib/Transforms/Utils/SimplifyIndVar.cpp
553–554 ↗(On Diff #117260)

Should we only expand SCEVConstant and SCEVUnknown?

If we should expand all SCEV that is Loop Invariant, should we make the SCEVExpander global, such that we have a global "InsertedExpressions" map (in the SCEVExpander) to remember the SCEV expression that we expanded?

etherzhhb marked 6 inline comments as done.Sep 30 2017, 9:18 AM
etherzhhb updated this revision to Diff 117270.Sep 30 2017, 9:22 PM

Looks like I need to pass the SCEVExpander from the IndVarSimpilfy pass to coordinate SCEV rewrite, otherwise we will fail test/Transforms/IndVarSimplify/pr20680.ll

etherzhhb updated this revision to Diff 117271.Sep 30 2017, 9:25 PM
etherzhhb marked an inline comment as done.

Update format

etherzhhb added inline comments.Sep 30 2017, 9:29 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
552 ↗(On Diff #117271)

We may only want to do the replace if S is invariant of the IV's Loop, which may be different from "L" which is the innermost loop that contains the IV user

efriedma added inline comments.Oct 2 2017, 2:10 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
552 ↗(On Diff #117271)

Yes; otherwise, the transform isn't doing anything useful.

We might need to call isHighCostExpansion here, so we don't generate something ridiculous?

555 ↗(On Diff #117271)

"I" is probably not the right place the put any expansion code, given it's inside the loop.

etherzhhb added inline comments.Oct 2 2017, 2:15 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
555 ↗(On Diff #117271)

SCEVExpander figure out the correct place by itself (at least in test4 of test/Transforms/IndVarSimplify/replace-iv-with-loop-invariant.ll), otherwise we need to find the preheader (and fallback to I if there is no preheader)

test/Transforms/IndVarSimplify/replace-iv-with-loop-invariant.ll
84 ↗(On Diff #117271)

Here the SCEVExpander expand the expression before the loop (before the phi)

etherzhhb added inline comments.Oct 2 2017, 2:19 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
552 ↗(On Diff #117271)

Yes, this make sense.

I did some experiments and we may want to actually write:

if (!SE->isLoopInvariant(S, IV's Loop) || !SE->isLoopInvariant(S, IV User's Loop))

If IV's Loop do not contains IV User's Loop

efriedma added inline comments.Oct 2 2017, 2:31 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
552 ↗(On Diff #117271)

Given a function in LCSSA form, I don't think this relevant? But feel free to prove me wrong. :)

etherzhhb added inline comments.Oct 2 2017, 3:17 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
552 ↗(On Diff #117271)

Not sure if we assume LCSSA (or SCEV could see through it), I hit some crash when I just test 'if (!SE->isLoopInvariant(S, IV's Loop))' and it turned out that IV's Loop do not contain IV's user. I will find those cases

etherzhhb updated this revision to Diff 117542.Oct 3 2017, 10:00 AM

Partially address reviewer's comment. This is a WIP patch

etherzhhb marked 2 inline comments as done.Oct 3 2017, 10:02 AM
etherzhhb added inline comments.
lib/Transforms/Utils/SimplifyIndVar.cpp
553 ↗(On Diff #117542)

Maybe we should not push IV users in pushIVUsers at all if IV users do not in the IV loop (e.g. LCSSA phi)

etherzhhb marked 3 inline comments as done.Oct 3 2017, 10:04 AM
efriedma added inline comments.Oct 3 2017, 12:08 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
553 ↗(On Diff #117542)

Yeah, that makes sense; we have special handling for exit values in IndVarSimplify::rewriteLoopExitValues.

etherzhhb updated this revision to Diff 117618.Oct 3 2017, 8:09 PM

Address reviewer comments

etherzhhb marked 4 inline comments as done.Oct 3 2017, 8:10 PM
hfinkel added inline comments.
lib/Transforms/Utils/SimplifyIndVar.cpp
562 ↗(On Diff #117618)

End comments with a period (here and also below).

etherzhhb updated this revision to Diff 118312.Oct 9 2017, 9:30 PM

Update comments

etherzhhb marked an inline comment as done.Oct 9 2017, 9:31 PM
efriedma added inline comments.Oct 10 2017, 3:05 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
557 ↗(On Diff #118312)

SE->getSCEVAtScope(SE->getSCEV(I), LI->getLoopFor(I->getParent())) should be equivalent to SE->getSCEV(I). The point of getSCEVAtScope is to compute the value of a SCEV outside of its associated loop (the exit value).

Sorry, I should have spotted this earlier.

etherzhhb added inline comments.Oct 10 2017, 4:02 PM
lib/Transforms/Utils/SimplifyIndVar.cpp
557 ↗(On Diff #118312)

Thanks for pointing this out, I will update the patch

Delete the redundant getSCEVAtScope

etherzhhb marked 2 inline comments as done.Oct 10 2017, 11:08 PM
This revision is now accepted and ready to land.Oct 11 2017, 12:49 PM
This revision was automatically updated to reflect the committed changes.
llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp