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.
Details
Diff Detail
Event Timeline
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2679 | Can you use SCEVExprContains here? |
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2679 | 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). |
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2679 | I see, how about using SCEVTraversal then? |
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2679 | Yes, it can be done. I'll update the patch. |
Reused SCEVTraversal, renamed the function for better correspondence between its name and semantics.
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 | 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); } |
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.
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2685 | It doesn't work, the way to go is FoundConstant |= isa<SCEVConstant>(S); |
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
2685 | 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.
Can you use SCEVExprContains here?