On Nov 25, 2013, at 2:57 AM, Richard Biener <richard.guent...@gmail.com> wrote:
> On Sat, Nov 23, 2013 at 8:21 PM, Mike Stump <mikest...@comcast.net> wrote:
>> Richi has asked the we break the wide-int patch so that the individual port 
>> and front end maintainers can review their parts without have to go through 
>> the entire patch.    This patch covers the cfg code.
>> 
>> Ok?
> 
> Hmm, this is an example of a wide_int (a widest_int) being used inside
> a structure with long lifetime.  With the patch there are two of those
> per loop plus up to one per statement in a loop body (quadratic in
> the loop depth).


> Now, for the number-of-iterations stuff I really would like to keep things
> cheaper in some way or another.  Shrinking MAX_BITSIZE_MODE_ANY_INT
> would be the easiest improvement for x86_64.

> That said, I'd like this to be addressed.

The port can limit the size like so:

/* Keep the OI and XI modes from confusing the compiler into thinking
   that these modes could actually be used for computation.  They are
   only holders for vectors during data movement.  */
#define MAX_BITSIZE_MODE_ANY_INT (128)

and that is now done on x86.

Ok?

A copy of the patch is below (unchanged)...

        * cfgloop.c
        (alloc_loop): Initialize nb_iterations_upper_bound and
        nb_iterations_estimate.
        (record_niter_bound): Use wide-int interfaces.
        (get_estimated_loop_iterations_int): Likewise.
        (get_estimated_loop_iterations): Likewise.
        (get_max_loop_iterations): Likewise.
        * cfgloop.h: Include wide-int.h.
        (struct nb_iter_bound): Change bound to widest_int.
        (struct loop): Change nb_iterations_upper_bound and
        nb_iterations_estimate to widest_int.
        (record_niter_bound): Switch to use widest_int.
        (get_estimated_loop_iterations): Likewise.
        (get_max_loop_iterations): Likewise.
        (gcov_type_to_double_int): Rename to gcov_type_to_wide_int and
        update for wide-int.
        * cgraph.c
        (cgraph_add_thunk): Use wide-int interfaces.


diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 09029c9..447302a 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -333,7 +333,8 @@ alloc_loop (void)
   loop->exits = ggc_alloc_cleared_loop_exit ();
   loop->exits->next = loop->exits->prev = loop->exits;
   loop->can_be_parallel = false;
-
+  loop->nb_iterations_upper_bound = 0;
+  loop->nb_iterations_estimate = 0;
   return loop;
 }
 
@@ -1784,21 +1785,21 @@ get_loop_location (struct loop *loop)
    I_BOUND times.  */
 
 void
-record_niter_bound (struct loop *loop, double_int i_bound, bool realistic,
-                   bool upper)
+record_niter_bound (struct loop *loop, const widest_int &i_bound,
+                   bool realistic, bool upper)
 {
   /* Update the bounds only when there is no previous estimation, or when the
      current estimation is smaller.  */
   if (upper
       && (!loop->any_upper_bound
-         || i_bound.ult (loop->nb_iterations_upper_bound)))
+         || wi::ltu_p (i_bound, loop->nb_iterations_upper_bound)))
     {
       loop->any_upper_bound = true;
       loop->nb_iterations_upper_bound = i_bound;
     }
   if (realistic
       && (!loop->any_estimate
-         || i_bound.ult (loop->nb_iterations_estimate)))
+         || wi::ltu_p (i_bound, loop->nb_iterations_estimate)))
     {
       loop->any_estimate = true;
       loop->nb_iterations_estimate = i_bound;
@@ -1808,7 +1809,8 @@ record_niter_bound (struct loop *loop, double_int 
i_bound, bool realistic,
      number of iterations, use the upper bound instead.  */
   if (loop->any_upper_bound
       && loop->any_estimate
-      && loop->nb_iterations_upper_bound.ult (loop->nb_iterations_estimate))
+      && wi::ltu_p (loop->nb_iterations_upper_bound,
+                   loop->nb_iterations_estimate))
     loop->nb_iterations_estimate = loop->nb_iterations_upper_bound;
 }
 
