On Tue, 30 Oct 2012, Jan Hubicka wrote: > Hi, > this is first patch of change of tree-ssa-loop-niter to consider bounds that > are > not in block dominating latch. This patch makes them to be recorded and they > are not used. I plan to followup with: > > 1) patch to add simple shortest path walk at the end of > estimate_numbers_of_iterations_loop > determining bound of i.e. > int a[10]; > int b[10]; > for (i=0;i<n;i++) > if (t()) > q(a[i]); > else > q(a[i]); > 2) make complette loop unrolling to kill all statements known to not be > executed > in the last iteration by __builtin_unreachable to silence part of > -Warray-bounds > warnings currently breaking bootstrap with -O3 > 3) make duplicate_loop_to_header_edge in peeling mode to do the same silencing > the rest of warnings > 4) make branch prediction code to drop the prediction on exits not dominating > latch. > > Bootstrapped/regtested x86_64-linux, OK?
Ok. Thanks, Richard. > * tree-ssa-loop-niter.c (number_of_iterations_exit): New parameter > EVERY_ITERATION with implicit value of true. > (record_estimate): Check dominance relationship of the basic block > we are estimating on instead of relying on UPPER to be false. > (struct ilb_data): Drop RELIABLE. > (idx_infer_loop_bounds): Update. > (infer_loop_bounds_from_ref): Drop parameter RELIABLE. > (infer_loop_bounds_from_array): Drop parameter RELIABLE. > (infer_loop_bounds_from_undefined): Update comments and handling > of RELIABLE. > (estimate_numbers_of_iterations_loop): Record all bounds. > Index: tree-ssa-loop-niter.c > =================================================================== > --- tree-ssa-loop-niter.c (revision 192986) > +++ tree-ssa-loop-niter.c (working copy) > @@ -1793,12 +1793,15 @@ loop_only_exit_p (const struct loop *loo > meaning described in comments at struct tree_niter_desc > declaration), false otherwise. If WARN is true and > -Wunsafe-loop-optimizations was given, warn if the optimizer is going to > use > - potentially unsafe assumptions. */ > + potentially unsafe assumptions. > + When EVERY_ITERATION is true, only tests that are known to be executed > + every iteration are considered (i.e. only test that alone bounds the > loop). > + */ > > bool > number_of_iterations_exit (struct loop *loop, edge exit, > struct tree_niter_desc *niter, > - bool warn) > + bool warn, bool every_iteration) > { > gimple stmt; > tree type; > @@ -1806,7 +1809,8 @@ number_of_iterations_exit (struct loop * > enum tree_code code; > affine_iv iv0, iv1; > > - if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src)) > + if (every_iteration > + && !dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src)) > return false; > > niter->assumptions = boolean_false_node; > @@ -2568,6 +2572,11 @@ record_estimate (struct loop *loop, tree > loop->bounds = elt; > } > > + /* If statement is executed on every path to the loop latch, we can > directly > + infer the upper bound on the # of iterations of the loop. */ > + if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (at_stmt))) > + return; > + > /* Update the number of iteration estimates according to the bound. > If at_stmt is an exit then the loop latch is executed at most BOUND > times, > otherwise it can be executed BOUND + 1 times. We will lower the > estimate > @@ -2651,7 +2660,6 @@ struct ilb_data > { > struct loop *loop; > gimple stmt; > - bool reliable; > }; > > static bool > @@ -2660,7 +2668,7 @@ idx_infer_loop_bounds (tree base, tree * > struct ilb_data *data = (struct ilb_data *) dta; > tree ev, init, step; > tree low, high, type, next; > - bool sign, upper = data->reliable, at_end = false; > + bool sign, upper = true, at_end = false; > struct loop *loop = data->loop; > > if (TREE_CODE (base) != ARRAY_REF) > @@ -2737,14 +2745,12 @@ idx_infer_loop_bounds (tree base, tree * > STMT is guaranteed to be executed in every iteration of LOOP.*/ > > static void > -infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref, > - bool reliable) > +infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref) > { > struct ilb_data data; > > data.loop = loop; > data.stmt = stmt; > - data.reliable = reliable; > for_each_index (&ref, idx_infer_loop_bounds, &data); > } > > @@ -2753,7 +2759,7 @@ infer_loop_bounds_from_ref (struct loop > executed in every iteration of LOOP. */ > > static void > -infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable) > +infer_loop_bounds_from_array (struct loop *loop, gimple stmt) > { > if (is_gimple_assign (stmt)) > { > @@ -2763,10 +2769,10 @@ infer_loop_bounds_from_array (struct loo > /* For each memory access, analyze its access function > and record a bound on the loop iteration domain. */ > if (REFERENCE_CLASS_P (op0)) > - infer_loop_bounds_from_ref (loop, stmt, op0, reliable); > + infer_loop_bounds_from_ref (loop, stmt, op0); > > if (REFERENCE_CLASS_P (op1)) > - infer_loop_bounds_from_ref (loop, stmt, op1, reliable); > + infer_loop_bounds_from_ref (loop, stmt, op1); > } > else if (is_gimple_call (stmt)) > { > @@ -2775,13 +2781,13 @@ infer_loop_bounds_from_array (struct loo > > lhs = gimple_call_lhs (stmt); > if (lhs && REFERENCE_CLASS_P (lhs)) > - infer_loop_bounds_from_ref (loop, stmt, lhs, reliable); > + infer_loop_bounds_from_ref (loop, stmt, lhs); > > for (i = 0; i < n; i++) > { > arg = gimple_call_arg (stmt, i); > if (REFERENCE_CLASS_P (arg)) > - infer_loop_bounds_from_ref (loop, stmt, arg, reliable); > + infer_loop_bounds_from_ref (loop, stmt, arg); > } > } > } > @@ -2910,14 +2916,15 @@ infer_loop_bounds_from_undefined (struct > > /* If BB is not executed in each iteration of the loop, we cannot > use the operations in it to infer reliable upper bound on the > - # of iterations of the loop. However, we can use it as a guess. */ > + # of iterations of the loop. However, we can use it as a guess. > + Reliable guesses come only from array bounds. */ > reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb); > > for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) > { > gimple stmt = gsi_stmt (bsi); > > - infer_loop_bounds_from_array (loop, stmt, reliable); > + infer_loop_bounds_from_array (loop, stmt); > > if (reliable) > { > @@ -3078,7 +3085,7 @@ estimate_numbers_of_iterations_loop (str > likely_exit = single_likely_exit (loop); > FOR_EACH_VEC_ELT (edge, exits, i, ex) > { > - if (!number_of_iterations_exit (loop, ex, &niter_desc, false)) > + if (!number_of_iterations_exit (loop, ex, &niter_desc, false, false)) > continue; > > niter = niter_desc.niter; > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend