This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Update profile in loop versioning and unrolling


Hello,

> Hence I'll strongly preapprove (perhaps even require?) that
> you delete nonzero_p, and change all remaining uses to integer_nonzerop
> before committing this patch.

here is the first part of the patch.  The main problem with the
transition is that zero_p and nonzero_p consider NULL to be equal to
zero -- because loop invariants are now represented as induction
variables with step == NULL.  For some reasons that I do not quite
recall now, I considered this better than having their step to be
zero; I do not think this is a good idea anymore, so I will get
rid of that in the followup patch.  To make the transition easier,
the patch temporarily introduces null_or_integer_zerop and
nonnull_and_integer_nonzerop functions, that will be converted
to integer_zerop and integer_nonzerop in that patch.

Bootstrapped & regtested on i686.

Zdenek

	* tree-ssa-loop-niter.c (zero_p, nonzero_p): Removed.
	(number_of_iterations_ne, number_of_iterations_lt_to_ne,
	assert_no_overflow_lt, assert_loop_rolls_lt,
	number_of_iterations_lt, number_of_iterations_le,
	number_of_iterations_cond, tree_simplify_using_condition_1,
	number_of_iterations_exit, find_loop_niter, loop_niter_by_eval,
	implies_nonnegative_p, implies_ge_p, record_nonwrapping_iv,
	idx_infer_loop_bounds, n_of_executions_at_most, scev_probably_wraps_p):
	Do not use zero_p/nonzero_p.
	* tree-ssa-loop-manip.c (determine_exit_conditions): Ditto.
	* tree-ssa-loop-ivopts.c (niter_for_exit, determine_biv_step,
	find_interesting_uses_op, find_interesting_uses_cond,
	find_interesting_uses_address, find_interesting_uses_stmt,
	strip_offset_1, add_candidate_1, add_old_ivs_candidates,
	difference_cost, determine_use_iv_cost_condition,
	rewrite_use_compare, remove_unused_ivs): Ditto.
	* tree-ssa-address.c (tree_mem_ref_addr, create_mem_ref_raw): Ditto.
	* tree-ssa-loop-prefetch.c (idx_analyze_ref): Ditto.
	* tree-cfg.c (find_taken_edge_cond_expr): Ditto.
	* tree.h (zero_p): Declaration removed.
	(null_or_integer_zerop, nonnull_and_integer_nonzerop): New.

Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 120117)
--- tree-ssa-loop-niter.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 52,87 ****
  
  */
  
- /* Returns true if ARG is either NULL_TREE or constant zero.  Unlike
-    integer_zerop, it does not care about overflow flags.  */
- 
- bool
- zero_p (tree arg)
- {
-   if (!arg)
-     return true;
- 
-   if (TREE_CODE (arg) != INTEGER_CST)
-     return false;
- 
-   return (TREE_INT_CST_LOW (arg) == 0 && TREE_INT_CST_HIGH (arg) == 0);
- }
- 
- /* Returns true if ARG a nonzero constant.  Unlike integer_nonzerop, it does
-    not care about overflow flags.  */
- 
- static bool
- nonzero_p (tree arg)
- {
-   if (!arg)
-     return false;
- 
-   if (TREE_CODE (arg) != INTEGER_CST)
-     return false;
- 
-   return (TREE_INT_CST_LOW (arg) != 0 || TREE_INT_CST_HIGH (arg) != 0);
- }
- 
  /* Returns inverse of X modulo 2^s, where MASK = 2^s-1.  */
  
  static tree
--- 52,57 ----
*************** number_of_iterations_ne (tree type, affi
*** 188,194 ****
        assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, c, d);
        assumption = fold_build2 (EQ_EXPR, boolean_type_node,
  				assumption, build_int_cst (niter_type, 0));
!       if (!nonzero_p (assumption))
  	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  					  niter->assumptions, assumption);
      }
--- 158,164 ----
        assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, c, d);
        assumption = fold_build2 (EQ_EXPR, boolean_type_node,
  				assumption, build_int_cst (niter_type, 0));
!       if (!integer_nonzerop (assumption))
  	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  					  niter->assumptions, assumption);
      }
