public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tom de Vries <vries@codesourcery.com>
To: Zdenek Dvorak <rakdver@kam.mff.cuni.cz>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH PR45098,  7/10] Nowrap limits iterations
Date: Fri, 20 May 2011 12:22:00 -0000	[thread overview]
Message-ID: <4DD63AE1.7070600@codesourcery.com> (raw)
In-Reply-To: <20110518211157.GA19788@kam.mff.cuni.cz>

[-- Attachment #1: Type: text/plain, Size: 2525 bytes --]

On 05/18/2011 11:11 PM, Zdenek Dvorak wrote:
> Hi,
> 
>> This patch attemps to estimate the number of iterations of the loop based on
>> nonwrapping arithmetic in the loop body.
>>
>> 2011-05-05  Tom de Vries  <tom@codesourcery.com>
>>
>> 	PR target/45098
>> 	* tree-ssa-loop-ivopts.c (struct ivopts_data): Add fields
>> 	max_iterations_p and max_iterations.
>> 	(is_nonwrap_use, max_loop_iterations, set_max_iterations): New function.
>> 	(may_eliminate_iv): Use max_iterations_p and max_iterations.
>> 	(tree_ssa_iv_optimize_loop): Use set_max_iterations.
> 
> what are the cases this handles better than the existing analysis of maximum numbers of iterations
> (estimate_numbers_of_iterations)?

Consider tr1:

extern int pfoo (int*)  __attribute__((pure));

int tr1 (int array[], unsigned int n)
{
  int sum = 0;
  unsigned int i;
  i = 0;
  while (1)
    {
      sum += pfoo (&array[i]);
      if (!(i < n))
        break;
      i++;
    }
  return sum;
}

The number of iterations is limited by &array[i]. &array[0x3fffffff] is still
ok, but &array[0x40000000] wraps. So i runs maximally from 0 to 0x3fffffff,
which is 0x40000000 loop iterations. Since &array[i] dominates the single
loop exit, any statement in the loop is executed at most 0x40000000 times.
That's also the amount registered in nb_iterations_upper_bound.
Since int *p has 0x40000000 distinct values, it's ok to replace the
exit test !(i < n) with p == &array[n].


On the other hand, consider tr6:

int tr6 (int array[], unsigned int n)
{
  int sum = 0;
  unsigned int i;
  for (i = 0; i < n; ++i)
      sum += pfoo (&array[i]);
  return sum;
}

The same holds as before, but &array[i] does not dominate the single
loop exit, so any statement in the loop is executed at most 0x40000001 times.
Note that the loop body is executed at most 0x40000000 times, and that only
the exit test is executed at most 0x40000001 times.
That's also the amount registered in nb_iterations_upper_bound.
Since int *p has only 0x40000000 distinct values, it's not ok to replace
the exit test in terms of p.


> Would it be possible to add the handling of these cases
> to estimate_numbers_of_iterations, rather than doing it just for ivopts?

Yes, I did that now.

Thanks,
- Tom

2011-05-05  Tom de Vries  <tom@codesourcery.com>

	PR target/45098
	* tree-ssa-loop-niter.c (infer_loop_bounds_from_pointer_arith): New
	function.
	(infer_loop_bounds_from_undefined): Use new function.
	* tree-ssa-loop-ivopts.c (may_eliminate_iv): Fix
	estimated_loop_iterations comparison.

[-- Attachment #2: 07_pr45098-nowrap-limits-iterations.patch --]
[-- Type: text/x-patch, Size: 3227 bytes --]

Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c (revision 173734)
+++ gcc/tree-ssa-loop-niter.c (working copy)
@@ -2835,6 +2835,54 @@ infer_loop_bounds_from_array (struct loo
    that signed arithmetics in STMT does not overflow.  */
 
 static void
+infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple stmt)
+{
+  tree def, base, step, scev, type, low, high;
+  tree var, ptr;
+
+  if (!is_gimple_assign (stmt)
+      || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
+    return;
+
+  def = gimple_assign_lhs (stmt);
+  if (TREE_CODE (def) != SSA_NAME)
+    return;
+
+  type = TREE_TYPE (def);
+  if (!nowrap_type_p (type))
+    return;
+
+  ptr = gimple_assign_rhs1 (stmt);
+  if (!expr_invariant_in_loop_p (loop, ptr))
+    return;
+
+  var = gimple_assign_rhs2 (stmt);
+  if (TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (var)))
+    return;
+
+  scev = instantiate_parameters (loop, analyze_scalar_evolution (loop, def));
+  if (chrec_contains_undetermined (scev))
+    return;
+
+  base = initial_condition_in_loop_num (scev, loop->num);
+  step = evolution_part_in_loop_num (scev, loop->num);
+
+  if (!base || !step
+      || TREE_CODE (step) != INTEGER_CST
+      || tree_contains_chrecs (base, NULL)
+      || chrec_contains_symbols_defined_in_loop (base, loop->num))
+    return;
+
+  low = lower_bound_in_type (type, type);
+  high = upper_bound_in_type (type, type);
+
+  record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true);
+}
+
+/* Determine information about number of iterations of a LOOP from the fact
+   that signed arithmetics in STMT does not overflow.  */
+
+static void
 infer_loop_bounds_from_signedness (struct loop *loop, gimple stmt)
 {
   tree def, base, step, scev, type, low, high;
@@ -2907,7 +2955,10 @@ infer_loop_bounds_from_undefined (struct
 	  infer_loop_bounds_from_array (loop, stmt, reliable);
 
 	  if (reliable)
-	    infer_loop_bounds_from_signedness (loop, stmt);
+            {
+              infer_loop_bounds_from_signedness (loop, stmt);
+              infer_loop_bounds_from_pointer_arith (loop, stmt);
+            }
   	}
 
     }
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c (revision 173734)
+++ gcc/tree-ssa-loop-ivopts.c (working copy)
@@ -4391,8 +4391,13 @@ may_eliminate_iv (struct ivopts_data *da
             {
               if (!estimated_loop_iterations (loop, true, &max_niter))
                 return false;
-              /* The loop bound is already adjusted by adding 1.  */
-              if (double_int_ucmp (max_niter, period_value) > 0)
+              /* The max iterations applies also to the number of times the loop
+                 exit condition is executed.  The number of distinct values of
+                 the cand is period_value + 1.  So, test for
+                 'period_value + 1 >= max_iterations'.
+               */
+              period_value = double_int_add (period_value, double_int_one);
+              if (double_int_ucmp (max_niter, period_value) > 0)
                 return false;
             }
           else

  reply	other threads:[~2011-05-20  9:58 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-17  7:23 [PATCH, PR45098] Tom de Vries
2011-05-17  7:25 ` [PATCH, PR45098, 1/10] Tom de Vries
2011-05-19 11:17   ` [PATCH PR45098, 1/10] Proc object-size fix Tom de Vries
2011-05-17  8:12 ` [PATCH, PR45098, 2/10] Tom de Vries
2011-05-18  9:39   ` Zdenek Dvorak
2011-05-17  8:30 ` [PATCH, PR45098, 3/10] Tom de Vries
2011-05-18 10:10   ` Zdenek Dvorak
2011-05-18 13:00     ` Tom de Vries
     [not found]       ` <20110518152457.GA13360@kam.mff.cuni.cz>
2011-05-18 19:30         ` Tom de Vries
2011-05-17  8:32 ` [PATCH, PR45098, 4/10] Tom de Vries
2011-05-18 17:46   ` [PATCH PR45098, 4/10] Iv init cost Tom de Vries
2011-05-18 22:59     ` Zdenek Dvorak
2011-05-25 14:20     ` Richard Sandiford
2011-05-26 12:24       ` Tom de Vries
2011-05-31 15:22         ` Richard Sandiford
2011-05-17  8:37 ` [PATCH, PR45098, 5/10] Tom de Vries
2011-05-18 17:48   ` [PATCH PR45098, 5/10] Bound cost Tom de Vries
2011-05-19  4:45     ` Zdenek Dvorak
2011-05-17  8:42 ` [PATCH, PR45098, 6/10] Tom de Vries
2011-05-18 17:48   ` [PATCH PR45098, 6/10] Bound cost - test cases Tom de Vries
2011-05-17  8:58 ` [PATCH, PR45098, 7/10] Tom de Vries
2011-05-18 17:52   ` [PATCH PR45098, 7/10] Nowrap limits iterations Tom de Vries
2011-05-19  4:45     ` Zdenek Dvorak
2011-05-20 12:22       ` Tom de Vries [this message]
2011-05-21 18:54         ` Zdenek Dvorak
2011-05-21 22:53           ` Tom de Vries
2011-05-28 17:58             ` Tom de Vries
2011-05-30 15:12               ` Zdenek Dvorak
2011-05-31  9:07                 ` Tom de Vries
2011-05-31  9:11                   ` Zdenek Dvorak
2011-06-11 10:13                     ` Tom de Vries
2011-06-12  1:17                       ` Zdenek Dvorak
2011-05-23 14:50           ` H.J. Lu
2011-05-17  9:03 ` [PATCH, PR45098, 8/10] Tom de Vries
2011-05-18 18:23   ` [PATCH PR45098, 8/10] Nowrap limits iterations - test cases Tom de Vries
2011-05-18 18:27   ` [PATCH PR45098, 9/10] Cheap shift-add Tom de Vries
2011-05-19  5:33     ` Zdenek Dvorak
2011-05-20 11:32       ` Tom de Vries
2011-05-20 20:09         ` Zdenek Dvorak
2011-05-21 15:05         ` Eric Botcazou
2011-05-22 19:33           ` Tom de Vries
2011-05-22 20:22             ` Richard Guenther
2011-05-22 21:11             ` Eric Botcazou
2011-05-17 10:03 ` [PATCH, PR45098, 9/10] Tom de Vries
2011-05-17 10:30 ` [PATCH, PR45098, 10/10] Tom de Vries
2011-05-18 18:30   ` [PATCH PR45098, 10/10] Cheap shift-add - test case Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DD63AE1.7070600@codesourcery.com \
    --to=vries@codesourcery.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rakdver@kam.mff.cuni.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).