summaryrefslogtreecommitdiff
path: root/gcc/cfgloop.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-20 23:47:35 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-20 23:47:35 +0000
commit6b40961666f073231ed8a76e6e33deeda063cde7 (patch)
tree8247eb4232e8be98b7f61bd68bab2fd1a9f06ca3 /gcc/cfgloop.c
parente6b1b76450af5f98696ecedd4bd9a0ed18cdb2a6 (diff)
parentfc1ce0cf396bf638746d546a557158d87f13849b (diff)
downloadgcc-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.c143
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;
+}