@@ -1819,13 +1821,13 @@ record_niter_bound (struct loop *loop, double_int 
i_bound, bool realistic,
 HOST_WIDE_INT
 get_estimated_loop_iterations_int (struct loop *loop)
 {
-  double_int nit;
+  widest_int nit;
   HOST_WIDE_INT hwi_nit;
 
   if (!get_estimated_loop_iterations (loop, &nit))
     return -1;
 
-  if (!nit.fits_shwi ())
+  if (!wi::fits_shwi_p (nit))
     return -1;
   hwi_nit = nit.to_shwi ();
 
@@ -1856,7 +1858,7 @@ max_stmt_executions_int (struct loop *loop)
    returns true.  */
 
 bool
-get_estimated_loop_iterations (struct loop *loop, double_int *nit)
+get_estimated_loop_iterations (struct loop *loop, widest_int *nit)
 {
   /* Even if the bound is not recorded, possibly we can derrive one from
      profile.  */
@@ -1864,7 +1866,7 @@ get_estimated_loop_iterations (struct loop *loop, 
double_int *nit)
     {
       if (loop->header->count)
        {
-          *nit = gcov_type_to_double_int
+          *nit = gcov_type_to_wide_int
                   (expected_loop_iterations_unbounded (loop) + 1);
          return true;
        }
@@ -1880,7 +1882,7 @@ get_estimated_loop_iterations (struct loop *loop, 
double_int *nit)
    false, otherwise returns true.  */
 
 bool
-get_max_loop_iterations (struct loop *loop, double_int *nit)
+get_max_loop_iterations (struct loop *loop, widest_int *nit)
 {
   if (!loop->any_upper_bound)
     return false;
@@ -1896,13 +1898,13 @@ get_max_loop_iterations (struct loop *loop, double_int 
*nit)
 HOST_WIDE_INT
 get_max_loop_iterations_int (struct loop *loop)
 {
-  double_int nit;
+  widest_int nit;
   HOST_WIDE_INT hwi_nit;
 
   if (!get_max_loop_iterations (loop, &nit))
     return -1;
 
-  if (!nit.fits_shwi ())
+  if (!wi::fits_shwi_p (nit))
     return -1;
   hwi_nit = nit.to_shwi ();
 
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 68285a6..69fa996 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_CFGLOOP_H
 
 #include "double-int.h"
+#include "wide-int.h"
 #include "bitmap.h"
 #include "sbitmap.h"
 #include "function.h"
@@ -62,7 +63,7 @@ struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
         overflows (as MAX + 1 is sometimes produced as the estimate on number
        of executions of STMT).
      b) it is consistent with the result of number_of_iterations_exit.  */
-  double_int bound;
+  widest_int bound;
 
   /* True if the statement will cause the loop to be leaved the (at most)
      BOUND + 1-st time it is executed, that is, all the statements after it
@@ -146,12 +147,12 @@ struct GTY ((chain_next ("%h.next"))) loop {
 
   /* An integer guaranteed to be greater or equal to nb_iterations.  Only
      valid if any_upper_bound is true.  */
-  double_int nb_iterations_upper_bound;
+  widest_int nb_iterations_upper_bound;
 
   /* An integer giving an estimate on nb_iterations.  Unlike
      nb_iterations_upper_bound, there is no guarantee that it is at least
      nb_iterations.  */
-  double_int nb_iterations_estimate;
+  widest_int nb_iterations_estimate;
 
   bool any_upper_bound;
   bool any_estimate;
@@ -734,27 +735,27 @@ loop_outermost (struct loop *loop)
   return (*loop->superloops)[1];
 }
 
-extern void record_niter_bound (struct loop *, double_int, bool, bool);
+extern void record_niter_bound (struct loop *, const widest_int &, bool, bool);
 extern HOST_WIDE_INT get_estimated_loop_iterations_int (struct loop *);
 extern HOST_WIDE_INT get_max_loop_iterations_int (struct loop *);
-extern bool get_estimated_loop_iterations (struct loop *loop, double_int *nit);
-extern bool get_max_loop_iterations (struct loop *loop, double_int *nit);
+extern bool get_estimated_loop_iterations (struct loop *loop, widest_int *nit);
+extern bool get_max_loop_iterations (struct loop *loop, widest_int *nit);
 extern int bb_loop_depth (const_basic_block);
 
-/* Converts VAL to double_int.  */
+/* Converts VAL to widest_int.  */
 
-static inline double_int
-gcov_type_to_double_int (gcov_type val)
+static inline widest_int
+gcov_type_to_wide_int (gcov_type val)
 {
-  double_int ret;
+  HOST_WIDE_INT a[2];
 
-  ret.low = (unsigned HOST_WIDE_INT) val;
+  a[0] = (unsigned HOST_WIDE_INT) val;
   /* If HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_WIDEST_INT, avoid shifting by
      the size of type.  */
   val >>= HOST_BITS_PER_WIDE_INT - 1;
   val >>= 1;
-  ret.high = (unsigned HOST_WIDE_INT) val;
+  a[1] = (unsigned HOST_WIDE_INT) val;
 
-  return ret;
+  return widest_int::from_array (a, 2);
 }
 #endif /* GCC_CFGLOOP_H */
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 009a165..cfbd79e 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -646,8 +646,7 @@ cgraph_add_thunk (struct cgraph_node *decl_node 
ATTRIBUTE_UNUSED,
   
   node = cgraph_create_node (alias);
   gcc_checking_assert (!virtual_offset
-                      || tree_to_double_int (virtual_offset) ==
-                            double_int::from_shwi (virtual_value));
+                      || wi::eq_p (virtual_offset, virtual_value));
   node->thunk.fixed_offset = fixed_offset;
   node->thunk.this_adjusting = this_adjusting;
   node->thunk.virtual_value = virtual_value;

Reply via email to