This is an archive of the discontinued LLVM Phabricator instance.

[ScopHelper] Cache ScopExpander results.
ClosedPublic

Authored by efriedma on May 18 2018, 2:29 PM.

Details

Summary

A naive SCEV visitor not linear in the number of SCEV expressions. For an expression like x*x, "x" will be visited twice. If x is itself an expression like x*x, that will be visited twice, etc, and the overall runtime is O(2^N) in the number of SCEV expressions.

To prevent this from happening, add a cache, so we only visit each SCEV expression once.

Not sure this is the best solution. Maybe we can instead check whether the SCEV is scop-invariant (in which case we never need to map the value). But we don't have a utility for that at the moment.

Diff Detail

Repository
rL LLVM

Event Timeline

efriedma created this revision.May 18 2018, 2:29 PM

SCEVExpander itself already has a cache. For some reason (I don't understand myself) ScopExpander recursively visits the SCEV before calling into SCEVExpander (and in the process expands subelements itself, then converts it back using getSCEV?!!!?). The SCEV has already been visited even before polly::expandCodeFor is called in trySynthesizeNewValue to replace original (non-SCEV) values by generated ones.

Usually, it's SCEVRewriteVisitor's job to do the cached, which the pre-process pass of SCEVExpander does not use.

Ideally, the caching (e.g. by SCEVExpander) should happen on BB-level. That is, BlockGenerator should hold the ScopExpander, such that expandCodeFor does not start with a clear cache every time it is called.

I know this is a lot of work, so I am fine with this as a quick fix.

Meinersbur accepted this revision.May 18 2018, 3:42 PM
This revision is now accepted and ready to land.May 18 2018, 3:42 PM
This revision was automatically updated to reflect the committed changes.