[llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Mar 14 14:09:21 PDT 2011
On Mon, Mar 14, 2011 at 1:28 PM, Andrew Trick <atrick at apple.com> wrote:
> Author: atrick
> Date: Mon Mar 14 12:28:02 2011
> New Revision: 127591
>
> URL: http://llvm.org/viewvc/llvm-project?rev=127591&view=rev
> Log:
> HowFarToZero can compute a trip count as long as the recurrence has no-self-wrap.
Have you read http://llvm.org/bugs/show_bug.cgi?id=8942#c3 ? That
goes a bit into why depending on no-self-wrap requires some
infrastructure changes.
-Eli
> Modified:
> llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127591&r1=127590&r2=127591&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 12:28:02 2011
> @@ -4978,15 +4978,6 @@
> const SCEV *Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop());
> const SCEV *Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop());
>
> - // If the AddRec is NUW, then (in an unsigned sense) it cannot be counting up
> - // to wrap to 0, it must be counting down to equal 0. Also, while counting
> - // down, it cannot "miss" 0 (which would cause it to wrap), regardless of what
> - // the stride is. As such, NUW addrec's will always become zero in
> - // "start / -stride" steps, and we know that the division is exact.
> - if (AddRec->getNoWrapFlags(SCEV::FlagNUW))
> - // FIXME: We really want an "isexact" bit for udiv.
> - return getUDivExpr(Start, getNegativeSCEV(Step));
> -
> // For now we handle only constant steps.
> //
> // TODO: Handle a nonconstant Step given AddRec<NUW>. If the
> @@ -5002,15 +4993,28 @@
> // For negative steps (counting down to zero):
> // N = Start/-Step
> // First compute the unsigned distance from zero in the direction of Step.
> - const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ?
> - getNegativeSCEV(Start) : Start;
> + bool CountDown = StepC->getValue()->getValue().isNegative();
> + const SCEV *Distance = CountDown ? Start : getNegativeSCEV(Start);
>
> // Handle unitary steps, which cannot wraparound.
> - if (StepC->getValue()->equalsInt(1)) // 1*N = -Start (mod 2^BW), so:
> - return Distance; // N = -Start (as unsigned)
> -
> - if (StepC->getValue()->isAllOnesValue()) // -1*N = -Start (mod 2^BW), so:
> - return Distance; // N = Start (as unsigned)
> + // 1*N = -Start; -1*N = Start (mod 2^BW), so:
> + // N = Distance (as unsigned)
> + if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue())
> + return Distance;
> +
> + // If the recurrence is known not to wraparound, unsigned divide computes the
> + // back edge count. We know that the value will either become zero (and thus
> + // the loop terminates), that the loop will terminate through some other exit
> + // condition first, or that the loop has undefined behavior. This means
> + // we can't "miss" the exit value, even with nonunit stride.
> + //
> + // FIXME: Prove that loops always exhibits *acceptable* undefined
> + // behavior. Loops must exhibit defined behavior until a wrapped value is
> + // actually used. So the trip count computed by udiv could be smaller than the
> + // number of well-defined iterations.
> + if (AddRec->getNoWrapFlags(SCEV::FlagNW))
> + // FIXME: We really want an "isexact" bit for udiv.
> + return getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
>
> // Then, try to solve the above equation provided that Start is constant.
> if (const SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start))
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list