diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-20 23:47:35 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-20 23:47:35 +0000 |
commit | 6b40961666f073231ed8a76e6e33deeda063cde7 (patch) | |
tree | 8247eb4232e8be98b7f61bd68bab2fd1a9f06ca3 /gcc/cfgloop.c | |
parent | e6b1b76450af5f98696ecedd4bd9a0ed18cdb2a6 (diff) | |
parent | fc1ce0cf396bf638746d546a557158d87f13849b (diff) | |
download | gcc-6b40961666f073231ed8a76e6e33deeda063cde7.tar.gz |
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@203881 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloop.c')
-rw-r--r-- | gcc/cfgloop.c | 143 |
1 files changed, 141 insertions, 2 deletions
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index f23eacd6454..18e0f52655c 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -434,7 +434,7 @@ flow_loops_find (struct loops *loops) /* Gather all loop headers in reverse completion order and allocate loop structures for loops that are not already present. */ - larray.create (loops->larray->length()); + larray.create (loops->larray->length ()); for (b = 0; b < n_basic_blocks - NUM_FIXED_BLOCKS; b++) { basic_block header = BASIC_BLOCK (rc_order[b]); @@ -510,7 +510,7 @@ flow_loops_find (struct loops *loops) } } - larray.release(); + larray.release (); return loops; } @@ -1782,3 +1782,142 @@ get_loop_location (struct loop *loop) return DECL_SOURCE_LOCATION (current_function_decl); } +/* Records that every statement in LOOP is executed I_BOUND times. + REALISTIC is true if I_BOUND is expected to be close to the real number + of iterations. UPPER is true if we are sure the loop iterates at most + I_BOUND times. */ + +void +record_niter_bound (struct loop *loop, const max_wide_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 + || 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 + || wi::ltu_p (i_bound, loop->nb_iterations_estimate))) + { + loop->any_estimate = true; + loop->nb_iterations_estimate = i_bound; + } + + /* If an upper bound is smaller than the realistic estimate of the + number of iterations, use the upper bound instead. */ + if (loop->any_upper_bound + && loop->any_estimate + && wi::ltu_p (loop->nb_iterations_upper_bound, + loop->nb_iterations_estimate)) + loop->nb_iterations_estimate = loop->nb_iterations_upper_bound; +} + +/* Similar to get_estimated_loop_iterations, but returns the estimate only + if it fits to HOST_WIDE_INT. If this is not the case, or the estimate + on the number of iterations of LOOP could not be derived, returns -1. */ + +HOST_WIDE_INT +get_estimated_loop_iterations_int (struct loop *loop) +{ + max_wide_int nit; + HOST_WIDE_INT hwi_nit; + + if (!get_estimated_loop_iterations (loop, &nit)) + return -1; + + if (!wi::fits_shwi_p (nit)) + return -1; + hwi_nit = nit.to_shwi (); + + return hwi_nit < 0 ? -1 : hwi_nit; +} + +/* Returns an upper bound on the number of executions of statements + in the LOOP. For statements before the loop exit, this exceeds + the number of execution of the latch by one. */ + +HOST_WIDE_INT +max_stmt_executions_int (struct loop *loop) +{ + HOST_WIDE_INT nit = get_max_loop_iterations_int (loop); + HOST_WIDE_INT snit; + + if (nit == -1) + return -1; + + snit = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) nit + 1); + + /* If the computation overflows, return -1. */ + return snit < 0 ? -1 : snit; +} + +/* Sets NIT to the estimated number of executions of the latch of the + LOOP. If we have no reliable estimate, the function returns false, otherwise + returns true. */ + +bool +get_estimated_loop_iterations (struct loop *loop, max_wide_int *nit) +{ + /* Even if the bound is not recorded, possibly we can derrive one from + profile. */ + if (!loop->any_estimate) + { + if (loop->header->count) + { + *nit = gcov_type_to_wide_int + (expected_loop_iterations_unbounded (loop) + 1); + return true; + } + return false; + } + + *nit = loop->nb_iterations_estimate; + return true; +} + +/* Sets NIT to an upper bound for the maximum number of executions of the + latch of the LOOP. If we have no reliable estimate, the function returns + false, otherwise returns true. */ + +bool +get_max_loop_iterations (struct loop *loop, max_wide_int *nit) +{ + if (!loop->any_upper_bound) + return false; + + *nit = loop->nb_iterations_upper_bound; + return true; +} + +/* Similar to get_max_loop_iterations, but returns the estimate only + if it fits to HOST_WIDE_INT. If this is not the case, or the estimate + on the number of iterations of LOOP could not be derived, returns -1. */ + +HOST_WIDE_INT +get_max_loop_iterations_int (struct loop *loop) +{ + max_wide_int nit; + HOST_WIDE_INT hwi_nit; + + if (!get_max_loop_iterations (loop, &nit)) + return -1; + + if (!wi::fits_shwi_p (nit)) + return -1; + hwi_nit = nit.to_shwi (); + + return hwi_nit < 0 ? -1 : hwi_nit; +} + +/* Returns the loop depth of the loop BB belongs to. */ + +int +bb_loop_depth (const_basic_block bb) +{ + return bb->loop_father ? loop_depth (bb->loop_father) : 0; +} |