diff mbox

wide-int, cfg

Message ID B100816C-8601-4F22-9869-721C51ED13AA@comcast.net
State New
Headers show

Commit Message

Mike Stump April 24, 2014, 7:02 p.m. UTC
On Nov 25, 2013, at 2:57 AM, Richard Biener <richard.guenther@gmail.com> wrote:
> On Sat, Nov 23, 2013 at 8:21 PM, Mike Stump <mikestump@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.

Comments

Richard Biener April 25, 2014, 8:40 a.m. UTC | #1
On Thu, Apr 24, 2014 at 9:02 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Nov 25, 2013, at 2:57 AM, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Sat, Nov 23, 2013 at 8:21 PM, Mike Stump <mikestump@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?

Ok ... but would it be possible to use the wide_int kind with embedded
variable-length array here as well (like for range_info?).

Thanks,
Richard.

> A copy of the patch is below (unchanged)...
>
diff mbox

Patch

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;