This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Do not visit nodes twice in containsConstantSomewhere
ClosedPublic

Authored by mkazantsev on Jul 26 2017, 11:59 PM.

Details

Summary

This patch reworks the function that searches constants in Add and Mul SCEV expression
chains so that now it does not visit a node more than once, and also renames this function
for better correspondence between its implementation and semantics.

Diff Detail

Repository
rL LLVM

Event Timeline

mkazantsev created this revision.Jul 26 2017, 11:59 PM
sanjoy added inline comments.Jul 27 2017, 12:36 AM
lib/Analysis/ScalarEvolution.cpp
2681 ↗(On Diff #108419)

Can you use SCEVExprContains here?

mkazantsev added inline comments.Jul 27 2017, 2:20 AM
lib/Analysis/ScalarEvolution.cpp
2681 ↗(On Diff #108419)

As far as I understand, SCEVExprContains just traverses through all operands of all types, and this method states that it only needs to pass through Add and Mul exprs. This method is only used when we try to recognize a formula C1*(C2+V) -> C1*C2 + C1*V. So we don't need just any constant, traversing through SCEVs of other types might be an overhead (and potentially change the behavior of users of this function).

sanjoy added inline comments.Jul 27 2017, 3:09 PM
lib/Analysis/ScalarEvolution.cpp
2681 ↗(On Diff #108419)

I see, how about using SCEVTraversal then?

mkazantsev added inline comments.Jul 27 2017, 8:09 PM
lib/Analysis/ScalarEvolution.cpp
2681 ↗(On Diff #108419)

Yes, it can be done. I'll update the patch.

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

Reused SCEVTraversal, renamed the function for better correspondence between its name and semantics.

sanjoy accepted this revision.Jul 27 2017, 9:46 PM

This LGTM, but I think the use site is using too large of a hammer. It only cares about binary add instructions in which one of the operands is a multiplication with a constant or a constant. We should write a check for just that, instead of traversing the whole expression like this.

For instance, I don't think the user should apply the transform in this case (C0 + X) * Y + Z (going by the comments) but it will apply this transform today.

Do you mind fixing that in a separate change?

lib/Analysis/ScalarEvolution.cpp
2685 ↗(On Diff #108579)

This is optional and stylistic, but you could have been briefer as:

bool follow(const SCEV *S) {
  FoundConstant = isa<SCEVConstant>(S);
  return isa<SCEVAddExpr>(S) || isa<SCEVMulExpr>(S);
}
This revision is now accepted and ready to land.Jul 27 2017, 9:46 PM

That's an interesting case. I will add a TODO item on that. Maybe the initial intention when this code was written is to use this helper in more places.

Added a TODO.

mkazantsev marked an inline comment as done.
mkazantsev added inline comments.Jul 27 2017, 10:25 PM
lib/Analysis/ScalarEvolution.cpp
2685 ↗(On Diff #108579)

It doesn't work, the way to go is

FoundConstant |= isa<SCEVConstant>(S);
sanjoy added inline comments.Jul 27 2017, 10:32 PM
lib/Analysis/ScalarEvolution.cpp
2685 ↗(On Diff #108579)

Interesting -- this indicates there is a small potential performance win -- we should should guard the push_back in SCEVTraversal::push also on isDone().

Not obvious it is a win or not: we will have to check isDone() between all pushes, and only save pushing remaining operands for the last SCEV. If we traverse through a big graph where we will never find what we was looking for, we will only do extra checks without benefits.

This revision was automatically updated to reflect the committed changes.