[llvm-commits] [llvm] r57049 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Transforms/IndVarsSimplify/2008-10-03-CouldNotCompute.ll

Dan Gohman gohman at apple.com
Mon Oct 6 10:56:52 PDT 2008


Hi Nick,

Is this the right approach? It would be much simpler to just
fix evaluateAtIteration to check for return value of
BinomialCoefficient for CNC and stop trying to do further
computation.

Or, are you envisioning someday adding code that would want
to take advantage of being able to keep going after getting
a CNC, because it's simpler to do so, or in hopes that it
might be cancelled out later?

Also, in the patch, there are several instances of code like this:

> +  if (isa<SCEVCouldNotCompute>(Op))
> +    return new SCEVCouldNotCompute();

Instead of creating a new SCEV object, code like this can
just return Op.

Dan

On Oct 4, 2008, at 4:19 AM, Nick Lewycky wrote:

> Author: nicholas
> Date: Sat Oct  4 06:19:07 2008
> New Revision: 57049
>
> URL: http://llvm.org/viewvc/llvm-project?rev=57049&view=rev
> Log:
> Allow the construction of SCEVs with SCEVCouldNotCompute operands, by
> implementing folding. Fixes PR2857.
>
> Added:
>    llvm/trunk/test/Transforms/IndVarsSimplify/2008-10-03- 
> CouldNotCompute.ll
> 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=57049&r1=57048&r2=57049&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat Oct  4 06:19:07  
> 2008
> @@ -676,6 +676,9 @@
>       return getAddRecExpr(Operands, AddRec->getLoop());
>   }
>
> +  if (isa<SCEVCouldNotCompute>(Op))
> +    return new SCEVCouldNotCompute();
> +
>   SCEVTruncateExpr *&Result = (*SCEVTruncates)[std::make_pair(Op,  
> Ty)];
>   if (Result == 0) Result = new SCEVTruncateExpr(Op, Ty);
>   return Result;
> @@ -691,6 +694,9 @@
>   // operands (often constants).  This would allow analysis of  
> something like
>   // this:  for (unsigned char X = 0; X < 100; ++X) { int Y = X; }
>
> +  if (isa<SCEVCouldNotCompute>(Op))
> +    return new SCEVCouldNotCompute();
> +
>   SCEVZeroExtendExpr *&Result = (*SCEVZeroExtends) 
> [std::make_pair(Op, Ty)];
>   if (Result == 0) Result = new SCEVZeroExtendExpr(Op, Ty);
>   return Result;
> @@ -706,6 +712,9 @@
>   // operands (often constants).  This would allow analysis of  
> something like
>   // this:  for (signed char X = 0; X < 100; ++X) { int Y = X; }
>
> +  if (isa<SCEVCouldNotCompute>(Op))
> +    return new SCEVCouldNotCompute();
> +
>   SCEVSignExtendExpr *&Result = (*SCEVSignExtends) 
> [std::make_pair(Op, Ty)];
>   if (Result == 0) Result = new SCEVSignExtendExpr(Op, Ty);
>   return Result;
> @@ -734,6 +743,10 @@
>   // Sort by complexity, this groups all similar expression types  
> together.
>   GroupByComplexity(Ops);
>
> +  // Could not compute plus anything equals could not compute.
> +  if (isa<SCEVCouldNotCompute>(Ops.back()))
> +    return new SCEVCouldNotCompute();
> +
>   // If there are any constants, fold them together.
>   unsigned Idx = 0;
>   if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
> @@ -959,6 +972,21 @@
>   // Sort by complexity, this groups all similar expression types  
> together.
>   GroupByComplexity(Ops);
>
> +  if (isa<SCEVCouldNotCompute>(Ops.back())) {
> +    // CNC * 0 = 0
> +    for (unsigned i = 0, e = Ops.size() - 1; i != e; ++i) {
> +      if (Ops[i]->getSCEVType() != scConstant)
> +        break;
> +
> +      SCEVConstant *SC = cast<SCEVConstant>(Ops[i]);
> +      if (SC->getValue()->isMinValue(false))
> +        return SC;
> +    }
> +
> +    // Otherwise, we can't compute it.
> +    return new SCEVCouldNotCompute();
> +  }
> +
>   // If there are any constants, fold them together.
>   unsigned Idx = 0;
>   if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
> @@ -1124,6 +1152,9 @@
>
>   // FIXME: implement folding of (X*4)/4 when we know X*4 doesn't  
> overflow.
>
> +  if (isa<SCEVCouldNotCompute>(LHS) || isa<SCEVCouldNotCompute>(RHS))
> +    return new SCEVCouldNotCompute();
> +
>   SCEVUDivExpr *&Result = (*SCEVUDivs)[std::make_pair(LHS, RHS)];
>   if (Result == 0) Result = new SCEVUDivExpr(LHS, RHS);
>   return Result;
> @@ -1171,6 +1202,12 @@
>     }
>   }
>
> +  // Refuse to build an AddRec out of SCEVCouldNotCompute.
> +  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
> +    if (isa<SCEVCouldNotCompute>(Operands[i]))
> +      return new SCEVCouldNotCompute();
> +  }
> +
>   SCEVAddRecExpr *&Result =
>     (*SCEVAddRecExprs)[std::make_pair(L,  
> std::vector<SCEV*>(Operands.begin(),
>                                                              
> Operands.end()))];
> @@ -1193,6 +1230,21 @@
>   // Sort by complexity, this groups all similar expression types  
> together.
>   GroupByComplexity(Ops);
>
> +  if (isa<SCEVCouldNotCompute>(Ops.back())) {
> +    // CNC smax +inf = +inf.
> +    for (unsigned i = 0, e = Ops.size() - 1; i != e; ++i) {
> +      if (Ops[i]->getSCEVType() != scConstant)
> +        break;
> +
> +      SCEVConstant *SC = cast<SCEVConstant>(Ops[i]);
> +      if (SC->getValue()->isMaxValue(true))
> +        return SC;
> +    }
> +
> +    // Otherwise, we can't compute it.
> +    return new SCEVCouldNotCompute();
> +  }
> +
>   // If there are any constants, fold them together.
>   unsigned Idx = 0;
>   if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
> @@ -1273,6 +1325,21 @@
>   // Sort by complexity, this groups all similar expression types  
> together.
>   GroupByComplexity(Ops);
>
> +  if (isa<SCEVCouldNotCompute>(Ops[0])) {
> +    // CNC umax inf = inf.
> +    for (unsigned i = 0, e = Ops.size() - 1; i != e; ++i) {
> +      if (Ops[i]->getSCEVType() != scConstant)
> +        break;
> +
> +      SCEVConstant *SC = cast<SCEVConstant>(Ops[i]);
> +      if (SC->getValue()->isMaxValue(false))
> +        return SC;
> +    }
> +
> +    // Otherwise, we can't compute it.
> +    return new SCEVCouldNotCompute();
> +  }
> +
>   // If there are any constants, fold them together.
>   unsigned Idx = 0;
>   if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
>
> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-10-03- 
> CouldNotCompute.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-10-03-CouldNotCompute.ll?rev=57049&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-10-03- 
> CouldNotCompute.ll (added)
> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-10-03- 
> CouldNotCompute.ll Sat Oct  4 06:19:07 2008
> @@ -0,0 +1,32 @@
> +; RUN: llvm-as < %s | opt -indvars
> +; PR2857
> +
> + at foo = external global i32		; <i32*> [#uses=1]
> +
> +define void @test(i32 %n, i32 %arg) {
> +entry:
> +	br i1 false, label %bb.nph, label %return
> +
> +bb.nph:		; preds = %entry
> +	%0 = load i32* @foo, align 4		; <i32> [#uses=1]
> +	%1 = sext i32 %0 to i64		; <i64> [#uses=1]
> +	br label %bb
> +
> +bb:		; preds = %bb, %bb.nph
> +	%.in = phi i32 [ %2, %bb ], [ %n, %bb.nph ]		; <i32> [#uses=1]
> +	%val.02 = phi i64 [ %5, %bb ], [ 0, %bb.nph ]		; <i64> [#uses=2]
> +	%result.01 = phi i64 [ %4, %bb ], [ 0, %bb.nph ]		; <i64> [#uses=1]
> +	%2 = add i32 %.in, -1		; <i32> [#uses=2]
> +	%3 = mul i64 %1, %val.02		; <i64> [#uses=1]
> +	%4 = add i64 %3, %result.01		; <i64> [#uses=2]
> +	%5 = add i64 %val.02, 1		; <i64> [#uses=1]
> +	%6 = icmp sgt i32 %2, 0		; <i1> [#uses=1]
> +	br i1 %6, label %bb, label %bb3.bb4_crit_edge
> +
> +bb3.bb4_crit_edge:		; preds = %bb
> +	%.lcssa = phi i64 [ %4, %bb ]		; <i64> [#uses=0]
> +	ret void
> +
> +return:		; preds = %entry
> +	ret void
> +}
>
>
> _______________________________________________
> 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