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;