This is an archive of the discontinued LLVM Phabricator instance.

[IndVars] Strengthen restricton in rewriteLoopExitValues
ClosedPublic

Authored by mkazantsev on Sep 3 2018, 1:08 AM.

Details

Summary

For some unclear reason rewriteLoopExitValues considers recalculation
after the loop profitable if it has some "soft uses" outside the loop (i.e. any
use other than call and return), even if we have proved that it has a user inside
the loop which we think will not be optimized away.

There is no existing unit test that would explain this. This patch provides an
example when rematerialisation of exit value is not profitable but it passes
this check due to presence of a "soft use" outside the loop.

It makes no sense to recalculate value on exit if we are going to compute it
due to some irremovable within the loop. This patch disallows applying this
transform in the described situation.

Diff Detail

Repository
rL LLVM

Event Timeline

mkazantsev created this revision.Sep 3 2018, 1:08 AM
etherzhhb requested changes to this revision.Sep 18 2018, 8:53 AM

For some unclear reason rewriteLoopExitValues considers recalculation
after the loop profitable if it has some "soft uses" outside the loop (i.e. any
use other than call and return), even if we have proved that it has a user inside
the loop which we think will not be optimized away.

This also confuse me. Why it must be "soft uses" outside the loop that matter?
What I can guess is that, if there is no use outside, there is *no need* to rewrite the exit value.

lib/Transforms/Scalar/IndVarSimplify.cpp
601–602 ↗(On Diff #165893)

looks like these comments describe the scenario of "SoftExternalUses", do we need to delete this as we deleted the corresponding code?

605–615 ↗(On Diff #165893)

we can further write:

// Skip if  Inst is used inside the loop in a way which can not be
//    optimized away.
if (llvm::any_of(Inst->users(), [L](auto *U) {
  return isa<CallInst>(UseInstr) && L->contains(UseInstr);
}))
  continue;

which is easier to read

607–608 ↗(On Diff #165893)

since opc is used only once now, maybe we could write:

if (isa<CallInst>(UseInstr) && L->contains(UseInstr)) {

Also, how about invoke?

This revision now requires changes to proceed.Sep 18 2018, 8:53 AM
etherzhhb added inline comments.Sep 18 2018, 8:58 AM
lib/Transforms/Scalar/IndVarSimplify.cpp
605–615 ↗(On Diff #165893)

I forgot there is a follow up patch to rewrite this :)

You could decide if you want to rewrite the loop or leave it to the next patch

607–608 ↗(On Diff #165893)

I think the invoke is addressed in the follow up patch

mkazantsev marked an inline comment as done.

Fixed comment. All style rework can be done in follow-up, provided that the dependent pass is going to isolate this code into a separate method.

mkazantsev added inline comments.Oct 23 2018, 8:15 PM
lib/Transforms/Scalar/IndVarSimplify.cpp
605–615 ↗(On Diff #165893)

Better to do it in a follow-up too. :)

607–608 ↗(On Diff #165893)

Yes, it's better to do it in a follow-up.

etherzhhb accepted this revision.Oct 30 2018, 1:31 PM

Sorry for the delay. I think since most of the suggested changes are actually in a follow up patch. LGTM

This revision is now accepted and ready to land.Oct 30 2018, 1:31 PM
This revision was automatically updated to reflect the committed changes.