comparison gcc/tree-ssa-loop-ch.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Loop header copying on trees. 1 /* Loop header copying on trees.
2 Copyright (C) 2004-2018 Free Software Foundation, Inc. 2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it 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 7 under the terms of the GNU General Public License as published by the
31 #include "tree-into-ssa.h" 31 #include "tree-into-ssa.h"
32 #include "cfgloop.h" 32 #include "cfgloop.h"
33 #include "tree-inline.h" 33 #include "tree-inline.h"
34 #include "tree-ssa-scopedtables.h" 34 #include "tree-ssa-scopedtables.h"
35 #include "tree-ssa-threadedge.h" 35 #include "tree-ssa-threadedge.h"
36 #include "params.h" 36 #include "tree-ssa-sccvn.h"
37 #include "tree-phinodes.h"
38 #include "ssa-iterators.h"
37 39
38 /* Duplicates headers of loops if they are small enough, so that the statements 40 /* 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 41 in the loop body are always executed when the loop is entered. This
40 increases effectiveness of code motion optimizations, and reduces the need 42 increases effectiveness of code motion optimizations, and reduces the need
41 for loop preconditioning. */ 43 for loop preconditioning. */
43 /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT 45 /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
44 instructions should be duplicated, limit is decreased by the actual 46 instructions should be duplicated, limit is decreased by the actual
45 amount. */ 47 amount. */
46 48
47 static bool 49 static bool
48 should_duplicate_loop_header_p (basic_block header, struct loop *loop, 50 should_duplicate_loop_header_p (basic_block header, class loop *loop,
49 int *limit) 51 int *limit)
50 { 52 {
51 gimple_stmt_iterator bsi; 53 gimple_stmt_iterator bsi;
52 gimple *last;
53 54
54 gcc_assert (!header->aux); 55 gcc_assert (!header->aux);
55 56
56 /* Loop header copying usually increases size of the code. This used not to 57 /* 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 be true, since quite often it is possible to verify that the condition is
96 " Not duplicating bb %i: it has mutiple predecestors.\n", 97 " Not duplicating bb %i: it has mutiple predecestors.\n",
97 header->index); 98 header->index);
98 return false; 99 return false;
99 } 100 }
100 101
101 last = last_stmt (header); 102 gcond *last = safe_dyn_cast <gcond *> (last_stmt (header));
102 if (gimple_code (last) != GIMPLE_COND) 103 if (!last)
103 { 104 {
104 if (dump_file && (dump_flags & TDF_DETAILS)) 105 if (dump_file && (dump_flags & TDF_DETAILS))
105 fprintf (dump_file, 106 fprintf (dump_file,
106 " Not duplicating bb %i: it does not end by conditional.\n", 107 " Not duplicating bb %i: it does not end by conditional.\n",
107 header->index); 108 header->index);
108 return false; 109 return false;
109 } 110 }
110 111
111 /* Count number of instructions and punt on calls. */ 112 for (gphi_iterator psi = gsi_start_phis (header); !gsi_end_p (psi);
113 gsi_next (&psi))
114 {
115 gphi *phi = psi.phi ();
116 tree res = gimple_phi_result (phi);
117 if (INTEGRAL_TYPE_P (TREE_TYPE (res))
118 || POINTER_TYPE_P (TREE_TYPE (res)))
119 gimple_set_uid (phi, 1 /* IV */);
120 else
121 gimple_set_uid (phi, 0);
122 }
123
124 /* Count number of instructions and punt on calls.
125 Populate stmts INV/IV flag to later apply heuristics to the
126 kind of conditions we want to copy. */
112 for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi)) 127 for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi))
113 { 128 {
114 last = gsi_stmt (bsi); 129 gimple *last = gsi_stmt (bsi);
115 130
116 if (gimple_code (last) == GIMPLE_LABEL) 131 if (gimple_code (last) == GIMPLE_LABEL)
117 continue; 132 continue;
118 133
119 if (is_gimple_debug (last)) 134 if (is_gimple_debug (last))
139 fprintf (dump_file, 154 fprintf (dump_file,
140 " Not duplicating bb %i contains too many insns.\n", 155 " Not duplicating bb %i contains too many insns.\n",
141 header->index); 156 header->index);
142 return false; 157 return false;
143 } 158 }
144 } 159
160 /* Classify the stmt based on whether its computation is based
161 on a IV or whether it is invariant in the loop. */
162 gimple_set_uid (last, 0);
163 if (!gimple_vuse (last))
164 {
165 bool inv = true;
166 bool iv = false;
167 ssa_op_iter i;
168 tree op;
169 FOR_EACH_SSA_TREE_OPERAND (op, last, i, SSA_OP_USE)
170 if (!SSA_NAME_IS_DEFAULT_DEF (op)
171 && flow_bb_inside_loop_p (loop,
172 gimple_bb (SSA_NAME_DEF_STMT (op))))
173 {
174 if (!(gimple_uid (SSA_NAME_DEF_STMT (op)) & 2 /* INV */))
175 inv = false;
176 if (gimple_uid (SSA_NAME_DEF_STMT (op)) & 1 /* IV */)
177 iv = true;
178 }
179 gimple_set_uid (last, (iv ? 1 : 0) | (inv ? 2 : 0));
180 }
181 }
182
183 /* If the condition tests a non-IV loop variant we do not want to rotate
184 the loop further. Unless this is the original loop header. */
185 tree lhs = gimple_cond_lhs (last);
186 tree rhs = gimple_cond_rhs (last);
187 if (header != loop->header
188 && ((TREE_CODE (lhs) == SSA_NAME
189 && !SSA_NAME_IS_DEFAULT_DEF (lhs)
190 && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (lhs)))
191 && gimple_uid (SSA_NAME_DEF_STMT (lhs)) == 0)
192 || (TREE_CODE (rhs) == SSA_NAME
193 && !SSA_NAME_IS_DEFAULT_DEF (rhs)
194 && flow_bb_inside_loop_p (loop,
195 gimple_bb (SSA_NAME_DEF_STMT (rhs)))
196 && gimple_uid (SSA_NAME_DEF_STMT (rhs)) == 0)))
197 {
198 if (dump_file && (dump_flags & TDF_DETAILS))
199 fprintf (dump_file,
200 " Not duplicating bb %i: condition based on non-IV loop"
201 " variant.\n", header->index);
202 return false;
203 }
204
145 if (dump_file && (dump_flags & TDF_DETAILS)) 205 if (dump_file && (dump_flags & TDF_DETAILS))
146 fprintf (dump_file, " Will duplicate bb %i\n", header->index); 206 fprintf (dump_file, " Will duplicate bb %i\n", header->index);
147 return true; 207 return true;
148 } 208 }
149 209
150 /* Checks whether LOOP is a do-while style loop. */ 210 /* Checks whether LOOP is a do-while style loop. */
151 211
152 static bool 212 static bool
153 do_while_loop_p (struct loop *loop) 213 do_while_loop_p (class loop *loop)
154 { 214 {
155 gimple *stmt = last_stmt (loop->latch); 215 gimple *stmt = last_stmt (loop->latch);
156 216
157 /* If the latch of the loop is not empty, it is not a do-while loop. */ 217 /* If the latch of the loop is not empty, it is not a do-while loop. */
158 if (stmt 218 if (stmt
205 265
206 /* Copies headers of all loops in FUN for which process_loop_p is true. */ 266 /* Copies headers of all loops in FUN for which process_loop_p is true. */
207 unsigned int copy_headers (function *fun); 267 unsigned int copy_headers (function *fun);
208 268
209 /* Return true to copy headers of LOOP or false to skip. */ 269 /* Return true to copy headers of LOOP or false to skip. */
210 virtual bool process_loop_p (struct loop *loop) = 0; 270 virtual bool process_loop_p (class loop *loop) = 0;
211 }; 271 };
212 272
213 const pass_data pass_data_ch = 273 const pass_data pass_data_ch =
214 { 274 {
215 GIMPLE_PASS, /* type */ 275 GIMPLE_PASS, /* type */
238 298
239 opt_pass * clone () { return new pass_ch (m_ctxt); } 299 opt_pass * clone () { return new pass_ch (m_ctxt); }
240 300
241 protected: 301 protected:
242 /* ch_base method: */ 302 /* ch_base method: */
243 virtual bool process_loop_p (struct loop *loop); 303 virtual bool process_loop_p (class loop *loop);
244 }; // class pass_ch 304 }; // class pass_ch
245 305
246 const pass_data pass_data_ch_vect = 306 const pass_data pass_data_ch_vect =
247 { 307 {
248 GIMPLE_PASS, /* type */ 308 GIMPLE_PASS, /* type */
276 /* Just copy headers, no initialization/finalization of loop structures. */ 336 /* Just copy headers, no initialization/finalization of loop structures. */
277 virtual unsigned int execute (function *); 337 virtual unsigned int execute (function *);
278 338
279 protected: 339 protected:
280 /* ch_base method: */ 340 /* ch_base method: */
281 virtual bool process_loop_p (struct loop *loop); 341 virtual bool process_loop_p (class loop *loop);
282 }; // class pass_ch_vect 342 }; // class pass_ch_vect
283 343
284 /* For all loops, copy the condition at the end of the loop body in front 344 /* For all loops, copy the condition at the end of the loop body in front
285 of the loop. This is beneficial since it increases efficiency of 345 of the loop. This is beneficial since it increases efficiency of
286 code motion optimizations. It also saves one jump on entry to the loop. */ 346 code motion optimizations. It also saves one jump on entry to the loop. */
287 347
288 unsigned int 348 unsigned int
289 ch_base::copy_headers (function *fun) 349 ch_base::copy_headers (function *fun)
290 { 350 {
291 struct loop *loop; 351 class loop *loop;
292 basic_block header; 352 basic_block header;
293 edge exit, entry; 353 edge exit, entry;
294 basic_block *bbs, *copied_bbs; 354 basic_block *bbs, *copied_bbs;
295 unsigned n_bbs; 355 unsigned n_bbs;
296 unsigned bbs_size; 356 unsigned bbs_size;
297 bool changed = false; 357 bool changed = false;
298 358
299 if (number_of_loops (fun) <= 1) 359 if (number_of_loops (fun) <= 1)
300 return 0; 360 return 0;
301 361
302 bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); 362 bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
303 copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); 363 copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
304 bbs_size = n_basic_blocks_for_fn (fun); 364 bbs_size = n_basic_blocks_for_fn (fun);
305 365
366 auto_vec<std::pair<edge, loop_p> > copied;
367
306 FOR_EACH_LOOP (loop, 0) 368 FOR_EACH_LOOP (loop, 0)
307 { 369 {
308 int initial_limit = PARAM_VALUE (PARAM_MAX_LOOP_HEADER_INSNS); 370 int initial_limit = param_max_loop_header_insns;
309 int remaining_limit = initial_limit; 371 int remaining_limit = initial_limit;
310 if (dump_file && (dump_flags & TDF_DETAILS)) 372 if (dump_file && (dump_flags & TDF_DETAILS))
311 fprintf (dump_file, 373 fprintf (dump_file,
312 "Analyzing loop %i\n", loop->num); 374 "Analyzing loop %i\n", loop->num);
313 375
338 else 400 else
339 exit = EDGE_SUCC (header, 1); 401 exit = EDGE_SUCC (header, 1);
340 bbs[n_bbs++] = header; 402 bbs[n_bbs++] = header;
341 gcc_assert (bbs_size > n_bbs); 403 gcc_assert (bbs_size > n_bbs);
342 header = exit->dest; 404 header = exit->dest;
343 /* Make sure to stop copying after we copied the first exit test.
344 Without further heuristics we do not want to rotate the loop
345 any further. */
346 if (loop_exits_from_bb_p (loop, exit->src))
347 break;
348 } 405 }
349 406
350 if (!exit) 407 if (!exit)
351 continue; 408 continue;
352 409
369 true)) 426 true))
370 { 427 {
371 fprintf (dump_file, "Duplication failed.\n"); 428 fprintf (dump_file, "Duplication failed.\n");
372 continue; 429 continue;
373 } 430 }
431 copied.safe_push (std::make_pair (entry, loop));
374 432
375 /* If the loop has the form "for (i = j; i < j + 10; i++)" then 433 /* If the loop has the form "for (i = j; i < j + 10; i++)" then
376 this copying can introduce a case where we rely on undefined 434 this copying can introduce a case where we rely on undefined
377 signed overflow to eliminate the preheader condition, because 435 signed overflow to eliminate the preheader condition, because
378 we assume that "j < j + 10" is true. We don't want to warn 436 we assume that "j < j + 10" is true. We don't want to warn
391 !gsi_end_p (bsi); 449 !gsi_end_p (bsi);
392 gsi_next (&bsi)) 450 gsi_next (&bsi))
393 { 451 {
394 gimple *stmt = gsi_stmt (bsi); 452 gimple *stmt = gsi_stmt (bsi);
395 if (gimple_code (stmt) == GIMPLE_COND) 453 if (gimple_code (stmt) == GIMPLE_COND)
396 gimple_set_no_warning (stmt, true); 454 {
455 tree lhs = gimple_cond_lhs (stmt);
456 if (gimple_cond_code (stmt) != EQ_EXPR
457 && gimple_cond_code (stmt) != NE_EXPR
458 && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
459 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)))
460 gimple_set_no_warning (stmt, true);
461 }
397 else if (is_gimple_assign (stmt)) 462 else if (is_gimple_assign (stmt))
398 { 463 {
399 enum tree_code rhs_code = gimple_assign_rhs_code (stmt); 464 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
400 if (TREE_CODE_CLASS (rhs_code) == tcc_comparison) 465 tree rhs1 = gimple_assign_rhs1 (stmt);
466 if (TREE_CODE_CLASS (rhs_code) == tcc_comparison
467 && rhs_code != EQ_EXPR
468 && rhs_code != NE_EXPR
469 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
470 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1)))
401 gimple_set_no_warning (stmt, true); 471 gimple_set_no_warning (stmt, true);
402 } 472 }
403 } 473 }
404 } 474 }
405 } 475 }
420 490
421 changed = true; 491 changed = true;
422 } 492 }
423 493
424 if (changed) 494 if (changed)
425 update_ssa (TODO_update_ssa); 495 {
496 update_ssa (TODO_update_ssa);
497 /* After updating SSA form perform CSE on the loop header
498 copies. This is esp. required for the pass before
499 vectorization since nothing cleans up copied exit tests
500 that can now be simplified. CSE from the entry of the
501 region we copied till all loop exit blocks but not
502 entering the loop itself. */
503 for (unsigned i = 0; i < copied.length (); ++i)
504 {
505 edge entry = copied[i].first;
506 loop_p loop = copied[i].second;
507 vec<edge> exit_edges = get_loop_exit_edges (loop);
508 bitmap exit_bbs = BITMAP_ALLOC (NULL);
509 for (unsigned j = 0; j < exit_edges.length (); ++j)
510 bitmap_set_bit (exit_bbs, exit_edges[j]->dest->index);
511 bitmap_set_bit (exit_bbs, loop->header->index);
512 do_rpo_vn (cfun, entry, exit_bbs);
513 BITMAP_FREE (exit_bbs);
514 exit_edges.release ();
515 }
516 }
426 free (bbs); 517 free (bbs);
427 free (copied_bbs); 518 free (copied_bbs);
428 519
429 return changed ? TODO_cleanup_cfg : 0; 520 return changed ? TODO_cleanup_cfg : 0;
430 } 521 }
455 } 546 }
456 547
457 /* Apply header copying according to a very simple test of do-while shape. */ 548 /* Apply header copying according to a very simple test of do-while shape. */
458 549
459 bool 550 bool
460 pass_ch::process_loop_p (struct loop *loop) 551 pass_ch::process_loop_p (class loop *loop)
461 { 552 {
462 return !do_while_loop_p (loop); 553 return !do_while_loop_p (loop);
463 } 554 }
464 555
465 /* Apply header-copying to loops where we might enable vectorization. */ 556 /* Apply header-copying to loops where we might enable vectorization. */
466 557
467 bool 558 bool
468 pass_ch_vect::process_loop_p (struct loop *loop) 559 pass_ch_vect::process_loop_p (class loop *loop)
469 { 560 {
470 if (!flag_tree_loop_vectorize && !loop->force_vectorize) 561 if (!flag_tree_loop_vectorize && !loop->force_vectorize)
471 return false; 562 return false;
472 563
473 if (loop->dont_vectorize) 564 if (loop->dont_vectorize)
474 return false; 565 return false;
475 566
476 if (!do_while_loop_p (loop)) 567 /* The vectorizer won't handle anything with multiple exits, so skip. */
477 return true;
478
479 /* The vectorizer won't handle anything with multiple exits, so skip. */
480 edge exit = single_exit (loop); 568 edge exit = single_exit (loop);
481 if (!exit) 569 if (!exit)
482 return false; 570 return false;
483 571
484 /* Copy headers iff there looks to be code in the loop after the exit block, 572 if (!do_while_loop_p (loop))
485 i.e. the exit block has an edge to another block (besides the latch, 573 return true;
486 which should be empty). */
487 edge_iterator ei;
488 edge e;
489 FOR_EACH_EDGE (e, ei, exit->src->succs)
490 if (!loop_exit_edge_p (loop, e)
491 && e->dest != loop->header
492 && e->dest != loop->latch)
493 return true;
494 574
495 return false; 575 return false;
496 } 576 }
497 577
498 } // anon namespace 578 } // anon namespace