This is an archive of the discontinued LLVM Phabricator instance.

[GuardWidening] Improve analysis of potential widening into hotter block
ClosedPublic

Authored by mkazantsev on Mar 17 2023, 2:17 AM.

Details

Summary

There is a piece of logic in GuardWidening which is very limited, and it happens
to ignore implicit control flow, therefore it "works fine" with guards expressed as
intrinsic calls. However, when the guards are represented as branches, its limitations
create a lot of trouble.

The intent here is to make sure that we do not widen code across complex CFG,
so that it can end up being in hotter code than it used to be. The old logic was limited
to unique immediate successor and that's it.

This patch changes the logic there to work the following way: when we need to check
if we can widen from DominatedBlock into DominatingBlock, we first try to find the
lowest (by CFG) transitive successor of DominatingBlock which is guaranteed to not
be significantly colder than the DominatingBlock. It means that every time we move
to either:

  • Unique successor of the current block, if it only has one successor;
  • The only taken successor, if the current block ends with br(const);
  • If one of successors ends with deopt, another one is taken;

If the lowest block we can find this way is the DominatedBlock, then it is safe to assume
that this widening won't move the code into a hotter location.

I did not touch the existing check with PDT. It looks fishy to me (post-dominance doesn't
really guarantee anything about hotness), but let's keep it as is and maybe fix later.

With this patch, Guard Widening can widen explicitly expressed branches across more than one
dominating guard if it's profitable.

Diff Detail

Event Timeline

mkazantsev created this revision.Mar 17 2023, 2:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2023, 2:17 AM
mkazantsev requested review of this revision.Mar 17 2023, 2:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2023, 2:17 AM

clang-formatted

skatkov added inline comments.Mar 17 2023, 2:28 AM
llvm/lib/Transforms/Scalar/GuardWidening.cpp
481

Don't you want to also check that we are ok if some of the successors ends up with deoptimization?

IfTrue/ifFalse ->getPostdominatingDeoptimizeCall() ?

mkazantsev added inline comments.Mar 17 2023, 3:48 AM
llvm/lib/Transforms/Scalar/GuardWidening.cpp
481

It's expensive. What is the advantage of this?

mkazantsev marked an inline comment as done.
mkazantsev edited the summary of this revision. (Show Details)

In fact, "ends with deopt" is indeed more general, as some of such speculations might not be guards.

skatkov added inline comments.Mar 19 2023, 8:29 PM
llvm/lib/Transforms/Scalar/GuardWidening.cpp
479

Crazy compile time heuristic. I guess that IfFalse terminates with deopt is more likely. So just re-order them.

mkazantsev marked an inline comment as done.
skatkov accepted this revision.Mar 19 2023, 10:42 PM

Generally looks good to me.

This revision is now accepted and ready to land.Mar 19 2023, 10:42 PM
This revision was landed with ongoing or failed builds.Mar 19 2023, 10:52 PM
This revision was automatically updated to reflect the committed changes.
mkazantsev reopened this revision.Mar 21 2023, 8:38 AM

I found an infinite loop, will file a test and fix tomorrow. Reverted for a while.

This revision is now accepted and ready to land.Mar 21 2023, 8:38 AM
mkazantsev closed this revision.Mar 22 2023, 8:59 PM