This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Avoid compile time explosion in ScalarEvolution::isImpliedCond
ClosedPublic

Authored by bjope on Oct 19 2021, 8:20 AM.

Details

Summary

As seen in PR51869 the ScalarEvolution::isImpliedCond function might
end up spending lots of time when doing the isKnownPredicate checks.

Calling isKnownPredicate for example result in isKnownViaInduction
being called, which might result in isLoopBackedgeGuardedByCond being
called, and then we might get one or more new calls to isImpliedCond.
Even if the scenario described here isn't an infinite loop, using
some random generated C programs as input indicates that those
isKnownPredicate checks quite often returns true. On the other hand,
the third condition that needs to be fulfilled in order to "prove
implications via truncation", i.e. the isImpliedCondBalancedTypes
check, is rarely fulfilled.
I also made some similar experiments to look at how often we would
get the same result when using isKnownViaNonRecursiveReasoning instead
of isKnownPredicate. So far I haven't seen a single case when codegen
is negatively impacted by using isKnownViaNonRecursiveReasoning. On
the other hand, it seems like we get rid of the compile time explosion
seen in PR51869 that way. Hence this patch.

Diff Detail

Event Timeline

bjope created this revision.Oct 19 2021, 8:20 AM
bjope requested review of this revision.Oct 19 2021, 8:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 19 2021, 8:20 AM
bjope added a comment.Oct 19 2021, 8:25 AM

I figure there might be some program out there for which this still will converge slowly etc, and I'm not sure exactly how to prove that this is better in general terms.

But at least this patch has a huge positive impact on compile time for the test case from PR51869 (and I haven't seen any case yet were we get a similarly huge penalty instead).

nikic added a reviewer: nikic.Oct 19 2021, 9:18 AM
nikic added a subscriber: nikic.

I think a better solution would be to replace isKnownPredicate() with isKnownViaNonRecursiveReasoning(). That's the primitive that isImpliedCond() normally uses.

nikic added a comment.Oct 19 2021, 9:41 AM

Compile time for...
...this patch: https://llvm-compile-time-tracker.com/compare.php?from=54d868991ab79abc5c52cf38939f0a45292e7506&to=c630a0d16f0f00c4e06bdd2ea9e4fa95a3f9e16e&stat=instructions
...non-recursive reasoning: https://llvm-compile-time-tracker.com/compare.php?from=54d868991ab79abc5c52cf38939f0a45292e7506&to=b6e305314a9fd6fb2d05987ac51ea836d9e64676&stat=instructions

So it's an improvement on CTMark either way, but I think using non-recursive reasoning is the more principled choice, because it doesn't rely on isImpliedCondBalancedTypes() returning false to prevent the CT explosion.

bjope planned changes to this revision.Oct 19 2021, 9:45 AM

I plan to update this patch into using isKnownViaNonRecursiveReasoning as suggested by @nikic

bjope updated this revision to Diff 380747.Oct 19 2021, 11:46 AM

Now using isKnownViaNonRecursiveReasoning instead of isKnownPredicate.

bjope retitled this revision from [SCEV] Avoid long execution time in ScalarEvolution::isImpliedCond to [SCEV] Avoid compile time explosion in ScalarEvolution::isImpliedCond.Oct 19 2021, 11:47 AM
bjope edited the summary of this revision. (Show Details)
nikic accepted this revision.Oct 19 2021, 12:18 PM

LGTM

This revision is now accepted and ready to land.Oct 19 2021, 12:18 PM
This revision was landed with ongoing or failed builds.Oct 19 2021, 12:39 PM
This revision was automatically updated to reflect the committed changes.