Bug 16358: simplify SCEVs with assumptions

Sebastian Pop spop at codeaurora.org
Mon Nov 25 17:40:42 PST 2013


Andrew Trick wrote:
> >> I'm nervous about managing SCEV caches that depend on query context
> >> because it is so hard to test and reason about the correctness, and
> >> it?s hard to know if compile time will become unbounded. Do we
> >> really need to solve this problem?
> >> 
> >> If the trip count computation could directly analyze expressions of
> >> this form:
> >> 
> >>  %conv = sext i16 %inc to i32
> >>  -->  (sext i16 {1,+,1}<%for.body> to i32)
> >> 
> >> And gather assumptions during the analysis, then SCEV simplification
> >> doesn't need to do the work. (In fact I think we should do less work
> >> in SCEV simplification).
> >> 
> >> Say we had a utility, e.g. ScalarEvolution::promoteIV, that would
> >> take a SCEV of the form:
> >> (sext i16 {1,+,1}<%for.body> to i32)
> >> 
> >> And return a new SCEV:
> >> {1,+,1}<%for.body>
> > 
> > I think that the underlying issue is: do you put nsw on this expression?
> No. Anyone using this result needs to prove the "i < 2**16" assumption or add a constraint to the loop.

It becomes pretty difficult to know in which cases the result of the number of
iterations under the assumption i < 2**16 can or cannot be used: in particular
because this result might be used in the computation of the scev of a next loop:

void foo(int n, int m, int *A) {
  short i;
  for (i = 0; i < n; i++)
    A[i] = 0;

  // End of loop value of i is n under the assumption that the first loop terminates.

  for (; i < m; i++)
    A[i] = 0;

The analysis of the initial value of i in the second loop depends on computing
the number of iteration of the first loop. So one would have to version the
second loop with all the constraints extracted to compute the niter for the
first loop. Knowing when an assumption extracted for the first loop has been
used or not to compute a SCEV of the second loop is non trivial.

Also another problem that I have seen is that the expression niter computes is
cached, so any subsequent queries to niter would have to provide the assumptions
under which the niter expression has been computed. So one would have to attach
to the cached value of a SCEV the assumptions under which that expression has
been computed.

> I think we can do more with trip count and dependence analysis queries without SCEV NSW flags... They were just convenient initially.
> -Andy
> > -Hal
> > 
> >> 
> >> Along with it's set of assumptions:
> >> "{1,+,1}<%for.body>" < 2**16
> >> 
> >> We can always factor code between getSignExtendExpr and promoteIV,
> >> but I'm only looking at a few lines of code to do this.

Agreed, if the extraction of assumptions happens in the same time as SCEV
analysis, we are speaking about a minimal change of a few lines of code.

> >> It up to the caller to prove the assumption as a loop precondition,
> >> undefined behavior inference, or whatever. In the case of trip count
> >> computation, HowManyLessThans would prove the assumptions that it
> >> can and report the rest to the client of the trip count query.
> >> Aggressive loop opts, like LoopVectorizer, can gather the
> >> assumptions from various queries and materialize the minimum number
> >> of constraints such that they all hold. SCEV could provide a utility
> >> to optimize the constraints.

Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

More information about the llvm-commits mailing list