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

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

557

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

Ok, will do

557

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

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

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

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
550

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
550

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

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

553–554

"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
553–554

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
85

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
550

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
550

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
550

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
552

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
552

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
552–553

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
549

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
549

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.
lib/Transforms/Utils/SimplifyIndVar.cpp