*************** number_of_iterations_lt_to_ne (tree type
*** 219,240 ****
  
    if (TREE_CODE (mod) != INTEGER_CST)
      return false;
!   if (nonzero_p (mod))
      mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
    tmod = fold_convert (type, mod);
  
!   if (nonzero_p (iv0->step))
      {
        /* The final value of the iv is iv1->base + MOD, assuming that this
  	 computation does not overflow, and that
  	 iv0->base <= iv1->base + MOD.  */
!       if (!iv1->no_overflow && !zero_p (mod))
  	{
  	  bound = fold_build2 (MINUS_EXPR, type,
  			       TYPE_MAX_VALUE (type), tmod);
  	  assumption = fold_build2 (LE_EXPR, boolean_type_node,
  				    iv1->base, bound);
! 	  if (zero_p (assumption))
  	    return false;
  	}
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
--- 189,210 ----
  
    if (TREE_CODE (mod) != INTEGER_CST)
      return false;
!   if (integer_nonzerop (mod))
      mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
    tmod = fold_convert (type, mod);
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      {
        /* The final value of the iv is iv1->base + MOD, assuming that this
  	 computation does not overflow, and that
  	 iv0->base <= iv1->base + MOD.  */
!       if (!iv1->no_overflow && !integer_zerop (mod))
  	{
  	  bound = fold_build2 (MINUS_EXPR, type,
  			       TYPE_MAX_VALUE (type), tmod);
  	  assumption = fold_build2 (LE_EXPR, boolean_type_node,
  				    iv1->base, bound);
! 	  if (integer_zerop (assumption))
  	    return false;
  	}
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
*************** number_of_iterations_lt_to_ne (tree type
*** 247,259 ****
        /* The final value of the iv is iv0->base - MOD, assuming that this
  	 computation does not overflow, and that
  	 iv0->base - MOD <= iv1->base. */
!       if (!iv0->no_overflow && !zero_p (mod))
  	{
  	  bound = fold_build2 (PLUS_EXPR, type,
  			       TYPE_MIN_VALUE (type), tmod);
  	  assumption = fold_build2 (GE_EXPR, boolean_type_node,
  				    iv0->base, bound);
! 	  if (zero_p (assumption))
  	    return false;
  	}
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
--- 217,229 ----
        /* The final value of the iv is iv0->base - MOD, assuming that this
  	 computation does not overflow, and that
  	 iv0->base - MOD <= iv1->base. */
!       if (!iv0->no_overflow && !integer_zerop (mod))
  	{
  	  bound = fold_build2 (PLUS_EXPR, type,
  			       TYPE_MIN_VALUE (type), tmod);
  	  assumption = fold_build2 (GE_EXPR, boolean_type_node,
  				    iv0->base, bound);
! 	  if (integer_zerop (assumption))
  	    return false;
  	}
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
*************** number_of_iterations_lt_to_ne (tree type
*** 262,272 ****
  			    iv1->base);
      }
  
!   if (!nonzero_p (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions,
  				      assumption);
!   if (!zero_p (noloop))
      niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
  				      niter->may_be_zero,
  				      noloop);
--- 232,242 ----
  			    iv1->base);
      }
  
!   if (!integer_nonzerop (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions,
  				      assumption);
!   if (!integer_zerop (noloop))
      niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
  				      niter->may_be_zero,
  				      noloop);
*************** assert_no_overflow_lt (tree type, affine
*** 286,292 ****
    tree bound, d, assumption, diff;
    tree niter_type = TREE_TYPE (step);
  
!   if (nonzero_p (iv0->step))
      {
        /* for (i = iv0->base; i < iv1->base; i += iv0->step) */
        if (iv0->no_overflow)
--- 256,262 ----
    tree bound, d, assumption, diff;
    tree niter_type = TREE_TYPE (step);
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      {
        /* for (i = iv0->base; i < iv1->base; i += iv0->step) */
        if (iv0->no_overflow)
*************** assert_no_overflow_lt (tree type, affine
*** 333,341 ****
  				iv0->base, bound);
      }
  
!   if (zero_p (assumption))
      return false;
!   if (!nonzero_p (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions, assumption);
      
--- 303,311 ----
  				iv0->base, bound);
      }
  
!   if (integer_zerop (assumption))
      return false;
!   if (!integer_nonzerop (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions, assumption);
      
*************** assert_loop_rolls_lt (tree type, affine_
*** 354,360 ****
    tree assumption = boolean_true_node, bound, diff;
    tree mbz, mbzl, mbzr;
  
!   if (nonzero_p (iv0->step))
      {
        diff = fold_build2 (MINUS_EXPR, type,
  			  iv0->step, build_int_cst (type, 1));
--- 324,330 ----
    tree assumption = boolean_true_node, bound, diff;
    tree mbz, mbzl, mbzr;
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      {
        diff = fold_build2 (MINUS_EXPR, type,
  			  iv0->step, build_int_cst (type, 1));
*************** assert_loop_rolls_lt (tree type, affine_
*** 394,403 ****
  
    mbz = fold_build2 (GT_EXPR, boolean_type_node, mbzl, mbzr);
  
!   if (!nonzero_p (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions, assumption);
!   if (!zero_p (mbz))
      niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
  				      niter->may_be_zero, mbz);
  }
--- 364,373 ----
  
    mbz = fold_build2 (GT_EXPR, boolean_type_node, mbzl, mbzr);
  
!   if (!integer_nonzerop (assumption))
      niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  				      niter->assumptions, assumption);
!   if (!integer_zerop (mbz))
      niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
  				      niter->may_be_zero, mbz);
  }
*************** number_of_iterations_lt (tree type, affi
*** 414,420 ****
    tree niter_type = unsigned_type_for (type);
    tree delta, step, s;
  
!   if (nonzero_p (iv0->step))
      {
        niter->control = *iv0;
        niter->cmp = LT_EXPR;
--- 384,390 ----
    tree niter_type = unsigned_type_for (type);
    tree delta, step, s;
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      {
        niter->control = *iv0;
        niter->cmp = LT_EXPR;
*************** number_of_iterations_lt (tree type, affi
*** 433,441 ****
  
    /* First handle the special case that the step is +-1.  */
    if ((iv0->step && integer_onep (iv0->step)
!        && zero_p (iv1->step))
        || (iv1->step && integer_all_onesp (iv1->step)
! 	  && zero_p (iv0->step)))
      {
        /* for (i = iv0->base; i < iv1->base; i++)
  
--- 403,411 ----
  
    /* First handle the special case that the step is +-1.  */
    if ((iv0->step && integer_onep (iv0->step)
!        && null_or_integer_zerop (iv1->step))
        || (iv1->step && integer_all_onesp (iv1->step)
! 	  && null_or_integer_zerop (iv0->step)))
      {
        /* for (i = iv0->base; i < iv1->base; i++)
  
*************** number_of_iterations_lt (tree type, affi
*** 451,457 ****
        return true;
      }
  
!   if (nonzero_p (iv0->step))
      step = fold_convert (niter_type, iv0->step);
    else
      step = fold_convert (niter_type,
--- 421,427 ----
        return true;
      }
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      step = fold_convert (niter_type, iv0->step);
    else
      step = fold_convert (niter_type,
*************** number_of_iterations_le (tree type, affi
*** 509,529 ****
  
    if (!never_infinite)
      {
!       if (nonzero_p (iv0->step))
  	assumption = fold_build2 (NE_EXPR, boolean_type_node,
  				  iv1->base, TYPE_MAX_VALUE (type));
        else
  	assumption = fold_build2 (NE_EXPR, boolean_type_node,
  				  iv0->base, TYPE_MIN_VALUE (type));
  
!       if (zero_p (assumption))
  	return false;
!       if (!nonzero_p (assumption))
  	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  					  niter->assumptions, assumption);
      }
  
!   if (nonzero_p (iv0->step))
      iv1->base = fold_build2 (PLUS_EXPR, type,
  			     iv1->base, build_int_cst (type, 1));
    else
--- 479,499 ----
  
    if (!never_infinite)
      {
!       if (nonnull_and_integer_nonzerop (iv0->step))
  	assumption = fold_build2 (NE_EXPR, boolean_type_node,
  				  iv1->base, TYPE_MAX_VALUE (type));
        else
  	assumption = fold_build2 (NE_EXPR, boolean_type_node,
  				  iv0->base, TYPE_MIN_VALUE (type));
  
!       if (integer_zerop (assumption))
  	return false;
!       if (!integer_nonzerop (assumption))
  	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  					  niter->assumptions, assumption);
      }
  
!   if (nonnull_and_integer_nonzerop (iv0->step))
      iv1->base = fold_build2 (PLUS_EXPR, type,
  			     iv1->base, build_int_cst (type, 1));
    else
*************** number_of_iterations_cond (tree type, af
*** 572,578 ****
    /* Make < comparison from > ones, and for NE_EXPR comparisons, ensure that
       the control variable is on lhs.  */
    if (code == GE_EXPR || code == GT_EXPR
!       || (code == NE_EXPR && zero_p (iv0->step)))
      {
        SWAP (iv0, iv1);
        code = swap_tree_comparison (code);
--- 542,548 ----
    /* Make < comparison from > ones, and for NE_EXPR comparisons, ensure that
       the control variable is on lhs.  */
    if (code == GE_EXPR || code == GT_EXPR
!       || (code == NE_EXPR && null_or_integer_zerop (iv0->step)))
      {
        SWAP (iv0, iv1);
        code = swap_tree_comparison (code);
*************** number_of_iterations_cond (tree type, af
*** 608,616 ****
  
    /* If the control induction variable does not overflow, the loop obviously
       cannot be infinite.  */
!   if (!zero_p (iv0->step) && iv0->no_overflow)
      never_infinite = true;
!   else if (!zero_p (iv1->step) && iv1->no_overflow)
      never_infinite = true;
    else
      never_infinite = false;
--- 578,586 ----
  
    /* If the control induction variable does not overflow, the loop obviously
       cannot be infinite.  */
!   if (!null_or_integer_zerop (iv0->step) && iv0->no_overflow)
      never_infinite = true;
!   else if (!null_or_integer_zerop (iv1->step) && iv1->no_overflow)
      never_infinite = true;
    else
      never_infinite = false;
*************** number_of_iterations_cond (tree type, af
*** 618,624 ****
    /* We can handle the case when neither of the sides of the comparison is
       invariant, provided that the test is NE_EXPR.  This rarely occurs in
       practice, but it is simple enough to manage.  */
!   if (!zero_p (iv0->step) && !zero_p (iv1->step))
      {
        if (code != NE_EXPR)
  	return false;
--- 588,594 ----
    /* We can handle the case when neither of the sides of the comparison is
       invariant, provided that the test is NE_EXPR.  This rarely occurs in
       practice, but it is simple enough to manage.  */
!   if (!null_or_integer_zerop (iv0->step) && !null_or_integer_zerop (iv1->step))
      {
        if (code != NE_EXPR)
  	return false;
*************** number_of_iterations_cond (tree type, af
*** 633,639 ****
    /* If the result of the comparison is a constant,  the loop is weird.  More
       precise handling would be possible, but the situation is not common enough
       to waste time on it.  */
!   if (zero_p (iv0->step) && zero_p (iv1->step))
      return false;
  
    /* Ignore loops of while (i-- < 10) type.  */
--- 603,609 ----
    /* If the result of the comparison is a constant,  the loop is weird.  More
       precise handling would be possible, but the situation is not common enough
       to waste time on it.  */
!   if (null_or_integer_zerop (iv0->step) && null_or_integer_zerop (iv1->step))
      return false;
  
    /* Ignore loops of while (i-- < 10) type.  */
*************** number_of_iterations_cond (tree type, af
*** 642,653 ****
        if (iv0->step && tree_int_cst_sign_bit (iv0->step))
  	return false;
  
!       if (!zero_p (iv1->step) && !tree_int_cst_sign_bit (iv1->step))
  	return false;
      }
  
    /* If the loop exits immediately, there is nothing to do.  */
!   if (zero_p (fold_build2 (code, boolean_type_node, iv0->base, iv1->base)))
      {
        niter->niter = build_int_cst (unsigned_type_for (type), 0);
        return true;
--- 612,623 ----
        if (iv0->step && tree_int_cst_sign_bit (iv0->step))
  	return false;
  
!       if (!null_or_integer_zerop (iv1->step) && !tree_int_cst_sign_bit (iv1->step))
  	return false;
      }
  
    /* If the loop exits immediately, there is nothing to do.  */
!   if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base)))
      {
        niter->niter = build_int_cst (unsigned_type_for (type), 0);
        return true;
*************** number_of_iterations_cond (tree type, af
*** 658,664 ****
    switch (code)
      {
      case NE_EXPR:
!       gcc_assert (zero_p (iv1->step));
        return number_of_iterations_ne (type, iv0, iv1->base, niter, never_infinite);
      case LT_EXPR:
        return number_of_iterations_lt (type, iv0, iv1, niter, never_infinite);
--- 628,634 ----
    switch (code)
      {
      case NE_EXPR:
!       gcc_assert (null_or_integer_zerop (iv1->step));
        return number_of_iterations_ne (type, iv0, iv1->base, niter, never_infinite);
      case LT_EXPR:
        return number_of_iterations_lt (type, iv0, iv1, niter, never_infinite);
*************** tree_simplify_using_condition_1 (tree co
*** 822,832 ****
        /* We know that e0 == e1.  Check whether we cannot simplify expr
  	 using this fact.  */
        e = simplify_replace_tree (expr, e0, e1);
!       if (zero_p (e) || nonzero_p (e))
  	return e;
  
        e = simplify_replace_tree (expr, e1, e0);
!       if (zero_p (e) || nonzero_p (e))
  	return e;
      }
    if (TREE_CODE (expr) == EQ_EXPR)
--- 792,802 ----
        /* We know that e0 == e1.  Check whether we cannot simplify expr
  	 using this fact.  */
        e = simplify_replace_tree (expr, e0, e1);
!       if (integer_zerop (e) || integer_nonzerop (e))
  	return e;
  
        e = simplify_replace_tree (expr, e1, e0);
!       if (integer_zerop (e) || integer_nonzerop (e))
  	return e;
      }
    if (TREE_CODE (expr) == EQ_EXPR)
*************** tree_simplify_using_condition_1 (tree co
*** 836,845 ****
  
        /* If e0 == e1 (EXPR) implies !COND, then EXPR cannot be true.  */
        e = simplify_replace_tree (cond, e0, e1);
!       if (zero_p (e))
  	return e;
        e = simplify_replace_tree (cond, e1, e0);
!       if (zero_p (e))
  	return e;
      }
    if (TREE_CODE (expr) == NE_EXPR)
--- 806,815 ----
  
        /* If e0 == e1 (EXPR) implies !COND, then EXPR cannot be true.  */
        e = simplify_replace_tree (cond, e0, e1);
!       if (integer_zerop (e))
  	return e;
        e = simplify_replace_tree (cond, e1, e0);
!       if (integer_zerop (e))
  	return e;
      }
    if (TREE_CODE (expr) == NE_EXPR)
*************** tree_simplify_using_condition_1 (tree co
*** 849,858 ****
  
        /* If e0 == e1 (!EXPR) implies !COND, then EXPR must be true.  */
        e = simplify_replace_tree (cond, e0, e1);
!       if (zero_p (e))
  	return boolean_true_node;
        e = simplify_replace_tree (cond, e1, e0);
!       if (zero_p (e))
  	return boolean_true_node;
      }
  
--- 819,828 ----
  
        /* If e0 == e1 (!EXPR) implies !COND, then EXPR must be true.  */
        e = simplify_replace_tree (cond, e0, e1);
!       if (integer_zerop (e))
  	return boolean_true_node;
        e = simplify_replace_tree (cond, e1, e0);
!       if (integer_zerop (e))
  	return boolean_true_node;
      }
  
*************** tree_simplify_using_condition_1 (tree co
*** 861,872 ****
    /* Check whether COND ==> EXPR.  */
    notcond = invert_truthvalue (cond);
    e = fold_binary (TRUTH_OR_EXPR, boolean_type_node, notcond, te);
!   if (nonzero_p (e))
      return e;
  
    /* Check whether COND ==> not EXPR.  */
    e = fold_binary (TRUTH_AND_EXPR, boolean_type_node, cond, te);
!   if (e && zero_p (e))
      return e;
  
    return expr;
--- 831,842 ----
    /* Check whether COND ==> EXPR.  */
    notcond = invert_truthvalue (cond);
    e = fold_binary (TRUTH_OR_EXPR, boolean_type_node, notcond, te);
!   if (e && integer_nonzerop (e))
      return e;
  
    /* Check whether COND ==> not EXPR.  */
    e = fold_binary (TRUTH_AND_EXPR, boolean_type_node, cond, te);
!   if (e && integer_zerop (e))
      return e;
  
    return expr;
*************** number_of_iterations_exit (struct loop *
*** 1129,1136 ****
    
        /* We can provide a more specific warning if one of the operator is
  	 constant and the other advances by +1 or -1.  */
!       if (!zero_p (iv1.step)
! 	  ? (zero_p (iv0.step)
  	     && (integer_onep (iv1.step) || integer_all_onesp (iv1.step)))
  	  : (iv0.step
  	     && (integer_onep (iv0.step) || integer_all_onesp (iv0.step))))
--- 1099,1106 ----
    
        /* We can provide a more specific warning if one of the operator is
  	 constant and the other advances by +1 or -1.  */
!       if (!null_or_integer_zerop (iv1.step)
! 	  ? (null_or_integer_zerop (iv0.step)
  	     && (integer_onep (iv1.step) || integer_all_onesp (iv1.step)))
  	  : (iv0.step
  	     && (integer_onep (iv0.step) || integer_all_onesp (iv0.step))))
*************** find_loop_niter (struct loop *loop, edge
*** 1176,1182 ****
        if (!number_of_iterations_exit (loop, ex, &desc, false))
  	continue;
  
!       if (nonzero_p (desc.may_be_zero))
  	{
  	  /* We exit in the first iteration through this exit.
  	     We won't find anything better.  */
--- 1146,1152 ----
        if (!number_of_iterations_exit (loop, ex, &desc, false))
  	continue;
  
!       if (integer_nonzerop (desc.may_be_zero))
  	{
  	  /* We exit in the first iteration through this exit.
  	     We won't find anything better.  */
*************** find_loop_niter (struct loop *loop, edge
*** 1185,1191 ****
  	  break;
  	}
  
!       if (!zero_p (desc.may_be_zero))
  	continue;
  
        aniter = desc.niter;
--- 1155,1161 ----
  	  break;
  	}
  
!       if (!integer_zerop (desc.may_be_zero))
  	continue;
  
        aniter = desc.niter;
*************** loop_niter_by_eval (struct loop *loop, e
*** 1415,1421 ****
  	aval[j] = get_val_for (op[j], val[j]);
  
        acnd = fold_binary (cmp, boolean_type_node, aval[0], aval[1]);
!       if (acnd && zero_p (acnd))
  	{
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    fprintf (dump_file,
--- 1385,1391 ----
  	aval[j] = get_val_for (op[j], val[j]);
  
        acnd = fold_binary (cmp, boolean_type_node, aval[0], aval[1]);
!       if (acnd && integer_zerop (acnd))
  	{
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    fprintf (dump_file,
*************** implies_nonnegative_p (tree cond, tree v
*** 1489,1502 ****
    if (tree_expr_nonnegative_p (val))
      return true;
  
!   if (nonzero_p (cond))
      return false;
  
    compare = fold_build2 (GE_EXPR,
  			 boolean_type_node, val, build_int_cst (type, 0));
    compare = tree_simplify_using_condition_1 (cond, compare);
  
!   return nonzero_p (compare);
  }
  
  /* Returns true if we can prove that COND ==> A >= B.  */
--- 1459,1472 ----
    if (tree_expr_nonnegative_p (val))
      return true;
  
!   if (integer_nonzerop (cond))
      return false;
  
    compare = fold_build2 (GE_EXPR,
  			 boolean_type_node, val, build_int_cst (type, 0));
    compare = tree_simplify_using_condition_1 (cond, compare);
  
!   return integer_nonzerop (compare);
  }
  
  /* Returns true if we can prove that COND ==> A >= B.  */
*************** implies_ge_p (tree cond, tree a, tree b)
*** 1506,1520 ****
  {
    tree compare = fold_build2 (GE_EXPR, boolean_type_node, a, b);
  
!   if (nonzero_p (compare))
      return true;
  
!   if (nonzero_p (cond))
      return false;
  
    compare = tree_simplify_using_condition_1 (cond, compare);
  
!   return nonzero_p (compare);
  }
  
  /* Returns a constant upper bound on the value of expression VAL.  VAL
--- 1476,1490 ----
  {
    tree compare = fold_build2 (GE_EXPR, boolean_type_node, a, b);
  
!   if (integer_nonzerop (compare))
      return true;
  
!   if (integer_nonzerop (cond))
      return false;
  
    compare = tree_simplify_using_condition_1 (cond, compare);
  
!   return integer_nonzerop (compare);
  }
  
  /* Returns a constant upper bound on the value of expression VAL.  VAL
*************** record_nonwrapping_iv (struct loop *loop
*** 1711,1717 ****
    tree niter_bound, extreme, delta;
    tree type = TREE_TYPE (base), unsigned_type;
  
!   if (TREE_CODE (step) != INTEGER_CST || zero_p (step))
      return;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 1681,1687 ----
    tree niter_bound, extreme, delta;
    tree type = TREE_TYPE (base), unsigned_type;
  
!   if (TREE_CODE (step) != INTEGER_CST || integer_zerop (step))
      return;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** idx_infer_loop_bounds (tree base, tree *
*** 1808,1814 ****
    if (!init
        || !step
        || TREE_CODE (step) != INTEGER_CST
!       || zero_p (step)
        || tree_contains_chrecs (init, NULL)
        || chrec_contains_symbols_defined_in_loop (init, loop->num))
      return true;
--- 1778,1784 ----
    if (!init
        || !step
        || TREE_CODE (step) != INTEGER_CST
!       || integer_zerop (step)
        || tree_contains_chrecs (init, NULL)
        || chrec_contains_symbols_defined_in_loop (init, loop->num))
      return true;
*************** n_of_executions_at_most (tree stmt,
*** 2070,2076 ****
  			 tree niter)
  {
    double_int bound = niter_bound->bound;
!   tree nit_type = TREE_TYPE (niter);
    enum tree_code cmp;
  
    gcc_assert (TYPE_UNSIGNED (nit_type));
--- 2040,2046 ----
  			 tree niter)
  {
    double_int bound = niter_bound->bound;
!   tree nit_type = TREE_TYPE (niter), e;
    enum tree_code cmp;
  
    gcc_assert (TYPE_UNSIGNED (nit_type));
*************** n_of_executions_at_most (tree stmt,
*** 2117,2125 ****
        cmp = GT_EXPR;
      }
  
!   return nonzero_p (fold_binary (cmp, boolean_type_node,
! 				 niter,
! 				 double_int_to_tree (nit_type, bound)));
  }
  
  /* Returns true if the arithmetics in TYPE can be assumed not to wrap.  */
--- 2087,2095 ----
        cmp = GT_EXPR;
      }
  
!   e = fold_binary (cmp, boolean_type_node,
! 		   niter, double_int_to_tree (nit_type, bound));
!   return e && integer_nonzerop (e);
  }
  
  /* Returns true if the arithmetics in TYPE can be assumed not to wrap.  */
*************** scev_probably_wraps_p (tree base, tree s
*** 2179,2185 ****
        || TREE_CODE (step) != INTEGER_CST)
      return true;
  
!   if (zero_p (step))
      return false;
  
    /* If we can use the fact that signed and pointer arithmetics does not
--- 2149,2155 ----
        || TREE_CODE (step) != INTEGER_CST)
      return true;
  
!   if (integer_zerop (step))
      return false;
  
    /* If we can use the fact that signed and pointer arithmetics does not
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 120117)
--- tree-ssa-loop-manip.c	(working copy)
*************** determine_exit_conditions (struct loop *
*** 706,712 ****
  	of the loop, i.e., BOUND - step * FACTOR does not overflow.
       3) # of iterations is at least FACTOR  */
  
!   if (!zero_p (desc->may_be_zero))
      cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  			invert_truthvalue (desc->may_be_zero),
  			cond);
--- 706,712 ----
  	of the loop, i.e., BOUND - step * FACTOR does not overflow.
       3) # of iterations is at least FACTOR  */
  
!   if (!integer_zerop (desc->may_be_zero))
      cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
  			invert_truthvalue (desc->may_be_zero),
  			cond);
Index: tree.h
===================================================================
*** tree.h	(revision 120117)
--- tree.h	(working copy)
*************** extern int integer_pow2p (tree);
*** 4075,4081 ****
  
  extern int integer_nonzerop (tree);
  
! extern bool zero_p (tree);
  extern bool cst_and_fits_in_hwi (tree);
  extern tree num_ending_zeros (tree);
  
--- 4075,4096 ----
  
  extern int integer_nonzerop (tree);
  
! /* Returns true if X is either NULL or zero.  */
! 
! static inline bool
! null_or_integer_zerop (tree x)
! {
!   return x == NULL_TREE || integer_zerop (x);
! }
! 
! /* Returns true if X is non-NULL and non-zero.  */
! 
! static inline bool
! nonnull_and_integer_nonzerop (tree x)
! {
!   return x != NULL_TREE && integer_nonzerop (x);
! }
! 
  extern bool cst_and_fits_in_hwi (tree);
  extern tree num_ending_zeros (tree);
  
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 120117)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** niter_for_exit (struct ivopts_data *data
*** 732,738 ****
  	 overlapping life ranges for them (PR 27283).  */
        if (number_of_iterations_exit (data->current_loop,
  				     exit, &desc, true)
! 	  && zero_p (desc.may_be_zero)
       	  && !contains_abnormal_ssa_name_p (desc.niter))
  	nfe_desc->niter = desc.niter;
        else
--- 732,738 ----
  	 overlapping life ranges for them (PR 27283).  */
        if (number_of_iterations_exit (data->current_loop,
  				     exit, &desc, true)
! 	  && integer_zerop (desc.may_be_zero)
       	  && !contains_abnormal_ssa_name_p (desc.niter))
  	nfe_desc->niter = desc.niter;
        else
*************** determine_biv_step (tree phi)
*** 904,910 ****
    if (!simple_iv (loop, phi, name, &iv, true))
      return NULL_TREE;
  
!   return (zero_p (iv.step) ? NULL_TREE : iv.step);
  }
  
  /* Finds basic ivs.  */
--- 904,910 ----
    if (!simple_iv (loop, phi, name, &iv, true))
      return NULL_TREE;
  
!   return (null_or_integer_zerop (iv.step) ? NULL_TREE : iv.step);
  }
  
  /* Finds basic ivs.  */
*************** find_interesting_uses_op (struct ivopts_
*** 1160,1166 ****
        return use;
      }
  
!   if (zero_p (iv->step))
      {
        record_invariant (data, op, true);
        return NULL;
--- 1160,1166 ----
        return use;
      }
  
!   if (null_or_integer_zerop (iv->step))
      {
        record_invariant (data, op, true);
        return NULL;
*************** find_interesting_uses_cond (struct ivopt
*** 1224,1244 ****
        (!iv0 || !iv1)
        /* Eliminating condition based on two ivs would be nontrivial.
  	 ??? TODO -- it is not really important to handle this case.  */
!       || (!zero_p (iv0->step) && !zero_p (iv1->step)))
      {
        find_interesting_uses_op (data, *op0_p);
        find_interesting_uses_op (data, *op1_p);
        return;
      }
  
!   if (zero_p (iv0->step) && zero_p (iv1->step))
      {
        /* If both are invariants, this is a work for unswitching.  */
        return;
      }
  
    civ = XNEW (struct iv);
!   *civ = zero_p (iv0->step) ? *iv1: *iv0;
    record_use (data, cond_p, civ, stmt, USE_COMPARE);
  }
  
--- 1224,1246 ----
        (!iv0 || !iv1)
        /* Eliminating condition based on two ivs would be nontrivial.
  	 ??? TODO -- it is not really important to handle this case.  */
!       || (!null_or_integer_zerop (iv0->step)
! 	  && !null_or_integer_zerop (iv1->step)))
      {
        find_interesting_uses_op (data, *op0_p);
        find_interesting_uses_op (data, *op1_p);
        return;
      }
  
!   if (null_or_integer_zerop (iv0->step)
!       && null_or_integer_zerop (iv1->step))
      {
        /* If both are invariants, this is a work for unswitching.  */
        return;
      }
  
    civ = XNEW (struct iv);
!   *civ = null_or_integer_zerop (iv0->step) ? *iv1: *iv0;
    record_use (data, cond_p, civ, stmt, USE_COMPARE);
  }
  
*************** find_interesting_uses_address (struct iv
*** 1514,1520 ****
  	    }
  	}
  
!       if (zero_p (step))
  	goto fail;
        base = tree_mem_ref_addr (type, base);
      }
--- 1516,1522 ----
  	    }
  	}
  
!       if (null_or_integer_zerop (step))
  	goto fail;
        base = tree_mem_ref_addr (type, base);
      }
*************** find_interesting_uses_address (struct iv
*** 1524,1530 ****
        ifs_ivopts_data.stmt = stmt;
        ifs_ivopts_data.step_p = &step;
        if (!for_each_index (&base, idx_find_step, &ifs_ivopts_data)
! 	  || zero_p (step))
  	goto fail;
  
        gcc_assert (TREE_CODE (base) != ALIGN_INDIRECT_REF);
--- 1526,1532 ----
        ifs_ivopts_data.stmt = stmt;
        ifs_ivopts_data.step_p = &step;
        if (!for_each_index (&base, idx_find_step, &ifs_ivopts_data)
! 	  || null_or_integer_zerop (step))
  	goto fail;
  
        gcc_assert (TREE_CODE (base) != ALIGN_INDIRECT_REF);
*************** find_interesting_uses_stmt (struct ivopt
*** 1598,1604 ****
  
  	  iv = get_iv (data, lhs);
  
! 	  if (iv && !zero_p (iv->step))
  	    return;
  	}
  
--- 1600,1606 ----
  
  	  iv = get_iv (data, lhs);
  
! 	  if (iv && !null_or_integer_zerop (iv->step))
  	    return;
  	}
  
*************** find_interesting_uses_stmt (struct ivopt
*** 1644,1650 ****
        lhs = PHI_RESULT (stmt);
        iv = get_iv (data, lhs);
  
!       if (iv && !zero_p (iv->step))
  	return;
      }
  
--- 1646,1652 ----
        lhs = PHI_RESULT (stmt);
        iv = get_iv (data, lhs);
  
!       if (iv && !null_or_integer_zerop (iv->step))
  	return;
      }
  
*************** strip_offset_1 (tree expr, bool inside_a
*** 1758,1764 ****
      {
      case INTEGER_CST:
        if (!cst_and_fits_in_hwi (expr)
! 	  || zero_p (expr))
  	return orig_expr;
  
        *offset = int_cst_value (expr);
--- 1760,1766 ----
      {
      case INTEGER_CST:
        if (!cst_and_fits_in_hwi (expr)
! 	  || integer_zerop (expr))
  	return orig_expr;
  
        *offset = int_cst_value (expr);
*************** strip_offset_1 (tree expr, bool inside_a
*** 1777,1785 ****
  	  && op1 == TREE_OPERAND (expr, 1))
  	return orig_expr;
  
!       if (zero_p (op1))
  	expr = op0;
!       else if (zero_p (op0))
  	{
  	  if (code == PLUS_EXPR)
  	    expr = op1;
--- 1779,1787 ----
  	  && op1 == TREE_OPERAND (expr, 1))
  	return orig_expr;
  
!       if (integer_zerop (op1))
  	expr = op0;
!       else if (integer_zerop (op0))
  	{
  	  if (code == PLUS_EXPR)
  	    expr = op1;
*************** strip_offset_1 (tree expr, bool inside_a
*** 1805,1811 ****
        *offset = off1 * st;
  
        if (top_compref
! 	  && zero_p (op1))
  	{
  	  /* Strip the component reference completely.  */
  	  op0 = TREE_OPERAND (expr, 0);
--- 1807,1813 ----
        *offset = off1 * st;
  
        if (top_compref
! 	  && integer_zerop (op1))
  	{
  	  /* Strip the component reference completely.  */
  	  op0 = TREE_OPERAND (expr, 0);
*************** add_candidate_1 (struct ivopts_data *dat
*** 1971,1979 ****
        if (!operand_equal_p (base, cand->iv->base, 0))
  	continue;
  
!       if (zero_p (cand->iv->step))
  	{
! 	  if (zero_p (step))
  	    break;
  	}
        else
--- 1973,1981 ----
        if (!operand_equal_p (base, cand->iv->base, 0))
  	continue;
  
!       if (null_or_integer_zerop (cand->iv->step))
  	{
! 	  if (null_or_integer_zerop (step))
  	    break;
  	}
        else
*************** add_old_ivs_candidates (struct ivopts_da
*** 2134,2140 ****
    EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, i, bi)
      {
        iv = ver_info (data, i)->iv;
!       if (iv && iv->biv_p && !zero_p (iv->step))
  	add_old_iv_candidates (data, iv);
      }
  }
--- 2136,2142 ----
    EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, i, bi)
      {
        iv = ver_info (data, i)->iv;
!       if (iv && iv->biv_p && !null_or_integer_zerop (iv->step))
  	add_old_iv_candidates (data, iv);
      }
  }
*************** difference_cost (struct ivopts_data *dat
*** 3340,3349 ****
        return 0;
      }
    *var_present = true;
!   if (zero_p (e2))
      return force_var_cost (data, e1, depends_on);
  
!   if (zero_p (e1))
      {
        cost = force_var_cost (data, e2, depends_on);
        cost += multiply_by_cost (-1, mode);
--- 3342,3351 ----
        return 0;
      }
    *var_present = true;
!   if (integer_zerop (e2))
      return force_var_cost (data, e1, depends_on);
  
!   if (integer_zerop (e1))
      {
        cost = force_var_cost (data, e2, depends_on);
        cost += multiply_by_cost (-1, mode);
*************** determine_use_iv_cost_condition (struct 
*** 3730,3736 ****
    if (TREE_CODE (cond) != SSA_NAME)
      {
        op = TREE_OPERAND (cond, 0);
!       if (TREE_CODE (op) == SSA_NAME && !zero_p (get_iv (data, op)->step))
  	op = TREE_OPERAND (cond, 1);
        if (TREE_CODE (op) == SSA_NAME)
  	{
--- 3732,3739 ----
    if (TREE_CODE (cond) != SSA_NAME)
      {
        op = TREE_OPERAND (cond, 0);
!       if (TREE_CODE (op) == SSA_NAME
! 	  && !null_or_integer_zerop (get_iv (data, op)->step))
  	op = TREE_OPERAND (cond, 1);
        if (TREE_CODE (op) == SSA_NAME)
  	{
*************** rewrite_use_compare (struct ivopts_data 
*** 5148,5154 ****
    cond = *use->op_p;
    op_p = &TREE_OPERAND (cond, 0);
    if (TREE_CODE (*op_p) != SSA_NAME
!       || zero_p (get_iv (data, *op_p)->step))
      op_p = &TREE_OPERAND (cond, 1);
  
    op = force_gimple_operand (comp, &stmts, true, SSA_NAME_VAR (*op_p));
--- 5151,5157 ----
    cond = *use->op_p;
    op_p = &TREE_OPERAND (cond, 0);
    if (TREE_CODE (*op_p) != SSA_NAME
!       || null_or_integer_zerop (get_iv (data, *op_p)->step))
      op_p = &TREE_OPERAND (cond, 1);
  
    op = force_gimple_operand (comp, &stmts, true, SSA_NAME_VAR (*op_p));
*************** remove_unused_ivs (struct ivopts_data *d
*** 5219,5225 ****
  
        info = ver_info (data, j);
        if (info->iv
! 	  && !zero_p (info->iv->step)
  	  && !info->inv_id
  	  && !info->iv->have_use_for
  	  && !info->preserve_biv)
--- 5222,5228 ----
  
        info = ver_info (data, j);
        if (info->iv
! 	  && !null_or_integer_zerop (info->iv->step)
  	  && !info->inv_id
  	  && !info->iv->have_use_for
  	  && !info->preserve_biv)
Index: tree-ssa-address.c
===================================================================
*** tree-ssa-address.c	(revision 120117)
--- tree-ssa-address.c	(working copy)
*************** tree_mem_ref_addr (tree type, tree mem_r
*** 281,287 ****
  	addr = act_elem;
      }
  
!   if (!zero_p (offset))
      {
        act_elem = fold_convert (type, offset);
  
--- 281,287 ----
  	addr = act_elem;
      }
  
!   if (offset && !integer_zerop (offset))
      {
        act_elem = fold_convert (type, offset);
  
*************** create_mem_ref_raw (tree type, struct me
*** 325,331 ****
    if (addr->step && integer_onep (addr->step))
      addr->step = NULL_TREE;
  
!   if (addr->offset && zero_p (addr->offset))
      addr->offset = NULL_TREE;
  
    return build7 (TARGET_MEM_REF, type,
--- 325,331 ----
    if (addr->step && integer_onep (addr->step))
      addr->step = NULL_TREE;
  
!   if (addr->offset && integer_zerop (addr->offset))
      addr->offset = NULL_TREE;
  
    return build7 (TARGET_MEM_REF, type,
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 120117)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** idx_analyze_ref (tree base, tree *index,
*** 337,343 ****
    ibase = iv.base;
    step = iv.step;
  
!   if (zero_p (step))
      istep = 0;
    else
      {
--- 337,343 ----
    ibase = iv.base;
    step = iv.step;
  
!   if (null_or_integer_zerop (step))
      istep = 0;
    else
      {
Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 120117)
--- tree-cfg.c	(working copy)
*************** find_taken_edge_cond_expr (basic_block b
*** 2153,2159 ****
    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
    gcc_assert (TREE_CODE (val) == INTEGER_CST);
!   return (zero_p (val) ? false_edge : true_edge);
  }
  
  /* Given an INTEGER_CST VAL and the entry block BB to a SWITCH_EXPR
--- 2153,2159 ----
    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
    gcc_assert (TREE_CODE (val) == INTEGER_CST);
!   return (integer_zerop (val) ? false_edge : true_edge);
  }
  
  /* Given an INTEGER_CST VAL and the entry block BB to a SWITCH_EXPR


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]