xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-loop-ch.c (revision 404ee5b9334f618040b6cdef96a0ff35a6fc4636)
1 /* Loop header copying on trees.
2    Copyright (C) 2004-2017 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "tree.h"
25 #include "gimple.h"
26 #include "cfghooks.h"
27 #include "tree-pass.h"
28 #include "gimple-ssa.h"
29 #include "gimple-iterator.h"
30 #include "tree-cfg.h"
31 #include "tree-into-ssa.h"
32 #include "cfgloop.h"
33 #include "tree-inline.h"
34 #include "tree-ssa-scopedtables.h"
35 #include "tree-ssa-threadedge.h"
36 #include "params.h"
37 
38 /* Duplicates headers of loops if they are small enough, so that the statements
39    in the loop body are always executed when the loop is entered.  This
40    increases effectiveness of code motion optimizations, and reduces the need
41    for loop preconditioning.  */
42 
43 /* Check whether we should duplicate HEADER of LOOP.  At most *LIMIT
44    instructions should be duplicated, limit is decreased by the actual
45    amount.  */
46 
47 static bool
48 should_duplicate_loop_header_p (basic_block header, struct loop *loop,
49 				int *limit)
50 {
51   gimple_stmt_iterator bsi;
52   gimple *last;
53 
54   gcc_assert (!header->aux);
55 
56   /* Loop header copying usually increases size of the code.  This used not to
57      be true, since quite often it is possible to verify that the condition is
58      satisfied in the first iteration and therefore to eliminate it.  Jump
59      threading handles these cases now.  */
60   if (optimize_loop_for_size_p (loop)
61       && !loop->force_vectorize)
62     {
63       if (dump_file && (dump_flags & TDF_DETAILS))
64 	fprintf (dump_file,
65 		 "  Not duplicating bb %i: optimizing for size.\n",
66 		 header->index);
67       return false;
68     }
69 
70   gcc_assert (EDGE_COUNT (header->succs) > 0);
71   if (single_succ_p (header))
72     {
73       if (dump_file && (dump_flags & TDF_DETAILS))
74 	fprintf (dump_file,
75 		 "  Not duplicating bb %i: it is single succ.\n",
76 		 header->index);
77       return false;
78     }
79 
80   if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)
81       && flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 1)->dest))
82     {
83       if (dump_file && (dump_flags & TDF_DETAILS))
84 	fprintf (dump_file,
85 		 "  Not duplicating bb %i: both sucessors are in loop.\n",
86 		 loop->num);
87       return false;
88     }
89 
90   /* If this is not the original loop header, we want it to have just
91      one predecessor in order to match the && pattern.  */
92   if (header != loop->header && !single_pred_p (header))
93     {
94       if (dump_file && (dump_flags & TDF_DETAILS))
95 	fprintf (dump_file,
96 		 "  Not duplicating bb %i: it has mutiple predecestors.\n",
97 		 header->index);
98       return false;
99     }
100 
101   last = last_stmt (header);
102   if (gimple_code (last) != GIMPLE_COND)
103     {
104       if (dump_file && (dump_flags & TDF_DETAILS))
105 	fprintf (dump_file,
106 		 "  Not duplicating bb %i: it does not end by conditional.\n",
107 		 header->index);
108       return false;
109     }
110 
111   /* Count number of instructions and punt on calls.  */
112   for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi))
113     {
114       last = gsi_stmt (bsi);
115 
116       if (gimple_code (last) == GIMPLE_LABEL)
117 	continue;
118 
119       if (is_gimple_debug (last))
120 	continue;
121 
122       if (gimple_code (last) == GIMPLE_CALL
123 	  && !gimple_inexpensive_call_p (as_a <gcall *> (last)))
124 	{
125 	  if (dump_file && (dump_flags & TDF_DETAILS))
126 	    fprintf (dump_file,
127 		     "  Not duplicating bb %i: it contains call.\n",
128 		     header->index);
129 	  return false;
130 	}
131 
132       *limit -= estimate_num_insns (last, &eni_size_weights);
133       if (*limit < 0)
134 	{
135 	  if (dump_file && (dump_flags & TDF_DETAILS))
136 	    fprintf (dump_file,
137 		     "  Not duplicating bb %i contains too many insns.\n",
138 		     header->index);
139 	  return false;
140 	}
141     }
142   if (dump_file && (dump_flags & TDF_DETAILS))
143     fprintf (dump_file, "    Will duplicate bb %i\n", header->index);
144   return true;
145 }
146 
147 /* Checks whether LOOP is a do-while style loop.  */
148 
149 static bool
150 do_while_loop_p (struct loop *loop)
151 {
152   gimple *stmt = last_stmt (loop->latch);
153 
154   /* If the latch of the loop is not empty, it is not a do-while loop.  */
155   if (stmt
156       && gimple_code (stmt) != GIMPLE_LABEL)
157     {
158       if (dump_file && (dump_flags & TDF_DETAILS))
159 	fprintf (dump_file,
160 		 "Loop %i is not do-while loop: latch is not empty.\n",
161 		 loop->num);
162       return false;
163     }
164 
165   /* If the header contains just a condition, it is not a do-while loop.  */
166   stmt = last_and_only_stmt (loop->header);
167   if (stmt
168       && gimple_code (stmt) == GIMPLE_COND)
169     {
170       if (dump_file && (dump_flags & TDF_DETAILS))
171 	fprintf (dump_file,
172 		 "Loop %i is not do-while loop: "
173 		 "header contains just condition.\n", loop->num);
174       return false;
175     }
176   if (dump_file && (dump_flags & TDF_DETAILS))
177     fprintf (dump_file, "Loop %i is do-while loop\n", loop->num);
178 
179   return true;
180 }
181 
182 namespace {
183 
184 /* Common superclass for both header-copying phases.  */
185 class ch_base : public gimple_opt_pass
186 {
187   protected:
188     ch_base (pass_data data, gcc::context *ctxt)
189       : gimple_opt_pass (data, ctxt)
190     {}
191 
192   /* Copies headers of all loops in FUN for which process_loop_p is true.  */
193   unsigned int copy_headers (function *fun);
194 
195   /* Return true to copy headers of LOOP or false to skip.  */
196   virtual bool process_loop_p (struct loop *loop) = 0;
197 };
198 
199 const pass_data pass_data_ch =
200 {
201   GIMPLE_PASS, /* type */
202   "ch", /* name */
203   OPTGROUP_LOOP, /* optinfo_flags */
204   TV_TREE_CH, /* tv_id */
205   ( PROP_cfg | PROP_ssa ), /* properties_required */
206   0, /* properties_provided */
207   0, /* properties_destroyed */
208   0, /* todo_flags_start */
209   0, /* todo_flags_finish */
210 };
211 
212 class pass_ch : public ch_base
213 {
214 public:
215   pass_ch (gcc::context *ctxt)
216     : ch_base (pass_data_ch, ctxt)
217   {}
218 
219   /* opt_pass methods: */
220   virtual bool gate (function *) { return flag_tree_ch != 0; }
221 
222   /* Initialize and finalize loop structures, copying headers inbetween.  */
223   virtual unsigned int execute (function *);
224 
225   opt_pass * clone () { return new pass_ch (m_ctxt); }
226 
227 protected:
228   /* ch_base method: */
229   virtual bool process_loop_p (struct loop *loop);
230 }; // class pass_ch
231 
232 const pass_data pass_data_ch_vect =
233 {
234   GIMPLE_PASS, /* type */
235   "ch_vect", /* name */
236   OPTGROUP_LOOP, /* optinfo_flags */
237   TV_TREE_CH, /* tv_id */
238   ( PROP_cfg | PROP_ssa ), /* properties_required */
239   0, /* properties_provided */
240   0, /* properties_destroyed */
241   0, /* todo_flags_start */
242   0, /* todo_flags_finish */
243 };
244 
245 /* This is a more aggressive version of the same pass, designed to run just
246    before if-conversion and vectorization, to put more loops into the form
247    required for those phases.  */
248 class pass_ch_vect : public ch_base
249 {
250 public:
251   pass_ch_vect (gcc::context *ctxt)
252     : ch_base (pass_data_ch_vect, ctxt)
253   {}
254 
255   /* opt_pass methods: */
256   virtual bool gate (function *fun)
257   {
258     return flag_tree_ch != 0
259 	   && (flag_tree_loop_vectorize != 0 || fun->has_force_vectorize_loops);
260   }
261 
262   /* Just copy headers, no initialization/finalization of loop structures.  */
263   virtual unsigned int execute (function *);
264 
265 protected:
266   /* ch_base method: */
267   virtual bool process_loop_p (struct loop *loop);
268 }; // class pass_ch_vect
269 
270 /* For all loops, copy the condition at the end of the loop body in front
271    of the loop.  This is beneficial since it increases efficiency of
272    code motion optimizations.  It also saves one jump on entry to the loop.  */
273 
274 unsigned int
275 ch_base::copy_headers (function *fun)
276 {
277   struct loop *loop;
278   basic_block header;
279   edge exit, entry;
280   basic_block *bbs, *copied_bbs;
281   unsigned n_bbs;
282   unsigned bbs_size;
283   bool changed = false;
284 
285   if (number_of_loops (fun) <= 1)
286       return 0;
287 
288   bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
289   copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
290   bbs_size = n_basic_blocks_for_fn (fun);
291 
292   FOR_EACH_LOOP (loop, 0)
293     {
294       int initial_limit = PARAM_VALUE (PARAM_MAX_LOOP_HEADER_INSNS);
295       int remaining_limit = initial_limit;
296       if (dump_file && (dump_flags & TDF_DETAILS))
297 	fprintf (dump_file,
298 		 "Analyzing loop %i\n", loop->num);
299 
300       header = loop->header;
301 
302       /* If the loop is already a do-while style one (either because it was
303 	 written as such, or because jump threading transformed it into one),
304 	 we might be in fact peeling the first iteration of the loop.  This
305 	 in general is not a good idea.  */
306       if (!process_loop_p (loop))
307 	continue;
308 
309       /* Iterate the header copying up to limit; this takes care of the cases
310 	 like while (a && b) {...}, where we want to have both of the conditions
311 	 copied.  TODO -- handle while (a || b) - like cases, by not requiring
312 	 the header to have just a single successor and copying up to
313 	 postdominator.  */
314 
315       exit = NULL;
316       n_bbs = 0;
317       while (should_duplicate_loop_header_p (header, loop, &remaining_limit))
318 	{
319 	  /* Find a successor of header that is inside a loop; i.e. the new
320 	     header after the condition is copied.  */
321 	  if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest))
322 	    exit = EDGE_SUCC (header, 0);
323 	  else
324 	    exit = EDGE_SUCC (header, 1);
325 	  bbs[n_bbs++] = header;
326 	  gcc_assert (bbs_size > n_bbs);
327 	  header = exit->dest;
328 	}
329 
330       if (!exit)
331 	continue;
332 
333       if (dump_file && (dump_flags & TDF_DETAILS))
334 	fprintf (dump_file,
335 		 "Duplicating header of the loop %d up to edge %d->%d,"
336 		 " %i insns.\n",
337 		 loop->num, exit->src->index, exit->dest->index,
338 		 initial_limit - remaining_limit);
339 
340       /* Ensure that the header will have just the latch as a predecessor
341 	 inside the loop.  */
342       if (!single_pred_p (exit->dest))
343 	exit = single_pred_edge (split_edge (exit));
344 
345       entry = loop_preheader_edge (loop);
346 
347       propagate_threaded_block_debug_into (exit->dest, entry->dest);
348       if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs,
349 					 true))
350 	{
351 	  fprintf (dump_file, "Duplication failed.\n");
352 	  continue;
353 	}
354 
355       /* If the loop has the form "for (i = j; i < j + 10; i++)" then
356 	 this copying can introduce a case where we rely on undefined
357 	 signed overflow to eliminate the preheader condition, because
358 	 we assume that "j < j + 10" is true.  We don't want to warn
359 	 about that case for -Wstrict-overflow, because in general we
360 	 don't warn about overflow involving loops.  Prevent the
361 	 warning by setting the no_warning flag in the condition.  */
362       if (warn_strict_overflow > 0)
363 	{
364 	  unsigned int i;
365 
366 	  for (i = 0; i < n_bbs; ++i)
367 	    {
368 	      gimple_stmt_iterator bsi;
369 
370 	      for (bsi = gsi_start_bb (copied_bbs[i]);
371 		   !gsi_end_p (bsi);
372 		   gsi_next (&bsi))
373 		{
374 		  gimple *stmt = gsi_stmt (bsi);
375 		  if (gimple_code (stmt) == GIMPLE_COND)
376 		    gimple_set_no_warning (stmt, true);
377 		  else if (is_gimple_assign (stmt))
378 		    {
379 		      enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
380 		      if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
381 			gimple_set_no_warning (stmt, true);
382 		    }
383 		}
384 	    }
385 	}
386 
387       /* Ensure that the latch and the preheader is simple (we know that they
388 	 are not now, since there was the loop exit condition.  */
389       split_edge (loop_preheader_edge (loop));
390       split_edge (loop_latch_edge (loop));
391 
392       changed = true;
393     }
394 
395   if (changed)
396     update_ssa (TODO_update_ssa);
397   free (bbs);
398   free (copied_bbs);
399 
400   return changed ? TODO_cleanup_cfg : 0;
401 }
402 
403 /* Initialize the loop structures we need, and finalize after.  */
404 
405 unsigned int
406 pass_ch::execute (function *fun)
407 {
408   loop_optimizer_init (LOOPS_HAVE_PREHEADERS
409 		       | LOOPS_HAVE_SIMPLE_LATCHES);
410 
411   unsigned int res = copy_headers (fun);
412 
413   loop_optimizer_finalize ();
414   return res;
415 }
416 
417 /* Assume an earlier phase has already initialized all the loop structures that
418    we need here (and perhaps others too), and that these will be finalized by
419    a later phase.  */
420 
421 unsigned int
422 pass_ch_vect::execute (function *fun)
423 {
424   return copy_headers (fun);
425 }
426 
427 /* Apply header copying according to a very simple test of do-while shape.  */
428 
429 bool
430 pass_ch::process_loop_p (struct loop *loop)
431 {
432   return !do_while_loop_p (loop);
433 }
434 
435 /* Apply header-copying to loops where we might enable vectorization.  */
436 
437 bool
438 pass_ch_vect::process_loop_p (struct loop *loop)
439 {
440   if (!flag_tree_vectorize && !loop->force_vectorize)
441     return false;
442 
443   if (loop->dont_vectorize)
444     return false;
445 
446   if (!do_while_loop_p (loop))
447     return true;
448 
449  /* The vectorizer won't handle anything with multiple exits, so skip.  */
450   edge exit = single_exit (loop);
451   if (!exit)
452     return false;
453 
454   /* Copy headers iff there looks to be code in the loop after the exit block,
455      i.e. the exit block has an edge to another block (besides the latch,
456      which should be empty).  */
457   edge_iterator ei;
458   edge e;
459   FOR_EACH_EDGE (e, ei, exit->src->succs)
460     if (!loop_exit_edge_p (loop, e)
461 	&& e->dest != loop->header
462 	&& e->dest != loop->latch)
463       return true;
464 
465   return false;
466 }
467 
468 } // anon namespace
469 
470 gimple_opt_pass *
471 make_pass_ch_vect (gcc::context *ctxt)
472 {
473   return new pass_ch_vect (ctxt);
474 }
475 
476 gimple_opt_pass *
477 make_pass_ch (gcc::context *ctxt)
478 {
479   return new pass_ch (ctxt);
480 }
481