1 /* Loop optimizations over tree-ssa. 2 Copyright (C) 2003-2019 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 "tree-pass.h" 27 #include "memmodel.h" 28 #include "tm_p.h" 29 #include "fold-const.h" 30 #include "gimple-iterator.h" 31 #include "tree-ssa-loop-ivopts.h" 32 #include "tree-ssa-loop-manip.h" 33 #include "tree-ssa-loop-niter.h" 34 #include "tree-ssa-loop.h" 35 #include "cfgloop.h" 36 #include "tree-inline.h" 37 #include "tree-scalar-evolution.h" 38 #include "tree-vectorizer.h" 39 #include "omp-general.h" 40 #include "diagnostic-core.h" 41 #include "stringpool.h" 42 #include "attribs.h" 43 44 45 /* A pass making sure loops are fixed up. */ 46 47 namespace { 48 49 const pass_data pass_data_fix_loops = 50 { 51 GIMPLE_PASS, /* type */ 52 "fix_loops", /* name */ 53 OPTGROUP_LOOP, /* optinfo_flags */ 54 TV_TREE_LOOP, /* tv_id */ 55 PROP_cfg, /* properties_required */ 56 0, /* properties_provided */ 57 0, /* properties_destroyed */ 58 0, /* todo_flags_start */ 59 0, /* todo_flags_finish */ 60 }; 61 62 class pass_fix_loops : public gimple_opt_pass 63 { 64 public: 65 pass_fix_loops (gcc::context *ctxt) 66 : gimple_opt_pass (pass_data_fix_loops, ctxt) 67 {} 68 69 /* opt_pass methods: */ 70 virtual bool gate (function *) { return flag_tree_loop_optimize; } 71 72 virtual unsigned int execute (function *fn); 73 }; // class pass_fix_loops 74 75 unsigned int 76 pass_fix_loops::execute (function *) 77 { 78 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) 79 { 80 calculate_dominance_info (CDI_DOMINATORS); 81 fix_loop_structure (NULL); 82 } 83 return 0; 84 } 85 86 } // anon namespace 87 88 gimple_opt_pass * 89 make_pass_fix_loops (gcc::context *ctxt) 90 { 91 return new pass_fix_loops (ctxt); 92 } 93 94 95 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize 96 but we also avoid running it when the IL doesn't contain any loop. */ 97 98 static bool 99 gate_loop (function *fn) 100 { 101 if (!flag_tree_loop_optimize) 102 return false; 103 104 /* For -fdump-passes which runs before loop discovery print the 105 state of -ftree-loop-optimize. */ 106 if (!loops_for_fn (fn)) 107 return true; 108 109 return number_of_loops (fn) > 1; 110 } 111 112 /* The loop superpass. */ 113 114 namespace { 115 116 const pass_data pass_data_tree_loop = 117 { 118 GIMPLE_PASS, /* type */ 119 "loop", /* name */ 120 OPTGROUP_LOOP, /* optinfo_flags */ 121 TV_TREE_LOOP, /* tv_id */ 122 PROP_cfg, /* properties_required */ 123 0, /* properties_provided */ 124 0, /* properties_destroyed */ 125 0, /* todo_flags_start */ 126 0, /* todo_flags_finish */ 127 }; 128 129 class pass_tree_loop : public gimple_opt_pass 130 { 131 public: 132 pass_tree_loop (gcc::context *ctxt) 133 : gimple_opt_pass (pass_data_tree_loop, ctxt) 134 {} 135 136 /* opt_pass methods: */ 137 virtual bool gate (function *fn) { return gate_loop (fn); } 138 139 }; // class pass_tree_loop 140 141 } // anon namespace 142 143 gimple_opt_pass * 144 make_pass_tree_loop (gcc::context *ctxt) 145 { 146 return new pass_tree_loop (ctxt); 147 } 148 149 /* Gate for oacc kernels pass group. */ 150 151 static bool 152 gate_oacc_kernels (function *fn) 153 { 154 if (!flag_openacc) 155 return false; 156 157 if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl))) 158 return false; 159 160 struct loop *loop; 161 FOR_EACH_LOOP (loop, 0) 162 if (loop->in_oacc_kernels_region) 163 return true; 164 165 return false; 166 } 167 168 /* The oacc kernels superpass. */ 169 170 namespace { 171 172 const pass_data pass_data_oacc_kernels = 173 { 174 GIMPLE_PASS, /* type */ 175 "oacc_kernels", /* name */ 176 OPTGROUP_LOOP, /* optinfo_flags */ 177 TV_TREE_LOOP, /* tv_id */ 178 PROP_cfg, /* properties_required */ 179 0, /* properties_provided */ 180 0, /* properties_destroyed */ 181 0, /* todo_flags_start */ 182 0, /* todo_flags_finish */ 183 }; 184 185 class pass_oacc_kernels : public gimple_opt_pass 186 { 187 public: 188 pass_oacc_kernels (gcc::context *ctxt) 189 : gimple_opt_pass (pass_data_oacc_kernels, ctxt) 190 {} 191 192 /* opt_pass methods: */ 193 virtual bool gate (function *fn) { return gate_oacc_kernels (fn); } 194 195 }; // class pass_oacc_kernels 196 197 } // anon namespace 198 199 gimple_opt_pass * 200 make_pass_oacc_kernels (gcc::context *ctxt) 201 { 202 return new pass_oacc_kernels (ctxt); 203 } 204 205 /* The ipa oacc superpass. */ 206 207 namespace { 208 209 const pass_data pass_data_ipa_oacc = 210 { 211 SIMPLE_IPA_PASS, /* type */ 212 "ipa_oacc", /* name */ 213 OPTGROUP_LOOP, /* optinfo_flags */ 214 TV_TREE_LOOP, /* tv_id */ 215 PROP_cfg, /* properties_required */ 216 0, /* properties_provided */ 217 0, /* properties_destroyed */ 218 0, /* todo_flags_start */ 219 0, /* todo_flags_finish */ 220 }; 221 222 class pass_ipa_oacc : public simple_ipa_opt_pass 223 { 224 public: 225 pass_ipa_oacc (gcc::context *ctxt) 226 : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt) 227 {} 228 229 /* opt_pass methods: */ 230 virtual bool gate (function *) 231 { 232 return (optimize 233 && flag_openacc 234 /* Don't bother doing anything if the program has errors. */ 235 && !seen_error ()); 236 } 237 238 }; // class pass_ipa_oacc 239 240 } // anon namespace 241 242 simple_ipa_opt_pass * 243 make_pass_ipa_oacc (gcc::context *ctxt) 244 { 245 return new pass_ipa_oacc (ctxt); 246 } 247 248 /* The ipa oacc kernels pass. */ 249 250 namespace { 251 252 const pass_data pass_data_ipa_oacc_kernels = 253 { 254 SIMPLE_IPA_PASS, /* type */ 255 "ipa_oacc_kernels", /* name */ 256 OPTGROUP_LOOP, /* optinfo_flags */ 257 TV_TREE_LOOP, /* tv_id */ 258 PROP_cfg, /* properties_required */ 259 0, /* properties_provided */ 260 0, /* properties_destroyed */ 261 0, /* todo_flags_start */ 262 0, /* todo_flags_finish */ 263 }; 264 265 class pass_ipa_oacc_kernels : public simple_ipa_opt_pass 266 { 267 public: 268 pass_ipa_oacc_kernels (gcc::context *ctxt) 269 : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt) 270 {} 271 272 }; // class pass_ipa_oacc_kernels 273 274 } // anon namespace 275 276 simple_ipa_opt_pass * 277 make_pass_ipa_oacc_kernels (gcc::context *ctxt) 278 { 279 return new pass_ipa_oacc_kernels (ctxt); 280 } 281 282 /* The no-loop superpass. */ 283 284 namespace { 285 286 const pass_data pass_data_tree_no_loop = 287 { 288 GIMPLE_PASS, /* type */ 289 "no_loop", /* name */ 290 OPTGROUP_NONE, /* optinfo_flags */ 291 TV_TREE_NOLOOP, /* tv_id */ 292 PROP_cfg, /* properties_required */ 293 0, /* properties_provided */ 294 0, /* properties_destroyed */ 295 0, /* todo_flags_start */ 296 0, /* todo_flags_finish */ 297 }; 298 299 class pass_tree_no_loop : public gimple_opt_pass 300 { 301 public: 302 pass_tree_no_loop (gcc::context *ctxt) 303 : gimple_opt_pass (pass_data_tree_no_loop, ctxt) 304 {} 305 306 /* opt_pass methods: */ 307 virtual bool gate (function *fn) { return !gate_loop (fn); } 308 309 }; // class pass_tree_no_loop 310 311 } // anon namespace 312 313 gimple_opt_pass * 314 make_pass_tree_no_loop (gcc::context *ctxt) 315 { 316 return new pass_tree_no_loop (ctxt); 317 } 318 319 320 /* Loop optimizer initialization. */ 321 322 namespace { 323 324 const pass_data pass_data_tree_loop_init = 325 { 326 GIMPLE_PASS, /* type */ 327 "loopinit", /* name */ 328 OPTGROUP_LOOP, /* optinfo_flags */ 329 TV_NONE, /* tv_id */ 330 PROP_cfg, /* properties_required */ 331 0, /* properties_provided */ 332 0, /* properties_destroyed */ 333 0, /* todo_flags_start */ 334 0, /* todo_flags_finish */ 335 }; 336 337 class pass_tree_loop_init : public gimple_opt_pass 338 { 339 public: 340 pass_tree_loop_init (gcc::context *ctxt) 341 : gimple_opt_pass (pass_data_tree_loop_init, ctxt) 342 {} 343 344 /* opt_pass methods: */ 345 virtual unsigned int execute (function *); 346 347 }; // class pass_tree_loop_init 348 349 unsigned int 350 pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED) 351 { 352 /* When processing a loop in the loop pipeline, we should be able to assert 353 that: 354 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS 355 | LOOP_CLOSED_SSA) 356 && scev_initialized_p ()) 357 */ 358 loop_optimizer_init (LOOPS_NORMAL 359 | LOOPS_HAVE_RECORDED_EXITS); 360 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); 361 scev_initialize (); 362 363 return 0; 364 } 365 366 } // anon namespace 367 368 gimple_opt_pass * 369 make_pass_tree_loop_init (gcc::context *ctxt) 370 { 371 return new pass_tree_loop_init (ctxt); 372 } 373 374 /* Loop autovectorization. */ 375 376 namespace { 377 378 const pass_data pass_data_vectorize = 379 { 380 GIMPLE_PASS, /* type */ 381 "vect", /* name */ 382 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */ 383 TV_TREE_VECTORIZATION, /* tv_id */ 384 ( PROP_cfg | PROP_ssa ), /* properties_required */ 385 0, /* properties_provided */ 386 0, /* properties_destroyed */ 387 0, /* todo_flags_start */ 388 0, /* todo_flags_finish */ 389 }; 390 391 class pass_vectorize : public gimple_opt_pass 392 { 393 public: 394 pass_vectorize (gcc::context *ctxt) 395 : gimple_opt_pass (pass_data_vectorize, ctxt) 396 {} 397 398 /* opt_pass methods: */ 399 virtual bool gate (function *fun) 400 { 401 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops; 402 } 403 404 virtual unsigned int execute (function *); 405 406 }; // class pass_vectorize 407 408 unsigned int 409 pass_vectorize::execute (function *fun) 410 { 411 if (number_of_loops (fun) <= 1) 412 return 0; 413 414 return vectorize_loops (); 415 } 416 417 } // anon namespace 418 419 gimple_opt_pass * 420 make_pass_vectorize (gcc::context *ctxt) 421 { 422 return new pass_vectorize (ctxt); 423 } 424 425 /* Propagation of constants using scev. */ 426 427 namespace { 428 429 const pass_data pass_data_scev_cprop = 430 { 431 GIMPLE_PASS, /* type */ 432 "sccp", /* name */ 433 OPTGROUP_LOOP, /* optinfo_flags */ 434 TV_SCEV_CONST, /* tv_id */ 435 ( PROP_cfg | PROP_ssa ), /* properties_required */ 436 0, /* properties_provided */ 437 0, /* properties_destroyed */ 438 0, /* todo_flags_start */ 439 0, /* todo_flags_finish */ 440 }; 441 442 class pass_scev_cprop : public gimple_opt_pass 443 { 444 public: 445 pass_scev_cprop (gcc::context *ctxt) 446 : gimple_opt_pass (pass_data_scev_cprop, ctxt) 447 {} 448 449 /* opt_pass methods: */ 450 virtual bool gate (function *) { return flag_tree_scev_cprop; } 451 virtual unsigned int execute (function *); 452 453 }; // class pass_scev_cprop 454 455 unsigned 456 pass_scev_cprop::execute (function *) 457 { 458 struct loop *loop; 459 bool any = false; 460 461 /* Perform final value replacement in loops, in case the replacement 462 expressions are cheap. */ 463 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) 464 any |= final_value_replacement_loop (loop); 465 466 return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0; 467 } 468 469 } // anon namespace 470 471 gimple_opt_pass * 472 make_pass_scev_cprop (gcc::context *ctxt) 473 { 474 return new pass_scev_cprop (ctxt); 475 } 476 477 /* Induction variable optimizations. */ 478 479 namespace { 480 481 const pass_data pass_data_iv_optimize = 482 { 483 GIMPLE_PASS, /* type */ 484 "ivopts", /* name */ 485 OPTGROUP_LOOP, /* optinfo_flags */ 486 TV_TREE_LOOP_IVOPTS, /* tv_id */ 487 ( PROP_cfg | PROP_ssa ), /* properties_required */ 488 0, /* properties_provided */ 489 0, /* properties_destroyed */ 490 0, /* todo_flags_start */ 491 TODO_update_ssa, /* todo_flags_finish */ 492 }; 493 494 class pass_iv_optimize : public gimple_opt_pass 495 { 496 public: 497 pass_iv_optimize (gcc::context *ctxt) 498 : gimple_opt_pass (pass_data_iv_optimize, ctxt) 499 {} 500 501 /* opt_pass methods: */ 502 virtual bool gate (function *) { return flag_ivopts != 0; } 503 virtual unsigned int execute (function *); 504 505 }; // class pass_iv_optimize 506 507 unsigned int 508 pass_iv_optimize::execute (function *fun) 509 { 510 if (number_of_loops (fun) <= 1) 511 return 0; 512 513 tree_ssa_iv_optimize (); 514 return 0; 515 } 516 517 } // anon namespace 518 519 gimple_opt_pass * 520 make_pass_iv_optimize (gcc::context *ctxt) 521 { 522 return new pass_iv_optimize (ctxt); 523 } 524 525 /* Loop optimizer finalization. */ 526 527 static unsigned int 528 tree_ssa_loop_done (void) 529 { 530 free_numbers_of_iterations_estimates (cfun); 531 scev_finalize (); 532 loop_optimizer_finalize (); 533 return 0; 534 } 535 536 namespace { 537 538 const pass_data pass_data_tree_loop_done = 539 { 540 GIMPLE_PASS, /* type */ 541 "loopdone", /* name */ 542 OPTGROUP_LOOP, /* optinfo_flags */ 543 TV_NONE, /* tv_id */ 544 PROP_cfg, /* properties_required */ 545 0, /* properties_provided */ 546 0, /* properties_destroyed */ 547 0, /* todo_flags_start */ 548 TODO_cleanup_cfg, /* todo_flags_finish */ 549 }; 550 551 class pass_tree_loop_done : public gimple_opt_pass 552 { 553 public: 554 pass_tree_loop_done (gcc::context *ctxt) 555 : gimple_opt_pass (pass_data_tree_loop_done, ctxt) 556 {} 557 558 /* opt_pass methods: */ 559 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); } 560 561 }; // class pass_tree_loop_done 562 563 } // anon namespace 564 565 gimple_opt_pass * 566 make_pass_tree_loop_done (gcc::context *ctxt) 567 { 568 return new pass_tree_loop_done (ctxt); 569 } 570 571 /* Calls CBCK for each index in memory reference ADDR_P. There are two 572 kinds situations handled; in each of these cases, the memory reference 573 and DATA are passed to the callback: 574 575 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also 576 pass the pointer to the index to the callback. 577 578 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the 579 pointer to addr to the callback. 580 581 If the callback returns false, the whole search stops and false is returned. 582 Otherwise the function returns true after traversing through the whole 583 reference *ADDR_P. */ 584 585 bool 586 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data) 587 { 588 tree *nxt, *idx; 589 590 for (; ; addr_p = nxt) 591 { 592 switch (TREE_CODE (*addr_p)) 593 { 594 case SSA_NAME: 595 return cbck (*addr_p, addr_p, data); 596 597 case MEM_REF: 598 nxt = &TREE_OPERAND (*addr_p, 0); 599 return cbck (*addr_p, nxt, data); 600 601 case BIT_FIELD_REF: 602 case VIEW_CONVERT_EXPR: 603 case REALPART_EXPR: 604 case IMAGPART_EXPR: 605 nxt = &TREE_OPERAND (*addr_p, 0); 606 break; 607 608 case COMPONENT_REF: 609 /* If the component has varying offset, it behaves like index 610 as well. */ 611 idx = &TREE_OPERAND (*addr_p, 2); 612 if (*idx 613 && !cbck (*addr_p, idx, data)) 614 return false; 615 616 nxt = &TREE_OPERAND (*addr_p, 0); 617 break; 618 619 case ARRAY_REF: 620 case ARRAY_RANGE_REF: 621 nxt = &TREE_OPERAND (*addr_p, 0); 622 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data)) 623 return false; 624 break; 625 626 case CONSTRUCTOR: 627 return true; 628 629 case ADDR_EXPR: 630 gcc_assert (is_gimple_min_invariant (*addr_p)); 631 return true; 632 633 case TARGET_MEM_REF: 634 idx = &TMR_BASE (*addr_p); 635 if (*idx 636 && !cbck (*addr_p, idx, data)) 637 return false; 638 idx = &TMR_INDEX (*addr_p); 639 if (*idx 640 && !cbck (*addr_p, idx, data)) 641 return false; 642 idx = &TMR_INDEX2 (*addr_p); 643 if (*idx 644 && !cbck (*addr_p, idx, data)) 645 return false; 646 return true; 647 648 default: 649 if (DECL_P (*addr_p) 650 || CONSTANT_CLASS_P (*addr_p)) 651 return true; 652 gcc_unreachable (); 653 } 654 } 655 } 656 657 658 /* The name and the length of the currently generated variable 659 for lsm. */ 660 #define MAX_LSM_NAME_LENGTH 40 661 static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1]; 662 static int lsm_tmp_name_length; 663 664 /* Adds S to lsm_tmp_name. */ 665 666 static void 667 lsm_tmp_name_add (const char *s) 668 { 669 int l = strlen (s) + lsm_tmp_name_length; 670 if (l > MAX_LSM_NAME_LENGTH) 671 return; 672 673 strcpy (lsm_tmp_name + lsm_tmp_name_length, s); 674 lsm_tmp_name_length = l; 675 } 676 677 /* Stores the name for temporary variable that replaces REF to 678 lsm_tmp_name. */ 679 680 static void 681 gen_lsm_tmp_name (tree ref) 682 { 683 const char *name; 684 685 switch (TREE_CODE (ref)) 686 { 687 case MEM_REF: 688 case TARGET_MEM_REF: 689 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 690 lsm_tmp_name_add ("_"); 691 break; 692 693 case ADDR_EXPR: 694 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 695 break; 696 697 case BIT_FIELD_REF: 698 case VIEW_CONVERT_EXPR: 699 case ARRAY_RANGE_REF: 700 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 701 break; 702 703 case REALPART_EXPR: 704 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 705 lsm_tmp_name_add ("_RE"); 706 break; 707 708 case IMAGPART_EXPR: 709 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 710 lsm_tmp_name_add ("_IM"); 711 break; 712 713 case COMPONENT_REF: 714 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 715 lsm_tmp_name_add ("_"); 716 name = get_name (TREE_OPERAND (ref, 1)); 717 if (!name) 718 name = "F"; 719 lsm_tmp_name_add (name); 720 break; 721 722 case ARRAY_REF: 723 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); 724 lsm_tmp_name_add ("_I"); 725 break; 726 727 case SSA_NAME: 728 case VAR_DECL: 729 case PARM_DECL: 730 case FUNCTION_DECL: 731 case LABEL_DECL: 732 name = get_name (ref); 733 if (!name) 734 name = "D"; 735 lsm_tmp_name_add (name); 736 break; 737 738 case STRING_CST: 739 lsm_tmp_name_add ("S"); 740 break; 741 742 case RESULT_DECL: 743 lsm_tmp_name_add ("R"); 744 break; 745 746 case INTEGER_CST: 747 default: 748 /* Nothing. */ 749 break; 750 } 751 } 752 753 /* Determines name for temporary variable that replaces REF. 754 The name is accumulated into the lsm_tmp_name variable. 755 N is added to the name of the temporary. */ 756 757 char * 758 get_lsm_tmp_name (tree ref, unsigned n, const char *suffix) 759 { 760 char ns[2]; 761 762 lsm_tmp_name_length = 0; 763 gen_lsm_tmp_name (ref); 764 lsm_tmp_name_add ("_lsm"); 765 if (n < 10) 766 { 767 ns[0] = '0' + n; 768 ns[1] = 0; 769 lsm_tmp_name_add (ns); 770 } 771 return lsm_tmp_name; 772 if (suffix != NULL) 773 lsm_tmp_name_add (suffix); 774 } 775 776 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */ 777 778 unsigned 779 tree_num_loop_insns (struct loop *loop, eni_weights *weights) 780 { 781 basic_block *body = get_loop_body (loop); 782 gimple_stmt_iterator gsi; 783 unsigned size = 0, i; 784 785 for (i = 0; i < loop->num_nodes; i++) 786 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi)) 787 size += estimate_num_insns (gsi_stmt (gsi), weights); 788 free (body); 789 790 return size; 791 } 792 793 794 795