1 /* Loop Vectorization 2 Copyright (C) 2003-2022 Free Software Foundation, Inc. 3 Contributed by Dorit Naishlos <dorit (at) il.ibm.com> and 4 Ira Rosen <irar (at) il.ibm.com> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 #define INCLUDE_ALGORITHM 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "backend.h" 27 #include "target.h" 28 #include "rtl.h" 29 #include "tree.h" 30 #include "gimple.h" 31 #include "cfghooks.h" 32 #include "tree-pass.h" 33 #include "ssa.h" 34 #include "optabs-tree.h" 35 #include "diagnostic-core.h" 36 #include "fold-const.h" 37 #include "stor-layout.h" 38 #include "cfganal.h" 39 #include "gimplify.h" 40 #include "gimple-iterator.h" 41 #include "gimplify-me.h" 42 #include "tree-ssa-loop-ivopts.h" 43 #include "tree-ssa-loop-manip.h" 44 #include "tree-ssa-loop-niter.h" 45 #include "tree-ssa-loop.h" 46 #include "cfgloop.h" 47 #include "tree-scalar-evolution.h" 48 #include "tree-vectorizer.h" 49 #include "gimple-fold.h" 50 #include "cgraph.h" 51 #include "tree-cfg.h" 52 #include "tree-if-conv.h" 53 #include "internal-fn.h" 54 #include "tree-vector-builder.h" 55 #include "vec-perm-indices.h" 56 #include "tree-eh.h" 57 #include "case-cfn-macros.h" 58 59 /* Loop Vectorization Pass. 60 61 This pass tries to vectorize loops. 62 63 For example, the vectorizer transforms the following simple loop: 64 65 short a[N]; short b[N]; short c[N]; int i; 66 67 for (i=0; i<N; i++){ 68 a[i] = b[i] + c[i]; 69 } 70 71 as if it was manually vectorized by rewriting the source code into: 72 73 typedef int __attribute__((mode(V8HI))) v8hi; 74 short a[N]; short b[N]; short c[N]; int i; 75 v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c; 76 v8hi va, vb, vc; 77 78 for (i=0; i<N/8; i++){ 79 vb = pb[i]; 80 vc = pc[i]; 81 va = vb + vc; 82 pa[i] = va; 83 } 84 85 The main entry to this pass is vectorize_loops(), in which 86 the vectorizer applies a set of analyses on a given set of loops, 87 followed by the actual vectorization transformation for the loops that 88 had successfully passed the analysis phase. 89 Throughout this pass we make a distinction between two types of 90 data: scalars (which are represented by SSA_NAMES), and memory references 91 ("data-refs"). These two types of data require different handling both 92 during analysis and transformation. The types of data-refs that the 93 vectorizer currently supports are ARRAY_REFS which base is an array DECL 94 (not a pointer), and INDIRECT_REFS through pointers; both array and pointer 95 accesses are required to have a simple (consecutive) access pattern. 96 97 Analysis phase: 98 =============== 99 The driver for the analysis phase is vect_analyze_loop(). 100 It applies a set of analyses, some of which rely on the scalar evolution 101 analyzer (scev) developed by Sebastian Pop. 102 103 During the analysis phase the vectorizer records some information 104 per stmt in a "stmt_vec_info" struct which is attached to each stmt in the 105 loop, as well as general information about the loop as a whole, which is 106 recorded in a "loop_vec_info" struct attached to each loop. 107 108 Transformation phase: 109 ===================== 110 The loop transformation phase scans all the stmts in the loop, and 111 creates a vector stmt (or a sequence of stmts) for each scalar stmt S in 112 the loop that needs to be vectorized. It inserts the vector code sequence 113 just before the scalar stmt S, and records a pointer to the vector code 114 in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct 115 attached to S). This pointer will be used for the vectorization of following 116 stmts which use the def of stmt S. Stmt S is removed if it writes to memory; 117 otherwise, we rely on dead code elimination for removing it. 118 119 For example, say stmt S1 was vectorized into stmt VS1: 120 121 VS1: vb = px[i]; 122 S1: b = x[i]; STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1 123 S2: a = b; 124 125 To vectorize stmt S2, the vectorizer first finds the stmt that defines 126 the operand 'b' (S1), and gets the relevant vector def 'vb' from the 127 vector stmt VS1 pointed to by STMT_VINFO_VEC_STMT (stmt_info (S1)). The 128 resulting sequence would be: 129 130 VS1: vb = px[i]; 131 S1: b = x[i]; STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1 132 VS2: va = vb; 133 S2: a = b; STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2 134 135 Operands that are not SSA_NAMEs, are data-refs that appear in 136 load/store operations (like 'x[i]' in S1), and are handled differently. 137 138 Target modeling: 139 ================= 140 Currently the only target specific information that is used is the 141 size of the vector (in bytes) - "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD". 142 Targets that can support different sizes of vectors, for now will need 143 to specify one value for "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD". More 144 flexibility will be added in the future. 145 146 Since we only vectorize operations which vector form can be 147 expressed using existing tree codes, to verify that an operation is 148 supported, the vectorizer checks the relevant optab at the relevant 149 machine_mode (e.g, optab_handler (add_optab, V8HImode)). If 150 the value found is CODE_FOR_nothing, then there's no target support, and 151 we can't vectorize the stmt. 152 153 For additional information on this project see: 154 http://gcc.gnu.org/projects/tree-ssa/vectorization.html 155 */ 156 157 static void vect_estimate_min_profitable_iters (loop_vec_info, int *, int *, 158 unsigned *); 159 static stmt_vec_info vect_is_simple_reduction (loop_vec_info, stmt_vec_info, 160 bool *, bool *); 161 162 /* Subroutine of vect_determine_vf_for_stmt that handles only one 163 statement. VECTYPE_MAYBE_SET_P is true if STMT_VINFO_VECTYPE 164 may already be set for general statements (not just data refs). */ 165 166 static opt_result 167 vect_determine_vf_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, 168 bool vectype_maybe_set_p, 169 poly_uint64 *vf) 170 { 171 gimple *stmt = stmt_info->stmt; 172 173 if ((!STMT_VINFO_RELEVANT_P (stmt_info) 174 && !STMT_VINFO_LIVE_P (stmt_info)) 175 || gimple_clobber_p (stmt)) 176 { 177 if (dump_enabled_p ()) 178 dump_printf_loc (MSG_NOTE, vect_location, "skip.\n"); 179 return opt_result::success (); 180 } 181 182 tree stmt_vectype, nunits_vectype; 183 opt_result res = vect_get_vector_types_for_stmt (vinfo, stmt_info, 184 &stmt_vectype, 185 &nunits_vectype); 186 if (!res) 187 return res; 188 189 if (stmt_vectype) 190 { 191 if (STMT_VINFO_VECTYPE (stmt_info)) 192 /* The only case when a vectype had been already set is for stmts 193 that contain a data ref, or for "pattern-stmts" (stmts generated 194 by the vectorizer to represent/replace a certain idiom). */ 195 gcc_assert ((STMT_VINFO_DATA_REF (stmt_info) 196 || vectype_maybe_set_p) 197 && STMT_VINFO_VECTYPE (stmt_info) == stmt_vectype); 198 else 199 STMT_VINFO_VECTYPE (stmt_info) = stmt_vectype; 200 } 201 202 if (nunits_vectype) 203 vect_update_max_nunits (vf, nunits_vectype); 204 205 return opt_result::success (); 206 } 207 208 /* Subroutine of vect_determine_vectorization_factor. Set the vector 209 types of STMT_INFO and all attached pattern statements and update 210 the vectorization factor VF accordingly. Return true on success 211 or false if something prevented vectorization. */ 212 213 static opt_result 214 vect_determine_vf_for_stmt (vec_info *vinfo, 215 stmt_vec_info stmt_info, poly_uint64 *vf) 216 { 217 if (dump_enabled_p ()) 218 dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: %G", 219 stmt_info->stmt); 220 opt_result res = vect_determine_vf_for_stmt_1 (vinfo, stmt_info, false, vf); 221 if (!res) 222 return res; 223 224 if (STMT_VINFO_IN_PATTERN_P (stmt_info) 225 && STMT_VINFO_RELATED_STMT (stmt_info)) 226 { 227 gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info); 228 stmt_info = STMT_VINFO_RELATED_STMT (stmt_info); 229 230 /* If a pattern statement has def stmts, analyze them too. */ 231 for (gimple_stmt_iterator si = gsi_start (pattern_def_seq); 232 !gsi_end_p (si); gsi_next (&si)) 233 { 234 stmt_vec_info def_stmt_info = vinfo->lookup_stmt (gsi_stmt (si)); 235 if (dump_enabled_p ()) 236 dump_printf_loc (MSG_NOTE, vect_location, 237 "==> examining pattern def stmt: %G", 238 def_stmt_info->stmt); 239 res = vect_determine_vf_for_stmt_1 (vinfo, def_stmt_info, true, vf); 240 if (!res) 241 return res; 242 } 243 244 if (dump_enabled_p ()) 245 dump_printf_loc (MSG_NOTE, vect_location, 246 "==> examining pattern statement: %G", 247 stmt_info->stmt); 248 res = vect_determine_vf_for_stmt_1 (vinfo, stmt_info, true, vf); 249 if (!res) 250 return res; 251 } 252 253 return opt_result::success (); 254 } 255 256 /* Function vect_determine_vectorization_factor 257 258 Determine the vectorization factor (VF). VF is the number of data elements 259 that are operated upon in parallel in a single iteration of the vectorized 260 loop. For example, when vectorizing a loop that operates on 4byte elements, 261 on a target with vector size (VS) 16byte, the VF is set to 4, since 4 262 elements can fit in a single vector register. 263 264 We currently support vectorization of loops in which all types operated upon 265 are of the same size. Therefore this function currently sets VF according to 266 the size of the types operated upon, and fails if there are multiple sizes 267 in the loop. 268 269 VF is also the factor by which the loop iterations are strip-mined, e.g.: 270 original loop: 271 for (i=0; i<N; i++){ 272 a[i] = b[i] + c[i]; 273 } 274 275 vectorized loop: 276 for (i=0; i<N; i+=VF){ 277 a[i:VF] = b[i:VF] + c[i:VF]; 278 } 279 */ 280 281 static opt_result 282 vect_determine_vectorization_factor (loop_vec_info loop_vinfo) 283 { 284 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 285 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); 286 unsigned nbbs = loop->num_nodes; 287 poly_uint64 vectorization_factor = 1; 288 tree scalar_type = NULL_TREE; 289 gphi *phi; 290 tree vectype; 291 stmt_vec_info stmt_info; 292 unsigned i; 293 294 DUMP_VECT_SCOPE ("vect_determine_vectorization_factor"); 295 296 for (i = 0; i < nbbs; i++) 297 { 298 basic_block bb = bbs[i]; 299 300 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); 301 gsi_next (&si)) 302 { 303 phi = si.phi (); 304 stmt_info = loop_vinfo->lookup_stmt (phi); 305 if (dump_enabled_p ()) 306 dump_printf_loc (MSG_NOTE, vect_location, "==> examining phi: %G", 307 phi); 308 309 gcc_assert (stmt_info); 310 311 if (STMT_VINFO_RELEVANT_P (stmt_info) 312 || STMT_VINFO_LIVE_P (stmt_info)) 313 { 314 gcc_assert (!STMT_VINFO_VECTYPE (stmt_info)); 315 scalar_type = TREE_TYPE (PHI_RESULT (phi)); 316 317 if (dump_enabled_p ()) 318 dump_printf_loc (MSG_NOTE, vect_location, 319 "get vectype for scalar type: %T\n", 320 scalar_type); 321 322 vectype = get_vectype_for_scalar_type (loop_vinfo, scalar_type); 323 if (!vectype) 324 return opt_result::failure_at (phi, 325 "not vectorized: unsupported " 326 "data-type %T\n", 327 scalar_type); 328 STMT_VINFO_VECTYPE (stmt_info) = vectype; 329 330 if (dump_enabled_p ()) 331 dump_printf_loc (MSG_NOTE, vect_location, "vectype: %T\n", 332 vectype); 333 334 if (dump_enabled_p ()) 335 { 336 dump_printf_loc (MSG_NOTE, vect_location, "nunits = "); 337 dump_dec (MSG_NOTE, TYPE_VECTOR_SUBPARTS (vectype)); 338 dump_printf (MSG_NOTE, "\n"); 339 } 340 341 vect_update_max_nunits (&vectorization_factor, vectype); 342 } 343 } 344 345 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); 346 gsi_next (&si)) 347 { 348 if (is_gimple_debug (gsi_stmt (si))) 349 continue; 350 stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); 351 opt_result res 352 = vect_determine_vf_for_stmt (loop_vinfo, 353 stmt_info, &vectorization_factor); 354 if (!res) 355 return res; 356 } 357 } 358 359 /* TODO: Analyze cost. Decide if worth while to vectorize. */ 360 if (dump_enabled_p ()) 361 { 362 dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = "); 363 dump_dec (MSG_NOTE, vectorization_factor); 364 dump_printf (MSG_NOTE, "\n"); 365 } 366 367 if (known_le (vectorization_factor, 1U)) 368 return opt_result::failure_at (vect_location, 369 "not vectorized: unsupported data-type\n"); 370 LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; 371 return opt_result::success (); 372 } 373 374 375 /* Function vect_is_simple_iv_evolution. 376 377 FORNOW: A simple evolution of an induction variables in the loop is 378 considered a polynomial evolution. */ 379 380 static bool 381 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, 382 tree * step) 383 { 384 tree init_expr; 385 tree step_expr; 386 tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb); 387 basic_block bb; 388 389 /* When there is no evolution in this loop, the evolution function 390 is not "simple". */ 391 if (evolution_part == NULL_TREE) 392 return false; 393 394 /* When the evolution is a polynomial of degree >= 2 395 the evolution function is not "simple". */ 396 if (tree_is_chrec (evolution_part)) 397 return false; 398 399 step_expr = evolution_part; 400 init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb)); 401 402 if (dump_enabled_p ()) 403 dump_printf_loc (MSG_NOTE, vect_location, "step: %T, init: %T\n", 404 step_expr, init_expr); 405 406 *init = init_expr; 407 *step = step_expr; 408 409 if (TREE_CODE (step_expr) != INTEGER_CST 410 && (TREE_CODE (step_expr) != SSA_NAME 411 || ((bb = gimple_bb (SSA_NAME_DEF_STMT (step_expr))) 412 && flow_bb_inside_loop_p (get_loop (cfun, loop_nb), bb)) 413 || (!INTEGRAL_TYPE_P (TREE_TYPE (step_expr)) 414 && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr)) 415 || !flag_associative_math))) 416 && (TREE_CODE (step_expr) != REAL_CST 417 || !flag_associative_math)) 418 { 419 if (dump_enabled_p ()) 420 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 421 "step unknown.\n"); 422 return false; 423 } 424 425 return true; 426 } 427 428 /* Return true if PHI, described by STMT_INFO, is the inner PHI in 429 what we are assuming is a double reduction. For example, given 430 a structure like this: 431 432 outer1: 433 x_1 = PHI <x_4(outer2), ...>; 434 ... 435 436 inner: 437 x_2 = PHI <x_1(outer1), ...>; 438 ... 439 x_3 = ...; 440 ... 441 442 outer2: 443 x_4 = PHI <x_3(inner)>; 444 ... 445 446 outer loop analysis would treat x_1 as a double reduction phi and 447 this function would then return true for x_2. */ 448 449 static bool 450 vect_inner_phi_in_double_reduction_p (loop_vec_info loop_vinfo, gphi *phi) 451 { 452 use_operand_p use_p; 453 ssa_op_iter op_iter; 454 FOR_EACH_PHI_ARG (use_p, phi, op_iter, SSA_OP_USE) 455 if (stmt_vec_info def_info = loop_vinfo->lookup_def (USE_FROM_PTR (use_p))) 456 if (STMT_VINFO_DEF_TYPE (def_info) == vect_double_reduction_def) 457 return true; 458 return false; 459 } 460 461 /* Function vect_analyze_scalar_cycles_1. 462 463 Examine the cross iteration def-use cycles of scalar variables 464 in LOOP. LOOP_VINFO represents the loop that is now being 465 considered for vectorization (can be LOOP, or an outer-loop 466 enclosing LOOP). */ 467 468 static void 469 vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, class loop *loop) 470 { 471 basic_block bb = loop->header; 472 tree init, step; 473 auto_vec<stmt_vec_info, 64> worklist; 474 gphi_iterator gsi; 475 bool double_reduc, reduc_chain; 476 477 DUMP_VECT_SCOPE ("vect_analyze_scalar_cycles"); 478 479 /* First - identify all inductions. Reduction detection assumes that all the 480 inductions have been identified, therefore, this order must not be 481 changed. */ 482 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 483 { 484 gphi *phi = gsi.phi (); 485 tree access_fn = NULL; 486 tree def = PHI_RESULT (phi); 487 stmt_vec_info stmt_vinfo = loop_vinfo->lookup_stmt (phi); 488 489 if (dump_enabled_p ()) 490 dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: %G", phi); 491 492 /* Skip virtual phi's. The data dependences that are associated with 493 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */ 494 if (virtual_operand_p (def)) 495 continue; 496 497 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type; 498 499 /* Analyze the evolution function. */ 500 access_fn = analyze_scalar_evolution (loop, def); 501 if (access_fn) 502 { 503 STRIP_NOPS (access_fn); 504 if (dump_enabled_p ()) 505 dump_printf_loc (MSG_NOTE, vect_location, 506 "Access function of PHI: %T\n", access_fn); 507 STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED (stmt_vinfo) 508 = initial_condition_in_loop_num (access_fn, loop->num); 509 STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) 510 = evolution_part_in_loop_num (access_fn, loop->num); 511 } 512 513 if (!access_fn 514 || vect_inner_phi_in_double_reduction_p (loop_vinfo, phi) 515 || !vect_is_simple_iv_evolution (loop->num, access_fn, &init, &step) 516 || (LOOP_VINFO_LOOP (loop_vinfo) != loop 517 && TREE_CODE (step) != INTEGER_CST)) 518 { 519 worklist.safe_push (stmt_vinfo); 520 continue; 521 } 522 523 gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED (stmt_vinfo) 524 != NULL_TREE); 525 gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) != NULL_TREE); 526 527 if (dump_enabled_p ()) 528 dump_printf_loc (MSG_NOTE, vect_location, "Detected induction.\n"); 529 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def; 530 } 531 532 533 /* Second - identify all reductions and nested cycles. */ 534 while (worklist.length () > 0) 535 { 536 stmt_vec_info stmt_vinfo = worklist.pop (); 537 gphi *phi = as_a <gphi *> (stmt_vinfo->stmt); 538 tree def = PHI_RESULT (phi); 539 540 if (dump_enabled_p ()) 541 dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: %G", phi); 542 543 gcc_assert (!virtual_operand_p (def) 544 && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type); 545 546 stmt_vec_info reduc_stmt_info 547 = vect_is_simple_reduction (loop_vinfo, stmt_vinfo, &double_reduc, 548 &reduc_chain); 549 if (reduc_stmt_info) 550 { 551 STMT_VINFO_REDUC_DEF (stmt_vinfo) = reduc_stmt_info; 552 STMT_VINFO_REDUC_DEF (reduc_stmt_info) = stmt_vinfo; 553 if (double_reduc) 554 { 555 if (dump_enabled_p ()) 556 dump_printf_loc (MSG_NOTE, vect_location, 557 "Detected double reduction.\n"); 558 559 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_double_reduction_def; 560 STMT_VINFO_DEF_TYPE (reduc_stmt_info) = vect_double_reduction_def; 561 } 562 else 563 { 564 if (loop != LOOP_VINFO_LOOP (loop_vinfo)) 565 { 566 if (dump_enabled_p ()) 567 dump_printf_loc (MSG_NOTE, vect_location, 568 "Detected vectorizable nested cycle.\n"); 569 570 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_nested_cycle; 571 } 572 else 573 { 574 if (dump_enabled_p ()) 575 dump_printf_loc (MSG_NOTE, vect_location, 576 "Detected reduction.\n"); 577 578 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def; 579 STMT_VINFO_DEF_TYPE (reduc_stmt_info) = vect_reduction_def; 580 /* Store the reduction cycles for possible vectorization in 581 loop-aware SLP if it was not detected as reduction 582 chain. */ 583 if (! reduc_chain) 584 LOOP_VINFO_REDUCTIONS (loop_vinfo).safe_push 585 (reduc_stmt_info); 586 } 587 } 588 } 589 else 590 if (dump_enabled_p ()) 591 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 592 "Unknown def-use cycle pattern.\n"); 593 } 594 } 595 596 597 /* Function vect_analyze_scalar_cycles. 598 599 Examine the cross iteration def-use cycles of scalar variables, by 600 analyzing the loop-header PHIs of scalar variables. Classify each 601 cycle as one of the following: invariant, induction, reduction, unknown. 602 We do that for the loop represented by LOOP_VINFO, and also to its 603 inner-loop, if exists. 604 Examples for scalar cycles: 605 606 Example1: reduction: 607 608 loop1: 609 for (i=0; i<N; i++) 610 sum += a[i]; 611 612 Example2: induction: 613 614 loop2: 615 for (i=0; i<N; i++) 616 a[i] = i; */ 617 618 static void 619 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo) 620 { 621 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 622 623 vect_analyze_scalar_cycles_1 (loop_vinfo, loop); 624 625 /* When vectorizing an outer-loop, the inner-loop is executed sequentially. 626 Reductions in such inner-loop therefore have different properties than 627 the reductions in the nest that gets vectorized: 628 1. When vectorized, they are executed in the same order as in the original 629 scalar loop, so we can't change the order of computation when 630 vectorizing them. 631 2. FIXME: Inner-loop reductions can be used in the inner-loop, so the 632 current checks are too strict. */ 633 634 if (loop->inner) 635 vect_analyze_scalar_cycles_1 (loop_vinfo, loop->inner); 636 } 637 638 /* Transfer group and reduction information from STMT_INFO to its 639 pattern stmt. */ 640 641 static void 642 vect_fixup_reduc_chain (stmt_vec_info stmt_info) 643 { 644 stmt_vec_info firstp = STMT_VINFO_RELATED_STMT (stmt_info); 645 stmt_vec_info stmtp; 646 gcc_assert (!REDUC_GROUP_FIRST_ELEMENT (firstp) 647 && REDUC_GROUP_FIRST_ELEMENT (stmt_info)); 648 REDUC_GROUP_SIZE (firstp) = REDUC_GROUP_SIZE (stmt_info); 649 do 650 { 651 stmtp = STMT_VINFO_RELATED_STMT (stmt_info); 652 gcc_checking_assert (STMT_VINFO_DEF_TYPE (stmtp) 653 == STMT_VINFO_DEF_TYPE (stmt_info)); 654 REDUC_GROUP_FIRST_ELEMENT (stmtp) = firstp; 655 stmt_info = REDUC_GROUP_NEXT_ELEMENT (stmt_info); 656 if (stmt_info) 657 REDUC_GROUP_NEXT_ELEMENT (stmtp) 658 = STMT_VINFO_RELATED_STMT (stmt_info); 659 } 660 while (stmt_info); 661 } 662 663 /* Fixup scalar cycles that now have their stmts detected as patterns. */ 664 665 static void 666 vect_fixup_scalar_cycles_with_patterns (loop_vec_info loop_vinfo) 667 { 668 stmt_vec_info first; 669 unsigned i; 670 671 FOR_EACH_VEC_ELT (LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo), i, first) 672 { 673 stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first); 674 while (next) 675 { 676 if ((STMT_VINFO_IN_PATTERN_P (next) 677 != STMT_VINFO_IN_PATTERN_P (first)) 678 || STMT_VINFO_REDUC_IDX (vect_stmt_to_vectorize (next)) == -1) 679 break; 680 next = REDUC_GROUP_NEXT_ELEMENT (next); 681 } 682 /* If all reduction chain members are well-formed patterns adjust 683 the group to group the pattern stmts instead. */ 684 if (! next 685 && STMT_VINFO_REDUC_IDX (vect_stmt_to_vectorize (first)) != -1) 686 { 687 if (STMT_VINFO_IN_PATTERN_P (first)) 688 { 689 vect_fixup_reduc_chain (first); 690 LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo)[i] 691 = STMT_VINFO_RELATED_STMT (first); 692 } 693 } 694 /* If not all stmt in the chain are patterns or if we failed 695 to update STMT_VINFO_REDUC_IDX dissolve the chain and handle 696 it as regular reduction instead. */ 697 else 698 { 699 stmt_vec_info vinfo = first; 700 stmt_vec_info last = NULL; 701 while (vinfo) 702 { 703 next = REDUC_GROUP_NEXT_ELEMENT (vinfo); 704 REDUC_GROUP_FIRST_ELEMENT (vinfo) = NULL; 705 REDUC_GROUP_NEXT_ELEMENT (vinfo) = NULL; 706 last = vinfo; 707 vinfo = next; 708 } 709 STMT_VINFO_DEF_TYPE (vect_stmt_to_vectorize (first)) 710 = vect_internal_def; 711 loop_vinfo->reductions.safe_push (vect_stmt_to_vectorize (last)); 712 LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).unordered_remove (i); 713 --i; 714 } 715 } 716 } 717 718 /* Function vect_get_loop_niters. 719 720 Determine how many iterations the loop is executed and place it 721 in NUMBER_OF_ITERATIONS. Place the number of latch iterations 722 in NUMBER_OF_ITERATIONSM1. Place the condition under which the 723 niter information holds in ASSUMPTIONS. 724 725 Return the loop exit condition. */ 726 727 728 static gcond * 729 vect_get_loop_niters (class loop *loop, tree *assumptions, 730 tree *number_of_iterations, tree *number_of_iterationsm1) 731 { 732 edge exit = single_exit (loop); 733 class tree_niter_desc niter_desc; 734 tree niter_assumptions, niter, may_be_zero; 735 gcond *cond = get_loop_exit_condition (loop); 736 737 *assumptions = boolean_true_node; 738 *number_of_iterationsm1 = chrec_dont_know; 739 *number_of_iterations = chrec_dont_know; 740 DUMP_VECT_SCOPE ("get_loop_niters"); 741 742 if (!exit) 743 return cond; 744 745 may_be_zero = NULL_TREE; 746 if (!number_of_iterations_exit_assumptions (loop, exit, &niter_desc, NULL) 747 || chrec_contains_undetermined (niter_desc.niter)) 748 return cond; 749 750 niter_assumptions = niter_desc.assumptions; 751 may_be_zero = niter_desc.may_be_zero; 752 niter = niter_desc.niter; 753 754 if (may_be_zero && integer_zerop (may_be_zero)) 755 may_be_zero = NULL_TREE; 756 757 if (may_be_zero) 758 { 759 if (COMPARISON_CLASS_P (may_be_zero)) 760 { 761 /* Try to combine may_be_zero with assumptions, this can simplify 762 computation of niter expression. */ 763 if (niter_assumptions && !integer_nonzerop (niter_assumptions)) 764 niter_assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, 765 niter_assumptions, 766 fold_build1 (TRUTH_NOT_EXPR, 767 boolean_type_node, 768 may_be_zero)); 769 else 770 niter = fold_build3 (COND_EXPR, TREE_TYPE (niter), may_be_zero, 771 build_int_cst (TREE_TYPE (niter), 0), 772 rewrite_to_non_trapping_overflow (niter)); 773 774 may_be_zero = NULL_TREE; 775 } 776 else if (integer_nonzerop (may_be_zero)) 777 { 778 *number_of_iterationsm1 = build_int_cst (TREE_TYPE (niter), 0); 779 *number_of_iterations = build_int_cst (TREE_TYPE (niter), 1); 780 return cond; 781 } 782 else 783 return cond; 784 } 785 786 *assumptions = niter_assumptions; 787 *number_of_iterationsm1 = niter; 788 789 /* We want the number of loop header executions which is the number 790 of latch executions plus one. 791 ??? For UINT_MAX latch executions this number overflows to zero 792 for loops like do { n++; } while (n != 0); */ 793 if (niter && !chrec_contains_undetermined (niter)) 794 niter = fold_build2 (PLUS_EXPR, TREE_TYPE (niter), unshare_expr (niter), 795 build_int_cst (TREE_TYPE (niter), 1)); 796 *number_of_iterations = niter; 797 798 return cond; 799 } 800 801 /* Function bb_in_loop_p 802 803 Used as predicate for dfs order traversal of the loop bbs. */ 804 805 static bool 806 bb_in_loop_p (const_basic_block bb, const void *data) 807 { 808 const class loop *const loop = (const class loop *)data; 809 if (flow_bb_inside_loop_p (loop, bb)) 810 return true; 811 return false; 812 } 813 814 815 /* Create and initialize a new loop_vec_info struct for LOOP_IN, as well as 816 stmt_vec_info structs for all the stmts in LOOP_IN. */ 817 818 _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared) 819 : vec_info (vec_info::loop, shared), 820 loop (loop_in), 821 bbs (XCNEWVEC (basic_block, loop->num_nodes)), 822 num_itersm1 (NULL_TREE), 823 num_iters (NULL_TREE), 824 num_iters_unchanged (NULL_TREE), 825 num_iters_assumptions (NULL_TREE), 826 vector_costs (nullptr), 827 scalar_costs (nullptr), 828 th (0), 829 versioning_threshold (0), 830 vectorization_factor (0), 831 main_loop_edge (nullptr), 832 skip_main_loop_edge (nullptr), 833 skip_this_loop_edge (nullptr), 834 reusable_accumulators (), 835 suggested_unroll_factor (1), 836 max_vectorization_factor (0), 837 mask_skip_niters (NULL_TREE), 838 rgroup_compare_type (NULL_TREE), 839 simd_if_cond (NULL_TREE), 840 unaligned_dr (NULL), 841 peeling_for_alignment (0), 842 ptr_mask (0), 843 ivexpr_map (NULL), 844 scan_map (NULL), 845 slp_unrolling_factor (1), 846 inner_loop_cost_factor (param_vect_inner_loop_cost_factor), 847 vectorizable (false), 848 can_use_partial_vectors_p (param_vect_partial_vector_usage != 0), 849 using_partial_vectors_p (false), 850 epil_using_partial_vectors_p (false), 851 partial_load_store_bias (0), 852 peeling_for_gaps (false), 853 peeling_for_niter (false), 854 no_data_dependencies (false), 855 has_mask_store (false), 856 scalar_loop_scaling (profile_probability::uninitialized ()), 857 scalar_loop (NULL), 858 orig_loop_info (NULL) 859 { 860 /* CHECKME: We want to visit all BBs before their successors (except for 861 latch blocks, for which this assertion wouldn't hold). In the simple 862 case of the loop forms we allow, a dfs order of the BBs would the same 863 as reversed postorder traversal, so we are safe. */ 864 865 unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p, 866 bbs, loop->num_nodes, loop); 867 gcc_assert (nbbs == loop->num_nodes); 868 869 for (unsigned int i = 0; i < nbbs; i++) 870 { 871 basic_block bb = bbs[i]; 872 gimple_stmt_iterator si; 873 874 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) 875 { 876 gimple *phi = gsi_stmt (si); 877 gimple_set_uid (phi, 0); 878 add_stmt (phi); 879 } 880 881 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) 882 { 883 gimple *stmt = gsi_stmt (si); 884 gimple_set_uid (stmt, 0); 885 if (is_gimple_debug (stmt)) 886 continue; 887 add_stmt (stmt); 888 /* If .GOMP_SIMD_LANE call for the current loop has 3 arguments, the 889 third argument is the #pragma omp simd if (x) condition, when 0, 890 loop shouldn't be vectorized, when non-zero constant, it should 891 be vectorized normally, otherwise versioned with vectorized loop 892 done if the condition is non-zero at runtime. */ 893 if (loop_in->simduid 894 && is_gimple_call (stmt) 895 && gimple_call_internal_p (stmt) 896 && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE 897 && gimple_call_num_args (stmt) >= 3 898 && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME 899 && (loop_in->simduid 900 == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))) 901 { 902 tree arg = gimple_call_arg (stmt, 2); 903 if (integer_zerop (arg) || TREE_CODE (arg) == SSA_NAME) 904 simd_if_cond = arg; 905 else 906 gcc_assert (integer_nonzerop (arg)); 907 } 908 } 909 } 910 911 epilogue_vinfos.create (6); 912 } 913 914 /* Free all levels of rgroup CONTROLS. */ 915 916 void 917 release_vec_loop_controls (vec<rgroup_controls> *controls) 918 { 919 rgroup_controls *rgc; 920 unsigned int i; 921 FOR_EACH_VEC_ELT (*controls, i, rgc) 922 rgc->controls.release (); 923 controls->release (); 924 } 925 926 /* Free all memory used by the _loop_vec_info, as well as all the 927 stmt_vec_info structs of all the stmts in the loop. */ 928 929 _loop_vec_info::~_loop_vec_info () 930 { 931 free (bbs); 932 933 release_vec_loop_controls (&masks); 934 release_vec_loop_controls (&lens); 935 delete ivexpr_map; 936 delete scan_map; 937 epilogue_vinfos.release (); 938 delete scalar_costs; 939 delete vector_costs; 940 941 /* When we release an epiloge vinfo that we do not intend to use 942 avoid clearing AUX of the main loop which should continue to 943 point to the main loop vinfo since otherwise we'll leak that. */ 944 if (loop->aux == this) 945 loop->aux = NULL; 946 } 947 948 /* Return an invariant or register for EXPR and emit necessary 949 computations in the LOOP_VINFO loop preheader. */ 950 951 tree 952 cse_and_gimplify_to_preheader (loop_vec_info loop_vinfo, tree expr) 953 { 954 if (is_gimple_reg (expr) 955 || is_gimple_min_invariant (expr)) 956 return expr; 957 958 if (! loop_vinfo->ivexpr_map) 959 loop_vinfo->ivexpr_map = new hash_map<tree_operand_hash, tree>; 960 tree &cached = loop_vinfo->ivexpr_map->get_or_insert (expr); 961 if (! cached) 962 { 963 gimple_seq stmts = NULL; 964 cached = force_gimple_operand (unshare_expr (expr), 965 &stmts, true, NULL_TREE); 966 if (stmts) 967 { 968 edge e = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo)); 969 gsi_insert_seq_on_edge_immediate (e, stmts); 970 } 971 } 972 return cached; 973 } 974 975 /* Return true if we can use CMP_TYPE as the comparison type to produce 976 all masks required to mask LOOP_VINFO. */ 977 978 static bool 979 can_produce_all_loop_masks_p (loop_vec_info loop_vinfo, tree cmp_type) 980 { 981 rgroup_controls *rgm; 982 unsigned int i; 983 FOR_EACH_VEC_ELT (LOOP_VINFO_MASKS (loop_vinfo), i, rgm) 984 if (rgm->type != NULL_TREE 985 && !direct_internal_fn_supported_p (IFN_WHILE_ULT, 986 cmp_type, rgm->type, 987 OPTIMIZE_FOR_SPEED)) 988 return false; 989 return true; 990 } 991 992 /* Calculate the maximum number of scalars per iteration for every 993 rgroup in LOOP_VINFO. */ 994 995 static unsigned int 996 vect_get_max_nscalars_per_iter (loop_vec_info loop_vinfo) 997 { 998 unsigned int res = 1; 999 unsigned int i; 1000 rgroup_controls *rgm; 1001 FOR_EACH_VEC_ELT (LOOP_VINFO_MASKS (loop_vinfo), i, rgm) 1002 res = MAX (res, rgm->max_nscalars_per_iter); 1003 return res; 1004 } 1005 1006 /* Calculate the minimum precision necessary to represent: 1007 1008 MAX_NITERS * FACTOR 1009 1010 as an unsigned integer, where MAX_NITERS is the maximum number of 1011 loop header iterations for the original scalar form of LOOP_VINFO. */ 1012 1013 static unsigned 1014 vect_min_prec_for_max_niters (loop_vec_info loop_vinfo, unsigned int factor) 1015 { 1016 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 1017 1018 /* Get the maximum number of iterations that is representable 1019 in the counter type. */ 1020 tree ni_type = TREE_TYPE (LOOP_VINFO_NITERSM1 (loop_vinfo)); 1021 widest_int max_ni = wi::to_widest (TYPE_MAX_VALUE (ni_type)) + 1; 1022 1023 /* Get a more refined estimate for the number of iterations. */ 1024 widest_int max_back_edges; 1025 if (max_loop_iterations (loop, &max_back_edges)) 1026 max_ni = wi::smin (max_ni, max_back_edges + 1); 1027 1028 /* Work out how many bits we need to represent the limit. */ 1029 return wi::min_precision (max_ni * factor, UNSIGNED); 1030 } 1031 1032 /* True if the loop needs peeling or partial vectors when vectorized. */ 1033 1034 static bool 1035 vect_need_peeling_or_partial_vectors_p (loop_vec_info loop_vinfo) 1036 { 1037 unsigned HOST_WIDE_INT const_vf; 1038 HOST_WIDE_INT max_niter 1039 = likely_max_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo)); 1040 1041 unsigned th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo); 1042 if (!th && LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo)) 1043 th = LOOP_VINFO_COST_MODEL_THRESHOLD (LOOP_VINFO_ORIG_LOOP_INFO 1044 (loop_vinfo)); 1045 1046 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 1047 && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0) 1048 { 1049 /* Work out the (constant) number of iterations that need to be 1050 peeled for reasons other than niters. */ 1051 unsigned int peel_niter = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); 1052 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)) 1053 peel_niter += 1; 1054 if (!multiple_p (LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter, 1055 LOOP_VINFO_VECT_FACTOR (loop_vinfo))) 1056 return true; 1057 } 1058 else if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) 1059 /* ??? When peeling for gaps but not alignment, we could 1060 try to check whether the (variable) niters is known to be 1061 VF * N + 1. That's something of a niche case though. */ 1062 || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) 1063 || !LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (&const_vf) 1064 || ((tree_ctz (LOOP_VINFO_NITERS (loop_vinfo)) 1065 < (unsigned) exact_log2 (const_vf)) 1066 /* In case of versioning, check if the maximum number of 1067 iterations is greater than th. If they are identical, 1068 the epilogue is unnecessary. */ 1069 && (!LOOP_REQUIRES_VERSIONING (loop_vinfo) 1070 || ((unsigned HOST_WIDE_INT) max_niter 1071 > (th / const_vf) * const_vf)))) 1072 return true; 1073 1074 return false; 1075 } 1076 1077 /* Each statement in LOOP_VINFO can be masked where necessary. Check 1078 whether we can actually generate the masks required. Return true if so, 1079 storing the type of the scalar IV in LOOP_VINFO_RGROUP_COMPARE_TYPE. */ 1080 1081 static bool 1082 vect_verify_full_masking (loop_vec_info loop_vinfo) 1083 { 1084 unsigned int min_ni_width; 1085 unsigned int max_nscalars_per_iter 1086 = vect_get_max_nscalars_per_iter (loop_vinfo); 1087 1088 /* Use a normal loop if there are no statements that need masking. 1089 This only happens in rare degenerate cases: it means that the loop 1090 has no loads, no stores, and no live-out values. */ 1091 if (LOOP_VINFO_MASKS (loop_vinfo).is_empty ()) 1092 return false; 1093 1094 /* Work out how many bits we need to represent the limit. */ 1095 min_ni_width 1096 = vect_min_prec_for_max_niters (loop_vinfo, max_nscalars_per_iter); 1097 1098 /* Find a scalar mode for which WHILE_ULT is supported. */ 1099 opt_scalar_int_mode cmp_mode_iter; 1100 tree cmp_type = NULL_TREE; 1101 tree iv_type = NULL_TREE; 1102 widest_int iv_limit = vect_iv_limit_for_partial_vectors (loop_vinfo); 1103 unsigned int iv_precision = UINT_MAX; 1104 1105 if (iv_limit != -1) 1106 iv_precision = wi::min_precision (iv_limit * max_nscalars_per_iter, 1107 UNSIGNED); 1108 1109 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT) 1110 { 1111 unsigned int cmp_bits = GET_MODE_BITSIZE (cmp_mode_iter.require ()); 1112 if (cmp_bits >= min_ni_width 1113 && targetm.scalar_mode_supported_p (cmp_mode_iter.require ())) 1114 { 1115 tree this_type = build_nonstandard_integer_type (cmp_bits, true); 1116 if (this_type 1117 && can_produce_all_loop_masks_p (loop_vinfo, this_type)) 1118 { 1119 /* Although we could stop as soon as we find a valid mode, 1120 there are at least two reasons why that's not always the 1121 best choice: 1122 1123 - An IV that's Pmode or wider is more likely to be reusable 1124 in address calculations than an IV that's narrower than 1125 Pmode. 1126 1127 - Doing the comparison in IV_PRECISION or wider allows 1128 a natural 0-based IV, whereas using a narrower comparison 1129 type requires mitigations against wrap-around. 1130 1131 Conversely, if the IV limit is variable, doing the comparison 1132 in a wider type than the original type can introduce 1133 unnecessary extensions, so picking the widest valid mode 1134 is not always a good choice either. 1135 1136 Here we prefer the first IV type that's Pmode or wider, 1137 and the first comparison type that's IV_PRECISION or wider. 1138 (The comparison type must be no wider than the IV type, 1139 to avoid extensions in the vector loop.) 1140 1141 ??? We might want to try continuing beyond Pmode for ILP32 1142 targets if CMP_BITS < IV_PRECISION. */ 1143 iv_type = this_type; 1144 if (!cmp_type || iv_precision > TYPE_PRECISION (cmp_type)) 1145 cmp_type = this_type; 1146 if (cmp_bits >= GET_MODE_BITSIZE (Pmode)) 1147 break; 1148 } 1149 } 1150 } 1151 1152 if (!cmp_type) 1153 return false; 1154 1155 LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo) = cmp_type; 1156 LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo) = iv_type; 1157 return true; 1158 } 1159 1160 /* Check whether we can use vector access with length based on precison 1161 comparison. So far, to keep it simple, we only allow the case that the 1162 precision of the target supported length is larger than the precision 1163 required by loop niters. */ 1164 1165 static bool 1166 vect_verify_loop_lens (loop_vec_info loop_vinfo) 1167 { 1168 if (LOOP_VINFO_LENS (loop_vinfo).is_empty ()) 1169 return false; 1170 1171 machine_mode len_load_mode = get_len_load_store_mode 1172 (loop_vinfo->vector_mode, true).require (); 1173 machine_mode len_store_mode = get_len_load_store_mode 1174 (loop_vinfo->vector_mode, false).require (); 1175 1176 signed char partial_load_bias = internal_len_load_store_bias 1177 (IFN_LEN_LOAD, len_load_mode); 1178 1179 signed char partial_store_bias = internal_len_load_store_bias 1180 (IFN_LEN_STORE, len_store_mode); 1181 1182 gcc_assert (partial_load_bias == partial_store_bias); 1183 1184 if (partial_load_bias == VECT_PARTIAL_BIAS_UNSUPPORTED) 1185 return false; 1186 1187 /* If the backend requires a bias of -1 for LEN_LOAD, we must not emit 1188 len_loads with a length of zero. In order to avoid that we prohibit 1189 more than one loop length here. */ 1190 if (partial_load_bias == -1 1191 && LOOP_VINFO_LENS (loop_vinfo).length () > 1) 1192 return false; 1193 1194 LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo) = partial_load_bias; 1195 1196 unsigned int max_nitems_per_iter = 1; 1197 unsigned int i; 1198 rgroup_controls *rgl; 1199 /* Find the maximum number of items per iteration for every rgroup. */ 1200 FOR_EACH_VEC_ELT (LOOP_VINFO_LENS (loop_vinfo), i, rgl) 1201 { 1202 unsigned nitems_per_iter = rgl->max_nscalars_per_iter * rgl->factor; 1203 max_nitems_per_iter = MAX (max_nitems_per_iter, nitems_per_iter); 1204 } 1205 1206 /* Work out how many bits we need to represent the length limit. */ 1207 unsigned int min_ni_prec 1208 = vect_min_prec_for_max_niters (loop_vinfo, max_nitems_per_iter); 1209 1210 /* Now use the maximum of below precisions for one suitable IV type: 1211 - the IV's natural precision 1212 - the precision needed to hold: the maximum number of scalar 1213 iterations multiplied by the scale factor (min_ni_prec above) 1214 - the Pmode precision 1215 1216 If min_ni_prec is less than the precision of the current niters, 1217 we perfer to still use the niters type. Prefer to use Pmode and 1218 wider IV to avoid narrow conversions. */ 1219 1220 unsigned int ni_prec 1221 = TYPE_PRECISION (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo))); 1222 min_ni_prec = MAX (min_ni_prec, ni_prec); 1223 min_ni_prec = MAX (min_ni_prec, GET_MODE_BITSIZE (Pmode)); 1224 1225 tree iv_type = NULL_TREE; 1226 opt_scalar_int_mode tmode_iter; 1227 FOR_EACH_MODE_IN_CLASS (tmode_iter, MODE_INT) 1228 { 1229 scalar_mode tmode = tmode_iter.require (); 1230 unsigned int tbits = GET_MODE_BITSIZE (tmode); 1231 1232 /* ??? Do we really want to construct one IV whose precision exceeds 1233 BITS_PER_WORD? */ 1234 if (tbits > BITS_PER_WORD) 1235 break; 1236 1237 /* Find the first available standard integral type. */ 1238 if (tbits >= min_ni_prec && targetm.scalar_mode_supported_p (tmode)) 1239 { 1240 iv_type = build_nonstandard_integer_type (tbits, true); 1241 break; 1242 } 1243 } 1244 1245 if (!iv_type) 1246 { 1247 if (dump_enabled_p ()) 1248 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1249 "can't vectorize with length-based partial vectors" 1250 " because there is no suitable iv type.\n"); 1251 return false; 1252 } 1253 1254 LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo) = iv_type; 1255 LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo) = iv_type; 1256 1257 return true; 1258 } 1259 1260 /* Calculate the cost of one scalar iteration of the loop. */ 1261 static void 1262 vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo) 1263 { 1264 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 1265 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); 1266 int nbbs = loop->num_nodes, factor; 1267 int innerloop_iters, i; 1268 1269 DUMP_VECT_SCOPE ("vect_compute_single_scalar_iteration_cost"); 1270 1271 /* Gather costs for statements in the scalar loop. */ 1272 1273 /* FORNOW. */ 1274 innerloop_iters = 1; 1275 if (loop->inner) 1276 innerloop_iters = LOOP_VINFO_INNER_LOOP_COST_FACTOR (loop_vinfo); 1277 1278 for (i = 0; i < nbbs; i++) 1279 { 1280 gimple_stmt_iterator si; 1281 basic_block bb = bbs[i]; 1282 1283 if (bb->loop_father == loop->inner) 1284 factor = innerloop_iters; 1285 else 1286 factor = 1; 1287 1288 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) 1289 { 1290 gimple *stmt = gsi_stmt (si); 1291 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (stmt); 1292 1293 if (!is_gimple_assign (stmt) && !is_gimple_call (stmt)) 1294 continue; 1295 1296 /* Skip stmts that are not vectorized inside the loop. */ 1297 stmt_vec_info vstmt_info = vect_stmt_to_vectorize (stmt_info); 1298 if (!STMT_VINFO_RELEVANT_P (vstmt_info) 1299 && (!STMT_VINFO_LIVE_P (vstmt_info) 1300 || !VECTORIZABLE_CYCLE_DEF 1301 (STMT_VINFO_DEF_TYPE (vstmt_info)))) 1302 continue; 1303 1304 vect_cost_for_stmt kind; 1305 if (STMT_VINFO_DATA_REF (stmt_info)) 1306 { 1307 if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))) 1308 kind = scalar_load; 1309 else 1310 kind = scalar_store; 1311 } 1312 else if (vect_nop_conversion_p (stmt_info)) 1313 continue; 1314 else 1315 kind = scalar_stmt; 1316 1317 /* We are using vect_prologue here to avoid scaling twice 1318 by the inner loop factor. */ 1319 record_stmt_cost (&LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), 1320 factor, kind, stmt_info, 0, vect_prologue); 1321 } 1322 } 1323 1324 /* Now accumulate cost. */ 1325 loop_vinfo->scalar_costs = init_cost (loop_vinfo, true); 1326 add_stmt_costs (loop_vinfo->scalar_costs, 1327 &LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo)); 1328 loop_vinfo->scalar_costs->finish_cost (nullptr); 1329 } 1330 1331 1332 /* Function vect_analyze_loop_form. 1333 1334 Verify that certain CFG restrictions hold, including: 1335 - the loop has a pre-header 1336 - the loop has a single entry and exit 1337 - the loop exit condition is simple enough 1338 - the number of iterations can be analyzed, i.e, a countable loop. The 1339 niter could be analyzed under some assumptions. */ 1340 1341 opt_result 1342 vect_analyze_loop_form (class loop *loop, vect_loop_form_info *info) 1343 { 1344 DUMP_VECT_SCOPE ("vect_analyze_loop_form"); 1345 1346 /* Different restrictions apply when we are considering an inner-most loop, 1347 vs. an outer (nested) loop. 1348 (FORNOW. May want to relax some of these restrictions in the future). */ 1349 1350 info->inner_loop_cond = NULL; 1351 if (!loop->inner) 1352 { 1353 /* Inner-most loop. We currently require that the number of BBs is 1354 exactly 2 (the header and latch). Vectorizable inner-most loops 1355 look like this: 1356 1357 (pre-header) 1358 | 1359 header <--------+ 1360 | | | 1361 | +--> latch --+ 1362 | 1363 (exit-bb) */ 1364 1365 if (loop->num_nodes != 2) 1366 return opt_result::failure_at (vect_location, 1367 "not vectorized:" 1368 " control flow in loop.\n"); 1369 1370 if (empty_block_p (loop->header)) 1371 return opt_result::failure_at (vect_location, 1372 "not vectorized: empty loop.\n"); 1373 } 1374 else 1375 { 1376 class loop *innerloop = loop->inner; 1377 edge entryedge; 1378 1379 /* Nested loop. We currently require that the loop is doubly-nested, 1380 contains a single inner loop, and the number of BBs is exactly 5. 1381 Vectorizable outer-loops look like this: 1382 1383 (pre-header) 1384 | 1385 header <---+ 1386 | | 1387 inner-loop | 1388 | | 1389 tail ------+ 1390 | 1391 (exit-bb) 1392 1393 The inner-loop has the properties expected of inner-most loops 1394 as described above. */ 1395 1396 if ((loop->inner)->inner || (loop->inner)->next) 1397 return opt_result::failure_at (vect_location, 1398 "not vectorized:" 1399 " multiple nested loops.\n"); 1400 1401 if (loop->num_nodes != 5) 1402 return opt_result::failure_at (vect_location, 1403 "not vectorized:" 1404 " control flow in loop.\n"); 1405 1406 entryedge = loop_preheader_edge (innerloop); 1407 if (entryedge->src != loop->header 1408 || !single_exit (innerloop) 1409 || single_exit (innerloop)->dest != EDGE_PRED (loop->latch, 0)->src) 1410 return opt_result::failure_at (vect_location, 1411 "not vectorized:" 1412 " unsupported outerloop form.\n"); 1413 1414 /* Analyze the inner-loop. */ 1415 vect_loop_form_info inner; 1416 opt_result res = vect_analyze_loop_form (loop->inner, &inner); 1417 if (!res) 1418 { 1419 if (dump_enabled_p ()) 1420 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1421 "not vectorized: Bad inner loop.\n"); 1422 return res; 1423 } 1424 1425 /* Don't support analyzing niter under assumptions for inner 1426 loop. */ 1427 if (!integer_onep (inner.assumptions)) 1428 return opt_result::failure_at (vect_location, 1429 "not vectorized: Bad inner loop.\n"); 1430 1431 if (!expr_invariant_in_loop_p (loop, inner.number_of_iterations)) 1432 return opt_result::failure_at (vect_location, 1433 "not vectorized: inner-loop count not" 1434 " invariant.\n"); 1435 1436 if (dump_enabled_p ()) 1437 dump_printf_loc (MSG_NOTE, vect_location, 1438 "Considering outer-loop vectorization.\n"); 1439 info->inner_loop_cond = inner.loop_cond; 1440 } 1441 1442 if (!single_exit (loop)) 1443 return opt_result::failure_at (vect_location, 1444 "not vectorized: multiple exits.\n"); 1445 if (EDGE_COUNT (loop->header->preds) != 2) 1446 return opt_result::failure_at (vect_location, 1447 "not vectorized:" 1448 " too many incoming edges.\n"); 1449 1450 /* We assume that the loop exit condition is at the end of the loop. i.e, 1451 that the loop is represented as a do-while (with a proper if-guard 1452 before the loop if needed), where the loop header contains all the 1453 executable statements, and the latch is empty. */ 1454 if (!empty_block_p (loop->latch) 1455 || !gimple_seq_empty_p (phi_nodes (loop->latch))) 1456 return opt_result::failure_at (vect_location, 1457 "not vectorized: latch block not empty.\n"); 1458 1459 /* Make sure the exit is not abnormal. */ 1460 edge e = single_exit (loop); 1461 if (e->flags & EDGE_ABNORMAL) 1462 return opt_result::failure_at (vect_location, 1463 "not vectorized:" 1464 " abnormal loop exit edge.\n"); 1465 1466 info->loop_cond 1467 = vect_get_loop_niters (loop, &info->assumptions, 1468 &info->number_of_iterations, 1469 &info->number_of_iterationsm1); 1470 if (!info->loop_cond) 1471 return opt_result::failure_at 1472 (vect_location, 1473 "not vectorized: complicated exit condition.\n"); 1474 1475 if (integer_zerop (info->assumptions) 1476 || !info->number_of_iterations 1477 || chrec_contains_undetermined (info->number_of_iterations)) 1478 return opt_result::failure_at 1479 (info->loop_cond, 1480 "not vectorized: number of iterations cannot be computed.\n"); 1481 1482 if (integer_zerop (info->number_of_iterations)) 1483 return opt_result::failure_at 1484 (info->loop_cond, 1485 "not vectorized: number of iterations = 0.\n"); 1486 1487 if (!(tree_fits_shwi_p (info->number_of_iterations) 1488 && tree_to_shwi (info->number_of_iterations) > 0)) 1489 { 1490 if (dump_enabled_p ()) 1491 { 1492 dump_printf_loc (MSG_NOTE, vect_location, 1493 "Symbolic number of iterations is "); 1494 dump_generic_expr (MSG_NOTE, TDF_DETAILS, info->number_of_iterations); 1495 dump_printf (MSG_NOTE, "\n"); 1496 } 1497 } 1498 1499 return opt_result::success (); 1500 } 1501 1502 /* Create a loop_vec_info for LOOP with SHARED and the 1503 vect_analyze_loop_form result. */ 1504 1505 loop_vec_info 1506 vect_create_loop_vinfo (class loop *loop, vec_info_shared *shared, 1507 const vect_loop_form_info *info, 1508 loop_vec_info main_loop_info) 1509 { 1510 loop_vec_info loop_vinfo = new _loop_vec_info (loop, shared); 1511 LOOP_VINFO_NITERSM1 (loop_vinfo) = info->number_of_iterationsm1; 1512 LOOP_VINFO_NITERS (loop_vinfo) = info->number_of_iterations; 1513 LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = info->number_of_iterations; 1514 LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = main_loop_info; 1515 /* Also record the assumptions for versioning. */ 1516 if (!integer_onep (info->assumptions) && !main_loop_info) 1517 LOOP_VINFO_NITERS_ASSUMPTIONS (loop_vinfo) = info->assumptions; 1518 1519 stmt_vec_info loop_cond_info = loop_vinfo->lookup_stmt (info->loop_cond); 1520 STMT_VINFO_TYPE (loop_cond_info) = loop_exit_ctrl_vec_info_type; 1521 if (info->inner_loop_cond) 1522 { 1523 stmt_vec_info inner_loop_cond_info 1524 = loop_vinfo->lookup_stmt (info->inner_loop_cond); 1525 STMT_VINFO_TYPE (inner_loop_cond_info) = loop_exit_ctrl_vec_info_type; 1526 /* If we have an estimate on the number of iterations of the inner 1527 loop use that to limit the scale for costing, otherwise use 1528 --param vect-inner-loop-cost-factor literally. */ 1529 widest_int nit; 1530 if (estimated_stmt_executions (loop->inner, &nit)) 1531 LOOP_VINFO_INNER_LOOP_COST_FACTOR (loop_vinfo) 1532 = wi::smin (nit, param_vect_inner_loop_cost_factor).to_uhwi (); 1533 } 1534 1535 return loop_vinfo; 1536 } 1537 1538 1539 1540 /* Scan the loop stmts and dependent on whether there are any (non-)SLP 1541 statements update the vectorization factor. */ 1542 1543 static void 1544 vect_update_vf_for_slp (loop_vec_info loop_vinfo) 1545 { 1546 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 1547 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); 1548 int nbbs = loop->num_nodes; 1549 poly_uint64 vectorization_factor; 1550 int i; 1551 1552 DUMP_VECT_SCOPE ("vect_update_vf_for_slp"); 1553 1554 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 1555 gcc_assert (known_ne (vectorization_factor, 0U)); 1556 1557 /* If all the stmts in the loop can be SLPed, we perform only SLP, and 1558 vectorization factor of the loop is the unrolling factor required by 1559 the SLP instances. If that unrolling factor is 1, we say, that we 1560 perform pure SLP on loop - cross iteration parallelism is not 1561 exploited. */ 1562 bool only_slp_in_loop = true; 1563 for (i = 0; i < nbbs; i++) 1564 { 1565 basic_block bb = bbs[i]; 1566 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); 1567 gsi_next (&si)) 1568 { 1569 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (si.phi ()); 1570 if (!stmt_info) 1571 continue; 1572 if ((STMT_VINFO_RELEVANT_P (stmt_info) 1573 || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) 1574 && !PURE_SLP_STMT (stmt_info)) 1575 /* STMT needs both SLP and loop-based vectorization. */ 1576 only_slp_in_loop = false; 1577 } 1578 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); 1579 gsi_next (&si)) 1580 { 1581 if (is_gimple_debug (gsi_stmt (si))) 1582 continue; 1583 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); 1584 stmt_info = vect_stmt_to_vectorize (stmt_info); 1585 if ((STMT_VINFO_RELEVANT_P (stmt_info) 1586 || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) 1587 && !PURE_SLP_STMT (stmt_info)) 1588 /* STMT needs both SLP and loop-based vectorization. */ 1589 only_slp_in_loop = false; 1590 } 1591 } 1592 1593 if (only_slp_in_loop) 1594 { 1595 if (dump_enabled_p ()) 1596 dump_printf_loc (MSG_NOTE, vect_location, 1597 "Loop contains only SLP stmts\n"); 1598 vectorization_factor = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo); 1599 } 1600 else 1601 { 1602 if (dump_enabled_p ()) 1603 dump_printf_loc (MSG_NOTE, vect_location, 1604 "Loop contains SLP and non-SLP stmts\n"); 1605 /* Both the vectorization factor and unroll factor have the form 1606 GET_MODE_SIZE (loop_vinfo->vector_mode) * X for some rational X, 1607 so they must have a common multiple. */ 1608 vectorization_factor 1609 = force_common_multiple (vectorization_factor, 1610 LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo)); 1611 } 1612 1613 LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; 1614 if (dump_enabled_p ()) 1615 { 1616 dump_printf_loc (MSG_NOTE, vect_location, 1617 "Updating vectorization factor to "); 1618 dump_dec (MSG_NOTE, vectorization_factor); 1619 dump_printf (MSG_NOTE, ".\n"); 1620 } 1621 } 1622 1623 /* Return true if STMT_INFO describes a double reduction phi and if 1624 the other phi in the reduction is also relevant for vectorization. 1625 This rejects cases such as: 1626 1627 outer1: 1628 x_1 = PHI <x_3(outer2), ...>; 1629 ... 1630 1631 inner: 1632 x_2 = ...; 1633 ... 1634 1635 outer2: 1636 x_3 = PHI <x_2(inner)>; 1637 1638 if nothing in x_2 or elsewhere makes x_1 relevant. */ 1639 1640 static bool 1641 vect_active_double_reduction_p (stmt_vec_info stmt_info) 1642 { 1643 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def) 1644 return false; 1645 1646 return STMT_VINFO_RELEVANT_P (STMT_VINFO_REDUC_DEF (stmt_info)); 1647 } 1648 1649 /* Function vect_analyze_loop_operations. 1650 1651 Scan the loop stmts and make sure they are all vectorizable. */ 1652 1653 static opt_result 1654 vect_analyze_loop_operations (loop_vec_info loop_vinfo) 1655 { 1656 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 1657 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); 1658 int nbbs = loop->num_nodes; 1659 int i; 1660 stmt_vec_info stmt_info; 1661 bool need_to_vectorize = false; 1662 bool ok; 1663 1664 DUMP_VECT_SCOPE ("vect_analyze_loop_operations"); 1665 1666 auto_vec<stmt_info_for_cost> cost_vec; 1667 1668 for (i = 0; i < nbbs; i++) 1669 { 1670 basic_block bb = bbs[i]; 1671 1672 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); 1673 gsi_next (&si)) 1674 { 1675 gphi *phi = si.phi (); 1676 ok = true; 1677 1678 stmt_info = loop_vinfo->lookup_stmt (phi); 1679 if (dump_enabled_p ()) 1680 dump_printf_loc (MSG_NOTE, vect_location, "examining phi: %G", phi); 1681 if (virtual_operand_p (gimple_phi_result (phi))) 1682 continue; 1683 1684 /* Inner-loop loop-closed exit phi in outer-loop vectorization 1685 (i.e., a phi in the tail of the outer-loop). */ 1686 if (! is_loop_header_bb_p (bb)) 1687 { 1688 /* FORNOW: we currently don't support the case that these phis 1689 are not used in the outerloop (unless it is double reduction, 1690 i.e., this phi is vect_reduction_def), cause this case 1691 requires to actually do something here. */ 1692 if (STMT_VINFO_LIVE_P (stmt_info) 1693 && !vect_active_double_reduction_p (stmt_info)) 1694 return opt_result::failure_at (phi, 1695 "Unsupported loop-closed phi" 1696 " in outer-loop.\n"); 1697 1698 /* If PHI is used in the outer loop, we check that its operand 1699 is defined in the inner loop. */ 1700 if (STMT_VINFO_RELEVANT_P (stmt_info)) 1701 { 1702 tree phi_op; 1703 1704 if (gimple_phi_num_args (phi) != 1) 1705 return opt_result::failure_at (phi, "unsupported phi"); 1706 1707 phi_op = PHI_ARG_DEF (phi, 0); 1708 stmt_vec_info op_def_info = loop_vinfo->lookup_def (phi_op); 1709 if (!op_def_info) 1710 return opt_result::failure_at (phi, "unsupported phi\n"); 1711 1712 if (STMT_VINFO_RELEVANT (op_def_info) != vect_used_in_outer 1713 && (STMT_VINFO_RELEVANT (op_def_info) 1714 != vect_used_in_outer_by_reduction)) 1715 return opt_result::failure_at (phi, "unsupported phi\n"); 1716 1717 if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def 1718 || (STMT_VINFO_DEF_TYPE (stmt_info) 1719 == vect_double_reduction_def)) 1720 && !vectorizable_lc_phi (loop_vinfo, 1721 stmt_info, NULL, NULL)) 1722 return opt_result::failure_at (phi, "unsupported phi\n"); 1723 } 1724 1725 continue; 1726 } 1727 1728 gcc_assert (stmt_info); 1729 1730 if ((STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope 1731 || STMT_VINFO_LIVE_P (stmt_info)) 1732 && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def) 1733 /* A scalar-dependence cycle that we don't support. */ 1734 return opt_result::failure_at (phi, 1735 "not vectorized:" 1736 " scalar dependence cycle.\n"); 1737 1738 if (STMT_VINFO_RELEVANT_P (stmt_info)) 1739 { 1740 need_to_vectorize = true; 1741 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def 1742 && ! PURE_SLP_STMT (stmt_info)) 1743 ok = vectorizable_induction (loop_vinfo, 1744 stmt_info, NULL, NULL, 1745 &cost_vec); 1746 else if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def 1747 || (STMT_VINFO_DEF_TYPE (stmt_info) 1748 == vect_double_reduction_def) 1749 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle) 1750 && ! PURE_SLP_STMT (stmt_info)) 1751 ok = vectorizable_reduction (loop_vinfo, 1752 stmt_info, NULL, NULL, &cost_vec); 1753 } 1754 1755 /* SLP PHIs are tested by vect_slp_analyze_node_operations. */ 1756 if (ok 1757 && STMT_VINFO_LIVE_P (stmt_info) 1758 && !PURE_SLP_STMT (stmt_info)) 1759 ok = vectorizable_live_operation (loop_vinfo, 1760 stmt_info, NULL, NULL, NULL, 1761 -1, false, &cost_vec); 1762 1763 if (!ok) 1764 return opt_result::failure_at (phi, 1765 "not vectorized: relevant phi not " 1766 "supported: %G", 1767 static_cast <gimple *> (phi)); 1768 } 1769 1770 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); 1771 gsi_next (&si)) 1772 { 1773 gimple *stmt = gsi_stmt (si); 1774 if (!gimple_clobber_p (stmt) 1775 && !is_gimple_debug (stmt)) 1776 { 1777 opt_result res 1778 = vect_analyze_stmt (loop_vinfo, 1779 loop_vinfo->lookup_stmt (stmt), 1780 &need_to_vectorize, 1781 NULL, NULL, &cost_vec); 1782 if (!res) 1783 return res; 1784 } 1785 } 1786 } /* bbs */ 1787 1788 add_stmt_costs (loop_vinfo->vector_costs, &cost_vec); 1789 1790 /* All operations in the loop are either irrelevant (deal with loop 1791 control, or dead), or only used outside the loop and can be moved 1792 out of the loop (e.g. invariants, inductions). The loop can be 1793 optimized away by scalar optimizations. We're better off not 1794 touching this loop. */ 1795 if (!need_to_vectorize) 1796 { 1797 if (dump_enabled_p ()) 1798 dump_printf_loc (MSG_NOTE, vect_location, 1799 "All the computation can be taken out of the loop.\n"); 1800 return opt_result::failure_at 1801 (vect_location, 1802 "not vectorized: redundant loop. no profit to vectorize.\n"); 1803 } 1804 1805 return opt_result::success (); 1806 } 1807 1808 /* Return true if we know that the iteration count is smaller than the 1809 vectorization factor. Return false if it isn't, or if we can't be sure 1810 either way. */ 1811 1812 static bool 1813 vect_known_niters_smaller_than_vf (loop_vec_info loop_vinfo) 1814 { 1815 unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo); 1816 1817 HOST_WIDE_INT max_niter; 1818 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) 1819 max_niter = LOOP_VINFO_INT_NITERS (loop_vinfo); 1820 else 1821 max_niter = max_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo)); 1822 1823 if (max_niter != -1 && (unsigned HOST_WIDE_INT) max_niter < assumed_vf) 1824 return true; 1825 1826 return false; 1827 } 1828 1829 /* Analyze the cost of the loop described by LOOP_VINFO. Decide if it 1830 is worthwhile to vectorize. Return 1 if definitely yes, 0 if 1831 definitely no, or -1 if it's worth retrying. */ 1832 1833 static int 1834 vect_analyze_loop_costing (loop_vec_info loop_vinfo, 1835 unsigned *suggested_unroll_factor) 1836 { 1837 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 1838 unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo); 1839 1840 /* Only loops that can handle partially-populated vectors can have iteration 1841 counts less than the vectorization factor. */ 1842 if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 1843 { 1844 if (vect_known_niters_smaller_than_vf (loop_vinfo)) 1845 { 1846 if (dump_enabled_p ()) 1847 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1848 "not vectorized: iteration count smaller than " 1849 "vectorization factor.\n"); 1850 return 0; 1851 } 1852 } 1853 1854 /* If using the "very cheap" model. reject cases in which we'd keep 1855 a copy of the scalar code (even if we might be able to vectorize it). */ 1856 if (loop_cost_model (loop) == VECT_COST_MODEL_VERY_CHEAP 1857 && (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) 1858 || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) 1859 || LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo))) 1860 { 1861 if (dump_enabled_p ()) 1862 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1863 "some scalar iterations would need to be peeled\n"); 1864 return 0; 1865 } 1866 1867 int min_profitable_iters, min_profitable_estimate; 1868 vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters, 1869 &min_profitable_estimate, 1870 suggested_unroll_factor); 1871 1872 if (min_profitable_iters < 0) 1873 { 1874 if (dump_enabled_p ()) 1875 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1876 "not vectorized: vectorization not profitable.\n"); 1877 if (dump_enabled_p ()) 1878 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1879 "not vectorized: vector version will never be " 1880 "profitable.\n"); 1881 return -1; 1882 } 1883 1884 int min_scalar_loop_bound = (param_min_vect_loop_bound 1885 * assumed_vf); 1886 1887 /* Use the cost model only if it is more conservative than user specified 1888 threshold. */ 1889 unsigned int th = (unsigned) MAX (min_scalar_loop_bound, 1890 min_profitable_iters); 1891 1892 LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th; 1893 1894 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 1895 && LOOP_VINFO_INT_NITERS (loop_vinfo) < th) 1896 { 1897 if (dump_enabled_p ()) 1898 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1899 "not vectorized: vectorization not profitable.\n"); 1900 if (dump_enabled_p ()) 1901 dump_printf_loc (MSG_NOTE, vect_location, 1902 "not vectorized: iteration count smaller than user " 1903 "specified loop bound parameter or minimum profitable " 1904 "iterations (whichever is more conservative).\n"); 1905 return 0; 1906 } 1907 1908 /* The static profitablity threshold min_profitable_estimate includes 1909 the cost of having to check at runtime whether the scalar loop 1910 should be used instead. If it turns out that we don't need or want 1911 such a check, the threshold we should use for the static estimate 1912 is simply the point at which the vector loop becomes more profitable 1913 than the scalar loop. */ 1914 if (min_profitable_estimate > min_profitable_iters 1915 && !LOOP_REQUIRES_VERSIONING (loop_vinfo) 1916 && !LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) 1917 && !LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) 1918 && !vect_apply_runtime_profitability_check_p (loop_vinfo)) 1919 { 1920 if (dump_enabled_p ()) 1921 dump_printf_loc (MSG_NOTE, vect_location, "no need for a runtime" 1922 " choice between the scalar and vector loops\n"); 1923 min_profitable_estimate = min_profitable_iters; 1924 } 1925 1926 /* If the vector loop needs multiple iterations to be beneficial then 1927 things are probably too close to call, and the conservative thing 1928 would be to stick with the scalar code. */ 1929 if (loop_cost_model (loop) == VECT_COST_MODEL_VERY_CHEAP 1930 && min_profitable_estimate > (int) vect_vf_for_cost (loop_vinfo)) 1931 { 1932 if (dump_enabled_p ()) 1933 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1934 "one iteration of the vector loop would be" 1935 " more expensive than the equivalent number of" 1936 " iterations of the scalar loop\n"); 1937 return 0; 1938 } 1939 1940 HOST_WIDE_INT estimated_niter; 1941 1942 /* If we are vectorizing an epilogue then we know the maximum number of 1943 scalar iterations it will cover is at least one lower than the 1944 vectorization factor of the main loop. */ 1945 if (LOOP_VINFO_EPILOGUE_P (loop_vinfo)) 1946 estimated_niter 1947 = vect_vf_for_cost (LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo)) - 1; 1948 else 1949 { 1950 estimated_niter = estimated_stmt_executions_int (loop); 1951 if (estimated_niter == -1) 1952 estimated_niter = likely_max_stmt_executions_int (loop); 1953 } 1954 if (estimated_niter != -1 1955 && ((unsigned HOST_WIDE_INT) estimated_niter 1956 < MAX (th, (unsigned) min_profitable_estimate))) 1957 { 1958 if (dump_enabled_p ()) 1959 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 1960 "not vectorized: estimated iteration count too " 1961 "small.\n"); 1962 if (dump_enabled_p ()) 1963 dump_printf_loc (MSG_NOTE, vect_location, 1964 "not vectorized: estimated iteration count smaller " 1965 "than specified loop bound parameter or minimum " 1966 "profitable iterations (whichever is more " 1967 "conservative).\n"); 1968 return -1; 1969 } 1970 1971 return 1; 1972 } 1973 1974 static opt_result 1975 vect_get_datarefs_in_loop (loop_p loop, basic_block *bbs, 1976 vec<data_reference_p> *datarefs, 1977 unsigned int *n_stmts) 1978 { 1979 *n_stmts = 0; 1980 for (unsigned i = 0; i < loop->num_nodes; i++) 1981 for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); 1982 !gsi_end_p (gsi); gsi_next (&gsi)) 1983 { 1984 gimple *stmt = gsi_stmt (gsi); 1985 if (is_gimple_debug (stmt)) 1986 continue; 1987 ++(*n_stmts); 1988 opt_result res = vect_find_stmt_data_reference (loop, stmt, datarefs, 1989 NULL, 0); 1990 if (!res) 1991 { 1992 if (is_gimple_call (stmt) && loop->safelen) 1993 { 1994 tree fndecl = gimple_call_fndecl (stmt), op; 1995 if (fndecl != NULL_TREE) 1996 { 1997 cgraph_node *node = cgraph_node::get (fndecl); 1998 if (node != NULL && node->simd_clones != NULL) 1999 { 2000 unsigned int j, n = gimple_call_num_args (stmt); 2001 for (j = 0; j < n; j++) 2002 { 2003 op = gimple_call_arg (stmt, j); 2004 if (DECL_P (op) 2005 || (REFERENCE_CLASS_P (op) 2006 && get_base_address (op))) 2007 break; 2008 } 2009 op = gimple_call_lhs (stmt); 2010 /* Ignore #pragma omp declare simd functions 2011 if they don't have data references in the 2012 call stmt itself. */ 2013 if (j == n 2014 && !(op 2015 && (DECL_P (op) 2016 || (REFERENCE_CLASS_P (op) 2017 && get_base_address (op))))) 2018 continue; 2019 } 2020 } 2021 } 2022 return res; 2023 } 2024 /* If dependence analysis will give up due to the limit on the 2025 number of datarefs stop here and fail fatally. */ 2026 if (datarefs->length () 2027 > (unsigned)param_loop_max_datarefs_for_datadeps) 2028 return opt_result::failure_at (stmt, "exceeded param " 2029 "loop-max-datarefs-for-datadeps\n"); 2030 } 2031 return opt_result::success (); 2032 } 2033 2034 /* Look for SLP-only access groups and turn each individual access into its own 2035 group. */ 2036 static void 2037 vect_dissolve_slp_only_groups (loop_vec_info loop_vinfo) 2038 { 2039 unsigned int i; 2040 struct data_reference *dr; 2041 2042 DUMP_VECT_SCOPE ("vect_dissolve_slp_only_groups"); 2043 2044 vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); 2045 FOR_EACH_VEC_ELT (datarefs, i, dr) 2046 { 2047 gcc_assert (DR_REF (dr)); 2048 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (DR_STMT (dr)); 2049 2050 /* Check if the load is a part of an interleaving chain. */ 2051 if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) 2052 { 2053 stmt_vec_info first_element = DR_GROUP_FIRST_ELEMENT (stmt_info); 2054 dr_vec_info *dr_info = STMT_VINFO_DR_INFO (first_element); 2055 unsigned int group_size = DR_GROUP_SIZE (first_element); 2056 2057 /* Check if SLP-only groups. */ 2058 if (!STMT_SLP_TYPE (stmt_info) 2059 && STMT_VINFO_SLP_VECT_ONLY (first_element)) 2060 { 2061 /* Dissolve the group. */ 2062 STMT_VINFO_SLP_VECT_ONLY (first_element) = false; 2063 2064 stmt_vec_info vinfo = first_element; 2065 while (vinfo) 2066 { 2067 stmt_vec_info next = DR_GROUP_NEXT_ELEMENT (vinfo); 2068 DR_GROUP_FIRST_ELEMENT (vinfo) = vinfo; 2069 DR_GROUP_NEXT_ELEMENT (vinfo) = NULL; 2070 DR_GROUP_SIZE (vinfo) = 1; 2071 if (STMT_VINFO_STRIDED_P (first_element)) 2072 DR_GROUP_GAP (vinfo) = 0; 2073 else 2074 DR_GROUP_GAP (vinfo) = group_size - 1; 2075 /* Duplicate and adjust alignment info, it needs to 2076 be present on each group leader, see dr_misalignment. */ 2077 if (vinfo != first_element) 2078 { 2079 dr_vec_info *dr_info2 = STMT_VINFO_DR_INFO (vinfo); 2080 dr_info2->target_alignment = dr_info->target_alignment; 2081 int misalignment = dr_info->misalignment; 2082 if (misalignment != DR_MISALIGNMENT_UNKNOWN) 2083 { 2084 HOST_WIDE_INT diff 2085 = (TREE_INT_CST_LOW (DR_INIT (dr_info2->dr)) 2086 - TREE_INT_CST_LOW (DR_INIT (dr_info->dr))); 2087 unsigned HOST_WIDE_INT align_c 2088 = dr_info->target_alignment.to_constant (); 2089 misalignment = (misalignment + diff) % align_c; 2090 } 2091 dr_info2->misalignment = misalignment; 2092 } 2093 vinfo = next; 2094 } 2095 } 2096 } 2097 } 2098 } 2099 2100 /* Determine if operating on full vectors for LOOP_VINFO might leave 2101 some scalar iterations still to do. If so, decide how we should 2102 handle those scalar iterations. The possibilities are: 2103 2104 (1) Make LOOP_VINFO operate on partial vectors instead of full vectors. 2105 In this case: 2106 2107 LOOP_VINFO_USING_PARTIAL_VECTORS_P == true 2108 LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P == false 2109 LOOP_VINFO_PEELING_FOR_NITER == false 2110 2111 (2) Make LOOP_VINFO operate on full vectors and use an epilogue loop 2112 to handle the remaining scalar iterations. In this case: 2113 2114 LOOP_VINFO_USING_PARTIAL_VECTORS_P == false 2115 LOOP_VINFO_PEELING_FOR_NITER == true 2116 2117 There are two choices: 2118 2119 (2a) Consider vectorizing the epilogue loop at the same VF as the 2120 main loop, but using partial vectors instead of full vectors. 2121 In this case: 2122 2123 LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P == true 2124 2125 (2b) Consider vectorizing the epilogue loop at lower VFs only. 2126 In this case: 2127 2128 LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P == false 2129 2130 When FOR_EPILOGUE_P is true, make this determination based on the 2131 assumption that LOOP_VINFO is an epilogue loop, otherwise make it 2132 based on the assumption that LOOP_VINFO is the main loop. The caller 2133 has made sure that the number of iterations is set appropriately for 2134 this value of FOR_EPILOGUE_P. */ 2135 2136 opt_result 2137 vect_determine_partial_vectors_and_peeling (loop_vec_info loop_vinfo, 2138 bool for_epilogue_p) 2139 { 2140 /* Determine whether there would be any scalar iterations left over. */ 2141 bool need_peeling_or_partial_vectors_p 2142 = vect_need_peeling_or_partial_vectors_p (loop_vinfo); 2143 2144 /* Decide whether to vectorize the loop with partial vectors. */ 2145 LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) = false; 2146 LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P (loop_vinfo) = false; 2147 if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) 2148 && need_peeling_or_partial_vectors_p) 2149 { 2150 /* For partial-vector-usage=1, try to push the handling of partial 2151 vectors to the epilogue, with the main loop continuing to operate 2152 on full vectors. 2153 2154 If we are unrolling we also do not want to use partial vectors. This 2155 is to avoid the overhead of generating multiple masks and also to 2156 avoid having to execute entire iterations of FALSE masked instructions 2157 when dealing with one or less full iterations. 2158 2159 ??? We could then end up failing to use partial vectors if we 2160 decide to peel iterations into a prologue, and if the main loop 2161 then ends up processing fewer than VF iterations. */ 2162 if ((param_vect_partial_vector_usage == 1 2163 || loop_vinfo->suggested_unroll_factor > 1) 2164 && !LOOP_VINFO_EPILOGUE_P (loop_vinfo) 2165 && !vect_known_niters_smaller_than_vf (loop_vinfo)) 2166 LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P (loop_vinfo) = true; 2167 else 2168 LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) = true; 2169 } 2170 2171 if (dump_enabled_p ()) 2172 { 2173 if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 2174 dump_printf_loc (MSG_NOTE, vect_location, 2175 "operating on partial vectors%s.\n", 2176 for_epilogue_p ? " for epilogue loop" : ""); 2177 else 2178 dump_printf_loc (MSG_NOTE, vect_location, 2179 "operating only on full vectors%s.\n", 2180 for_epilogue_p ? " for epilogue loop" : ""); 2181 } 2182 2183 if (for_epilogue_p) 2184 { 2185 loop_vec_info orig_loop_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); 2186 gcc_assert (orig_loop_vinfo); 2187 if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 2188 gcc_assert (known_lt (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 2189 LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo))); 2190 } 2191 2192 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 2193 && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 2194 { 2195 /* Check that the loop processes at least one full vector. */ 2196 poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 2197 tree scalar_niters = LOOP_VINFO_NITERS (loop_vinfo); 2198 if (known_lt (wi::to_widest (scalar_niters), vf)) 2199 return opt_result::failure_at (vect_location, 2200 "loop does not have enough iterations" 2201 " to support vectorization.\n"); 2202 2203 /* If we need to peel an extra epilogue iteration to handle data 2204 accesses with gaps, check that there are enough scalar iterations 2205 available. 2206 2207 The check above is redundant with this one when peeling for gaps, 2208 but the distinction is useful for diagnostics. */ 2209 tree scalar_nitersm1 = LOOP_VINFO_NITERSM1 (loop_vinfo); 2210 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) 2211 && known_lt (wi::to_widest (scalar_nitersm1), vf)) 2212 return opt_result::failure_at (vect_location, 2213 "loop does not have enough iterations" 2214 " to support peeling for gaps.\n"); 2215 } 2216 2217 LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) 2218 = (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) 2219 && need_peeling_or_partial_vectors_p); 2220 2221 return opt_result::success (); 2222 } 2223 2224 /* Function vect_analyze_loop_2. 2225 2226 Apply a set of analyses on LOOP, and create a loop_vec_info struct 2227 for it. The different analyses will record information in the 2228 loop_vec_info struct. */ 2229 static opt_result 2230 vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, 2231 unsigned *suggested_unroll_factor) 2232 { 2233 opt_result ok = opt_result::success (); 2234 int res; 2235 unsigned int max_vf = MAX_VECTORIZATION_FACTOR; 2236 poly_uint64 min_vf = 2; 2237 loop_vec_info orig_loop_vinfo = NULL; 2238 2239 /* If we are dealing with an epilogue then orig_loop_vinfo points to the 2240 loop_vec_info of the first vectorized loop. */ 2241 if (LOOP_VINFO_EPILOGUE_P (loop_vinfo)) 2242 orig_loop_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); 2243 else 2244 orig_loop_vinfo = loop_vinfo; 2245 gcc_assert (orig_loop_vinfo); 2246 2247 /* The first group of checks is independent of the vector size. */ 2248 fatal = true; 2249 2250 if (LOOP_VINFO_SIMD_IF_COND (loop_vinfo) 2251 && integer_zerop (LOOP_VINFO_SIMD_IF_COND (loop_vinfo))) 2252 return opt_result::failure_at (vect_location, 2253 "not vectorized: simd if(0)\n"); 2254 2255 /* Find all data references in the loop (which correspond to vdefs/vuses) 2256 and analyze their evolution in the loop. */ 2257 2258 loop_p loop = LOOP_VINFO_LOOP (loop_vinfo); 2259 2260 /* Gather the data references and count stmts in the loop. */ 2261 if (!LOOP_VINFO_DATAREFS (loop_vinfo).exists ()) 2262 { 2263 opt_result res 2264 = vect_get_datarefs_in_loop (loop, LOOP_VINFO_BBS (loop_vinfo), 2265 &LOOP_VINFO_DATAREFS (loop_vinfo), 2266 &LOOP_VINFO_N_STMTS (loop_vinfo)); 2267 if (!res) 2268 { 2269 if (dump_enabled_p ()) 2270 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2271 "not vectorized: loop contains function " 2272 "calls or data references that cannot " 2273 "be analyzed\n"); 2274 return res; 2275 } 2276 loop_vinfo->shared->save_datarefs (); 2277 } 2278 else 2279 loop_vinfo->shared->check_datarefs (); 2280 2281 /* Analyze the data references and also adjust the minimal 2282 vectorization factor according to the loads and stores. */ 2283 2284 ok = vect_analyze_data_refs (loop_vinfo, &min_vf, &fatal); 2285 if (!ok) 2286 { 2287 if (dump_enabled_p ()) 2288 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2289 "bad data references.\n"); 2290 return ok; 2291 } 2292 2293 /* Classify all cross-iteration scalar data-flow cycles. 2294 Cross-iteration cycles caused by virtual phis are analyzed separately. */ 2295 vect_analyze_scalar_cycles (loop_vinfo); 2296 2297 vect_pattern_recog (loop_vinfo); 2298 2299 vect_fixup_scalar_cycles_with_patterns (loop_vinfo); 2300 2301 /* Analyze the access patterns of the data-refs in the loop (consecutive, 2302 complex, etc.). FORNOW: Only handle consecutive access pattern. */ 2303 2304 ok = vect_analyze_data_ref_accesses (loop_vinfo, NULL); 2305 if (!ok) 2306 { 2307 if (dump_enabled_p ()) 2308 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2309 "bad data access.\n"); 2310 return ok; 2311 } 2312 2313 /* Data-flow analysis to detect stmts that do not need to be vectorized. */ 2314 2315 ok = vect_mark_stmts_to_be_vectorized (loop_vinfo, &fatal); 2316 if (!ok) 2317 { 2318 if (dump_enabled_p ()) 2319 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2320 "unexpected pattern.\n"); 2321 return ok; 2322 } 2323 2324 /* While the rest of the analysis below depends on it in some way. */ 2325 fatal = false; 2326 2327 /* Analyze data dependences between the data-refs in the loop 2328 and adjust the maximum vectorization factor according to 2329 the dependences. 2330 FORNOW: fail at the first data dependence that we encounter. */ 2331 2332 ok = vect_analyze_data_ref_dependences (loop_vinfo, &max_vf); 2333 if (!ok) 2334 { 2335 if (dump_enabled_p ()) 2336 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2337 "bad data dependence.\n"); 2338 return ok; 2339 } 2340 if (max_vf != MAX_VECTORIZATION_FACTOR 2341 && maybe_lt (max_vf, min_vf)) 2342 return opt_result::failure_at (vect_location, "bad data dependence.\n"); 2343 LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo) = max_vf; 2344 2345 ok = vect_determine_vectorization_factor (loop_vinfo); 2346 if (!ok) 2347 { 2348 if (dump_enabled_p ()) 2349 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2350 "can't determine vectorization factor.\n"); 2351 return ok; 2352 } 2353 if (max_vf != MAX_VECTORIZATION_FACTOR 2354 && maybe_lt (max_vf, LOOP_VINFO_VECT_FACTOR (loop_vinfo))) 2355 return opt_result::failure_at (vect_location, "bad data dependence.\n"); 2356 2357 /* Compute the scalar iteration cost. */ 2358 vect_compute_single_scalar_iteration_cost (loop_vinfo); 2359 2360 poly_uint64 saved_vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 2361 2362 /* Check the SLP opportunities in the loop, analyze and build SLP trees. */ 2363 ok = vect_analyze_slp (loop_vinfo, LOOP_VINFO_N_STMTS (loop_vinfo)); 2364 if (!ok) 2365 return ok; 2366 2367 /* If there are any SLP instances mark them as pure_slp. */ 2368 bool slp = vect_make_slp_decision (loop_vinfo); 2369 if (slp) 2370 { 2371 /* Find stmts that need to be both vectorized and SLPed. */ 2372 vect_detect_hybrid_slp (loop_vinfo); 2373 2374 /* Update the vectorization factor based on the SLP decision. */ 2375 vect_update_vf_for_slp (loop_vinfo); 2376 2377 /* Optimize the SLP graph with the vectorization factor fixed. */ 2378 vect_optimize_slp (loop_vinfo); 2379 2380 /* Gather the loads reachable from the SLP graph entries. */ 2381 vect_gather_slp_loads (loop_vinfo); 2382 } 2383 2384 bool saved_can_use_partial_vectors_p 2385 = LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo); 2386 2387 /* We don't expect to have to roll back to anything other than an empty 2388 set of rgroups. */ 2389 gcc_assert (LOOP_VINFO_MASKS (loop_vinfo).is_empty ()); 2390 2391 /* This is the point where we can re-start analysis with SLP forced off. */ 2392 start_over: 2393 2394 /* Apply the suggested unrolling factor, this was determined by the backend 2395 during finish_cost the first time we ran the analyzis for this 2396 vector mode. */ 2397 if (loop_vinfo->suggested_unroll_factor > 1) 2398 LOOP_VINFO_VECT_FACTOR (loop_vinfo) *= loop_vinfo->suggested_unroll_factor; 2399 2400 /* Now the vectorization factor is final. */ 2401 poly_uint64 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 2402 gcc_assert (known_ne (vectorization_factor, 0U)); 2403 2404 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ()) 2405 { 2406 dump_printf_loc (MSG_NOTE, vect_location, 2407 "vectorization_factor = "); 2408 dump_dec (MSG_NOTE, vectorization_factor); 2409 dump_printf (MSG_NOTE, ", niters = %wd\n", 2410 LOOP_VINFO_INT_NITERS (loop_vinfo)); 2411 } 2412 2413 loop_vinfo->vector_costs = init_cost (loop_vinfo, false); 2414 2415 /* Analyze the alignment of the data-refs in the loop. 2416 Fail if a data reference is found that cannot be vectorized. */ 2417 2418 ok = vect_analyze_data_refs_alignment (loop_vinfo); 2419 if (!ok) 2420 { 2421 if (dump_enabled_p ()) 2422 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2423 "bad data alignment.\n"); 2424 return ok; 2425 } 2426 2427 /* Prune the list of ddrs to be tested at run-time by versioning for alias. 2428 It is important to call pruning after vect_analyze_data_ref_accesses, 2429 since we use grouping information gathered by interleaving analysis. */ 2430 ok = vect_prune_runtime_alias_test_list (loop_vinfo); 2431 if (!ok) 2432 return ok; 2433 2434 /* Do not invoke vect_enhance_data_refs_alignment for epilogue 2435 vectorization, since we do not want to add extra peeling or 2436 add versioning for alignment. */ 2437 if (!LOOP_VINFO_EPILOGUE_P (loop_vinfo)) 2438 /* This pass will decide on using loop versioning and/or loop peeling in 2439 order to enhance the alignment of data references in the loop. */ 2440 ok = vect_enhance_data_refs_alignment (loop_vinfo); 2441 if (!ok) 2442 return ok; 2443 2444 if (slp) 2445 { 2446 /* Analyze operations in the SLP instances. Note this may 2447 remove unsupported SLP instances which makes the above 2448 SLP kind detection invalid. */ 2449 unsigned old_size = LOOP_VINFO_SLP_INSTANCES (loop_vinfo).length (); 2450 vect_slp_analyze_operations (loop_vinfo); 2451 if (LOOP_VINFO_SLP_INSTANCES (loop_vinfo).length () != old_size) 2452 { 2453 ok = opt_result::failure_at (vect_location, 2454 "unsupported SLP instances\n"); 2455 goto again; 2456 } 2457 2458 /* Check whether any load in ALL SLP instances is possibly permuted. */ 2459 slp_tree load_node, slp_root; 2460 unsigned i, x; 2461 slp_instance instance; 2462 bool can_use_lanes = true; 2463 FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), x, instance) 2464 { 2465 slp_root = SLP_INSTANCE_TREE (instance); 2466 int group_size = SLP_TREE_LANES (slp_root); 2467 tree vectype = SLP_TREE_VECTYPE (slp_root); 2468 bool loads_permuted = false; 2469 FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, load_node) 2470 { 2471 if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ()) 2472 continue; 2473 unsigned j; 2474 stmt_vec_info load_info; 2475 FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (load_node), j, load_info) 2476 if (SLP_TREE_LOAD_PERMUTATION (load_node)[j] != j) 2477 { 2478 loads_permuted = true; 2479 break; 2480 } 2481 } 2482 2483 /* If the loads and stores can be handled with load/store-lane 2484 instructions record it and move on to the next instance. */ 2485 if (loads_permuted 2486 && SLP_INSTANCE_KIND (instance) == slp_inst_kind_store 2487 && vect_store_lanes_supported (vectype, group_size, false)) 2488 { 2489 FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, load_node) 2490 { 2491 stmt_vec_info stmt_vinfo = DR_GROUP_FIRST_ELEMENT 2492 (SLP_TREE_SCALAR_STMTS (load_node)[0]); 2493 /* Use SLP for strided accesses (or if we can't 2494 load-lanes). */ 2495 if (STMT_VINFO_STRIDED_P (stmt_vinfo) 2496 || ! vect_load_lanes_supported 2497 (STMT_VINFO_VECTYPE (stmt_vinfo), 2498 DR_GROUP_SIZE (stmt_vinfo), false)) 2499 break; 2500 } 2501 2502 can_use_lanes 2503 = can_use_lanes && i == SLP_INSTANCE_LOADS (instance).length (); 2504 2505 if (can_use_lanes && dump_enabled_p ()) 2506 dump_printf_loc (MSG_NOTE, vect_location, 2507 "SLP instance %p can use load/store-lanes\n", 2508 instance); 2509 } 2510 else 2511 { 2512 can_use_lanes = false; 2513 break; 2514 } 2515 } 2516 2517 /* If all SLP instances can use load/store-lanes abort SLP and try again 2518 with SLP disabled. */ 2519 if (can_use_lanes) 2520 { 2521 ok = opt_result::failure_at (vect_location, 2522 "Built SLP cancelled: can use " 2523 "load/store-lanes\n"); 2524 if (dump_enabled_p ()) 2525 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2526 "Built SLP cancelled: all SLP instances support " 2527 "load/store-lanes\n"); 2528 goto again; 2529 } 2530 } 2531 2532 /* Dissolve SLP-only groups. */ 2533 vect_dissolve_slp_only_groups (loop_vinfo); 2534 2535 /* Scan all the remaining operations in the loop that are not subject 2536 to SLP and make sure they are vectorizable. */ 2537 ok = vect_analyze_loop_operations (loop_vinfo); 2538 if (!ok) 2539 { 2540 if (dump_enabled_p ()) 2541 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2542 "bad operation or unsupported loop bound.\n"); 2543 return ok; 2544 } 2545 2546 /* For now, we don't expect to mix both masking and length approaches for one 2547 loop, disable it if both are recorded. */ 2548 if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) 2549 && !LOOP_VINFO_MASKS (loop_vinfo).is_empty () 2550 && !LOOP_VINFO_LENS (loop_vinfo).is_empty ()) 2551 { 2552 if (dump_enabled_p ()) 2553 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2554 "can't vectorize a loop with partial vectors" 2555 " because we don't expect to mix different" 2556 " approaches with partial vectors for the" 2557 " same loop.\n"); 2558 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 2559 } 2560 2561 /* If we still have the option of using partial vectors, 2562 check whether we can generate the necessary loop controls. */ 2563 if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) 2564 && !vect_verify_full_masking (loop_vinfo) 2565 && !vect_verify_loop_lens (loop_vinfo)) 2566 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 2567 2568 /* If we're vectorizing an epilogue loop, the vectorized loop either needs 2569 to be able to handle fewer than VF scalars, or needs to have a lower VF 2570 than the main loop. */ 2571 if (LOOP_VINFO_EPILOGUE_P (loop_vinfo) 2572 && !LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) 2573 && maybe_ge (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 2574 LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo))) 2575 return opt_result::failure_at (vect_location, 2576 "Vectorization factor too high for" 2577 " epilogue loop.\n"); 2578 2579 /* Decide whether this loop_vinfo should use partial vectors or peeling, 2580 assuming that the loop will be used as a main loop. We will redo 2581 this analysis later if we instead decide to use the loop as an 2582 epilogue loop. */ 2583 ok = vect_determine_partial_vectors_and_peeling (loop_vinfo, false); 2584 if (!ok) 2585 return ok; 2586 2587 /* Check the costings of the loop make vectorizing worthwhile. */ 2588 res = vect_analyze_loop_costing (loop_vinfo, suggested_unroll_factor); 2589 if (res < 0) 2590 { 2591 ok = opt_result::failure_at (vect_location, 2592 "Loop costings may not be worthwhile.\n"); 2593 goto again; 2594 } 2595 if (!res) 2596 return opt_result::failure_at (vect_location, 2597 "Loop costings not worthwhile.\n"); 2598 2599 /* If an epilogue loop is required make sure we can create one. */ 2600 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) 2601 || LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo)) 2602 { 2603 if (dump_enabled_p ()) 2604 dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required\n"); 2605 if (!vect_can_advance_ivs_p (loop_vinfo) 2606 || !slpeel_can_duplicate_loop_p (LOOP_VINFO_LOOP (loop_vinfo), 2607 single_exit (LOOP_VINFO_LOOP 2608 (loop_vinfo)))) 2609 { 2610 ok = opt_result::failure_at (vect_location, 2611 "not vectorized: can't create required " 2612 "epilog loop\n"); 2613 goto again; 2614 } 2615 } 2616 2617 /* During peeling, we need to check if number of loop iterations is 2618 enough for both peeled prolog loop and vector loop. This check 2619 can be merged along with threshold check of loop versioning, so 2620 increase threshold for this case if necessary. 2621 2622 If we are analyzing an epilogue we still want to check what its 2623 versioning threshold would be. If we decide to vectorize the epilogues we 2624 will want to use the lowest versioning threshold of all epilogues and main 2625 loop. This will enable us to enter a vectorized epilogue even when 2626 versioning the loop. We can't simply check whether the epilogue requires 2627 versioning though since we may have skipped some versioning checks when 2628 analyzing the epilogue. For instance, checks for alias versioning will be 2629 skipped when dealing with epilogues as we assume we already checked them 2630 for the main loop. So instead we always check the 'orig_loop_vinfo'. */ 2631 if (LOOP_REQUIRES_VERSIONING (orig_loop_vinfo)) 2632 { 2633 poly_uint64 niters_th = 0; 2634 unsigned int th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo); 2635 2636 if (!vect_use_loop_mask_for_alignment_p (loop_vinfo)) 2637 { 2638 /* Niters for peeled prolog loop. */ 2639 if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) < 0) 2640 { 2641 dr_vec_info *dr_info = LOOP_VINFO_UNALIGNED_DR (loop_vinfo); 2642 tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt); 2643 niters_th += TYPE_VECTOR_SUBPARTS (vectype) - 1; 2644 } 2645 else 2646 niters_th += LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); 2647 } 2648 2649 /* Niters for at least one iteration of vectorized loop. */ 2650 if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 2651 niters_th += LOOP_VINFO_VECT_FACTOR (loop_vinfo); 2652 /* One additional iteration because of peeling for gap. */ 2653 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)) 2654 niters_th += 1; 2655 2656 /* Use the same condition as vect_transform_loop to decide when to use 2657 the cost to determine a versioning threshold. */ 2658 if (vect_apply_runtime_profitability_check_p (loop_vinfo) 2659 && ordered_p (th, niters_th)) 2660 niters_th = ordered_max (poly_uint64 (th), niters_th); 2661 2662 LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo) = niters_th; 2663 } 2664 2665 gcc_assert (known_eq (vectorization_factor, 2666 LOOP_VINFO_VECT_FACTOR (loop_vinfo))); 2667 2668 /* Ok to vectorize! */ 2669 LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1; 2670 return opt_result::success (); 2671 2672 again: 2673 /* Ensure that "ok" is false (with an opt_problem if dumping is enabled). */ 2674 gcc_assert (!ok); 2675 2676 /* Try again with SLP forced off but if we didn't do any SLP there is 2677 no point in re-trying. */ 2678 if (!slp) 2679 return ok; 2680 2681 /* If there are reduction chains re-trying will fail anyway. */ 2682 if (! LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).is_empty ()) 2683 return ok; 2684 2685 /* Likewise if the grouped loads or stores in the SLP cannot be handled 2686 via interleaving or lane instructions. */ 2687 slp_instance instance; 2688 slp_tree node; 2689 unsigned i, j; 2690 FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance) 2691 { 2692 stmt_vec_info vinfo; 2693 vinfo = SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance))[0]; 2694 if (! STMT_VINFO_GROUPED_ACCESS (vinfo)) 2695 continue; 2696 vinfo = DR_GROUP_FIRST_ELEMENT (vinfo); 2697 unsigned int size = DR_GROUP_SIZE (vinfo); 2698 tree vectype = STMT_VINFO_VECTYPE (vinfo); 2699 if (! vect_store_lanes_supported (vectype, size, false) 2700 && ! known_eq (TYPE_VECTOR_SUBPARTS (vectype), 1U) 2701 && ! vect_grouped_store_supported (vectype, size)) 2702 return opt_result::failure_at (vinfo->stmt, 2703 "unsupported grouped store\n"); 2704 FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), j, node) 2705 { 2706 vinfo = SLP_TREE_SCALAR_STMTS (node)[0]; 2707 vinfo = DR_GROUP_FIRST_ELEMENT (vinfo); 2708 bool single_element_p = !DR_GROUP_NEXT_ELEMENT (vinfo); 2709 size = DR_GROUP_SIZE (vinfo); 2710 vectype = STMT_VINFO_VECTYPE (vinfo); 2711 if (! vect_load_lanes_supported (vectype, size, false) 2712 && ! vect_grouped_load_supported (vectype, single_element_p, 2713 size)) 2714 return opt_result::failure_at (vinfo->stmt, 2715 "unsupported grouped load\n"); 2716 } 2717 } 2718 2719 if (dump_enabled_p ()) 2720 dump_printf_loc (MSG_NOTE, vect_location, 2721 "re-trying with SLP disabled\n"); 2722 2723 /* Roll back state appropriately. No SLP this time. */ 2724 slp = false; 2725 /* Restore vectorization factor as it were without SLP. */ 2726 LOOP_VINFO_VECT_FACTOR (loop_vinfo) = saved_vectorization_factor; 2727 /* Free the SLP instances. */ 2728 FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), j, instance) 2729 vect_free_slp_instance (instance); 2730 LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release (); 2731 /* Reset SLP type to loop_vect on all stmts. */ 2732 for (i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i) 2733 { 2734 basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i]; 2735 for (gimple_stmt_iterator si = gsi_start_phis (bb); 2736 !gsi_end_p (si); gsi_next (&si)) 2737 { 2738 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); 2739 STMT_SLP_TYPE (stmt_info) = loop_vect; 2740 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def 2741 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def) 2742 { 2743 /* vectorizable_reduction adjusts reduction stmt def-types, 2744 restore them to that of the PHI. */ 2745 STMT_VINFO_DEF_TYPE (STMT_VINFO_REDUC_DEF (stmt_info)) 2746 = STMT_VINFO_DEF_TYPE (stmt_info); 2747 STMT_VINFO_DEF_TYPE (vect_stmt_to_vectorize 2748 (STMT_VINFO_REDUC_DEF (stmt_info))) 2749 = STMT_VINFO_DEF_TYPE (stmt_info); 2750 } 2751 } 2752 for (gimple_stmt_iterator si = gsi_start_bb (bb); 2753 !gsi_end_p (si); gsi_next (&si)) 2754 { 2755 if (is_gimple_debug (gsi_stmt (si))) 2756 continue; 2757 stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); 2758 STMT_SLP_TYPE (stmt_info) = loop_vect; 2759 if (STMT_VINFO_IN_PATTERN_P (stmt_info)) 2760 { 2761 stmt_vec_info pattern_stmt_info 2762 = STMT_VINFO_RELATED_STMT (stmt_info); 2763 if (STMT_VINFO_SLP_VECT_ONLY_PATTERN (pattern_stmt_info)) 2764 STMT_VINFO_IN_PATTERN_P (stmt_info) = false; 2765 2766 gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info); 2767 STMT_SLP_TYPE (pattern_stmt_info) = loop_vect; 2768 for (gimple_stmt_iterator pi = gsi_start (pattern_def_seq); 2769 !gsi_end_p (pi); gsi_next (&pi)) 2770 STMT_SLP_TYPE (loop_vinfo->lookup_stmt (gsi_stmt (pi))) 2771 = loop_vect; 2772 } 2773 } 2774 } 2775 /* Free optimized alias test DDRS. */ 2776 LOOP_VINFO_LOWER_BOUNDS (loop_vinfo).truncate (0); 2777 LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).release (); 2778 LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).release (); 2779 /* Reset target cost data. */ 2780 delete loop_vinfo->vector_costs; 2781 loop_vinfo->vector_costs = nullptr; 2782 /* Reset accumulated rgroup information. */ 2783 release_vec_loop_controls (&LOOP_VINFO_MASKS (loop_vinfo)); 2784 release_vec_loop_controls (&LOOP_VINFO_LENS (loop_vinfo)); 2785 /* Reset assorted flags. */ 2786 LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = false; 2787 LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = false; 2788 LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = 0; 2789 LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo) = 0; 2790 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) 2791 = saved_can_use_partial_vectors_p; 2792 2793 goto start_over; 2794 } 2795 2796 /* Return true if vectorizing a loop using NEW_LOOP_VINFO appears 2797 to be better than vectorizing it using OLD_LOOP_VINFO. Assume that 2798 OLD_LOOP_VINFO is better unless something specifically indicates 2799 otherwise. 2800 2801 Note that this deliberately isn't a partial order. */ 2802 2803 static bool 2804 vect_better_loop_vinfo_p (loop_vec_info new_loop_vinfo, 2805 loop_vec_info old_loop_vinfo) 2806 { 2807 struct loop *loop = LOOP_VINFO_LOOP (new_loop_vinfo); 2808 gcc_assert (LOOP_VINFO_LOOP (old_loop_vinfo) == loop); 2809 2810 poly_int64 new_vf = LOOP_VINFO_VECT_FACTOR (new_loop_vinfo); 2811 poly_int64 old_vf = LOOP_VINFO_VECT_FACTOR (old_loop_vinfo); 2812 2813 /* Always prefer a VF of loop->simdlen over any other VF. */ 2814 if (loop->simdlen) 2815 { 2816 bool new_simdlen_p = known_eq (new_vf, loop->simdlen); 2817 bool old_simdlen_p = known_eq (old_vf, loop->simdlen); 2818 if (new_simdlen_p != old_simdlen_p) 2819 return new_simdlen_p; 2820 } 2821 2822 const auto *old_costs = old_loop_vinfo->vector_costs; 2823 const auto *new_costs = new_loop_vinfo->vector_costs; 2824 if (loop_vec_info main_loop = LOOP_VINFO_ORIG_LOOP_INFO (old_loop_vinfo)) 2825 return new_costs->better_epilogue_loop_than_p (old_costs, main_loop); 2826 2827 return new_costs->better_main_loop_than_p (old_costs); 2828 } 2829 2830 /* Decide whether to replace OLD_LOOP_VINFO with NEW_LOOP_VINFO. Return 2831 true if we should. */ 2832 2833 static bool 2834 vect_joust_loop_vinfos (loop_vec_info new_loop_vinfo, 2835 loop_vec_info old_loop_vinfo) 2836 { 2837 if (!vect_better_loop_vinfo_p (new_loop_vinfo, old_loop_vinfo)) 2838 return false; 2839 2840 if (dump_enabled_p ()) 2841 dump_printf_loc (MSG_NOTE, vect_location, 2842 "***** Preferring vector mode %s to vector mode %s\n", 2843 GET_MODE_NAME (new_loop_vinfo->vector_mode), 2844 GET_MODE_NAME (old_loop_vinfo->vector_mode)); 2845 return true; 2846 } 2847 2848 /* Analyze LOOP with VECTOR_MODES[MODE_I] and as epilogue if MAIN_LOOP_VINFO is 2849 not NULL. Set AUTODETECTED_VECTOR_MODE if VOIDmode and advance 2850 MODE_I to the next mode useful to analyze. 2851 Return the loop_vinfo on success and wrapped null on failure. */ 2852 2853 static opt_loop_vec_info 2854 vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, 2855 const vect_loop_form_info *loop_form_info, 2856 loop_vec_info main_loop_vinfo, 2857 const vector_modes &vector_modes, unsigned &mode_i, 2858 machine_mode &autodetected_vector_mode, 2859 bool &fatal) 2860 { 2861 loop_vec_info loop_vinfo 2862 = vect_create_loop_vinfo (loop, shared, loop_form_info, main_loop_vinfo); 2863 2864 machine_mode vector_mode = vector_modes[mode_i]; 2865 loop_vinfo->vector_mode = vector_mode; 2866 unsigned int suggested_unroll_factor = 1; 2867 2868 /* Run the main analysis. */ 2869 opt_result res = vect_analyze_loop_2 (loop_vinfo, fatal, 2870 &suggested_unroll_factor); 2871 if (dump_enabled_p ()) 2872 dump_printf_loc (MSG_NOTE, vect_location, 2873 "***** Analysis %s with vector mode %s\n", 2874 res ? "succeeded" : " failed", 2875 GET_MODE_NAME (loop_vinfo->vector_mode)); 2876 2877 if (res && !main_loop_vinfo && suggested_unroll_factor > 1) 2878 { 2879 if (dump_enabled_p ()) 2880 dump_printf_loc (MSG_NOTE, vect_location, 2881 "***** Re-trying analysis for unrolling" 2882 " with unroll factor %d.\n", 2883 suggested_unroll_factor); 2884 loop_vec_info unroll_vinfo 2885 = vect_create_loop_vinfo (loop, shared, loop_form_info, main_loop_vinfo); 2886 unroll_vinfo->vector_mode = vector_mode; 2887 unroll_vinfo->suggested_unroll_factor = suggested_unroll_factor; 2888 opt_result new_res = vect_analyze_loop_2 (unroll_vinfo, fatal, NULL); 2889 if (new_res) 2890 { 2891 delete loop_vinfo; 2892 loop_vinfo = unroll_vinfo; 2893 } 2894 else 2895 delete unroll_vinfo; 2896 } 2897 2898 /* Remember the autodetected vector mode. */ 2899 if (vector_mode == VOIDmode) 2900 autodetected_vector_mode = loop_vinfo->vector_mode; 2901 2902 /* Advance mode_i, first skipping modes that would result in the 2903 same analysis result. */ 2904 while (mode_i + 1 < vector_modes.length () 2905 && vect_chooses_same_modes_p (loop_vinfo, 2906 vector_modes[mode_i + 1])) 2907 { 2908 if (dump_enabled_p ()) 2909 dump_printf_loc (MSG_NOTE, vect_location, 2910 "***** The result for vector mode %s would" 2911 " be the same\n", 2912 GET_MODE_NAME (vector_modes[mode_i + 1])); 2913 mode_i += 1; 2914 } 2915 if (mode_i + 1 < vector_modes.length () 2916 && VECTOR_MODE_P (autodetected_vector_mode) 2917 && (related_vector_mode (vector_modes[mode_i + 1], 2918 GET_MODE_INNER (autodetected_vector_mode)) 2919 == autodetected_vector_mode) 2920 && (related_vector_mode (autodetected_vector_mode, 2921 GET_MODE_INNER (vector_modes[mode_i + 1])) 2922 == vector_modes[mode_i + 1])) 2923 { 2924 if (dump_enabled_p ()) 2925 dump_printf_loc (MSG_NOTE, vect_location, 2926 "***** Skipping vector mode %s, which would" 2927 " repeat the analysis for %s\n", 2928 GET_MODE_NAME (vector_modes[mode_i + 1]), 2929 GET_MODE_NAME (autodetected_vector_mode)); 2930 mode_i += 1; 2931 } 2932 mode_i++; 2933 2934 if (!res) 2935 { 2936 delete loop_vinfo; 2937 if (fatal) 2938 gcc_checking_assert (main_loop_vinfo == NULL); 2939 return opt_loop_vec_info::propagate_failure (res); 2940 } 2941 2942 return opt_loop_vec_info::success (loop_vinfo); 2943 } 2944 2945 /* Function vect_analyze_loop. 2946 2947 Apply a set of analyses on LOOP, and create a loop_vec_info struct 2948 for it. The different analyses will record information in the 2949 loop_vec_info struct. */ 2950 opt_loop_vec_info 2951 vect_analyze_loop (class loop *loop, vec_info_shared *shared) 2952 { 2953 DUMP_VECT_SCOPE ("analyze_loop_nest"); 2954 2955 if (loop_outer (loop) 2956 && loop_vec_info_for_loop (loop_outer (loop)) 2957 && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop)))) 2958 return opt_loop_vec_info::failure_at (vect_location, 2959 "outer-loop already vectorized.\n"); 2960 2961 if (!find_loop_nest (loop, &shared->loop_nest)) 2962 return opt_loop_vec_info::failure_at 2963 (vect_location, 2964 "not vectorized: loop nest containing two or more consecutive inner" 2965 " loops cannot be vectorized\n"); 2966 2967 /* Analyze the loop form. */ 2968 vect_loop_form_info loop_form_info; 2969 opt_result res = vect_analyze_loop_form (loop, &loop_form_info); 2970 if (!res) 2971 { 2972 if (dump_enabled_p ()) 2973 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 2974 "bad loop form.\n"); 2975 return opt_loop_vec_info::propagate_failure (res); 2976 } 2977 if (!integer_onep (loop_form_info.assumptions)) 2978 { 2979 /* We consider to vectorize this loop by versioning it under 2980 some assumptions. In order to do this, we need to clear 2981 existing information computed by scev and niter analyzer. */ 2982 scev_reset_htab (); 2983 free_numbers_of_iterations_estimates (loop); 2984 /* Also set flag for this loop so that following scev and niter 2985 analysis are done under the assumptions. */ 2986 loop_constraint_set (loop, LOOP_C_FINITE); 2987 } 2988 2989 auto_vector_modes vector_modes; 2990 /* Autodetect first vector size we try. */ 2991 vector_modes.safe_push (VOIDmode); 2992 unsigned int autovec_flags 2993 = targetm.vectorize.autovectorize_vector_modes (&vector_modes, 2994 loop->simdlen != 0); 2995 bool pick_lowest_cost_p = ((autovec_flags & VECT_COMPARE_COSTS) 2996 && !unlimited_cost_model (loop)); 2997 machine_mode autodetected_vector_mode = VOIDmode; 2998 opt_loop_vec_info first_loop_vinfo = opt_loop_vec_info::success (NULL); 2999 unsigned int mode_i = 0; 3000 unsigned HOST_WIDE_INT simdlen = loop->simdlen; 3001 3002 /* Keep track of the VF for each mode. Initialize all to 0 which indicates 3003 a mode has not been analyzed. */ 3004 auto_vec<poly_uint64, 8> cached_vf_per_mode; 3005 for (unsigned i = 0; i < vector_modes.length (); ++i) 3006 cached_vf_per_mode.safe_push (0); 3007 3008 /* First determine the main loop vectorization mode, either the first 3009 one that works, starting with auto-detecting the vector mode and then 3010 following the targets order of preference, or the one with the 3011 lowest cost if pick_lowest_cost_p. */ 3012 while (1) 3013 { 3014 bool fatal; 3015 unsigned int last_mode_i = mode_i; 3016 /* Set cached VF to -1 prior to analysis, which indicates a mode has 3017 failed. */ 3018 cached_vf_per_mode[last_mode_i] = -1; 3019 opt_loop_vec_info loop_vinfo 3020 = vect_analyze_loop_1 (loop, shared, &loop_form_info, 3021 NULL, vector_modes, mode_i, 3022 autodetected_vector_mode, fatal); 3023 if (fatal) 3024 break; 3025 3026 if (loop_vinfo) 3027 { 3028 /* Analyzis has been successful so update the VF value. The 3029 VF should always be a multiple of unroll_factor and we want to 3030 capture the original VF here. */ 3031 cached_vf_per_mode[last_mode_i] 3032 = exact_div (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 3033 loop_vinfo->suggested_unroll_factor); 3034 /* Once we hit the desired simdlen for the first time, 3035 discard any previous attempts. */ 3036 if (simdlen 3037 && known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), simdlen)) 3038 { 3039 delete first_loop_vinfo; 3040 first_loop_vinfo = opt_loop_vec_info::success (NULL); 3041 simdlen = 0; 3042 } 3043 else if (pick_lowest_cost_p 3044 && first_loop_vinfo 3045 && vect_joust_loop_vinfos (loop_vinfo, first_loop_vinfo)) 3046 { 3047 /* Pick loop_vinfo over first_loop_vinfo. */ 3048 delete first_loop_vinfo; 3049 first_loop_vinfo = opt_loop_vec_info::success (NULL); 3050 } 3051 if (first_loop_vinfo == NULL) 3052 first_loop_vinfo = loop_vinfo; 3053 else 3054 { 3055 delete loop_vinfo; 3056 loop_vinfo = opt_loop_vec_info::success (NULL); 3057 } 3058 3059 /* Commit to first_loop_vinfo if we have no reason to try 3060 alternatives. */ 3061 if (!simdlen && !pick_lowest_cost_p) 3062 break; 3063 } 3064 if (mode_i == vector_modes.length () 3065 || autodetected_vector_mode == VOIDmode) 3066 break; 3067 3068 /* Try the next biggest vector size. */ 3069 if (dump_enabled_p ()) 3070 dump_printf_loc (MSG_NOTE, vect_location, 3071 "***** Re-trying analysis with vector mode %s\n", 3072 GET_MODE_NAME (vector_modes[mode_i])); 3073 } 3074 if (!first_loop_vinfo) 3075 return opt_loop_vec_info::propagate_failure (res); 3076 3077 if (dump_enabled_p ()) 3078 dump_printf_loc (MSG_NOTE, vect_location, 3079 "***** Choosing vector mode %s\n", 3080 GET_MODE_NAME (first_loop_vinfo->vector_mode)); 3081 3082 /* Only vectorize epilogues if PARAM_VECT_EPILOGUES_NOMASK is 3083 enabled, SIMDUID is not set, it is the innermost loop and we have 3084 either already found the loop's SIMDLEN or there was no SIMDLEN to 3085 begin with. 3086 TODO: Enable epilogue vectorization for loops with SIMDUID set. */ 3087 bool vect_epilogues = (!simdlen 3088 && loop->inner == NULL 3089 && param_vect_epilogues_nomask 3090 && LOOP_VINFO_PEELING_FOR_NITER (first_loop_vinfo) 3091 && !loop->simduid); 3092 if (!vect_epilogues) 3093 return first_loop_vinfo; 3094 3095 /* Now analyze first_loop_vinfo for epilogue vectorization. */ 3096 poly_uint64 lowest_th = LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo); 3097 3098 /* For epilogues start the analysis from the first mode. The motivation 3099 behind starting from the beginning comes from cases where the VECTOR_MODES 3100 array may contain length-agnostic and length-specific modes. Their 3101 ordering is not guaranteed, so we could end up picking a mode for the main 3102 loop that is after the epilogue's optimal mode. */ 3103 vector_modes[0] = autodetected_vector_mode; 3104 mode_i = 0; 3105 3106 bool supports_partial_vectors = 3107 partial_vectors_supported_p () && param_vect_partial_vector_usage != 0; 3108 poly_uint64 first_vinfo_vf = LOOP_VINFO_VECT_FACTOR (first_loop_vinfo); 3109 3110 while (1) 3111 { 3112 /* If the target does not support partial vectors we can shorten the 3113 number of modes to analyze for the epilogue as we know we can't pick a 3114 mode that would lead to a VF at least as big as the 3115 FIRST_VINFO_VF. */ 3116 if (!supports_partial_vectors 3117 && maybe_ge (cached_vf_per_mode[mode_i], first_vinfo_vf)) 3118 { 3119 mode_i++; 3120 if (mode_i == vector_modes.length ()) 3121 break; 3122 continue; 3123 } 3124 3125 if (dump_enabled_p ()) 3126 dump_printf_loc (MSG_NOTE, vect_location, 3127 "***** Re-trying epilogue analysis with vector " 3128 "mode %s\n", GET_MODE_NAME (vector_modes[mode_i])); 3129 3130 bool fatal; 3131 opt_loop_vec_info loop_vinfo 3132 = vect_analyze_loop_1 (loop, shared, &loop_form_info, 3133 first_loop_vinfo, 3134 vector_modes, mode_i, 3135 autodetected_vector_mode, fatal); 3136 if (fatal) 3137 break; 3138 3139 if (loop_vinfo) 3140 { 3141 if (pick_lowest_cost_p) 3142 { 3143 /* Keep trying to roll back vectorization attempts while the 3144 loop_vec_infos they produced were worse than this one. */ 3145 vec<loop_vec_info> &vinfos = first_loop_vinfo->epilogue_vinfos; 3146 while (!vinfos.is_empty () 3147 && vect_joust_loop_vinfos (loop_vinfo, vinfos.last ())) 3148 { 3149 gcc_assert (vect_epilogues); 3150 delete vinfos.pop (); 3151 } 3152 } 3153 /* For now only allow one epilogue loop. */ 3154 if (first_loop_vinfo->epilogue_vinfos.is_empty ()) 3155 { 3156 first_loop_vinfo->epilogue_vinfos.safe_push (loop_vinfo); 3157 poly_uint64 th = LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo); 3158 gcc_assert (!LOOP_REQUIRES_VERSIONING (loop_vinfo) 3159 || maybe_ne (lowest_th, 0U)); 3160 /* Keep track of the known smallest versioning 3161 threshold. */ 3162 if (ordered_p (lowest_th, th)) 3163 lowest_th = ordered_min (lowest_th, th); 3164 } 3165 else 3166 { 3167 delete loop_vinfo; 3168 loop_vinfo = opt_loop_vec_info::success (NULL); 3169 } 3170 3171 /* For now only allow one epilogue loop, but allow 3172 pick_lowest_cost_p to replace it, so commit to the 3173 first epilogue if we have no reason to try alternatives. */ 3174 if (!pick_lowest_cost_p) 3175 break; 3176 } 3177 3178 if (mode_i == vector_modes.length ()) 3179 break; 3180 3181 } 3182 3183 if (!first_loop_vinfo->epilogue_vinfos.is_empty ()) 3184 { 3185 LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo) = lowest_th; 3186 if (dump_enabled_p ()) 3187 dump_printf_loc (MSG_NOTE, vect_location, 3188 "***** Choosing epilogue vector mode %s\n", 3189 GET_MODE_NAME 3190 (first_loop_vinfo->epilogue_vinfos[0]->vector_mode)); 3191 } 3192 3193 return first_loop_vinfo; 3194 } 3195 3196 /* Return true if there is an in-order reduction function for CODE, storing 3197 it in *REDUC_FN if so. */ 3198 3199 static bool 3200 fold_left_reduction_fn (code_helper code, internal_fn *reduc_fn) 3201 { 3202 if (code == PLUS_EXPR) 3203 { 3204 *reduc_fn = IFN_FOLD_LEFT_PLUS; 3205 return true; 3206 } 3207 return false; 3208 } 3209 3210 /* Function reduction_fn_for_scalar_code 3211 3212 Input: 3213 CODE - tree_code of a reduction operations. 3214 3215 Output: 3216 REDUC_FN - the corresponding internal function to be used to reduce the 3217 vector of partial results into a single scalar result, or IFN_LAST 3218 if the operation is a supported reduction operation, but does not have 3219 such an internal function. 3220 3221 Return FALSE if CODE currently cannot be vectorized as reduction. */ 3222 3223 bool 3224 reduction_fn_for_scalar_code (code_helper code, internal_fn *reduc_fn) 3225 { 3226 if (code.is_tree_code ()) 3227 switch (tree_code (code)) 3228 { 3229 case MAX_EXPR: 3230 *reduc_fn = IFN_REDUC_MAX; 3231 return true; 3232 3233 case MIN_EXPR: 3234 *reduc_fn = IFN_REDUC_MIN; 3235 return true; 3236 3237 case PLUS_EXPR: 3238 *reduc_fn = IFN_REDUC_PLUS; 3239 return true; 3240 3241 case BIT_AND_EXPR: 3242 *reduc_fn = IFN_REDUC_AND; 3243 return true; 3244 3245 case BIT_IOR_EXPR: 3246 *reduc_fn = IFN_REDUC_IOR; 3247 return true; 3248 3249 case BIT_XOR_EXPR: 3250 *reduc_fn = IFN_REDUC_XOR; 3251 return true; 3252 3253 case MULT_EXPR: 3254 case MINUS_EXPR: 3255 *reduc_fn = IFN_LAST; 3256 return true; 3257 3258 default: 3259 return false; 3260 } 3261 else 3262 switch (combined_fn (code)) 3263 { 3264 CASE_CFN_FMAX: 3265 *reduc_fn = IFN_REDUC_FMAX; 3266 return true; 3267 3268 CASE_CFN_FMIN: 3269 *reduc_fn = IFN_REDUC_FMIN; 3270 return true; 3271 3272 default: 3273 return false; 3274 } 3275 } 3276 3277 /* If there is a neutral value X such that a reduction would not be affected 3278 by the introduction of additional X elements, return that X, otherwise 3279 return null. CODE is the code of the reduction and SCALAR_TYPE is type 3280 of the scalar elements. If the reduction has just a single initial value 3281 then INITIAL_VALUE is that value, otherwise it is null. */ 3282 3283 tree 3284 neutral_op_for_reduction (tree scalar_type, code_helper code, 3285 tree initial_value) 3286 { 3287 if (code.is_tree_code ()) 3288 switch (tree_code (code)) 3289 { 3290 case WIDEN_SUM_EXPR: 3291 case DOT_PROD_EXPR: 3292 case SAD_EXPR: 3293 case PLUS_EXPR: 3294 case MINUS_EXPR: 3295 case BIT_IOR_EXPR: 3296 case BIT_XOR_EXPR: 3297 return build_zero_cst (scalar_type); 3298 3299 case MULT_EXPR: 3300 return build_one_cst (scalar_type); 3301 3302 case BIT_AND_EXPR: 3303 return build_all_ones_cst (scalar_type); 3304 3305 case MAX_EXPR: 3306 case MIN_EXPR: 3307 return initial_value; 3308 3309 default: 3310 return NULL_TREE; 3311 } 3312 else 3313 switch (combined_fn (code)) 3314 { 3315 CASE_CFN_FMIN: 3316 CASE_CFN_FMAX: 3317 return initial_value; 3318 3319 default: 3320 return NULL_TREE; 3321 } 3322 } 3323 3324 /* Error reporting helper for vect_is_simple_reduction below. GIMPLE statement 3325 STMT is printed with a message MSG. */ 3326 3327 static void 3328 report_vect_op (dump_flags_t msg_type, gimple *stmt, const char *msg) 3329 { 3330 dump_printf_loc (msg_type, vect_location, "%s%G", msg, stmt); 3331 } 3332 3333 /* Return true if we need an in-order reduction for operation CODE 3334 on type TYPE. NEED_WRAPPING_INTEGRAL_OVERFLOW is true if integer 3335 overflow must wrap. */ 3336 3337 bool 3338 needs_fold_left_reduction_p (tree type, code_helper code) 3339 { 3340 /* CHECKME: check for !flag_finite_math_only too? */ 3341 if (SCALAR_FLOAT_TYPE_P (type)) 3342 { 3343 if (code.is_tree_code ()) 3344 switch (tree_code (code)) 3345 { 3346 case MIN_EXPR: 3347 case MAX_EXPR: 3348 return false; 3349 3350 default: 3351 return !flag_associative_math; 3352 } 3353 else 3354 switch (combined_fn (code)) 3355 { 3356 CASE_CFN_FMIN: 3357 CASE_CFN_FMAX: 3358 return false; 3359 3360 default: 3361 return !flag_associative_math; 3362 } 3363 } 3364 3365 if (INTEGRAL_TYPE_P (type)) 3366 return (!code.is_tree_code () 3367 || !operation_no_trapping_overflow (type, tree_code (code))); 3368 3369 if (SAT_FIXED_POINT_TYPE_P (type)) 3370 return true; 3371 3372 return false; 3373 } 3374 3375 /* Return true if the reduction PHI in LOOP with latch arg LOOP_ARG and 3376 has a handled computation expression. Store the main reduction 3377 operation in *CODE. */ 3378 3379 static bool 3380 check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi, 3381 tree loop_arg, code_helper *code, 3382 vec<std::pair<ssa_op_iter, use_operand_p> > &path, 3383 bool inner_loop_of_double_reduc) 3384 { 3385 auto_bitmap visited; 3386 tree lookfor = PHI_RESULT (phi); 3387 ssa_op_iter curri; 3388 use_operand_p curr = op_iter_init_phiuse (&curri, phi, SSA_OP_USE); 3389 while (USE_FROM_PTR (curr) != loop_arg) 3390 curr = op_iter_next_use (&curri); 3391 curri.i = curri.numops; 3392 do 3393 { 3394 path.safe_push (std::make_pair (curri, curr)); 3395 tree use = USE_FROM_PTR (curr); 3396 if (use == lookfor) 3397 break; 3398 gimple *def = SSA_NAME_DEF_STMT (use); 3399 if (gimple_nop_p (def) 3400 || ! flow_bb_inside_loop_p (loop, gimple_bb (def))) 3401 { 3402 pop: 3403 do 3404 { 3405 std::pair<ssa_op_iter, use_operand_p> x = path.pop (); 3406 curri = x.first; 3407 curr = x.second; 3408 do 3409 curr = op_iter_next_use (&curri); 3410 /* Skip already visited or non-SSA operands (from iterating 3411 over PHI args). */ 3412 while (curr != NULL_USE_OPERAND_P 3413 && (TREE_CODE (USE_FROM_PTR (curr)) != SSA_NAME 3414 || ! bitmap_set_bit (visited, 3415 SSA_NAME_VERSION 3416 (USE_FROM_PTR (curr))))); 3417 } 3418 while (curr == NULL_USE_OPERAND_P && ! path.is_empty ()); 3419 if (curr == NULL_USE_OPERAND_P) 3420 break; 3421 } 3422 else 3423 { 3424 if (gimple_code (def) == GIMPLE_PHI) 3425 curr = op_iter_init_phiuse (&curri, as_a <gphi *>(def), SSA_OP_USE); 3426 else 3427 curr = op_iter_init_use (&curri, def, SSA_OP_USE); 3428 while (curr != NULL_USE_OPERAND_P 3429 && (TREE_CODE (USE_FROM_PTR (curr)) != SSA_NAME 3430 || ! bitmap_set_bit (visited, 3431 SSA_NAME_VERSION 3432 (USE_FROM_PTR (curr))))) 3433 curr = op_iter_next_use (&curri); 3434 if (curr == NULL_USE_OPERAND_P) 3435 goto pop; 3436 } 3437 } 3438 while (1); 3439 if (dump_file && (dump_flags & TDF_DETAILS)) 3440 { 3441 dump_printf_loc (MSG_NOTE, loc, "reduction path: "); 3442 unsigned i; 3443 std::pair<ssa_op_iter, use_operand_p> *x; 3444 FOR_EACH_VEC_ELT (path, i, x) 3445 dump_printf (MSG_NOTE, "%T ", USE_FROM_PTR (x->second)); 3446 dump_printf (MSG_NOTE, "\n"); 3447 } 3448 3449 /* Check whether the reduction path detected is valid. */ 3450 bool fail = path.length () == 0; 3451 bool neg = false; 3452 int sign = -1; 3453 *code = ERROR_MARK; 3454 for (unsigned i = 1; i < path.length (); ++i) 3455 { 3456 gimple *use_stmt = USE_STMT (path[i].second); 3457 gimple_match_op op; 3458 if (!gimple_extract_op (use_stmt, &op)) 3459 { 3460 fail = true; 3461 break; 3462 } 3463 unsigned int opi = op.num_ops; 3464 if (gassign *assign = dyn_cast<gassign *> (use_stmt)) 3465 { 3466 /* The following make sure we can compute the operand index 3467 easily plus it mostly disallows chaining via COND_EXPR condition 3468 operands. */ 3469 for (opi = 0; opi < op.num_ops; ++opi) 3470 if (gimple_assign_rhs1_ptr (assign) + opi == path[i].second->use) 3471 break; 3472 } 3473 else if (gcall *call = dyn_cast<gcall *> (use_stmt)) 3474 { 3475 for (opi = 0; opi < op.num_ops; ++opi) 3476 if (gimple_call_arg_ptr (call, opi) == path[i].second->use) 3477 break; 3478 } 3479 if (opi == op.num_ops) 3480 { 3481 fail = true; 3482 break; 3483 } 3484 op.code = canonicalize_code (op.code, op.type); 3485 if (op.code == MINUS_EXPR) 3486 { 3487 op.code = PLUS_EXPR; 3488 /* Track whether we negate the reduction value each iteration. */ 3489 if (op.ops[1] == op.ops[opi]) 3490 neg = ! neg; 3491 } 3492 if (CONVERT_EXPR_CODE_P (op.code) 3493 && tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))) 3494 ; 3495 else if (*code == ERROR_MARK) 3496 { 3497 *code = op.code; 3498 sign = TYPE_SIGN (op.type); 3499 } 3500 else if (op.code != *code) 3501 { 3502 fail = true; 3503 break; 3504 } 3505 else if ((op.code == MIN_EXPR 3506 || op.code == MAX_EXPR) 3507 && sign != TYPE_SIGN (op.type)) 3508 { 3509 fail = true; 3510 break; 3511 } 3512 /* Check there's only a single stmt the op is used on. For the 3513 not value-changing tail and the last stmt allow out-of-loop uses, 3514 but not when this is the inner loop of a double reduction. 3515 ??? We could relax this and handle arbitrary live stmts by 3516 forcing a scalar epilogue for example. */ 3517 imm_use_iterator imm_iter; 3518 use_operand_p use_p; 3519 gimple *op_use_stmt; 3520 unsigned cnt = 0; 3521 FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op.ops[opi]) 3522 if (!is_gimple_debug (op_use_stmt) 3523 && ((*code != ERROR_MARK || inner_loop_of_double_reduc) 3524 || flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt)))) 3525 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) 3526 cnt++; 3527 if (cnt != 1) 3528 { 3529 fail = true; 3530 break; 3531 } 3532 } 3533 return ! fail && ! neg && *code != ERROR_MARK; 3534 } 3535 3536 bool 3537 check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi, 3538 tree loop_arg, enum tree_code code) 3539 { 3540 auto_vec<std::pair<ssa_op_iter, use_operand_p> > path; 3541 code_helper code_; 3542 return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path, false) 3543 && code_ == code); 3544 } 3545 3546 3547 3548 /* Function vect_is_simple_reduction 3549 3550 (1) Detect a cross-iteration def-use cycle that represents a simple 3551 reduction computation. We look for the following pattern: 3552 3553 loop_header: 3554 a1 = phi < a0, a2 > 3555 a3 = ... 3556 a2 = operation (a3, a1) 3557 3558 or 3559 3560 a3 = ... 3561 loop_header: 3562 a1 = phi < a0, a2 > 3563 a2 = operation (a3, a1) 3564 3565 such that: 3566 1. operation is commutative and associative and it is safe to 3567 change the order of the computation 3568 2. no uses for a2 in the loop (a2 is used out of the loop) 3569 3. no uses of a1 in the loop besides the reduction operation 3570 4. no uses of a1 outside the loop. 3571 3572 Conditions 1,4 are tested here. 3573 Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized. 3574 3575 (2) Detect a cross-iteration def-use cycle in nested loops, i.e., 3576 nested cycles. 3577 3578 (3) Detect cycles of phi nodes in outer-loop vectorization, i.e., double 3579 reductions: 3580 3581 a1 = phi < a0, a2 > 3582 inner loop (def of a3) 3583 a2 = phi < a3 > 3584 3585 (4) Detect condition expressions, ie: 3586 for (int i = 0; i < N; i++) 3587 if (a[i] < val) 3588 ret_val = a[i]; 3589 3590 */ 3591 3592 static stmt_vec_info 3593 vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info, 3594 bool *double_reduc, bool *reduc_chain_p) 3595 { 3596 gphi *phi = as_a <gphi *> (phi_info->stmt); 3597 gimple *phi_use_stmt = NULL; 3598 imm_use_iterator imm_iter; 3599 use_operand_p use_p; 3600 3601 *double_reduc = false; 3602 *reduc_chain_p = false; 3603 STMT_VINFO_REDUC_TYPE (phi_info) = TREE_CODE_REDUCTION; 3604 3605 tree phi_name = PHI_RESULT (phi); 3606 /* ??? If there are no uses of the PHI result the inner loop reduction 3607 won't be detected as possibly double-reduction by vectorizable_reduction 3608 because that tries to walk the PHI arg from the preheader edge which 3609 can be constant. See PR60382. */ 3610 if (has_zero_uses (phi_name)) 3611 return NULL; 3612 class loop *loop = (gimple_bb (phi))->loop_father; 3613 unsigned nphi_def_loop_uses = 0; 3614 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, phi_name) 3615 { 3616 gimple *use_stmt = USE_STMT (use_p); 3617 if (is_gimple_debug (use_stmt)) 3618 continue; 3619 3620 if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) 3621 { 3622 if (dump_enabled_p ()) 3623 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 3624 "intermediate value used outside loop.\n"); 3625 3626 return NULL; 3627 } 3628 3629 nphi_def_loop_uses++; 3630 phi_use_stmt = use_stmt; 3631 } 3632 3633 tree latch_def = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop)); 3634 if (TREE_CODE (latch_def) != SSA_NAME) 3635 { 3636 if (dump_enabled_p ()) 3637 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 3638 "reduction: not ssa_name: %T\n", latch_def); 3639 return NULL; 3640 } 3641 3642 stmt_vec_info def_stmt_info = loop_info->lookup_def (latch_def); 3643 if (!def_stmt_info 3644 || !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt_info->stmt))) 3645 return NULL; 3646 3647 bool nested_in_vect_loop 3648 = flow_loop_nested_p (LOOP_VINFO_LOOP (loop_info), loop); 3649 unsigned nlatch_def_loop_uses = 0; 3650 auto_vec<gphi *, 3> lcphis; 3651 bool inner_loop_of_double_reduc = false; 3652 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, latch_def) 3653 { 3654 gimple *use_stmt = USE_STMT (use_p); 3655 if (is_gimple_debug (use_stmt)) 3656 continue; 3657 if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) 3658 nlatch_def_loop_uses++; 3659 else 3660 { 3661 /* We can have more than one loop-closed PHI. */ 3662 lcphis.safe_push (as_a <gphi *> (use_stmt)); 3663 if (nested_in_vect_loop 3664 && (STMT_VINFO_DEF_TYPE (loop_info->lookup_stmt (use_stmt)) 3665 == vect_double_reduction_def)) 3666 inner_loop_of_double_reduc = true; 3667 } 3668 } 3669 3670 /* If we are vectorizing an inner reduction we are executing that 3671 in the original order only in case we are not dealing with a 3672 double reduction. */ 3673 if (nested_in_vect_loop && !inner_loop_of_double_reduc) 3674 { 3675 if (dump_enabled_p ()) 3676 report_vect_op (MSG_NOTE, def_stmt_info->stmt, 3677 "detected nested cycle: "); 3678 return def_stmt_info; 3679 } 3680 3681 /* When the inner loop of a double reduction ends up with more than 3682 one loop-closed PHI we have failed to classify alternate such 3683 PHIs as double reduction, leading to wrong code. See PR103237. */ 3684 if (inner_loop_of_double_reduc && lcphis.length () != 1) 3685 { 3686 if (dump_enabled_p ()) 3687 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 3688 "unhandle double reduction\n"); 3689 return NULL; 3690 } 3691 3692 /* If this isn't a nested cycle or if the nested cycle reduction value 3693 is used ouside of the inner loop we cannot handle uses of the reduction 3694 value. */ 3695 if (nlatch_def_loop_uses > 1 || nphi_def_loop_uses > 1) 3696 { 3697 if (dump_enabled_p ()) 3698 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 3699 "reduction used in loop.\n"); 3700 return NULL; 3701 } 3702 3703 /* If DEF_STMT is a phi node itself, we expect it to have a single argument 3704 defined in the inner loop. */ 3705 if (gphi *def_stmt = dyn_cast <gphi *> (def_stmt_info->stmt)) 3706 { 3707 tree op1 = PHI_ARG_DEF (def_stmt, 0); 3708 if (gimple_phi_num_args (def_stmt) != 1 3709 || TREE_CODE (op1) != SSA_NAME) 3710 { 3711 if (dump_enabled_p ()) 3712 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 3713 "unsupported phi node definition.\n"); 3714 3715 return NULL; 3716 } 3717 3718 gimple *def1 = SSA_NAME_DEF_STMT (op1); 3719 if (gimple_bb (def1) 3720 && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) 3721 && loop->inner 3722 && flow_bb_inside_loop_p (loop->inner, gimple_bb (def1)) 3723 && (is_gimple_assign (def1) || is_gimple_call (def1)) 3724 && is_a <gphi *> (phi_use_stmt) 3725 && flow_bb_inside_loop_p (loop->inner, gimple_bb (phi_use_stmt))) 3726 { 3727 if (dump_enabled_p ()) 3728 report_vect_op (MSG_NOTE, def_stmt, 3729 "detected double reduction: "); 3730 3731 *double_reduc = true; 3732 return def_stmt_info; 3733 } 3734 3735 return NULL; 3736 } 3737 3738 /* Look for the expression computing latch_def from then loop PHI result. */ 3739 auto_vec<std::pair<ssa_op_iter, use_operand_p> > path; 3740 code_helper code; 3741 if (check_reduction_path (vect_location, loop, phi, latch_def, &code, 3742 path, inner_loop_of_double_reduc)) 3743 { 3744 STMT_VINFO_REDUC_CODE (phi_info) = code; 3745 if (code == COND_EXPR && !nested_in_vect_loop) 3746 STMT_VINFO_REDUC_TYPE (phi_info) = COND_REDUCTION; 3747 3748 /* Fill in STMT_VINFO_REDUC_IDX and gather stmts for an SLP 3749 reduction chain for which the additional restriction is that 3750 all operations in the chain are the same. */ 3751 auto_vec<stmt_vec_info, 8> reduc_chain; 3752 unsigned i; 3753 bool is_slp_reduc = !nested_in_vect_loop && code != COND_EXPR; 3754 for (i = path.length () - 1; i >= 1; --i) 3755 { 3756 gimple *stmt = USE_STMT (path[i].second); 3757 stmt_vec_info stmt_info = loop_info->lookup_stmt (stmt); 3758 gimple_match_op op; 3759 if (!gimple_extract_op (stmt, &op)) 3760 gcc_unreachable (); 3761 if (gassign *assign = dyn_cast<gassign *> (stmt)) 3762 STMT_VINFO_REDUC_IDX (stmt_info) 3763 = path[i].second->use - gimple_assign_rhs1_ptr (assign); 3764 else 3765 { 3766 gcall *call = as_a<gcall *> (stmt); 3767 STMT_VINFO_REDUC_IDX (stmt_info) 3768 = path[i].second->use - gimple_call_arg_ptr (call, 0); 3769 } 3770 bool leading_conversion = (CONVERT_EXPR_CODE_P (op.code) 3771 && (i == 1 || i == path.length () - 1)); 3772 if ((op.code != code && !leading_conversion) 3773 /* We can only handle the final value in epilogue 3774 generation for reduction chains. */ 3775 || (i != 1 && !has_single_use (gimple_get_lhs (stmt)))) 3776 is_slp_reduc = false; 3777 /* For reduction chains we support a trailing/leading 3778 conversions. We do not store those in the actual chain. */ 3779 if (leading_conversion) 3780 continue; 3781 reduc_chain.safe_push (stmt_info); 3782 } 3783 if (is_slp_reduc && reduc_chain.length () > 1) 3784 { 3785 for (unsigned i = 0; i < reduc_chain.length () - 1; ++i) 3786 { 3787 REDUC_GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0]; 3788 REDUC_GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1]; 3789 } 3790 REDUC_GROUP_FIRST_ELEMENT (reduc_chain.last ()) = reduc_chain[0]; 3791 REDUC_GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL; 3792 3793 /* Save the chain for further analysis in SLP detection. */ 3794 LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (reduc_chain[0]); 3795 REDUC_GROUP_SIZE (reduc_chain[0]) = reduc_chain.length (); 3796 3797 *reduc_chain_p = true; 3798 if (dump_enabled_p ()) 3799 dump_printf_loc (MSG_NOTE, vect_location, 3800 "reduction: detected reduction chain\n"); 3801 } 3802 else if (dump_enabled_p ()) 3803 dump_printf_loc (MSG_NOTE, vect_location, 3804 "reduction: detected reduction\n"); 3805 3806 return def_stmt_info; 3807 } 3808 3809 if (dump_enabled_p ()) 3810 dump_printf_loc (MSG_NOTE, vect_location, 3811 "reduction: unknown pattern\n"); 3812 3813 return NULL; 3814 } 3815 3816 /* Estimate the number of peeled epilogue iterations for LOOP_VINFO. 3817 PEEL_ITERS_PROLOGUE is the number of peeled prologue iterations, 3818 or -1 if not known. */ 3819 3820 static int 3821 vect_get_peel_iters_epilogue (loop_vec_info loop_vinfo, int peel_iters_prologue) 3822 { 3823 int assumed_vf = vect_vf_for_cost (loop_vinfo); 3824 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) || peel_iters_prologue == -1) 3825 { 3826 if (dump_enabled_p ()) 3827 dump_printf_loc (MSG_NOTE, vect_location, 3828 "cost model: epilogue peel iters set to vf/2 " 3829 "because loop iterations are unknown .\n"); 3830 return assumed_vf / 2; 3831 } 3832 else 3833 { 3834 int niters = LOOP_VINFO_INT_NITERS (loop_vinfo); 3835 peel_iters_prologue = MIN (niters, peel_iters_prologue); 3836 int peel_iters_epilogue = (niters - peel_iters_prologue) % assumed_vf; 3837 /* If we need to peel for gaps, but no peeling is required, we have to 3838 peel VF iterations. */ 3839 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) && !peel_iters_epilogue) 3840 peel_iters_epilogue = assumed_vf; 3841 return peel_iters_epilogue; 3842 } 3843 } 3844 3845 /* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times. */ 3846 int 3847 vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue, 3848 int *peel_iters_epilogue, 3849 stmt_vector_for_cost *scalar_cost_vec, 3850 stmt_vector_for_cost *prologue_cost_vec, 3851 stmt_vector_for_cost *epilogue_cost_vec) 3852 { 3853 int retval = 0; 3854 3855 *peel_iters_epilogue 3856 = vect_get_peel_iters_epilogue (loop_vinfo, peel_iters_prologue); 3857 3858 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) 3859 { 3860 /* If peeled iterations are known but number of scalar loop 3861 iterations are unknown, count a taken branch per peeled loop. */ 3862 if (peel_iters_prologue > 0) 3863 retval = record_stmt_cost (prologue_cost_vec, 1, cond_branch_taken, 3864 vect_prologue); 3865 if (*peel_iters_epilogue > 0) 3866 retval += record_stmt_cost (epilogue_cost_vec, 1, cond_branch_taken, 3867 vect_epilogue); 3868 } 3869 3870 stmt_info_for_cost *si; 3871 int j; 3872 if (peel_iters_prologue) 3873 FOR_EACH_VEC_ELT (*scalar_cost_vec, j, si) 3874 retval += record_stmt_cost (prologue_cost_vec, 3875 si->count * peel_iters_prologue, 3876 si->kind, si->stmt_info, si->misalign, 3877 vect_prologue); 3878 if (*peel_iters_epilogue) 3879 FOR_EACH_VEC_ELT (*scalar_cost_vec, j, si) 3880 retval += record_stmt_cost (epilogue_cost_vec, 3881 si->count * *peel_iters_epilogue, 3882 si->kind, si->stmt_info, si->misalign, 3883 vect_epilogue); 3884 3885 return retval; 3886 } 3887 3888 /* Function vect_estimate_min_profitable_iters 3889 3890 Return the number of iterations required for the vector version of the 3891 loop to be profitable relative to the cost of the scalar version of the 3892 loop. 3893 3894 *RET_MIN_PROFITABLE_NITERS is a cost model profitability threshold 3895 of iterations for vectorization. -1 value means loop vectorization 3896 is not profitable. This returned value may be used for dynamic 3897 profitability check. 3898 3899 *RET_MIN_PROFITABLE_ESTIMATE is a profitability threshold to be used 3900 for static check against estimated number of iterations. */ 3901 3902 static void 3903 vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, 3904 int *ret_min_profitable_niters, 3905 int *ret_min_profitable_estimate, 3906 unsigned *suggested_unroll_factor) 3907 { 3908 int min_profitable_iters; 3909 int min_profitable_estimate; 3910 int peel_iters_prologue; 3911 int peel_iters_epilogue; 3912 unsigned vec_inside_cost = 0; 3913 int vec_outside_cost = 0; 3914 unsigned vec_prologue_cost = 0; 3915 unsigned vec_epilogue_cost = 0; 3916 int scalar_single_iter_cost = 0; 3917 int scalar_outside_cost = 0; 3918 int assumed_vf = vect_vf_for_cost (loop_vinfo); 3919 int npeel = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); 3920 vector_costs *target_cost_data = loop_vinfo->vector_costs; 3921 3922 /* Cost model disabled. */ 3923 if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo))) 3924 { 3925 if (dump_enabled_p ()) 3926 dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled.\n"); 3927 *ret_min_profitable_niters = 0; 3928 *ret_min_profitable_estimate = 0; 3929 return; 3930 } 3931 3932 /* Requires loop versioning tests to handle misalignment. */ 3933 if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)) 3934 { 3935 /* FIXME: Make cost depend on complexity of individual check. */ 3936 unsigned len = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).length (); 3937 (void) add_stmt_cost (target_cost_data, len, scalar_stmt, vect_prologue); 3938 if (dump_enabled_p ()) 3939 dump_printf (MSG_NOTE, 3940 "cost model: Adding cost of checks for loop " 3941 "versioning to treat misalignment.\n"); 3942 } 3943 3944 /* Requires loop versioning with alias checks. */ 3945 if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)) 3946 { 3947 /* FIXME: Make cost depend on complexity of individual check. */ 3948 unsigned len = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).length (); 3949 (void) add_stmt_cost (target_cost_data, len, scalar_stmt, vect_prologue); 3950 len = LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).length (); 3951 if (len) 3952 /* Count LEN - 1 ANDs and LEN comparisons. */ 3953 (void) add_stmt_cost (target_cost_data, len * 2 - 1, 3954 scalar_stmt, vect_prologue); 3955 len = LOOP_VINFO_LOWER_BOUNDS (loop_vinfo).length (); 3956 if (len) 3957 { 3958 /* Count LEN - 1 ANDs and LEN comparisons. */ 3959 unsigned int nstmts = len * 2 - 1; 3960 /* +1 for each bias that needs adding. */ 3961 for (unsigned int i = 0; i < len; ++i) 3962 if (!LOOP_VINFO_LOWER_BOUNDS (loop_vinfo)[i].unsigned_p) 3963 nstmts += 1; 3964 (void) add_stmt_cost (target_cost_data, nstmts, 3965 scalar_stmt, vect_prologue); 3966 } 3967 if (dump_enabled_p ()) 3968 dump_printf (MSG_NOTE, 3969 "cost model: Adding cost of checks for loop " 3970 "versioning aliasing.\n"); 3971 } 3972 3973 /* Requires loop versioning with niter checks. */ 3974 if (LOOP_REQUIRES_VERSIONING_FOR_NITERS (loop_vinfo)) 3975 { 3976 /* FIXME: Make cost depend on complexity of individual check. */ 3977 (void) add_stmt_cost (target_cost_data, 1, vector_stmt, 3978 NULL, NULL, NULL_TREE, 0, vect_prologue); 3979 if (dump_enabled_p ()) 3980 dump_printf (MSG_NOTE, 3981 "cost model: Adding cost of checks for loop " 3982 "versioning niters.\n"); 3983 } 3984 3985 if (LOOP_REQUIRES_VERSIONING (loop_vinfo)) 3986 (void) add_stmt_cost (target_cost_data, 1, cond_branch_taken, 3987 vect_prologue); 3988 3989 /* Count statements in scalar loop. Using this as scalar cost for a single 3990 iteration for now. 3991 3992 TODO: Add outer loop support. 3993 3994 TODO: Consider assigning different costs to different scalar 3995 statements. */ 3996 3997 scalar_single_iter_cost = loop_vinfo->scalar_costs->total_cost (); 3998 3999 /* Add additional cost for the peeled instructions in prologue and epilogue 4000 loop. (For fully-masked loops there will be no peeling.) 4001 4002 FORNOW: If we don't know the value of peel_iters for prologue or epilogue 4003 at compile-time - we assume it's vf/2 (the worst would be vf-1). 4004 4005 TODO: Build an expression that represents peel_iters for prologue and 4006 epilogue to be used in a run-time test. */ 4007 4008 bool prologue_need_br_taken_cost = false; 4009 bool prologue_need_br_not_taken_cost = false; 4010 4011 /* Calculate peel_iters_prologue. */ 4012 if (vect_use_loop_mask_for_alignment_p (loop_vinfo)) 4013 peel_iters_prologue = 0; 4014 else if (npeel < 0) 4015 { 4016 peel_iters_prologue = assumed_vf / 2; 4017 if (dump_enabled_p ()) 4018 dump_printf (MSG_NOTE, "cost model: " 4019 "prologue peel iters set to vf/2.\n"); 4020 4021 /* If peeled iterations are unknown, count a taken branch and a not taken 4022 branch per peeled loop. Even if scalar loop iterations are known, 4023 vector iterations are not known since peeled prologue iterations are 4024 not known. Hence guards remain the same. */ 4025 prologue_need_br_taken_cost = true; 4026 prologue_need_br_not_taken_cost = true; 4027 } 4028 else 4029 { 4030 peel_iters_prologue = npeel; 4031 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && peel_iters_prologue > 0) 4032 /* If peeled iterations are known but number of scalar loop 4033 iterations are unknown, count a taken branch per peeled loop. */ 4034 prologue_need_br_taken_cost = true; 4035 } 4036 4037 bool epilogue_need_br_taken_cost = false; 4038 bool epilogue_need_br_not_taken_cost = false; 4039 4040 /* Calculate peel_iters_epilogue. */ 4041 if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 4042 /* We need to peel exactly one iteration for gaps. */ 4043 peel_iters_epilogue = LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) ? 1 : 0; 4044 else if (npeel < 0) 4045 { 4046 /* If peeling for alignment is unknown, loop bound of main loop 4047 becomes unknown. */ 4048 peel_iters_epilogue = assumed_vf / 2; 4049 if (dump_enabled_p ()) 4050 dump_printf (MSG_NOTE, "cost model: " 4051 "epilogue peel iters set to vf/2 because " 4052 "peeling for alignment is unknown.\n"); 4053 4054 /* See the same reason above in peel_iters_prologue calculation. */ 4055 epilogue_need_br_taken_cost = true; 4056 epilogue_need_br_not_taken_cost = true; 4057 } 4058 else 4059 { 4060 peel_iters_epilogue = vect_get_peel_iters_epilogue (loop_vinfo, npeel); 4061 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && peel_iters_epilogue > 0) 4062 /* If peeled iterations are known but number of scalar loop 4063 iterations are unknown, count a taken branch per peeled loop. */ 4064 epilogue_need_br_taken_cost = true; 4065 } 4066 4067 stmt_info_for_cost *si; 4068 int j; 4069 /* Add costs associated with peel_iters_prologue. */ 4070 if (peel_iters_prologue) 4071 FOR_EACH_VEC_ELT (LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), j, si) 4072 { 4073 (void) add_stmt_cost (target_cost_data, 4074 si->count * peel_iters_prologue, si->kind, 4075 si->stmt_info, si->node, si->vectype, 4076 si->misalign, vect_prologue); 4077 } 4078 4079 /* Add costs associated with peel_iters_epilogue. */ 4080 if (peel_iters_epilogue) 4081 FOR_EACH_VEC_ELT (LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), j, si) 4082 { 4083 (void) add_stmt_cost (target_cost_data, 4084 si->count * peel_iters_epilogue, si->kind, 4085 si->stmt_info, si->node, si->vectype, 4086 si->misalign, vect_epilogue); 4087 } 4088 4089 /* Add possible cond_branch_taken/cond_branch_not_taken cost. */ 4090 4091 if (prologue_need_br_taken_cost) 4092 (void) add_stmt_cost (target_cost_data, 1, cond_branch_taken, 4093 vect_prologue); 4094 4095 if (prologue_need_br_not_taken_cost) 4096 (void) add_stmt_cost (target_cost_data, 1, 4097 cond_branch_not_taken, vect_prologue); 4098 4099 if (epilogue_need_br_taken_cost) 4100 (void) add_stmt_cost (target_cost_data, 1, cond_branch_taken, 4101 vect_epilogue); 4102 4103 if (epilogue_need_br_not_taken_cost) 4104 (void) add_stmt_cost (target_cost_data, 1, 4105 cond_branch_not_taken, vect_epilogue); 4106 4107 /* Take care of special costs for rgroup controls of partial vectors. */ 4108 if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) 4109 { 4110 /* Calculate how many masks we need to generate. */ 4111 unsigned int num_masks = 0; 4112 rgroup_controls *rgm; 4113 unsigned int num_vectors_m1; 4114 FOR_EACH_VEC_ELT (LOOP_VINFO_MASKS (loop_vinfo), num_vectors_m1, rgm) 4115 if (rgm->type) 4116 num_masks += num_vectors_m1 + 1; 4117 gcc_assert (num_masks > 0); 4118 4119 /* In the worst case, we need to generate each mask in the prologue 4120 and in the loop body. One of the loop body mask instructions 4121 replaces the comparison in the scalar loop, and since we don't 4122 count the scalar comparison against the scalar body, we shouldn't 4123 count that vector instruction against the vector body either. 4124 4125 Sometimes we can use unpacks instead of generating prologue 4126 masks and sometimes the prologue mask will fold to a constant, 4127 so the actual prologue cost might be smaller. However, it's 4128 simpler and safer to use the worst-case cost; if this ends up 4129 being the tie-breaker between vectorizing or not, then it's 4130 probably better not to vectorize. */ 4131 (void) add_stmt_cost (target_cost_data, num_masks, 4132 vector_stmt, NULL, NULL, NULL_TREE, 0, 4133 vect_prologue); 4134 (void) add_stmt_cost (target_cost_data, num_masks - 1, 4135 vector_stmt, NULL, NULL, NULL_TREE, 0, 4136 vect_body); 4137 } 4138 else if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo)) 4139 { 4140 /* Referring to the functions vect_set_loop_condition_partial_vectors 4141 and vect_set_loop_controls_directly, we need to generate each 4142 length in the prologue and in the loop body if required. Although 4143 there are some possible optimizations, we consider the worst case 4144 here. */ 4145 4146 bool niters_known_p = LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo); 4147 signed char partial_load_store_bias 4148 = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); 4149 bool need_iterate_p 4150 = (!LOOP_VINFO_EPILOGUE_P (loop_vinfo) 4151 && !vect_known_niters_smaller_than_vf (loop_vinfo)); 4152 4153 /* Calculate how many statements to be added. */ 4154 unsigned int prologue_stmts = 0; 4155 unsigned int body_stmts = 0; 4156 4157 rgroup_controls *rgc; 4158 unsigned int num_vectors_m1; 4159 FOR_EACH_VEC_ELT (LOOP_VINFO_LENS (loop_vinfo), num_vectors_m1, rgc) 4160 if (rgc->type) 4161 { 4162 /* May need one SHIFT for nitems_total computation. */ 4163 unsigned nitems = rgc->max_nscalars_per_iter * rgc->factor; 4164 if (nitems != 1 && !niters_known_p) 4165 prologue_stmts += 1; 4166 4167 /* May need one MAX and one MINUS for wrap around. */ 4168 if (vect_rgroup_iv_might_wrap_p (loop_vinfo, rgc)) 4169 prologue_stmts += 2; 4170 4171 /* Need one MAX and one MINUS for each batch limit excepting for 4172 the 1st one. */ 4173 prologue_stmts += num_vectors_m1 * 2; 4174 4175 unsigned int num_vectors = num_vectors_m1 + 1; 4176 4177 /* Need to set up lengths in prologue, only one MIN required 4178 for each since start index is zero. */ 4179 prologue_stmts += num_vectors; 4180 4181 /* If we have a non-zero partial load bias, we need one PLUS 4182 to adjust the load length. */ 4183 if (partial_load_store_bias != 0) 4184 body_stmts += 1; 4185 4186 /* Each may need two MINs and one MINUS to update lengths in body 4187 for next iteration. */ 4188 if (need_iterate_p) 4189 body_stmts += 3 * num_vectors; 4190 } 4191 4192 (void) add_stmt_cost (target_cost_data, prologue_stmts, 4193 scalar_stmt, vect_prologue); 4194 (void) add_stmt_cost (target_cost_data, body_stmts, 4195 scalar_stmt, vect_body); 4196 } 4197 4198 /* FORNOW: The scalar outside cost is incremented in one of the 4199 following ways: 4200 4201 1. The vectorizer checks for alignment and aliasing and generates 4202 a condition that allows dynamic vectorization. A cost model 4203 check is ANDED with the versioning condition. Hence scalar code 4204 path now has the added cost of the versioning check. 4205 4206 if (cost > th & versioning_check) 4207 jmp to vector code 4208 4209 Hence run-time scalar is incremented by not-taken branch cost. 4210 4211 2. The vectorizer then checks if a prologue is required. If the 4212 cost model check was not done before during versioning, it has to 4213 be done before the prologue check. 4214 4215 if (cost <= th) 4216 prologue = scalar_iters 4217 if (prologue == 0) 4218 jmp to vector code 4219 else 4220 execute prologue 4221 if (prologue == num_iters) 4222 go to exit 4223 4224 Hence the run-time scalar cost is incremented by a taken branch, 4225 plus a not-taken branch, plus a taken branch cost. 4226 4227 3. The vectorizer then checks if an epilogue is required. If the 4228 cost model check was not done before during prologue check, it 4229 has to be done with the epilogue check. 4230 4231 if (prologue == 0) 4232 jmp to vector code 4233 else 4234 execute prologue 4235 if (prologue == num_iters) 4236 go to exit 4237 vector code: 4238 if ((cost <= th) | (scalar_iters-prologue-epilogue == 0)) 4239 jmp to epilogue 4240 4241 Hence the run-time scalar cost should be incremented by 2 taken 4242 branches. 4243 4244 TODO: The back end may reorder the BBS's differently and reverse 4245 conditions/branch directions. Change the estimates below to 4246 something more reasonable. */ 4247 4248 /* If the number of iterations is known and we do not do versioning, we can 4249 decide whether to vectorize at compile time. Hence the scalar version 4250 do not carry cost model guard costs. */ 4251 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 4252 || LOOP_REQUIRES_VERSIONING (loop_vinfo)) 4253 { 4254 /* Cost model check occurs at versioning. */ 4255 if (LOOP_REQUIRES_VERSIONING (loop_vinfo)) 4256 scalar_outside_cost += vect_get_stmt_cost (cond_branch_not_taken); 4257 else 4258 { 4259 /* Cost model check occurs at prologue generation. */ 4260 if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) < 0) 4261 scalar_outside_cost += 2 * vect_get_stmt_cost (cond_branch_taken) 4262 + vect_get_stmt_cost (cond_branch_not_taken); 4263 /* Cost model check occurs at epilogue generation. */ 4264 else 4265 scalar_outside_cost += 2 * vect_get_stmt_cost (cond_branch_taken); 4266 } 4267 } 4268 4269 /* Complete the target-specific cost calculations. */ 4270 finish_cost (loop_vinfo->vector_costs, loop_vinfo->scalar_costs, 4271 &vec_prologue_cost, &vec_inside_cost, &vec_epilogue_cost, 4272 suggested_unroll_factor); 4273 4274 if (suggested_unroll_factor && *suggested_unroll_factor > 1 4275 && LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo) != MAX_VECTORIZATION_FACTOR 4276 && !known_le (LOOP_VINFO_VECT_FACTOR (loop_vinfo) * 4277 *suggested_unroll_factor, 4278 LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo))) 4279 { 4280 if (dump_enabled_p ()) 4281 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 4282 "can't unroll as unrolled vectorization factor larger" 4283 " than maximum vectorization factor: " 4284 HOST_WIDE_INT_PRINT_UNSIGNED "\n", 4285 LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo)); 4286 *suggested_unroll_factor = 1; 4287 } 4288 4289 vec_outside_cost = (int)(vec_prologue_cost + vec_epilogue_cost); 4290 4291 if (dump_enabled_p ()) 4292 { 4293 dump_printf_loc (MSG_NOTE, vect_location, "Cost model analysis: \n"); 4294 dump_printf (MSG_NOTE, " Vector inside of loop cost: %d\n", 4295 vec_inside_cost); 4296 dump_printf (MSG_NOTE, " Vector prologue cost: %d\n", 4297 vec_prologue_cost); 4298 dump_printf (MSG_NOTE, " Vector epilogue cost: %d\n", 4299 vec_epilogue_cost); 4300 dump_printf (MSG_NOTE, " Scalar iteration cost: %d\n", 4301 scalar_single_iter_cost); 4302 dump_printf (MSG_NOTE, " Scalar outside cost: %d\n", 4303 scalar_outside_cost); 4304 dump_printf (MSG_NOTE, " Vector outside cost: %d\n", 4305 vec_outside_cost); 4306 dump_printf (MSG_NOTE, " prologue iterations: %d\n", 4307 peel_iters_prologue); 4308 dump_printf (MSG_NOTE, " epilogue iterations: %d\n", 4309 peel_iters_epilogue); 4310 } 4311 4312 /* Calculate number of iterations required to make the vector version 4313 profitable, relative to the loop bodies only. The following condition 4314 must hold true: 4315 SIC * niters + SOC > VIC * ((niters - NPEEL) / VF) + VOC 4316 where 4317 SIC = scalar iteration cost, VIC = vector iteration cost, 4318 VOC = vector outside cost, VF = vectorization factor, 4319 NPEEL = prologue iterations + epilogue iterations, 4320 SOC = scalar outside cost for run time cost model check. */ 4321 4322 int saving_per_viter = (scalar_single_iter_cost * assumed_vf 4323 - vec_inside_cost); 4324 if (saving_per_viter <= 0) 4325 { 4326 if (LOOP_VINFO_LOOP (loop_vinfo)->force_vectorize) 4327 warning_at (vect_location.get_location_t (), OPT_Wopenmp_simd, 4328 "vectorization did not happen for a simd loop"); 4329 4330 if (dump_enabled_p ()) 4331 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 4332 "cost model: the vector iteration cost = %d " 4333 "divided by the scalar iteration cost = %d " 4334 "is greater or equal to the vectorization factor = %d" 4335 ".\n", 4336 vec_inside_cost, scalar_single_iter_cost, assumed_vf); 4337 *ret_min_profitable_niters = -1; 4338 *ret_min_profitable_estimate = -1; 4339 return; 4340 } 4341 4342 /* ??? The "if" arm is written to handle all cases; see below for what 4343 we would do for !LOOP_VINFO_USING_PARTIAL_VECTORS_P. */ 4344 if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 4345 { 4346 /* Rewriting the condition above in terms of the number of 4347 vector iterations (vniters) rather than the number of 4348 scalar iterations (niters) gives: 4349 4350 SIC * (vniters * VF + NPEEL) + SOC > VIC * vniters + VOC 4351 4352 <==> vniters * (SIC * VF - VIC) > VOC - SIC * NPEEL - SOC 4353 4354 For integer N, X and Y when X > 0: 4355 4356 N * X > Y <==> N >= (Y /[floor] X) + 1. */ 4357 int outside_overhead = (vec_outside_cost 4358 - scalar_single_iter_cost * peel_iters_prologue 4359 - scalar_single_iter_cost * peel_iters_epilogue 4360 - scalar_outside_cost); 4361 /* We're only interested in cases that require at least one 4362 vector iteration. */ 4363 int min_vec_niters = 1; 4364 if (outside_overhead > 0) 4365 min_vec_niters = outside_overhead / saving_per_viter + 1; 4366 4367 if (dump_enabled_p ()) 4368 dump_printf (MSG_NOTE, " Minimum number of vector iterations: %d\n", 4369 min_vec_niters); 4370 4371 if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 4372 { 4373 /* Now that we know the minimum number of vector iterations, 4374 find the minimum niters for which the scalar cost is larger: 4375 4376 SIC * niters > VIC * vniters + VOC - SOC 4377 4378 We know that the minimum niters is no more than 4379 vniters * VF + NPEEL, but it might be (and often is) less 4380 than that if a partial vector iteration is cheaper than the 4381 equivalent scalar code. */ 4382 int threshold = (vec_inside_cost * min_vec_niters 4383 + vec_outside_cost 4384 - scalar_outside_cost); 4385 if (threshold <= 0) 4386 min_profitable_iters = 1; 4387 else 4388 min_profitable_iters = threshold / scalar_single_iter_cost + 1; 4389 } 4390 else 4391 /* Convert the number of vector iterations into a number of 4392 scalar iterations. */ 4393 min_profitable_iters = (min_vec_niters * assumed_vf 4394 + peel_iters_prologue 4395 + peel_iters_epilogue); 4396 } 4397 else 4398 { 4399 min_profitable_iters = ((vec_outside_cost - scalar_outside_cost) 4400 * assumed_vf 4401 - vec_inside_cost * peel_iters_prologue 4402 - vec_inside_cost * peel_iters_epilogue); 4403 if (min_profitable_iters <= 0) 4404 min_profitable_iters = 0; 4405 else 4406 { 4407 min_profitable_iters /= saving_per_viter; 4408 4409 if ((scalar_single_iter_cost * assumed_vf * min_profitable_iters) 4410 <= (((int) vec_inside_cost * min_profitable_iters) 4411 + (((int) vec_outside_cost - scalar_outside_cost) 4412 * assumed_vf))) 4413 min_profitable_iters++; 4414 } 4415 } 4416 4417 if (dump_enabled_p ()) 4418 dump_printf (MSG_NOTE, 4419 " Calculated minimum iters for profitability: %d\n", 4420 min_profitable_iters); 4421 4422 if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) 4423 && min_profitable_iters < (assumed_vf + peel_iters_prologue)) 4424 /* We want the vectorized loop to execute at least once. */ 4425 min_profitable_iters = assumed_vf + peel_iters_prologue; 4426 else if (min_profitable_iters < peel_iters_prologue) 4427 /* For LOOP_VINFO_USING_PARTIAL_VECTORS_P, we need to ensure the 4428 vectorized loop executes at least once. */ 4429 min_profitable_iters = peel_iters_prologue; 4430 4431 if (dump_enabled_p ()) 4432 dump_printf_loc (MSG_NOTE, vect_location, 4433 " Runtime profitability threshold = %d\n", 4434 min_profitable_iters); 4435 4436 *ret_min_profitable_niters = min_profitable_iters; 4437 4438 /* Calculate number of iterations required to make the vector version 4439 profitable, relative to the loop bodies only. 4440 4441 Non-vectorized variant is SIC * niters and it must win over vector 4442 variant on the expected loop trip count. The following condition must hold true: 4443 SIC * niters > VIC * ((niters - NPEEL) / VF) + VOC + SOC */ 4444 4445 if (vec_outside_cost <= 0) 4446 min_profitable_estimate = 0; 4447 /* ??? This "else if" arm is written to handle all cases; see below for 4448 what we would do for !LOOP_VINFO_USING_PARTIAL_VECTORS_P. */ 4449 else if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 4450 { 4451 /* This is a repeat of the code above, but with + SOC rather 4452 than - SOC. */ 4453 int outside_overhead = (vec_outside_cost 4454 - scalar_single_iter_cost * peel_iters_prologue 4455 - scalar_single_iter_cost * peel_iters_epilogue 4456 + scalar_outside_cost); 4457 int min_vec_niters = 1; 4458 if (outside_overhead > 0) 4459 min_vec_niters = outside_overhead / saving_per_viter + 1; 4460 4461 if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 4462 { 4463 int threshold = (vec_inside_cost * min_vec_niters 4464 + vec_outside_cost 4465 + scalar_outside_cost); 4466 min_profitable_estimate = threshold / scalar_single_iter_cost + 1; 4467 } 4468 else 4469 min_profitable_estimate = (min_vec_niters * assumed_vf 4470 + peel_iters_prologue 4471 + peel_iters_epilogue); 4472 } 4473 else 4474 { 4475 min_profitable_estimate = ((vec_outside_cost + scalar_outside_cost) 4476 * assumed_vf 4477 - vec_inside_cost * peel_iters_prologue 4478 - vec_inside_cost * peel_iters_epilogue) 4479 / ((scalar_single_iter_cost * assumed_vf) 4480 - vec_inside_cost); 4481 } 4482 min_profitable_estimate = MAX (min_profitable_estimate, min_profitable_iters); 4483 if (dump_enabled_p ()) 4484 dump_printf_loc (MSG_NOTE, vect_location, 4485 " Static estimate profitability threshold = %d\n", 4486 min_profitable_estimate); 4487 4488 *ret_min_profitable_estimate = min_profitable_estimate; 4489 } 4490 4491 /* Writes into SEL a mask for a vec_perm, equivalent to a vec_shr by OFFSET 4492 vector elements (not bits) for a vector with NELT elements. */ 4493 static void 4494 calc_vec_perm_mask_for_shift (unsigned int offset, unsigned int nelt, 4495 vec_perm_builder *sel) 4496 { 4497 /* The encoding is a single stepped pattern. Any wrap-around is handled 4498 by vec_perm_indices. */ 4499 sel->new_vector (nelt, 1, 3); 4500 for (unsigned int i = 0; i < 3; i++) 4501 sel->quick_push (i + offset); 4502 } 4503 4504 /* Checks whether the target supports whole-vector shifts for vectors of mode 4505 MODE. This is the case if _either_ the platform handles vec_shr_optab, _or_ 4506 it supports vec_perm_const with masks for all necessary shift amounts. */ 4507 static bool 4508 have_whole_vector_shift (machine_mode mode) 4509 { 4510 if (optab_handler (vec_shr_optab, mode) != CODE_FOR_nothing) 4511 return true; 4512 4513 /* Variable-length vectors should be handled via the optab. */ 4514 unsigned int nelt; 4515 if (!GET_MODE_NUNITS (mode).is_constant (&nelt)) 4516 return false; 4517 4518 vec_perm_builder sel; 4519 vec_perm_indices indices; 4520 for (unsigned int i = nelt / 2; i >= 1; i /= 2) 4521 { 4522 calc_vec_perm_mask_for_shift (i, nelt, &sel); 4523 indices.new_vector (sel, 2, nelt); 4524 if (!can_vec_perm_const_p (mode, indices, false)) 4525 return false; 4526 } 4527 return true; 4528 } 4529 4530 /* TODO: Close dependency between vect_model_*_cost and vectorizable_* 4531 functions. Design better to avoid maintenance issues. */ 4532 4533 /* Function vect_model_reduction_cost. 4534 4535 Models cost for a reduction operation, including the vector ops 4536 generated within the strip-mine loop in some cases, the initial 4537 definition before the loop, and the epilogue code that must be generated. */ 4538 4539 static void 4540 vect_model_reduction_cost (loop_vec_info loop_vinfo, 4541 stmt_vec_info stmt_info, internal_fn reduc_fn, 4542 vect_reduction_type reduction_type, 4543 int ncopies, stmt_vector_for_cost *cost_vec) 4544 { 4545 int prologue_cost = 0, epilogue_cost = 0, inside_cost = 0; 4546 tree vectype; 4547 machine_mode mode; 4548 class loop *loop = NULL; 4549 4550 if (loop_vinfo) 4551 loop = LOOP_VINFO_LOOP (loop_vinfo); 4552 4553 /* Condition reductions generate two reductions in the loop. */ 4554 if (reduction_type == COND_REDUCTION) 4555 ncopies *= 2; 4556 4557 vectype = STMT_VINFO_VECTYPE (stmt_info); 4558 mode = TYPE_MODE (vectype); 4559 stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info); 4560 4561 gimple_match_op op; 4562 if (!gimple_extract_op (orig_stmt_info->stmt, &op)) 4563 gcc_unreachable (); 4564 4565 if (reduction_type == EXTRACT_LAST_REDUCTION) 4566 /* No extra instructions are needed in the prologue. The loop body 4567 operations are costed in vectorizable_condition. */ 4568 inside_cost = 0; 4569 else if (reduction_type == FOLD_LEFT_REDUCTION) 4570 { 4571 /* No extra instructions needed in the prologue. */ 4572 prologue_cost = 0; 4573 4574 if (reduc_fn != IFN_LAST) 4575 /* Count one reduction-like operation per vector. */ 4576 inside_cost = record_stmt_cost (cost_vec, ncopies, vec_to_scalar, 4577 stmt_info, 0, vect_body); 4578 else 4579 { 4580 /* Use NELEMENTS extracts and NELEMENTS scalar ops. */ 4581 unsigned int nelements = ncopies * vect_nunits_for_cost (vectype); 4582 inside_cost = record_stmt_cost (cost_vec, nelements, 4583 vec_to_scalar, stmt_info, 0, 4584 vect_body); 4585 inside_cost += record_stmt_cost (cost_vec, nelements, 4586 scalar_stmt, stmt_info, 0, 4587 vect_body); 4588 } 4589 } 4590 else 4591 { 4592 /* Add in cost for initial definition. 4593 For cond reduction we have four vectors: initial index, step, 4594 initial result of the data reduction, initial value of the index 4595 reduction. */ 4596 int prologue_stmts = reduction_type == COND_REDUCTION ? 4 : 1; 4597 prologue_cost += record_stmt_cost (cost_vec, prologue_stmts, 4598 scalar_to_vec, stmt_info, 0, 4599 vect_prologue); 4600 } 4601 4602 /* Determine cost of epilogue code. 4603 4604 We have a reduction operator that will reduce the vector in one statement. 4605 Also requires scalar extract. */ 4606 4607 if (!loop || !nested_in_vect_loop_p (loop, orig_stmt_info)) 4608 { 4609 if (reduc_fn != IFN_LAST) 4610 { 4611 if (reduction_type == COND_REDUCTION) 4612 { 4613 /* An EQ stmt and an COND_EXPR stmt. */ 4614 epilogue_cost += record_stmt_cost (cost_vec, 2, 4615 vector_stmt, stmt_info, 0, 4616 vect_epilogue); 4617 /* Reduction of the max index and a reduction of the found 4618 values. */ 4619 epilogue_cost += record_stmt_cost (cost_vec, 2, 4620 vec_to_scalar, stmt_info, 0, 4621 vect_epilogue); 4622 /* A broadcast of the max value. */ 4623 epilogue_cost += record_stmt_cost (cost_vec, 1, 4624 scalar_to_vec, stmt_info, 0, 4625 vect_epilogue); 4626 } 4627 else 4628 { 4629 epilogue_cost += record_stmt_cost (cost_vec, 1, vector_stmt, 4630 stmt_info, 0, vect_epilogue); 4631 epilogue_cost += record_stmt_cost (cost_vec, 1, 4632 vec_to_scalar, stmt_info, 0, 4633 vect_epilogue); 4634 } 4635 } 4636 else if (reduction_type == COND_REDUCTION) 4637 { 4638 unsigned estimated_nunits = vect_nunits_for_cost (vectype); 4639 /* Extraction of scalar elements. */ 4640 epilogue_cost += record_stmt_cost (cost_vec, 4641 2 * estimated_nunits, 4642 vec_to_scalar, stmt_info, 0, 4643 vect_epilogue); 4644 /* Scalar max reductions via COND_EXPR / MAX_EXPR. */ 4645 epilogue_cost += record_stmt_cost (cost_vec, 4646 2 * estimated_nunits - 3, 4647 scalar_stmt, stmt_info, 0, 4648 vect_epilogue); 4649 } 4650 else if (reduction_type == EXTRACT_LAST_REDUCTION 4651 || reduction_type == FOLD_LEFT_REDUCTION) 4652 /* No extra instructions need in the epilogue. */ 4653 ; 4654 else 4655 { 4656 int vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype)); 4657 tree bitsize = TYPE_SIZE (op.type); 4658 int element_bitsize = tree_to_uhwi (bitsize); 4659 int nelements = vec_size_in_bits / element_bitsize; 4660 4661 if (op.code == COND_EXPR) 4662 op.code = MAX_EXPR; 4663 4664 /* We have a whole vector shift available. */ 4665 if (VECTOR_MODE_P (mode) 4666 && directly_supported_p (op.code, vectype) 4667 && have_whole_vector_shift (mode)) 4668 { 4669 /* Final reduction via vector shifts and the reduction operator. 4670 Also requires scalar extract. */ 4671 epilogue_cost += record_stmt_cost (cost_vec, 4672 exact_log2 (nelements) * 2, 4673 vector_stmt, stmt_info, 0, 4674 vect_epilogue); 4675 epilogue_cost += record_stmt_cost (cost_vec, 1, 4676 vec_to_scalar, stmt_info, 0, 4677 vect_epilogue); 4678 } 4679 else 4680 /* Use extracts and reduction op for final reduction. For N 4681 elements, we have N extracts and N-1 reduction ops. */ 4682 epilogue_cost += record_stmt_cost (cost_vec, 4683 nelements + nelements - 1, 4684 vector_stmt, stmt_info, 0, 4685 vect_epilogue); 4686 } 4687 } 4688 4689 if (dump_enabled_p ()) 4690 dump_printf (MSG_NOTE, 4691 "vect_model_reduction_cost: inside_cost = %d, " 4692 "prologue_cost = %d, epilogue_cost = %d .\n", inside_cost, 4693 prologue_cost, epilogue_cost); 4694 } 4695 4696 /* SEQ is a sequence of instructions that initialize the reduction 4697 described by REDUC_INFO. Emit them in the appropriate place. */ 4698 4699 static void 4700 vect_emit_reduction_init_stmts (loop_vec_info loop_vinfo, 4701 stmt_vec_info reduc_info, gimple *seq) 4702 { 4703 if (reduc_info->reused_accumulator) 4704 { 4705 /* When reusing an accumulator from the main loop, we only need 4706 initialization instructions if the main loop can be skipped. 4707 In that case, emit the initialization instructions at the end 4708 of the guard block that does the skip. */ 4709 edge skip_edge = loop_vinfo->skip_main_loop_edge; 4710 gcc_assert (skip_edge); 4711 gimple_stmt_iterator gsi = gsi_last_bb (skip_edge->src); 4712 gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); 4713 } 4714 else 4715 { 4716 /* The normal case: emit the initialization instructions on the 4717 preheader edge. */ 4718 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 4719 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), seq); 4720 } 4721 } 4722 4723 /* Function get_initial_def_for_reduction 4724 4725 Input: 4726 REDUC_INFO - the info_for_reduction 4727 INIT_VAL - the initial value of the reduction variable 4728 NEUTRAL_OP - a value that has no effect on the reduction, as per 4729 neutral_op_for_reduction 4730 4731 Output: 4732 Return a vector variable, initialized according to the operation that 4733 STMT_VINFO performs. This vector will be used as the initial value 4734 of the vector of partial results. 4735 4736 The value we need is a vector in which element 0 has value INIT_VAL 4737 and every other element has value NEUTRAL_OP. */ 4738 4739 static tree 4740 get_initial_def_for_reduction (loop_vec_info loop_vinfo, 4741 stmt_vec_info reduc_info, 4742 tree init_val, tree neutral_op) 4743 { 4744 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 4745 tree scalar_type = TREE_TYPE (init_val); 4746 tree vectype = get_vectype_for_scalar_type (loop_vinfo, scalar_type); 4747 tree init_def; 4748 gimple_seq stmts = NULL; 4749 4750 gcc_assert (vectype); 4751 4752 gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type) 4753 || SCALAR_FLOAT_TYPE_P (scalar_type)); 4754 4755 gcc_assert (nested_in_vect_loop_p (loop, reduc_info) 4756 || loop == (gimple_bb (reduc_info->stmt))->loop_father); 4757 4758 if (operand_equal_p (init_val, neutral_op)) 4759 { 4760 /* If both elements are equal then the vector described above is 4761 just a splat. */ 4762 neutral_op = gimple_convert (&stmts, TREE_TYPE (vectype), neutral_op); 4763 init_def = gimple_build_vector_from_val (&stmts, vectype, neutral_op); 4764 } 4765 else 4766 { 4767 neutral_op = gimple_convert (&stmts, TREE_TYPE (vectype), neutral_op); 4768 init_val = gimple_convert (&stmts, TREE_TYPE (vectype), init_val); 4769 if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ()) 4770 { 4771 /* Construct a splat of NEUTRAL_OP and insert INIT_VAL into 4772 element 0. */ 4773 init_def = gimple_build_vector_from_val (&stmts, vectype, 4774 neutral_op); 4775 init_def = gimple_build (&stmts, CFN_VEC_SHL_INSERT, 4776 vectype, init_def, init_val); 4777 } 4778 else 4779 { 4780 /* Build {INIT_VAL, NEUTRAL_OP, NEUTRAL_OP, ...}. */ 4781 tree_vector_builder elts (vectype, 1, 2); 4782 elts.quick_push (init_val); 4783 elts.quick_push (neutral_op); 4784 init_def = gimple_build_vector (&stmts, &elts); 4785 } 4786 } 4787 4788 if (stmts) 4789 vect_emit_reduction_init_stmts (loop_vinfo, reduc_info, stmts); 4790 return init_def; 4791 } 4792 4793 /* Get at the initial defs for the reduction PHIs for REDUC_INFO, 4794 which performs a reduction involving GROUP_SIZE scalar statements. 4795 NUMBER_OF_VECTORS is the number of vector defs to create. If NEUTRAL_OP 4796 is nonnull, introducing extra elements of that value will not change the 4797 result. */ 4798 4799 static void 4800 get_initial_defs_for_reduction (loop_vec_info loop_vinfo, 4801 stmt_vec_info reduc_info, 4802 vec<tree> *vec_oprnds, 4803 unsigned int number_of_vectors, 4804 unsigned int group_size, tree neutral_op) 4805 { 4806 vec<tree> &initial_values = reduc_info->reduc_initial_values; 4807 unsigned HOST_WIDE_INT nunits; 4808 unsigned j, number_of_places_left_in_vector; 4809 tree vector_type = STMT_VINFO_VECTYPE (reduc_info); 4810 unsigned int i; 4811 4812 gcc_assert (group_size == initial_values.length () || neutral_op); 4813 4814 /* NUMBER_OF_COPIES is the number of times we need to use the same values in 4815 created vectors. It is greater than 1 if unrolling is performed. 4816 4817 For example, we have two scalar operands, s1 and s2 (e.g., group of 4818 strided accesses of size two), while NUNITS is four (i.e., four scalars 4819 of this type can be packed in a vector). The output vector will contain 4820 two copies of each scalar operand: {s1, s2, s1, s2}. (NUMBER_OF_COPIES 4821 will be 2). 4822 4823 If REDUC_GROUP_SIZE > NUNITS, the scalars will be split into several 4824 vectors containing the operands. 4825 4826 For example, NUNITS is four as before, and the group size is 8 4827 (s1, s2, ..., s8). We will create two vectors {s1, s2, s3, s4} and 4828 {s5, s6, s7, s8}. */ 4829 4830 if (!TYPE_VECTOR_SUBPARTS (vector_type).is_constant (&nunits)) 4831 nunits = group_size; 4832 4833 number_of_places_left_in_vector = nunits; 4834 bool constant_p = true; 4835 tree_vector_builder elts (vector_type, nunits, 1); 4836 elts.quick_grow (nunits); 4837 gimple_seq ctor_seq = NULL; 4838 for (j = 0; j < nunits * number_of_vectors; ++j) 4839 { 4840 tree op; 4841 i = j % group_size; 4842 4843 /* Get the def before the loop. In reduction chain we have only 4844 one initial value. Else we have as many as PHIs in the group. */ 4845 if (i >= initial_values.length () || (j > i && neutral_op)) 4846 op = neutral_op; 4847 else 4848 op = initial_values[i]; 4849 4850 /* Create 'vect_ = {op0,op1,...,opn}'. */ 4851 number_of_places_left_in_vector--; 4852 elts[nunits - number_of_places_left_in_vector - 1] = op; 4853 if (!CONSTANT_CLASS_P (op)) 4854 constant_p = false; 4855 4856 if (number_of_places_left_in_vector == 0) 4857 { 4858 tree init; 4859 if (constant_p && !neutral_op 4860 ? multiple_p (TYPE_VECTOR_SUBPARTS (vector_type), nunits) 4861 : known_eq (TYPE_VECTOR_SUBPARTS (vector_type), nunits)) 4862 /* Build the vector directly from ELTS. */ 4863 init = gimple_build_vector (&ctor_seq, &elts); 4864 else if (neutral_op) 4865 { 4866 /* Build a vector of the neutral value and shift the 4867 other elements into place. */ 4868 init = gimple_build_vector_from_val (&ctor_seq, vector_type, 4869 neutral_op); 4870 int k = nunits; 4871 while (k > 0 && elts[k - 1] == neutral_op) 4872 k -= 1; 4873 while (k > 0) 4874 { 4875 k -= 1; 4876 init = gimple_build (&ctor_seq, CFN_VEC_SHL_INSERT, 4877 vector_type, init, elts[k]); 4878 } 4879 } 4880 else 4881 { 4882 /* First time round, duplicate ELTS to fill the 4883 required number of vectors. */ 4884 duplicate_and_interleave (loop_vinfo, &ctor_seq, vector_type, 4885 elts, number_of_vectors, *vec_oprnds); 4886 break; 4887 } 4888 vec_oprnds->quick_push (init); 4889 4890 number_of_places_left_in_vector = nunits; 4891 elts.new_vector (vector_type, nunits, 1); 4892 elts.quick_grow (nunits); 4893 constant_p = true; 4894 } 4895 } 4896 if (ctor_seq != NULL) 4897 vect_emit_reduction_init_stmts (loop_vinfo, reduc_info, ctor_seq); 4898 } 4899 4900 /* For a statement STMT_INFO taking part in a reduction operation return 4901 the stmt_vec_info the meta information is stored on. */ 4902 4903 stmt_vec_info 4904 info_for_reduction (vec_info *vinfo, stmt_vec_info stmt_info) 4905 { 4906 stmt_info = vect_orig_stmt (stmt_info); 4907 gcc_assert (STMT_VINFO_REDUC_DEF (stmt_info)); 4908 if (!is_a <gphi *> (stmt_info->stmt) 4909 || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) 4910 stmt_info = STMT_VINFO_REDUC_DEF (stmt_info); 4911 gphi *phi = as_a <gphi *> (stmt_info->stmt); 4912 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def) 4913 { 4914 if (gimple_phi_num_args (phi) == 1) 4915 stmt_info = STMT_VINFO_REDUC_DEF (stmt_info); 4916 } 4917 else if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle) 4918 { 4919 stmt_vec_info info = vinfo->lookup_def (vect_phi_initial_value (phi)); 4920 if (info && STMT_VINFO_DEF_TYPE (info) == vect_double_reduction_def) 4921 stmt_info = info; 4922 } 4923 return stmt_info; 4924 } 4925 4926 /* See if LOOP_VINFO is an epilogue loop whose main loop had a reduction that 4927 REDUC_INFO can build on. Adjust REDUC_INFO and return true if so, otherwise 4928 return false. */ 4929 4930 static bool 4931 vect_find_reusable_accumulator (loop_vec_info loop_vinfo, 4932 stmt_vec_info reduc_info) 4933 { 4934 loop_vec_info main_loop_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); 4935 if (!main_loop_vinfo) 4936 return false; 4937 4938 if (STMT_VINFO_REDUC_TYPE (reduc_info) != TREE_CODE_REDUCTION) 4939 return false; 4940 4941 unsigned int num_phis = reduc_info->reduc_initial_values.length (); 4942 auto_vec<tree, 16> main_loop_results (num_phis); 4943 auto_vec<tree, 16> initial_values (num_phis); 4944 if (edge main_loop_edge = loop_vinfo->main_loop_edge) 4945 { 4946 /* The epilogue loop can be entered either from the main loop or 4947 from an earlier guard block. */ 4948 edge skip_edge = loop_vinfo->skip_main_loop_edge; 4949 for (tree incoming_value : reduc_info->reduc_initial_values) 4950 { 4951 /* Look for: 4952 4953 INCOMING_VALUE = phi<MAIN_LOOP_RESULT(main loop), 4954 INITIAL_VALUE(guard block)>. */ 4955 gcc_assert (TREE_CODE (incoming_value) == SSA_NAME); 4956 4957 gphi *phi = as_a <gphi *> (SSA_NAME_DEF_STMT (incoming_value)); 4958 gcc_assert (gimple_bb (phi) == main_loop_edge->dest); 4959 4960 tree from_main_loop = PHI_ARG_DEF_FROM_EDGE (phi, main_loop_edge); 4961 tree from_skip = PHI_ARG_DEF_FROM_EDGE (phi, skip_edge); 4962 4963 main_loop_results.quick_push (from_main_loop); 4964 initial_values.quick_push (from_skip); 4965 } 4966 } 4967 else 4968 /* The main loop dominates the epilogue loop. */ 4969 main_loop_results.splice (reduc_info->reduc_initial_values); 4970 4971 /* See if the main loop has the kind of accumulator we need. */ 4972 vect_reusable_accumulator *accumulator 4973 = main_loop_vinfo->reusable_accumulators.get (main_loop_results[0]); 4974 if (!accumulator 4975 || num_phis != accumulator->reduc_info->reduc_scalar_results.length () 4976 || !std::equal (main_loop_results.begin (), main_loop_results.end (), 4977 accumulator->reduc_info->reduc_scalar_results.begin ())) 4978 return false; 4979 4980 /* Handle the case where we can reduce wider vectors to narrower ones. */ 4981 tree vectype = STMT_VINFO_VECTYPE (reduc_info); 4982 tree old_vectype = TREE_TYPE (accumulator->reduc_input); 4983 unsigned HOST_WIDE_INT m; 4984 if (!constant_multiple_p (TYPE_VECTOR_SUBPARTS (old_vectype), 4985 TYPE_VECTOR_SUBPARTS (vectype), &m)) 4986 return false; 4987 /* Check the intermediate vector types and operations are available. */ 4988 tree prev_vectype = old_vectype; 4989 poly_uint64 intermediate_nunits = TYPE_VECTOR_SUBPARTS (old_vectype); 4990 while (known_gt (intermediate_nunits, TYPE_VECTOR_SUBPARTS (vectype))) 4991 { 4992 intermediate_nunits = exact_div (intermediate_nunits, 2); 4993 tree intermediate_vectype = get_related_vectype_for_scalar_type 4994 (TYPE_MODE (vectype), TREE_TYPE (vectype), intermediate_nunits); 4995 if (!intermediate_vectype 4996 || !directly_supported_p (STMT_VINFO_REDUC_CODE (reduc_info), 4997 intermediate_vectype) 4998 || !can_vec_extract (TYPE_MODE (prev_vectype), 4999 TYPE_MODE (intermediate_vectype))) 5000 return false; 5001 prev_vectype = intermediate_vectype; 5002 } 5003 5004 /* Non-SLP reductions might apply an adjustment after the reduction 5005 operation, in order to simplify the initialization of the accumulator. 5006 If the epilogue loop carries on from where the main loop left off, 5007 it should apply the same adjustment to the final reduction result. 5008 5009 If the epilogue loop can also be entered directly (rather than via 5010 the main loop), we need to be able to handle that case in the same way, 5011 with the same adjustment. (In principle we could add a PHI node 5012 to select the correct adjustment, but in practice that shouldn't be 5013 necessary.) */ 5014 tree main_adjustment 5015 = STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (accumulator->reduc_info); 5016 if (loop_vinfo->main_loop_edge && main_adjustment) 5017 { 5018 gcc_assert (num_phis == 1); 5019 tree initial_value = initial_values[0]; 5020 /* Check that we can use INITIAL_VALUE as the adjustment and 5021 initialize the accumulator with a neutral value instead. */ 5022 if (!operand_equal_p (initial_value, main_adjustment)) 5023 return false; 5024 code_helper code = STMT_VINFO_REDUC_CODE (reduc_info); 5025 initial_values[0] = neutral_op_for_reduction (TREE_TYPE (initial_value), 5026 code, initial_value); 5027 } 5028 STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (reduc_info) = main_adjustment; 5029 reduc_info->reduc_initial_values.truncate (0); 5030 reduc_info->reduc_initial_values.splice (initial_values); 5031 reduc_info->reused_accumulator = accumulator; 5032 return true; 5033 } 5034 5035 /* Reduce the vector VEC_DEF down to VECTYPE with reduction operation 5036 CODE emitting stmts before GSI. Returns a vector def of VECTYPE. */ 5037 5038 static tree 5039 vect_create_partial_epilog (tree vec_def, tree vectype, code_helper code, 5040 gimple_seq *seq) 5041 { 5042 unsigned nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec_def)).to_constant (); 5043 unsigned nunits1 = TYPE_VECTOR_SUBPARTS (vectype).to_constant (); 5044 tree stype = TREE_TYPE (vectype); 5045 tree new_temp = vec_def; 5046 while (nunits > nunits1) 5047 { 5048 nunits /= 2; 5049 tree vectype1 = get_related_vectype_for_scalar_type (TYPE_MODE (vectype), 5050 stype, nunits); 5051 unsigned int bitsize = tree_to_uhwi (TYPE_SIZE (vectype1)); 5052 5053 /* The target has to make sure we support lowpart/highpart 5054 extraction, either via direct vector extract or through 5055 an integer mode punning. */ 5056 tree dst1, dst2; 5057 gimple *epilog_stmt; 5058 if (convert_optab_handler (vec_extract_optab, 5059 TYPE_MODE (TREE_TYPE (new_temp)), 5060 TYPE_MODE (vectype1)) 5061 != CODE_FOR_nothing) 5062 { 5063 /* Extract sub-vectors directly once vec_extract becomes 5064 a conversion optab. */ 5065 dst1 = make_ssa_name (vectype1); 5066 epilog_stmt 5067 = gimple_build_assign (dst1, BIT_FIELD_REF, 5068 build3 (BIT_FIELD_REF, vectype1, 5069 new_temp, TYPE_SIZE (vectype1), 5070 bitsize_int (0))); 5071 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5072 dst2 = make_ssa_name (vectype1); 5073 epilog_stmt 5074 = gimple_build_assign (dst2, BIT_FIELD_REF, 5075 build3 (BIT_FIELD_REF, vectype1, 5076 new_temp, TYPE_SIZE (vectype1), 5077 bitsize_int (bitsize))); 5078 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5079 } 5080 else 5081 { 5082 /* Extract via punning to appropriately sized integer mode 5083 vector. */ 5084 tree eltype = build_nonstandard_integer_type (bitsize, 1); 5085 tree etype = build_vector_type (eltype, 2); 5086 gcc_assert (convert_optab_handler (vec_extract_optab, 5087 TYPE_MODE (etype), 5088 TYPE_MODE (eltype)) 5089 != CODE_FOR_nothing); 5090 tree tem = make_ssa_name (etype); 5091 epilog_stmt = gimple_build_assign (tem, VIEW_CONVERT_EXPR, 5092 build1 (VIEW_CONVERT_EXPR, 5093 etype, new_temp)); 5094 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5095 new_temp = tem; 5096 tem = make_ssa_name (eltype); 5097 epilog_stmt 5098 = gimple_build_assign (tem, BIT_FIELD_REF, 5099 build3 (BIT_FIELD_REF, eltype, 5100 new_temp, TYPE_SIZE (eltype), 5101 bitsize_int (0))); 5102 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5103 dst1 = make_ssa_name (vectype1); 5104 epilog_stmt = gimple_build_assign (dst1, VIEW_CONVERT_EXPR, 5105 build1 (VIEW_CONVERT_EXPR, 5106 vectype1, tem)); 5107 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5108 tem = make_ssa_name (eltype); 5109 epilog_stmt 5110 = gimple_build_assign (tem, BIT_FIELD_REF, 5111 build3 (BIT_FIELD_REF, eltype, 5112 new_temp, TYPE_SIZE (eltype), 5113 bitsize_int (bitsize))); 5114 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5115 dst2 = make_ssa_name (vectype1); 5116 epilog_stmt = gimple_build_assign (dst2, VIEW_CONVERT_EXPR, 5117 build1 (VIEW_CONVERT_EXPR, 5118 vectype1, tem)); 5119 gimple_seq_add_stmt_without_update (seq, epilog_stmt); 5120 } 5121 5122 new_temp = gimple_build (seq, code, vectype1, dst1, dst2); 5123 } 5124 5125 return new_temp; 5126 } 5127 5128 /* Function vect_create_epilog_for_reduction 5129 5130 Create code at the loop-epilog to finalize the result of a reduction 5131 computation. 5132 5133 STMT_INFO is the scalar reduction stmt that is being vectorized. 5134 SLP_NODE is an SLP node containing a group of reduction statements. The 5135 first one in this group is STMT_INFO. 5136 SLP_NODE_INSTANCE is the SLP node instance containing SLP_NODE 5137 REDUC_INDEX says which rhs operand of the STMT_INFO is the reduction phi 5138 (counting from 0) 5139 5140 This function: 5141 1. Completes the reduction def-use cycles. 5142 2. "Reduces" each vector of partial results VECT_DEFS into a single result, 5143 by calling the function specified by REDUC_FN if available, or by 5144 other means (whole-vector shifts or a scalar loop). 5145 The function also creates a new phi node at the loop exit to preserve 5146 loop-closed form, as illustrated below. 5147 5148 The flow at the entry to this function: 5149 5150 loop: 5151 vec_def = phi <vec_init, null> # REDUCTION_PHI 5152 VECT_DEF = vector_stmt # vectorized form of STMT_INFO 5153 s_loop = scalar_stmt # (scalar) STMT_INFO 5154 loop_exit: 5155 s_out0 = phi <s_loop> # (scalar) EXIT_PHI 5156 use <s_out0> 5157 use <s_out0> 5158 5159 The above is transformed by this function into: 5160 5161 loop: 5162 vec_def = phi <vec_init, VECT_DEF> # REDUCTION_PHI 5163 VECT_DEF = vector_stmt # vectorized form of STMT_INFO 5164 s_loop = scalar_stmt # (scalar) STMT_INFO 5165 loop_exit: 5166 s_out0 = phi <s_loop> # (scalar) EXIT_PHI 5167 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI 5168 v_out2 = reduce <v_out1> 5169 s_out3 = extract_field <v_out2, 0> 5170 s_out4 = adjust_result <s_out3> 5171 use <s_out4> 5172 use <s_out4> 5173 */ 5174 5175 static void 5176 vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, 5177 stmt_vec_info stmt_info, 5178 slp_tree slp_node, 5179 slp_instance slp_node_instance) 5180 { 5181 stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); 5182 gcc_assert (reduc_info->is_reduc_info); 5183 /* For double reductions we need to get at the inner loop reduction 5184 stmt which has the meta info attached. Our stmt_info is that of the 5185 loop-closed PHI of the inner loop which we remember as 5186 def for the reduction PHI generation. */ 5187 bool double_reduc = false; 5188 stmt_vec_info rdef_info = stmt_info; 5189 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def) 5190 { 5191 gcc_assert (!slp_node); 5192 double_reduc = true; 5193 stmt_info = loop_vinfo->lookup_def (gimple_phi_arg_def 5194 (stmt_info->stmt, 0)); 5195 stmt_info = vect_stmt_to_vectorize (stmt_info); 5196 } 5197 gphi *reduc_def_stmt 5198 = as_a <gphi *> (STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info))->stmt); 5199 code_helper code = STMT_VINFO_REDUC_CODE (reduc_info); 5200 internal_fn reduc_fn = STMT_VINFO_REDUC_FN (reduc_info); 5201 tree vectype; 5202 machine_mode mode; 5203 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *outer_loop = NULL; 5204 basic_block exit_bb; 5205 tree scalar_dest; 5206 tree scalar_type; 5207 gimple *new_phi = NULL, *phi; 5208 gimple_stmt_iterator exit_gsi; 5209 tree new_temp = NULL_TREE, new_name, new_scalar_dest; 5210 gimple *epilog_stmt = NULL; 5211 gimple *exit_phi; 5212 tree bitsize; 5213 tree def; 5214 tree orig_name, scalar_result; 5215 imm_use_iterator imm_iter, phi_imm_iter; 5216 use_operand_p use_p, phi_use_p; 5217 gimple *use_stmt; 5218 auto_vec<tree> reduc_inputs; 5219 int j, i; 5220 vec<tree> &scalar_results = reduc_info->reduc_scalar_results; 5221 unsigned int group_size = 1, k; 5222 auto_vec<gimple *> phis; 5223 /* SLP reduction without reduction chain, e.g., 5224 # a1 = phi <a2, a0> 5225 # b1 = phi <b2, b0> 5226 a2 = operation (a1) 5227 b2 = operation (b1) */ 5228 bool slp_reduc = (slp_node && !REDUC_GROUP_FIRST_ELEMENT (stmt_info)); 5229 bool direct_slp_reduc; 5230 tree induction_index = NULL_TREE; 5231 5232 if (slp_node) 5233 group_size = SLP_TREE_LANES (slp_node); 5234 5235 if (nested_in_vect_loop_p (loop, stmt_info)) 5236 { 5237 outer_loop = loop; 5238 loop = loop->inner; 5239 gcc_assert (!slp_node && double_reduc); 5240 } 5241 5242 vectype = STMT_VINFO_REDUC_VECTYPE (reduc_info); 5243 gcc_assert (vectype); 5244 mode = TYPE_MODE (vectype); 5245 5246 tree induc_val = NULL_TREE; 5247 tree adjustment_def = NULL; 5248 if (slp_node) 5249 ; 5250 else 5251 { 5252 /* Optimize: for induction condition reduction, if we can't use zero 5253 for induc_val, use initial_def. */ 5254 if (STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION) 5255 induc_val = STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info); 5256 else if (double_reduc) 5257 ; 5258 else 5259 adjustment_def = STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (reduc_info); 5260 } 5261 5262 stmt_vec_info single_live_out_stmt[] = { stmt_info }; 5263 array_slice<const stmt_vec_info> live_out_stmts = single_live_out_stmt; 5264 if (slp_reduc) 5265 /* All statements produce live-out values. */ 5266 live_out_stmts = SLP_TREE_SCALAR_STMTS (slp_node); 5267 else if (slp_node) 5268 { 5269 /* The last statement in the reduction chain produces the live-out 5270 value. Note SLP optimization can shuffle scalar stmts to 5271 optimize permutations so we have to search for the last stmt. */ 5272 for (k = 0; k < group_size; ++k) 5273 if (!REDUC_GROUP_NEXT_ELEMENT (SLP_TREE_SCALAR_STMTS (slp_node)[k])) 5274 { 5275 single_live_out_stmt[0] = SLP_TREE_SCALAR_STMTS (slp_node)[k]; 5276 break; 5277 } 5278 } 5279 5280 unsigned vec_num; 5281 int ncopies; 5282 if (slp_node) 5283 { 5284 vec_num = SLP_TREE_VEC_STMTS (slp_node_instance->reduc_phis).length (); 5285 ncopies = 1; 5286 } 5287 else 5288 { 5289 stmt_vec_info reduc_info = loop_vinfo->lookup_stmt (reduc_def_stmt); 5290 vec_num = 1; 5291 ncopies = STMT_VINFO_VEC_STMTS (reduc_info).length (); 5292 } 5293 5294 /* For cond reductions we want to create a new vector (INDEX_COND_EXPR) 5295 which is updated with the current index of the loop for every match of 5296 the original loop's cond_expr (VEC_STMT). This results in a vector 5297 containing the last time the condition passed for that vector lane. 5298 The first match will be a 1 to allow 0 to be used for non-matching 5299 indexes. If there are no matches at all then the vector will be all 5300 zeroes. 5301 5302 PR92772: This algorithm is broken for architectures that support 5303 masked vectors, but do not provide fold_extract_last. */ 5304 if (STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION) 5305 { 5306 auto_vec<std::pair<tree, bool>, 2> ccompares; 5307 stmt_vec_info cond_info = STMT_VINFO_REDUC_DEF (reduc_info); 5308 cond_info = vect_stmt_to_vectorize (cond_info); 5309 while (cond_info != reduc_info) 5310 { 5311 if (gimple_assign_rhs_code (cond_info->stmt) == COND_EXPR) 5312 { 5313 gimple *vec_stmt = STMT_VINFO_VEC_STMTS (cond_info)[0]; 5314 gcc_assert (gimple_assign_rhs_code (vec_stmt) == VEC_COND_EXPR); 5315 ccompares.safe_push 5316 (std::make_pair (unshare_expr (gimple_assign_rhs1 (vec_stmt)), 5317 STMT_VINFO_REDUC_IDX (cond_info) == 2)); 5318 } 5319 cond_info 5320 = loop_vinfo->lookup_def (gimple_op (cond_info->stmt, 5321 1 + STMT_VINFO_REDUC_IDX 5322 (cond_info))); 5323 cond_info = vect_stmt_to_vectorize (cond_info); 5324 } 5325 gcc_assert (ccompares.length () != 0); 5326 5327 tree indx_before_incr, indx_after_incr; 5328 poly_uint64 nunits_out = TYPE_VECTOR_SUBPARTS (vectype); 5329 int scalar_precision 5330 = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (vectype))); 5331 tree cr_index_scalar_type = make_unsigned_type (scalar_precision); 5332 tree cr_index_vector_type = get_related_vectype_for_scalar_type 5333 (TYPE_MODE (vectype), cr_index_scalar_type, 5334 TYPE_VECTOR_SUBPARTS (vectype)); 5335 5336 /* First we create a simple vector induction variable which starts 5337 with the values {1,2,3,...} (SERIES_VECT) and increments by the 5338 vector size (STEP). */ 5339 5340 /* Create a {1,2,3,...} vector. */ 5341 tree series_vect = build_index_vector (cr_index_vector_type, 1, 1); 5342 5343 /* Create a vector of the step value. */ 5344 tree step = build_int_cst (cr_index_scalar_type, nunits_out); 5345 tree vec_step = build_vector_from_val (cr_index_vector_type, step); 5346 5347 /* Create an induction variable. */ 5348 gimple_stmt_iterator incr_gsi; 5349 bool insert_after; 5350 standard_iv_increment_position (loop, &incr_gsi, &insert_after); 5351 create_iv (series_vect, vec_step, NULL_TREE, loop, &incr_gsi, 5352 insert_after, &indx_before_incr, &indx_after_incr); 5353 5354 /* Next create a new phi node vector (NEW_PHI_TREE) which starts 5355 filled with zeros (VEC_ZERO). */ 5356 5357 /* Create a vector of 0s. */ 5358 tree zero = build_zero_cst (cr_index_scalar_type); 5359 tree vec_zero = build_vector_from_val (cr_index_vector_type, zero); 5360 5361 /* Create a vector phi node. */ 5362 tree new_phi_tree = make_ssa_name (cr_index_vector_type); 5363 new_phi = create_phi_node (new_phi_tree, loop->header); 5364 add_phi_arg (as_a <gphi *> (new_phi), vec_zero, 5365 loop_preheader_edge (loop), UNKNOWN_LOCATION); 5366 5367 /* Now take the condition from the loops original cond_exprs 5368 and produce a new cond_exprs (INDEX_COND_EXPR) which for 5369 every match uses values from the induction variable 5370 (INDEX_BEFORE_INCR) otherwise uses values from the phi node 5371 (NEW_PHI_TREE). 5372 Finally, we update the phi (NEW_PHI_TREE) to take the value of 5373 the new cond_expr (INDEX_COND_EXPR). */ 5374 gimple_seq stmts = NULL; 5375 for (int i = ccompares.length () - 1; i != -1; --i) 5376 { 5377 tree ccompare = ccompares[i].first; 5378 if (ccompares[i].second) 5379 new_phi_tree = gimple_build (&stmts, VEC_COND_EXPR, 5380 cr_index_vector_type, 5381 ccompare, 5382 indx_before_incr, new_phi_tree); 5383 else 5384 new_phi_tree = gimple_build (&stmts, VEC_COND_EXPR, 5385 cr_index_vector_type, 5386 ccompare, 5387 new_phi_tree, indx_before_incr); 5388 } 5389 gsi_insert_seq_before (&incr_gsi, stmts, GSI_SAME_STMT); 5390 5391 /* Update the phi with the vec cond. */ 5392 induction_index = new_phi_tree; 5393 add_phi_arg (as_a <gphi *> (new_phi), induction_index, 5394 loop_latch_edge (loop), UNKNOWN_LOCATION); 5395 } 5396 5397 /* 2. Create epilog code. 5398 The reduction epilog code operates across the elements of the vector 5399 of partial results computed by the vectorized loop. 5400 The reduction epilog code consists of: 5401 5402 step 1: compute the scalar result in a vector (v_out2) 5403 step 2: extract the scalar result (s_out3) from the vector (v_out2) 5404 step 3: adjust the scalar result (s_out3) if needed. 5405 5406 Step 1 can be accomplished using one the following three schemes: 5407 (scheme 1) using reduc_fn, if available. 5408 (scheme 2) using whole-vector shifts, if available. 5409 (scheme 3) using a scalar loop. In this case steps 1+2 above are 5410 combined. 5411 5412 The overall epilog code looks like this: 5413 5414 s_out0 = phi <s_loop> # original EXIT_PHI 5415 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI 5416 v_out2 = reduce <v_out1> # step 1 5417 s_out3 = extract_field <v_out2, 0> # step 2 5418 s_out4 = adjust_result <s_out3> # step 3 5419 5420 (step 3 is optional, and steps 1 and 2 may be combined). 5421 Lastly, the uses of s_out0 are replaced by s_out4. */ 5422 5423 5424 /* 2.1 Create new loop-exit-phis to preserve loop-closed form: 5425 v_out1 = phi <VECT_DEF> 5426 Store them in NEW_PHIS. */ 5427 if (double_reduc) 5428 loop = outer_loop; 5429 exit_bb = single_exit (loop)->dest; 5430 exit_gsi = gsi_after_labels (exit_bb); 5431 reduc_inputs.create (slp_node ? vec_num : ncopies); 5432 for (unsigned i = 0; i < vec_num; i++) 5433 { 5434 gimple_seq stmts = NULL; 5435 if (slp_node) 5436 def = vect_get_slp_vect_def (slp_node, i); 5437 else 5438 def = gimple_get_lhs (STMT_VINFO_VEC_STMTS (rdef_info)[0]); 5439 for (j = 0; j < ncopies; j++) 5440 { 5441 tree new_def = copy_ssa_name (def); 5442 phi = create_phi_node (new_def, exit_bb); 5443 if (j) 5444 def = gimple_get_lhs (STMT_VINFO_VEC_STMTS (rdef_info)[j]); 5445 SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def); 5446 new_def = gimple_convert (&stmts, vectype, new_def); 5447 reduc_inputs.quick_push (new_def); 5448 } 5449 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5450 } 5451 5452 /* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3 5453 (i.e. when reduc_fn is not available) and in the final adjustment 5454 code (if needed). Also get the original scalar reduction variable as 5455 defined in the loop. In case STMT is a "pattern-stmt" (i.e. - it 5456 represents a reduction pattern), the tree-code and scalar-def are 5457 taken from the original stmt that the pattern-stmt (STMT) replaces. 5458 Otherwise (it is a regular reduction) - the tree-code and scalar-def 5459 are taken from STMT. */ 5460 5461 stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info); 5462 if (orig_stmt_info != stmt_info) 5463 { 5464 /* Reduction pattern */ 5465 gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info)); 5466 gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info) == stmt_info); 5467 } 5468 5469 scalar_dest = gimple_get_lhs (orig_stmt_info->stmt); 5470 scalar_type = TREE_TYPE (scalar_dest); 5471 scalar_results.truncate (0); 5472 scalar_results.reserve_exact (group_size); 5473 new_scalar_dest = vect_create_destination_var (scalar_dest, NULL); 5474 bitsize = TYPE_SIZE (scalar_type); 5475 5476 /* True if we should implement SLP_REDUC using native reduction operations 5477 instead of scalar operations. */ 5478 direct_slp_reduc = (reduc_fn != IFN_LAST 5479 && slp_reduc 5480 && !TYPE_VECTOR_SUBPARTS (vectype).is_constant ()); 5481 5482 /* In case of reduction chain, e.g., 5483 # a1 = phi <a3, a0> 5484 a2 = operation (a1) 5485 a3 = operation (a2), 5486 5487 we may end up with more than one vector result. Here we reduce them 5488 to one vector. 5489 5490 The same is true if we couldn't use a single defuse cycle. */ 5491 if (REDUC_GROUP_FIRST_ELEMENT (stmt_info) 5492 || direct_slp_reduc 5493 || ncopies > 1) 5494 { 5495 gimple_seq stmts = NULL; 5496 tree single_input = reduc_inputs[0]; 5497 for (k = 1; k < reduc_inputs.length (); k++) 5498 single_input = gimple_build (&stmts, code, vectype, 5499 single_input, reduc_inputs[k]); 5500 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5501 5502 reduc_inputs.truncate (0); 5503 reduc_inputs.safe_push (single_input); 5504 } 5505 5506 tree orig_reduc_input = reduc_inputs[0]; 5507 5508 /* If this loop is an epilogue loop that can be skipped after the 5509 main loop, we can only share a reduction operation between the 5510 main loop and the epilogue if we put it at the target of the 5511 skip edge. 5512 5513 We can still reuse accumulators if this check fails. Doing so has 5514 the minor(?) benefit of making the epilogue loop's scalar result 5515 independent of the main loop's scalar result. */ 5516 bool unify_with_main_loop_p = false; 5517 if (reduc_info->reused_accumulator 5518 && loop_vinfo->skip_this_loop_edge 5519 && single_succ_p (exit_bb) 5520 && single_succ (exit_bb) == loop_vinfo->skip_this_loop_edge->dest) 5521 { 5522 unify_with_main_loop_p = true; 5523 5524 basic_block reduc_block = loop_vinfo->skip_this_loop_edge->dest; 5525 reduc_inputs[0] = make_ssa_name (vectype); 5526 gphi *new_phi = create_phi_node (reduc_inputs[0], reduc_block); 5527 add_phi_arg (new_phi, orig_reduc_input, single_succ_edge (exit_bb), 5528 UNKNOWN_LOCATION); 5529 add_phi_arg (new_phi, reduc_info->reused_accumulator->reduc_input, 5530 loop_vinfo->skip_this_loop_edge, UNKNOWN_LOCATION); 5531 exit_gsi = gsi_after_labels (reduc_block); 5532 } 5533 5534 /* Shouldn't be used beyond this point. */ 5535 exit_bb = nullptr; 5536 5537 if (STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION 5538 && reduc_fn != IFN_LAST) 5539 { 5540 /* For condition reductions, we have a vector (REDUC_INPUTS 0) containing 5541 various data values where the condition matched and another vector 5542 (INDUCTION_INDEX) containing all the indexes of those matches. We 5543 need to extract the last matching index (which will be the index with 5544 highest value) and use this to index into the data vector. 5545 For the case where there were no matches, the data vector will contain 5546 all default values and the index vector will be all zeros. */ 5547 5548 /* Get various versions of the type of the vector of indexes. */ 5549 tree index_vec_type = TREE_TYPE (induction_index); 5550 gcc_checking_assert (TYPE_UNSIGNED (index_vec_type)); 5551 tree index_scalar_type = TREE_TYPE (index_vec_type); 5552 tree index_vec_cmp_type = truth_type_for (index_vec_type); 5553 5554 /* Get an unsigned integer version of the type of the data vector. */ 5555 int scalar_precision 5556 = GET_MODE_PRECISION (SCALAR_TYPE_MODE (scalar_type)); 5557 tree scalar_type_unsigned = make_unsigned_type (scalar_precision); 5558 tree vectype_unsigned = get_same_sized_vectype (scalar_type_unsigned, 5559 vectype); 5560 5561 /* First we need to create a vector (ZERO_VEC) of zeros and another 5562 vector (MAX_INDEX_VEC) filled with the last matching index, which we 5563 can create using a MAX reduction and then expanding. 5564 In the case where the loop never made any matches, the max index will 5565 be zero. */ 5566 5567 /* Vector of {0, 0, 0,...}. */ 5568 tree zero_vec = build_zero_cst (vectype); 5569 5570 /* Find maximum value from the vector of found indexes. */ 5571 tree max_index = make_ssa_name (index_scalar_type); 5572 gcall *max_index_stmt = gimple_build_call_internal (IFN_REDUC_MAX, 5573 1, induction_index); 5574 gimple_call_set_lhs (max_index_stmt, max_index); 5575 gsi_insert_before (&exit_gsi, max_index_stmt, GSI_SAME_STMT); 5576 5577 /* Vector of {max_index, max_index, max_index,...}. */ 5578 tree max_index_vec = make_ssa_name (index_vec_type); 5579 tree max_index_vec_rhs = build_vector_from_val (index_vec_type, 5580 max_index); 5581 gimple *max_index_vec_stmt = gimple_build_assign (max_index_vec, 5582 max_index_vec_rhs); 5583 gsi_insert_before (&exit_gsi, max_index_vec_stmt, GSI_SAME_STMT); 5584 5585 /* Next we compare the new vector (MAX_INDEX_VEC) full of max indexes 5586 with the vector (INDUCTION_INDEX) of found indexes, choosing values 5587 from the data vector (REDUC_INPUTS 0) for matches, 0 (ZERO_VEC) 5588 otherwise. Only one value should match, resulting in a vector 5589 (VEC_COND) with one data value and the rest zeros. 5590 In the case where the loop never made any matches, every index will 5591 match, resulting in a vector with all data values (which will all be 5592 the default value). */ 5593 5594 /* Compare the max index vector to the vector of found indexes to find 5595 the position of the max value. */ 5596 tree vec_compare = make_ssa_name (index_vec_cmp_type); 5597 gimple *vec_compare_stmt = gimple_build_assign (vec_compare, EQ_EXPR, 5598 induction_index, 5599 max_index_vec); 5600 gsi_insert_before (&exit_gsi, vec_compare_stmt, GSI_SAME_STMT); 5601 5602 /* Use the compare to choose either values from the data vector or 5603 zero. */ 5604 tree vec_cond = make_ssa_name (vectype); 5605 gimple *vec_cond_stmt = gimple_build_assign (vec_cond, VEC_COND_EXPR, 5606 vec_compare, 5607 reduc_inputs[0], 5608 zero_vec); 5609 gsi_insert_before (&exit_gsi, vec_cond_stmt, GSI_SAME_STMT); 5610 5611 /* Finally we need to extract the data value from the vector (VEC_COND) 5612 into a scalar (MATCHED_DATA_REDUC). Logically we want to do a OR 5613 reduction, but because this doesn't exist, we can use a MAX reduction 5614 instead. The data value might be signed or a float so we need to cast 5615 it first. 5616 In the case where the loop never made any matches, the data values are 5617 all identical, and so will reduce down correctly. */ 5618 5619 /* Make the matched data values unsigned. */ 5620 tree vec_cond_cast = make_ssa_name (vectype_unsigned); 5621 tree vec_cond_cast_rhs = build1 (VIEW_CONVERT_EXPR, vectype_unsigned, 5622 vec_cond); 5623 gimple *vec_cond_cast_stmt = gimple_build_assign (vec_cond_cast, 5624 VIEW_CONVERT_EXPR, 5625 vec_cond_cast_rhs); 5626 gsi_insert_before (&exit_gsi, vec_cond_cast_stmt, GSI_SAME_STMT); 5627 5628 /* Reduce down to a scalar value. */ 5629 tree data_reduc = make_ssa_name (scalar_type_unsigned); 5630 gcall *data_reduc_stmt = gimple_build_call_internal (IFN_REDUC_MAX, 5631 1, vec_cond_cast); 5632 gimple_call_set_lhs (data_reduc_stmt, data_reduc); 5633 gsi_insert_before (&exit_gsi, data_reduc_stmt, GSI_SAME_STMT); 5634 5635 /* Convert the reduced value back to the result type and set as the 5636 result. */ 5637 gimple_seq stmts = NULL; 5638 new_temp = gimple_build (&stmts, VIEW_CONVERT_EXPR, scalar_type, 5639 data_reduc); 5640 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5641 scalar_results.safe_push (new_temp); 5642 } 5643 else if (STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION 5644 && reduc_fn == IFN_LAST) 5645 { 5646 /* Condition reduction without supported IFN_REDUC_MAX. Generate 5647 idx = 0; 5648 idx_val = induction_index[0]; 5649 val = data_reduc[0]; 5650 for (idx = 0, val = init, i = 0; i < nelts; ++i) 5651 if (induction_index[i] > idx_val) 5652 val = data_reduc[i], idx_val = induction_index[i]; 5653 return val; */ 5654 5655 tree data_eltype = TREE_TYPE (vectype); 5656 tree idx_eltype = TREE_TYPE (TREE_TYPE (induction_index)); 5657 unsigned HOST_WIDE_INT el_size = tree_to_uhwi (TYPE_SIZE (idx_eltype)); 5658 poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (induction_index)); 5659 /* Enforced by vectorizable_reduction, which ensures we have target 5660 support before allowing a conditional reduction on variable-length 5661 vectors. */ 5662 unsigned HOST_WIDE_INT v_size = el_size * nunits.to_constant (); 5663 tree idx_val = NULL_TREE, val = NULL_TREE; 5664 for (unsigned HOST_WIDE_INT off = 0; off < v_size; off += el_size) 5665 { 5666 tree old_idx_val = idx_val; 5667 tree old_val = val; 5668 idx_val = make_ssa_name (idx_eltype); 5669 epilog_stmt = gimple_build_assign (idx_val, BIT_FIELD_REF, 5670 build3 (BIT_FIELD_REF, idx_eltype, 5671 induction_index, 5672 bitsize_int (el_size), 5673 bitsize_int (off))); 5674 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5675 val = make_ssa_name (data_eltype); 5676 epilog_stmt = gimple_build_assign (val, BIT_FIELD_REF, 5677 build3 (BIT_FIELD_REF, 5678 data_eltype, 5679 reduc_inputs[0], 5680 bitsize_int (el_size), 5681 bitsize_int (off))); 5682 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5683 if (off != 0) 5684 { 5685 tree new_idx_val = idx_val; 5686 if (off != v_size - el_size) 5687 { 5688 new_idx_val = make_ssa_name (idx_eltype); 5689 epilog_stmt = gimple_build_assign (new_idx_val, 5690 MAX_EXPR, idx_val, 5691 old_idx_val); 5692 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5693 } 5694 tree new_val = make_ssa_name (data_eltype); 5695 epilog_stmt = gimple_build_assign (new_val, 5696 COND_EXPR, 5697 build2 (GT_EXPR, 5698 boolean_type_node, 5699 idx_val, 5700 old_idx_val), 5701 val, old_val); 5702 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5703 idx_val = new_idx_val; 5704 val = new_val; 5705 } 5706 } 5707 /* Convert the reduced value back to the result type and set as the 5708 result. */ 5709 gimple_seq stmts = NULL; 5710 val = gimple_convert (&stmts, scalar_type, val); 5711 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5712 scalar_results.safe_push (val); 5713 } 5714 5715 /* 2.3 Create the reduction code, using one of the three schemes described 5716 above. In SLP we simply need to extract all the elements from the 5717 vector (without reducing them), so we use scalar shifts. */ 5718 else if (reduc_fn != IFN_LAST && !slp_reduc) 5719 { 5720 tree tmp; 5721 tree vec_elem_type; 5722 5723 /* Case 1: Create: 5724 v_out2 = reduc_expr <v_out1> */ 5725 5726 if (dump_enabled_p ()) 5727 dump_printf_loc (MSG_NOTE, vect_location, 5728 "Reduce using direct vector reduction.\n"); 5729 5730 gimple_seq stmts = NULL; 5731 vec_elem_type = TREE_TYPE (vectype); 5732 new_temp = gimple_build (&stmts, as_combined_fn (reduc_fn), 5733 vec_elem_type, reduc_inputs[0]); 5734 new_temp = gimple_convert (&stmts, scalar_type, new_temp); 5735 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5736 5737 if ((STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION) 5738 && induc_val) 5739 { 5740 /* Earlier we set the initial value to be a vector if induc_val 5741 values. Check the result and if it is induc_val then replace 5742 with the original initial value, unless induc_val is 5743 the same as initial_def already. */ 5744 tree zcompare = build2 (EQ_EXPR, boolean_type_node, new_temp, 5745 induc_val); 5746 tree initial_def = reduc_info->reduc_initial_values[0]; 5747 5748 tmp = make_ssa_name (new_scalar_dest); 5749 epilog_stmt = gimple_build_assign (tmp, COND_EXPR, zcompare, 5750 initial_def, new_temp); 5751 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5752 new_temp = tmp; 5753 } 5754 5755 scalar_results.safe_push (new_temp); 5756 } 5757 else if (direct_slp_reduc) 5758 { 5759 /* Here we create one vector for each of the REDUC_GROUP_SIZE results, 5760 with the elements for other SLP statements replaced with the 5761 neutral value. We can then do a normal reduction on each vector. */ 5762 5763 /* Enforced by vectorizable_reduction. */ 5764 gcc_assert (reduc_inputs.length () == 1); 5765 gcc_assert (pow2p_hwi (group_size)); 5766 5767 gimple_seq seq = NULL; 5768 5769 /* Build a vector {0, 1, 2, ...}, with the same number of elements 5770 and the same element size as VECTYPE. */ 5771 tree index = build_index_vector (vectype, 0, 1); 5772 tree index_type = TREE_TYPE (index); 5773 tree index_elt_type = TREE_TYPE (index_type); 5774 tree mask_type = truth_type_for (index_type); 5775 5776 /* Create a vector that, for each element, identifies which of 5777 the REDUC_GROUP_SIZE results should use it. */ 5778 tree index_mask = build_int_cst (index_elt_type, group_size - 1); 5779 index = gimple_build (&seq, BIT_AND_EXPR, index_type, index, 5780 build_vector_from_val (index_type, index_mask)); 5781 5782 /* Get a neutral vector value. This is simply a splat of the neutral 5783 scalar value if we have one, otherwise the initial scalar value 5784 is itself a neutral value. */ 5785 tree vector_identity = NULL_TREE; 5786 tree neutral_op = NULL_TREE; 5787 if (slp_node) 5788 { 5789 tree initial_value = NULL_TREE; 5790 if (REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 5791 initial_value = reduc_info->reduc_initial_values[0]; 5792 neutral_op = neutral_op_for_reduction (TREE_TYPE (vectype), code, 5793 initial_value); 5794 } 5795 if (neutral_op) 5796 vector_identity = gimple_build_vector_from_val (&seq, vectype, 5797 neutral_op); 5798 for (unsigned int i = 0; i < group_size; ++i) 5799 { 5800 /* If there's no univeral neutral value, we can use the 5801 initial scalar value from the original PHI. This is used 5802 for MIN and MAX reduction, for example. */ 5803 if (!neutral_op) 5804 { 5805 tree scalar_value = reduc_info->reduc_initial_values[i]; 5806 scalar_value = gimple_convert (&seq, TREE_TYPE (vectype), 5807 scalar_value); 5808 vector_identity = gimple_build_vector_from_val (&seq, vectype, 5809 scalar_value); 5810 } 5811 5812 /* Calculate the equivalent of: 5813 5814 sel[j] = (index[j] == i); 5815 5816 which selects the elements of REDUC_INPUTS[0] that should 5817 be included in the result. */ 5818 tree compare_val = build_int_cst (index_elt_type, i); 5819 compare_val = build_vector_from_val (index_type, compare_val); 5820 tree sel = gimple_build (&seq, EQ_EXPR, mask_type, 5821 index, compare_val); 5822 5823 /* Calculate the equivalent of: 5824 5825 vec = seq ? reduc_inputs[0] : vector_identity; 5826 5827 VEC is now suitable for a full vector reduction. */ 5828 tree vec = gimple_build (&seq, VEC_COND_EXPR, vectype, 5829 sel, reduc_inputs[0], vector_identity); 5830 5831 /* Do the reduction and convert it to the appropriate type. */ 5832 tree scalar = gimple_build (&seq, as_combined_fn (reduc_fn), 5833 TREE_TYPE (vectype), vec); 5834 scalar = gimple_convert (&seq, scalar_type, scalar); 5835 scalar_results.safe_push (scalar); 5836 } 5837 gsi_insert_seq_before (&exit_gsi, seq, GSI_SAME_STMT); 5838 } 5839 else 5840 { 5841 bool reduce_with_shift; 5842 tree vec_temp; 5843 5844 gcc_assert (slp_reduc || reduc_inputs.length () == 1); 5845 5846 /* See if the target wants to do the final (shift) reduction 5847 in a vector mode of smaller size and first reduce upper/lower 5848 halves against each other. */ 5849 enum machine_mode mode1 = mode; 5850 tree stype = TREE_TYPE (vectype); 5851 unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype).to_constant (); 5852 unsigned nunits1 = nunits; 5853 if ((mode1 = targetm.vectorize.split_reduction (mode)) != mode 5854 && reduc_inputs.length () == 1) 5855 { 5856 nunits1 = GET_MODE_NUNITS (mode1).to_constant (); 5857 /* For SLP reductions we have to make sure lanes match up, but 5858 since we're doing individual element final reduction reducing 5859 vector width here is even more important. 5860 ??? We can also separate lanes with permutes, for the common 5861 case of power-of-two group-size odd/even extracts would work. */ 5862 if (slp_reduc && nunits != nunits1) 5863 { 5864 nunits1 = least_common_multiple (nunits1, group_size); 5865 gcc_assert (exact_log2 (nunits1) != -1 && nunits1 <= nunits); 5866 } 5867 } 5868 if (!slp_reduc 5869 && (mode1 = targetm.vectorize.split_reduction (mode)) != mode) 5870 nunits1 = GET_MODE_NUNITS (mode1).to_constant (); 5871 5872 tree vectype1 = get_related_vectype_for_scalar_type (TYPE_MODE (vectype), 5873 stype, nunits1); 5874 reduce_with_shift = have_whole_vector_shift (mode1); 5875 if (!VECTOR_MODE_P (mode1) 5876 || !directly_supported_p (code, vectype1)) 5877 reduce_with_shift = false; 5878 5879 /* First reduce the vector to the desired vector size we should 5880 do shift reduction on by combining upper and lower halves. */ 5881 gimple_seq stmts = NULL; 5882 new_temp = vect_create_partial_epilog (reduc_inputs[0], vectype1, 5883 code, &stmts); 5884 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5885 reduc_inputs[0] = new_temp; 5886 5887 if (reduce_with_shift && !slp_reduc) 5888 { 5889 int element_bitsize = tree_to_uhwi (bitsize); 5890 /* Enforced by vectorizable_reduction, which disallows SLP reductions 5891 for variable-length vectors and also requires direct target support 5892 for loop reductions. */ 5893 int vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype1)); 5894 int nelements = vec_size_in_bits / element_bitsize; 5895 vec_perm_builder sel; 5896 vec_perm_indices indices; 5897 5898 int elt_offset; 5899 5900 tree zero_vec = build_zero_cst (vectype1); 5901 /* Case 2: Create: 5902 for (offset = nelements/2; offset >= 1; offset/=2) 5903 { 5904 Create: va' = vec_shift <va, offset> 5905 Create: va = vop <va, va'> 5906 } */ 5907 5908 tree rhs; 5909 5910 if (dump_enabled_p ()) 5911 dump_printf_loc (MSG_NOTE, vect_location, 5912 "Reduce using vector shifts\n"); 5913 5914 gimple_seq stmts = NULL; 5915 new_temp = gimple_convert (&stmts, vectype1, new_temp); 5916 for (elt_offset = nelements / 2; 5917 elt_offset >= 1; 5918 elt_offset /= 2) 5919 { 5920 calc_vec_perm_mask_for_shift (elt_offset, nelements, &sel); 5921 indices.new_vector (sel, 2, nelements); 5922 tree mask = vect_gen_perm_mask_any (vectype1, indices); 5923 new_name = gimple_build (&stmts, VEC_PERM_EXPR, vectype1, 5924 new_temp, zero_vec, mask); 5925 new_temp = gimple_build (&stmts, code, 5926 vectype1, new_name, new_temp); 5927 } 5928 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 5929 5930 /* 2.4 Extract the final scalar result. Create: 5931 s_out3 = extract_field <v_out2, bitpos> */ 5932 5933 if (dump_enabled_p ()) 5934 dump_printf_loc (MSG_NOTE, vect_location, 5935 "extract scalar result\n"); 5936 5937 rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, 5938 bitsize, bitsize_zero_node); 5939 epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); 5940 new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); 5941 gimple_assign_set_lhs (epilog_stmt, new_temp); 5942 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 5943 scalar_results.safe_push (new_temp); 5944 } 5945 else 5946 { 5947 /* Case 3: Create: 5948 s = extract_field <v_out2, 0> 5949 for (offset = element_size; 5950 offset < vector_size; 5951 offset += element_size;) 5952 { 5953 Create: s' = extract_field <v_out2, offset> 5954 Create: s = op <s, s'> // For non SLP cases 5955 } */ 5956 5957 if (dump_enabled_p ()) 5958 dump_printf_loc (MSG_NOTE, vect_location, 5959 "Reduce using scalar code.\n"); 5960 5961 int vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype1)); 5962 int element_bitsize = tree_to_uhwi (bitsize); 5963 tree compute_type = TREE_TYPE (vectype); 5964 gimple_seq stmts = NULL; 5965 FOR_EACH_VEC_ELT (reduc_inputs, i, vec_temp) 5966 { 5967 int bit_offset; 5968 new_temp = gimple_build (&stmts, BIT_FIELD_REF, compute_type, 5969 vec_temp, bitsize, bitsize_zero_node); 5970 5971 /* In SLP we don't need to apply reduction operation, so we just 5972 collect s' values in SCALAR_RESULTS. */ 5973 if (slp_reduc) 5974 scalar_results.safe_push (new_temp); 5975 5976 for (bit_offset = element_bitsize; 5977 bit_offset < vec_size_in_bits; 5978 bit_offset += element_bitsize) 5979 { 5980 tree bitpos = bitsize_int (bit_offset); 5981 new_name = gimple_build (&stmts, BIT_FIELD_REF, 5982 compute_type, vec_temp, 5983 bitsize, bitpos); 5984 if (slp_reduc) 5985 { 5986 /* In SLP we don't need to apply reduction operation, so 5987 we just collect s' values in SCALAR_RESULTS. */ 5988 new_temp = new_name; 5989 scalar_results.safe_push (new_name); 5990 } 5991 else 5992 new_temp = gimple_build (&stmts, code, compute_type, 5993 new_name, new_temp); 5994 } 5995 } 5996 5997 /* The only case where we need to reduce scalar results in SLP, is 5998 unrolling. If the size of SCALAR_RESULTS is greater than 5999 REDUC_GROUP_SIZE, we reduce them combining elements modulo 6000 REDUC_GROUP_SIZE. */ 6001 if (slp_reduc) 6002 { 6003 tree res, first_res, new_res; 6004 6005 /* Reduce multiple scalar results in case of SLP unrolling. */ 6006 for (j = group_size; scalar_results.iterate (j, &res); 6007 j++) 6008 { 6009 first_res = scalar_results[j % group_size]; 6010 new_res = gimple_build (&stmts, code, compute_type, 6011 first_res, res); 6012 scalar_results[j % group_size] = new_res; 6013 } 6014 scalar_results.truncate (group_size); 6015 for (k = 0; k < group_size; k++) 6016 scalar_results[k] = gimple_convert (&stmts, scalar_type, 6017 scalar_results[k]); 6018 } 6019 else 6020 { 6021 /* Not SLP - we have one scalar to keep in SCALAR_RESULTS. */ 6022 new_temp = gimple_convert (&stmts, scalar_type, new_temp); 6023 scalar_results.safe_push (new_temp); 6024 } 6025 6026 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 6027 } 6028 6029 if ((STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION) 6030 && induc_val) 6031 { 6032 /* Earlier we set the initial value to be a vector if induc_val 6033 values. Check the result and if it is induc_val then replace 6034 with the original initial value, unless induc_val is 6035 the same as initial_def already. */ 6036 tree zcompare = build2 (EQ_EXPR, boolean_type_node, new_temp, 6037 induc_val); 6038 tree initial_def = reduc_info->reduc_initial_values[0]; 6039 6040 tree tmp = make_ssa_name (new_scalar_dest); 6041 epilog_stmt = gimple_build_assign (tmp, COND_EXPR, zcompare, 6042 initial_def, new_temp); 6043 gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); 6044 scalar_results[0] = tmp; 6045 } 6046 } 6047 6048 /* 2.5 Adjust the final result by the initial value of the reduction 6049 variable. (When such adjustment is not needed, then 6050 'adjustment_def' is zero). For example, if code is PLUS we create: 6051 new_temp = loop_exit_def + adjustment_def */ 6052 6053 if (adjustment_def) 6054 { 6055 gcc_assert (!slp_reduc); 6056 gimple_seq stmts = NULL; 6057 if (double_reduc) 6058 { 6059 gcc_assert (VECTOR_TYPE_P (TREE_TYPE (adjustment_def))); 6060 adjustment_def = gimple_convert (&stmts, vectype, adjustment_def); 6061 new_temp = gimple_build (&stmts, code, vectype, 6062 reduc_inputs[0], adjustment_def); 6063 } 6064 else 6065 { 6066 new_temp = scalar_results[0]; 6067 gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) != VECTOR_TYPE); 6068 adjustment_def = gimple_convert (&stmts, TREE_TYPE (vectype), 6069 adjustment_def); 6070 new_temp = gimple_convert (&stmts, TREE_TYPE (vectype), new_temp); 6071 new_temp = gimple_build (&stmts, code, TREE_TYPE (vectype), 6072 new_temp, adjustment_def); 6073 new_temp = gimple_convert (&stmts, scalar_type, new_temp); 6074 } 6075 6076 epilog_stmt = gimple_seq_last_stmt (stmts); 6077 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 6078 scalar_results[0] = new_temp; 6079 } 6080 6081 /* Record this operation if it could be reused by the epilogue loop. */ 6082 if (STMT_VINFO_REDUC_TYPE (reduc_info) == TREE_CODE_REDUCTION 6083 && vec_num == 1) 6084 loop_vinfo->reusable_accumulators.put (scalar_results[0], 6085 { orig_reduc_input, reduc_info }); 6086 6087 if (double_reduc) 6088 loop = outer_loop; 6089 6090 /* 2.6 Handle the loop-exit phis. Replace the uses of scalar loop-exit 6091 phis with new adjusted scalar results, i.e., replace use <s_out0> 6092 with use <s_out4>. 6093 6094 Transform: 6095 loop_exit: 6096 s_out0 = phi <s_loop> # (scalar) EXIT_PHI 6097 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI 6098 v_out2 = reduce <v_out1> 6099 s_out3 = extract_field <v_out2, 0> 6100 s_out4 = adjust_result <s_out3> 6101 use <s_out0> 6102 use <s_out0> 6103 6104 into: 6105 6106 loop_exit: 6107 s_out0 = phi <s_loop> # (scalar) EXIT_PHI 6108 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI 6109 v_out2 = reduce <v_out1> 6110 s_out3 = extract_field <v_out2, 0> 6111 s_out4 = adjust_result <s_out3> 6112 use <s_out4> 6113 use <s_out4> */ 6114 6115 gcc_assert (live_out_stmts.size () == scalar_results.length ()); 6116 for (k = 0; k < live_out_stmts.size (); k++) 6117 { 6118 stmt_vec_info scalar_stmt_info = vect_orig_stmt (live_out_stmts[k]); 6119 scalar_dest = gimple_get_lhs (scalar_stmt_info->stmt); 6120 6121 phis.create (3); 6122 /* Find the loop-closed-use at the loop exit of the original scalar 6123 result. (The reduction result is expected to have two immediate uses, 6124 one at the latch block, and one at the loop exit). For double 6125 reductions we are looking for exit phis of the outer loop. */ 6126 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest) 6127 { 6128 if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p)))) 6129 { 6130 if (!is_gimple_debug (USE_STMT (use_p))) 6131 phis.safe_push (USE_STMT (use_p)); 6132 } 6133 else 6134 { 6135 if (double_reduc && gimple_code (USE_STMT (use_p)) == GIMPLE_PHI) 6136 { 6137 tree phi_res = PHI_RESULT (USE_STMT (use_p)); 6138 6139 FOR_EACH_IMM_USE_FAST (phi_use_p, phi_imm_iter, phi_res) 6140 { 6141 if (!flow_bb_inside_loop_p (loop, 6142 gimple_bb (USE_STMT (phi_use_p))) 6143 && !is_gimple_debug (USE_STMT (phi_use_p))) 6144 phis.safe_push (USE_STMT (phi_use_p)); 6145 } 6146 } 6147 } 6148 } 6149 6150 FOR_EACH_VEC_ELT (phis, i, exit_phi) 6151 { 6152 /* Replace the uses: */ 6153 orig_name = PHI_RESULT (exit_phi); 6154 6155 /* Look for a single use at the target of the skip edge. */ 6156 if (unify_with_main_loop_p) 6157 { 6158 use_operand_p use_p; 6159 gimple *user; 6160 if (!single_imm_use (orig_name, &use_p, &user)) 6161 gcc_unreachable (); 6162 orig_name = gimple_get_lhs (user); 6163 } 6164 6165 scalar_result = scalar_results[k]; 6166 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) 6167 { 6168 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) 6169 SET_USE (use_p, scalar_result); 6170 update_stmt (use_stmt); 6171 } 6172 } 6173 6174 phis.release (); 6175 } 6176 } 6177 6178 /* Return a vector of type VECTYPE that is equal to the vector select 6179 operation "MASK ? VEC : IDENTITY". Insert the select statements 6180 before GSI. */ 6181 6182 static tree 6183 merge_with_identity (gimple_stmt_iterator *gsi, tree mask, tree vectype, 6184 tree vec, tree identity) 6185 { 6186 tree cond = make_temp_ssa_name (vectype, NULL, "cond"); 6187 gimple *new_stmt = gimple_build_assign (cond, VEC_COND_EXPR, 6188 mask, vec, identity); 6189 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); 6190 return cond; 6191 } 6192 6193 /* Successively apply CODE to each element of VECTOR_RHS, in left-to-right 6194 order, starting with LHS. Insert the extraction statements before GSI and 6195 associate the new scalar SSA names with variable SCALAR_DEST. 6196 Return the SSA name for the result. */ 6197 6198 static tree 6199 vect_expand_fold_left (gimple_stmt_iterator *gsi, tree scalar_dest, 6200 tree_code code, tree lhs, tree vector_rhs) 6201 { 6202 tree vectype = TREE_TYPE (vector_rhs); 6203 tree scalar_type = TREE_TYPE (vectype); 6204 tree bitsize = TYPE_SIZE (scalar_type); 6205 unsigned HOST_WIDE_INT vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype)); 6206 unsigned HOST_WIDE_INT element_bitsize = tree_to_uhwi (bitsize); 6207 6208 for (unsigned HOST_WIDE_INT bit_offset = 0; 6209 bit_offset < vec_size_in_bits; 6210 bit_offset += element_bitsize) 6211 { 6212 tree bitpos = bitsize_int (bit_offset); 6213 tree rhs = build3 (BIT_FIELD_REF, scalar_type, vector_rhs, 6214 bitsize, bitpos); 6215 6216 gassign *stmt = gimple_build_assign (scalar_dest, rhs); 6217 rhs = make_ssa_name (scalar_dest, stmt); 6218 gimple_assign_set_lhs (stmt, rhs); 6219 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 6220 6221 stmt = gimple_build_assign (scalar_dest, code, lhs, rhs); 6222 tree new_name = make_ssa_name (scalar_dest, stmt); 6223 gimple_assign_set_lhs (stmt, new_name); 6224 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 6225 lhs = new_name; 6226 } 6227 return lhs; 6228 } 6229 6230 /* Get a masked internal function equivalent to REDUC_FN. VECTYPE_IN is the 6231 type of the vector input. */ 6232 6233 static internal_fn 6234 get_masked_reduction_fn (internal_fn reduc_fn, tree vectype_in) 6235 { 6236 internal_fn mask_reduc_fn; 6237 6238 switch (reduc_fn) 6239 { 6240 case IFN_FOLD_LEFT_PLUS: 6241 mask_reduc_fn = IFN_MASK_FOLD_LEFT_PLUS; 6242 break; 6243 6244 default: 6245 return IFN_LAST; 6246 } 6247 6248 if (direct_internal_fn_supported_p (mask_reduc_fn, vectype_in, 6249 OPTIMIZE_FOR_SPEED)) 6250 return mask_reduc_fn; 6251 return IFN_LAST; 6252 } 6253 6254 /* Perform an in-order reduction (FOLD_LEFT_REDUCTION). STMT_INFO is the 6255 statement that sets the live-out value. REDUC_DEF_STMT is the phi 6256 statement. CODE is the operation performed by STMT_INFO and OPS are 6257 its scalar operands. REDUC_INDEX is the index of the operand in 6258 OPS that is set by REDUC_DEF_STMT. REDUC_FN is the function that 6259 implements in-order reduction, or IFN_LAST if we should open-code it. 6260 VECTYPE_IN is the type of the vector input. MASKS specifies the masks 6261 that should be used to control the operation in a fully-masked loop. */ 6262 6263 static bool 6264 vectorize_fold_left_reduction (loop_vec_info loop_vinfo, 6265 stmt_vec_info stmt_info, 6266 gimple_stmt_iterator *gsi, 6267 gimple **vec_stmt, slp_tree slp_node, 6268 gimple *reduc_def_stmt, 6269 tree_code code, internal_fn reduc_fn, 6270 tree ops[3], tree vectype_in, 6271 int reduc_index, vec_loop_masks *masks) 6272 { 6273 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 6274 tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); 6275 internal_fn mask_reduc_fn = get_masked_reduction_fn (reduc_fn, vectype_in); 6276 6277 int ncopies; 6278 if (slp_node) 6279 ncopies = 1; 6280 else 6281 ncopies = vect_get_num_copies (loop_vinfo, vectype_in); 6282 6283 gcc_assert (!nested_in_vect_loop_p (loop, stmt_info)); 6284 gcc_assert (ncopies == 1); 6285 gcc_assert (TREE_CODE_LENGTH (code) == binary_op); 6286 6287 if (slp_node) 6288 gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (vectype_out), 6289 TYPE_VECTOR_SUBPARTS (vectype_in))); 6290 6291 tree op0 = ops[1 - reduc_index]; 6292 6293 int group_size = 1; 6294 stmt_vec_info scalar_dest_def_info; 6295 auto_vec<tree> vec_oprnds0; 6296 if (slp_node) 6297 { 6298 auto_vec<vec<tree> > vec_defs (2); 6299 vect_get_slp_defs (loop_vinfo, slp_node, &vec_defs); 6300 vec_oprnds0.safe_splice (vec_defs[1 - reduc_index]); 6301 vec_defs[0].release (); 6302 vec_defs[1].release (); 6303 group_size = SLP_TREE_SCALAR_STMTS (slp_node).length (); 6304 scalar_dest_def_info = SLP_TREE_SCALAR_STMTS (slp_node)[group_size - 1]; 6305 } 6306 else 6307 { 6308 vect_get_vec_defs_for_operand (loop_vinfo, stmt_info, 1, 6309 op0, &vec_oprnds0); 6310 scalar_dest_def_info = stmt_info; 6311 } 6312 6313 tree scalar_dest = gimple_assign_lhs (scalar_dest_def_info->stmt); 6314 tree scalar_type = TREE_TYPE (scalar_dest); 6315 tree reduc_var = gimple_phi_result (reduc_def_stmt); 6316 6317 int vec_num = vec_oprnds0.length (); 6318 gcc_assert (vec_num == 1 || slp_node); 6319 tree vec_elem_type = TREE_TYPE (vectype_out); 6320 gcc_checking_assert (useless_type_conversion_p (scalar_type, vec_elem_type)); 6321 6322 tree vector_identity = NULL_TREE; 6323 if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) 6324 vector_identity = build_zero_cst (vectype_out); 6325 6326 tree scalar_dest_var = vect_create_destination_var (scalar_dest, NULL); 6327 int i; 6328 tree def0; 6329 FOR_EACH_VEC_ELT (vec_oprnds0, i, def0) 6330 { 6331 gimple *new_stmt; 6332 tree mask = NULL_TREE; 6333 if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) 6334 mask = vect_get_loop_mask (gsi, masks, vec_num, vectype_in, i); 6335 6336 /* Handle MINUS by adding the negative. */ 6337 if (reduc_fn != IFN_LAST && code == MINUS_EXPR) 6338 { 6339 tree negated = make_ssa_name (vectype_out); 6340 new_stmt = gimple_build_assign (negated, NEGATE_EXPR, def0); 6341 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); 6342 def0 = negated; 6343 } 6344 6345 if (mask && mask_reduc_fn == IFN_LAST) 6346 def0 = merge_with_identity (gsi, mask, vectype_out, def0, 6347 vector_identity); 6348 6349 /* On the first iteration the input is simply the scalar phi 6350 result, and for subsequent iterations it is the output of 6351 the preceding operation. */ 6352 if (reduc_fn != IFN_LAST || (mask && mask_reduc_fn != IFN_LAST)) 6353 { 6354 if (mask && mask_reduc_fn != IFN_LAST) 6355 new_stmt = gimple_build_call_internal (mask_reduc_fn, 3, reduc_var, 6356 def0, mask); 6357 else 6358 new_stmt = gimple_build_call_internal (reduc_fn, 2, reduc_var, 6359 def0); 6360 /* For chained SLP reductions the output of the previous reduction 6361 operation serves as the input of the next. For the final statement 6362 the output cannot be a temporary - we reuse the original 6363 scalar destination of the last statement. */ 6364 if (i != vec_num - 1) 6365 { 6366 gimple_set_lhs (new_stmt, scalar_dest_var); 6367 reduc_var = make_ssa_name (scalar_dest_var, new_stmt); 6368 gimple_set_lhs (new_stmt, reduc_var); 6369 } 6370 } 6371 else 6372 { 6373 reduc_var = vect_expand_fold_left (gsi, scalar_dest_var, code, 6374 reduc_var, def0); 6375 new_stmt = SSA_NAME_DEF_STMT (reduc_var); 6376 /* Remove the statement, so that we can use the same code paths 6377 as for statements that we've just created. */ 6378 gimple_stmt_iterator tmp_gsi = gsi_for_stmt (new_stmt); 6379 gsi_remove (&tmp_gsi, true); 6380 } 6381 6382 if (i == vec_num - 1) 6383 { 6384 gimple_set_lhs (new_stmt, scalar_dest); 6385 vect_finish_replace_stmt (loop_vinfo, 6386 scalar_dest_def_info, 6387 new_stmt); 6388 } 6389 else 6390 vect_finish_stmt_generation (loop_vinfo, 6391 scalar_dest_def_info, 6392 new_stmt, gsi); 6393 6394 if (slp_node) 6395 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); 6396 else 6397 { 6398 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); 6399 *vec_stmt = new_stmt; 6400 } 6401 } 6402 6403 return true; 6404 } 6405 6406 /* Function is_nonwrapping_integer_induction. 6407 6408 Check if STMT_VINO (which is part of loop LOOP) both increments and 6409 does not cause overflow. */ 6410 6411 static bool 6412 is_nonwrapping_integer_induction (stmt_vec_info stmt_vinfo, class loop *loop) 6413 { 6414 gphi *phi = as_a <gphi *> (stmt_vinfo->stmt); 6415 tree base = STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED (stmt_vinfo); 6416 tree step = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo); 6417 tree lhs_type = TREE_TYPE (gimple_phi_result (phi)); 6418 widest_int ni, max_loop_value, lhs_max; 6419 wi::overflow_type overflow = wi::OVF_NONE; 6420 6421 /* Make sure the loop is integer based. */ 6422 if (TREE_CODE (base) != INTEGER_CST 6423 || TREE_CODE (step) != INTEGER_CST) 6424 return false; 6425 6426 /* Check that the max size of the loop will not wrap. */ 6427 6428 if (TYPE_OVERFLOW_UNDEFINED (lhs_type)) 6429 return true; 6430 6431 if (! max_stmt_executions (loop, &ni)) 6432 return false; 6433 6434 max_loop_value = wi::mul (wi::to_widest (step), ni, TYPE_SIGN (lhs_type), 6435 &overflow); 6436 if (overflow) 6437 return false; 6438 6439 max_loop_value = wi::add (wi::to_widest (base), max_loop_value, 6440 TYPE_SIGN (lhs_type), &overflow); 6441 if (overflow) 6442 return false; 6443 6444 return (wi::min_precision (max_loop_value, TYPE_SIGN (lhs_type)) 6445 <= TYPE_PRECISION (lhs_type)); 6446 } 6447 6448 /* Check if masking can be supported by inserting a conditional expression. 6449 CODE is the code for the operation. COND_FN is the conditional internal 6450 function, if it exists. VECTYPE_IN is the type of the vector input. */ 6451 static bool 6452 use_mask_by_cond_expr_p (code_helper code, internal_fn cond_fn, 6453 tree vectype_in) 6454 { 6455 if (cond_fn != IFN_LAST 6456 && direct_internal_fn_supported_p (cond_fn, vectype_in, 6457 OPTIMIZE_FOR_SPEED)) 6458 return false; 6459 6460 if (code.is_tree_code ()) 6461 switch (tree_code (code)) 6462 { 6463 case DOT_PROD_EXPR: 6464 case SAD_EXPR: 6465 return true; 6466 6467 default: 6468 break; 6469 } 6470 return false; 6471 } 6472 6473 /* Insert a conditional expression to enable masked vectorization. CODE is the 6474 code for the operation. VOP is the array of operands. MASK is the loop 6475 mask. GSI is a statement iterator used to place the new conditional 6476 expression. */ 6477 static void 6478 build_vect_cond_expr (code_helper code, tree vop[3], tree mask, 6479 gimple_stmt_iterator *gsi) 6480 { 6481 switch (tree_code (code)) 6482 { 6483 case DOT_PROD_EXPR: 6484 { 6485 tree vectype = TREE_TYPE (vop[1]); 6486 tree zero = build_zero_cst (vectype); 6487 tree masked_op1 = make_temp_ssa_name (vectype, NULL, "masked_op1"); 6488 gassign *select = gimple_build_assign (masked_op1, VEC_COND_EXPR, 6489 mask, vop[1], zero); 6490 gsi_insert_before (gsi, select, GSI_SAME_STMT); 6491 vop[1] = masked_op1; 6492 break; 6493 } 6494 6495 case SAD_EXPR: 6496 { 6497 tree vectype = TREE_TYPE (vop[1]); 6498 tree masked_op1 = make_temp_ssa_name (vectype, NULL, "masked_op1"); 6499 gassign *select = gimple_build_assign (masked_op1, VEC_COND_EXPR, 6500 mask, vop[1], vop[0]); 6501 gsi_insert_before (gsi, select, GSI_SAME_STMT); 6502 vop[1] = masked_op1; 6503 break; 6504 } 6505 6506 default: 6507 gcc_unreachable (); 6508 } 6509 } 6510 6511 /* Function vectorizable_reduction. 6512 6513 Check if STMT_INFO performs a reduction operation that can be vectorized. 6514 If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized 6515 stmt to replace it, put it in VEC_STMT, and insert it at GSI. 6516 Return true if STMT_INFO is vectorizable in this way. 6517 6518 This function also handles reduction idioms (patterns) that have been 6519 recognized in advance during vect_pattern_recog. In this case, STMT_INFO 6520 may be of this form: 6521 X = pattern_expr (arg0, arg1, ..., X) 6522 and its STMT_VINFO_RELATED_STMT points to the last stmt in the original 6523 sequence that had been detected and replaced by the pattern-stmt 6524 (STMT_INFO). 6525 6526 This function also handles reduction of condition expressions, for example: 6527 for (int i = 0; i < N; i++) 6528 if (a[i] < value) 6529 last = a[i]; 6530 This is handled by vectorising the loop and creating an additional vector 6531 containing the loop indexes for which "a[i] < value" was true. In the 6532 function epilogue this is reduced to a single max value and then used to 6533 index into the vector of results. 6534 6535 In some cases of reduction patterns, the type of the reduction variable X is 6536 different than the type of the other arguments of STMT_INFO. 6537 In such cases, the vectype that is used when transforming STMT_INFO into 6538 a vector stmt is different than the vectype that is used to determine the 6539 vectorization factor, because it consists of a different number of elements 6540 than the actual number of elements that are being operated upon in parallel. 6541 6542 For example, consider an accumulation of shorts into an int accumulator. 6543 On some targets it's possible to vectorize this pattern operating on 8 6544 shorts at a time (hence, the vectype for purposes of determining the 6545 vectorization factor should be V8HI); on the other hand, the vectype that 6546 is used to create the vector form is actually V4SI (the type of the result). 6547 6548 Upon entry to this function, STMT_VINFO_VECTYPE records the vectype that 6549 indicates what is the actual level of parallelism (V8HI in the example), so 6550 that the right vectorization factor would be derived. This vectype 6551 corresponds to the type of arguments to the reduction stmt, and should *NOT* 6552 be used to create the vectorized stmt. The right vectype for the vectorized 6553 stmt is obtained from the type of the result X: 6554 get_vectype_for_scalar_type (vinfo, TREE_TYPE (X)) 6555 6556 This means that, contrary to "regular" reductions (or "regular" stmts in 6557 general), the following equation: 6558 STMT_VINFO_VECTYPE == get_vectype_for_scalar_type (vinfo, TREE_TYPE (X)) 6559 does *NOT* necessarily hold for reduction patterns. */ 6560 6561 bool 6562 vectorizable_reduction (loop_vec_info loop_vinfo, 6563 stmt_vec_info stmt_info, slp_tree slp_node, 6564 slp_instance slp_node_instance, 6565 stmt_vector_for_cost *cost_vec) 6566 { 6567 tree vectype_in = NULL_TREE; 6568 tree vectype_op[3] = { NULL_TREE, NULL_TREE, NULL_TREE }; 6569 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 6570 enum vect_def_type cond_reduc_dt = vect_unknown_def_type; 6571 stmt_vec_info cond_stmt_vinfo = NULL; 6572 int i; 6573 int ncopies; 6574 bool single_defuse_cycle = false; 6575 bool nested_cycle = false; 6576 bool double_reduc = false; 6577 int vec_num; 6578 tree cr_index_scalar_type = NULL_TREE, cr_index_vector_type = NULL_TREE; 6579 tree cond_reduc_val = NULL_TREE; 6580 6581 /* Make sure it was already recognized as a reduction computation. */ 6582 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def 6583 && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def 6584 && STMT_VINFO_DEF_TYPE (stmt_info) != vect_nested_cycle) 6585 return false; 6586 6587 /* The stmt we store reduction analysis meta on. */ 6588 stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); 6589 reduc_info->is_reduc_info = true; 6590 6591 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle) 6592 { 6593 if (is_a <gphi *> (stmt_info->stmt)) 6594 { 6595 if (slp_node) 6596 { 6597 /* We eventually need to set a vector type on invariant 6598 arguments. */ 6599 unsigned j; 6600 slp_tree child; 6601 FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (slp_node), j, child) 6602 if (!vect_maybe_update_slp_op_vectype 6603 (child, SLP_TREE_VECTYPE (slp_node))) 6604 { 6605 if (dump_enabled_p ()) 6606 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6607 "incompatible vector types for " 6608 "invariants\n"); 6609 return false; 6610 } 6611 } 6612 /* Analysis for double-reduction is done on the outer 6613 loop PHI, nested cycles have no further restrictions. */ 6614 STMT_VINFO_TYPE (stmt_info) = cycle_phi_info_type; 6615 } 6616 else 6617 STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type; 6618 return true; 6619 } 6620 6621 stmt_vec_info orig_stmt_of_analysis = stmt_info; 6622 stmt_vec_info phi_info = stmt_info; 6623 if (!is_a <gphi *> (stmt_info->stmt)) 6624 { 6625 STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type; 6626 return true; 6627 } 6628 if (slp_node) 6629 { 6630 slp_node_instance->reduc_phis = slp_node; 6631 /* ??? We're leaving slp_node to point to the PHIs, we only 6632 need it to get at the number of vector stmts which wasn't 6633 yet initialized for the instance root. */ 6634 } 6635 if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def) 6636 stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (stmt_info)); 6637 else 6638 { 6639 gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) 6640 == vect_double_reduction_def); 6641 use_operand_p use_p; 6642 gimple *use_stmt; 6643 bool res = single_imm_use (gimple_phi_result (stmt_info->stmt), 6644 &use_p, &use_stmt); 6645 gcc_assert (res); 6646 phi_info = loop_vinfo->lookup_stmt (use_stmt); 6647 stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (phi_info)); 6648 } 6649 6650 /* PHIs should not participate in patterns. */ 6651 gcc_assert (!STMT_VINFO_RELATED_STMT (phi_info)); 6652 gphi *reduc_def_phi = as_a <gphi *> (phi_info->stmt); 6653 6654 /* Verify following REDUC_IDX from the latch def leads us back to the PHI 6655 and compute the reduction chain length. Discover the real 6656 reduction operation stmt on the way (stmt_info and slp_for_stmt_info). */ 6657 tree reduc_def 6658 = PHI_ARG_DEF_FROM_EDGE (reduc_def_phi, 6659 loop_latch_edge 6660 (gimple_bb (reduc_def_phi)->loop_father)); 6661 unsigned reduc_chain_length = 0; 6662 bool only_slp_reduc_chain = true; 6663 stmt_info = NULL; 6664 slp_tree slp_for_stmt_info = slp_node ? slp_node_instance->root : NULL; 6665 while (reduc_def != PHI_RESULT (reduc_def_phi)) 6666 { 6667 stmt_vec_info def = loop_vinfo->lookup_def (reduc_def); 6668 stmt_vec_info vdef = vect_stmt_to_vectorize (def); 6669 if (STMT_VINFO_REDUC_IDX (vdef) == -1) 6670 { 6671 if (dump_enabled_p ()) 6672 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6673 "reduction chain broken by patterns.\n"); 6674 return false; 6675 } 6676 if (!REDUC_GROUP_FIRST_ELEMENT (vdef)) 6677 only_slp_reduc_chain = false; 6678 /* For epilogue generation live members of the chain need 6679 to point back to the PHI via their original stmt for 6680 info_for_reduction to work. For SLP we need to look at 6681 all lanes here - even though we only will vectorize from 6682 the SLP node with live lane zero the other live lanes also 6683 need to be identified as part of a reduction to be able 6684 to skip code generation for them. */ 6685 if (slp_for_stmt_info) 6686 { 6687 for (auto s : SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)) 6688 if (STMT_VINFO_LIVE_P (s)) 6689 STMT_VINFO_REDUC_DEF (vect_orig_stmt (s)) = phi_info; 6690 } 6691 else if (STMT_VINFO_LIVE_P (vdef)) 6692 STMT_VINFO_REDUC_DEF (def) = phi_info; 6693 gimple_match_op op; 6694 if (!gimple_extract_op (vdef->stmt, &op)) 6695 { 6696 if (dump_enabled_p ()) 6697 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6698 "reduction chain includes unsupported" 6699 " statement type.\n"); 6700 return false; 6701 } 6702 if (CONVERT_EXPR_CODE_P (op.code)) 6703 { 6704 if (!tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))) 6705 { 6706 if (dump_enabled_p ()) 6707 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6708 "conversion in the reduction chain.\n"); 6709 return false; 6710 } 6711 } 6712 else if (!stmt_info) 6713 /* First non-conversion stmt. */ 6714 stmt_info = vdef; 6715 reduc_def = op.ops[STMT_VINFO_REDUC_IDX (vdef)]; 6716 reduc_chain_length++; 6717 if (!stmt_info && slp_node) 6718 slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; 6719 } 6720 /* PHIs should not participate in patterns. */ 6721 gcc_assert (!STMT_VINFO_RELATED_STMT (phi_info)); 6722 6723 if (nested_in_vect_loop_p (loop, stmt_info)) 6724 { 6725 loop = loop->inner; 6726 nested_cycle = true; 6727 } 6728 6729 /* STMT_VINFO_REDUC_DEF doesn't point to the first but the last 6730 element. */ 6731 if (slp_node && REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 6732 { 6733 gcc_assert (!REDUC_GROUP_NEXT_ELEMENT (stmt_info)); 6734 stmt_info = REDUC_GROUP_FIRST_ELEMENT (stmt_info); 6735 } 6736 if (REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 6737 gcc_assert (slp_node 6738 && REDUC_GROUP_FIRST_ELEMENT (stmt_info) == stmt_info); 6739 6740 /* 1. Is vectorizable reduction? */ 6741 /* Not supportable if the reduction variable is used in the loop, unless 6742 it's a reduction chain. */ 6743 if (STMT_VINFO_RELEVANT (stmt_info) > vect_used_in_outer 6744 && !REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 6745 return false; 6746 6747 /* Reductions that are not used even in an enclosing outer-loop, 6748 are expected to be "live" (used out of the loop). */ 6749 if (STMT_VINFO_RELEVANT (stmt_info) == vect_unused_in_scope 6750 && !STMT_VINFO_LIVE_P (stmt_info)) 6751 return false; 6752 6753 /* 2. Has this been recognized as a reduction pattern? 6754 6755 Check if STMT represents a pattern that has been recognized 6756 in earlier analysis stages. For stmts that represent a pattern, 6757 the STMT_VINFO_RELATED_STMT field records the last stmt in 6758 the original sequence that constitutes the pattern. */ 6759 6760 stmt_vec_info orig_stmt_info = STMT_VINFO_RELATED_STMT (stmt_info); 6761 if (orig_stmt_info) 6762 { 6763 gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info)); 6764 gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info)); 6765 } 6766 6767 /* 3. Check the operands of the operation. The first operands are defined 6768 inside the loop body. The last operand is the reduction variable, 6769 which is defined by the loop-header-phi. */ 6770 6771 tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); 6772 STMT_VINFO_REDUC_VECTYPE (reduc_info) = vectype_out; 6773 gimple_match_op op; 6774 if (!gimple_extract_op (stmt_info->stmt, &op)) 6775 gcc_unreachable (); 6776 bool lane_reduc_code_p = (op.code == DOT_PROD_EXPR 6777 || op.code == WIDEN_SUM_EXPR 6778 || op.code == SAD_EXPR); 6779 enum optab_subtype optab_query_kind = optab_vector; 6780 if (op.code == DOT_PROD_EXPR 6781 && (TYPE_SIGN (TREE_TYPE (op.ops[0])) 6782 != TYPE_SIGN (TREE_TYPE (op.ops[1])))) 6783 optab_query_kind = optab_vector_mixed_sign; 6784 6785 if (!POINTER_TYPE_P (op.type) && !INTEGRAL_TYPE_P (op.type) 6786 && !SCALAR_FLOAT_TYPE_P (op.type)) 6787 return false; 6788 6789 /* Do not try to vectorize bit-precision reductions. */ 6790 if (!type_has_mode_precision_p (op.type)) 6791 return false; 6792 6793 /* For lane-reducing ops we're reducing the number of reduction PHIs 6794 which means the only use of that may be in the lane-reducing operation. */ 6795 if (lane_reduc_code_p 6796 && reduc_chain_length != 1 6797 && !only_slp_reduc_chain) 6798 { 6799 if (dump_enabled_p ()) 6800 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6801 "lane-reducing reduction with extra stmts.\n"); 6802 return false; 6803 } 6804 6805 /* All uses but the last are expected to be defined in the loop. 6806 The last use is the reduction variable. In case of nested cycle this 6807 assumption is not true: we use reduc_index to record the index of the 6808 reduction variable. */ 6809 slp_tree *slp_op = XALLOCAVEC (slp_tree, op.num_ops); 6810 /* We need to skip an extra operand for COND_EXPRs with embedded 6811 comparison. */ 6812 unsigned opno_adjust = 0; 6813 if (op.code == COND_EXPR && COMPARISON_CLASS_P (op.ops[0])) 6814 opno_adjust = 1; 6815 for (i = 0; i < (int) op.num_ops; i++) 6816 { 6817 /* The condition of COND_EXPR is checked in vectorizable_condition(). */ 6818 if (i == 0 && op.code == COND_EXPR) 6819 continue; 6820 6821 stmt_vec_info def_stmt_info; 6822 enum vect_def_type dt; 6823 if (!vect_is_simple_use (loop_vinfo, stmt_info, slp_for_stmt_info, 6824 i + opno_adjust, &op.ops[i], &slp_op[i], &dt, 6825 &vectype_op[i], &def_stmt_info)) 6826 { 6827 if (dump_enabled_p ()) 6828 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6829 "use not simple.\n"); 6830 return false; 6831 } 6832 if (i == STMT_VINFO_REDUC_IDX (stmt_info)) 6833 continue; 6834 6835 /* There should be only one cycle def in the stmt, the one 6836 leading to reduc_def. */ 6837 if (VECTORIZABLE_CYCLE_DEF (dt)) 6838 return false; 6839 6840 if (!vectype_op[i]) 6841 vectype_op[i] 6842 = get_vectype_for_scalar_type (loop_vinfo, 6843 TREE_TYPE (op.ops[i]), slp_op[i]); 6844 6845 /* To properly compute ncopies we are interested in the widest 6846 non-reduction input type in case we're looking at a widening 6847 accumulation that we later handle in vect_transform_reduction. */ 6848 if (lane_reduc_code_p 6849 && vectype_op[i] 6850 && (!vectype_in 6851 || (GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (vectype_in))) 6852 < GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (vectype_op[i])))))) 6853 vectype_in = vectype_op[i]; 6854 6855 /* Record how the non-reduction-def value of COND_EXPR is defined. 6856 ??? For a chain of multiple CONDs we'd have to match them up all. */ 6857 if (op.code == COND_EXPR && reduc_chain_length == 1) 6858 { 6859 if (dt == vect_constant_def) 6860 { 6861 cond_reduc_dt = dt; 6862 cond_reduc_val = op.ops[i]; 6863 } 6864 else if (dt == vect_induction_def 6865 && def_stmt_info 6866 && is_nonwrapping_integer_induction (def_stmt_info, loop)) 6867 { 6868 cond_reduc_dt = dt; 6869 cond_stmt_vinfo = def_stmt_info; 6870 } 6871 } 6872 } 6873 if (!vectype_in) 6874 vectype_in = STMT_VINFO_VECTYPE (phi_info); 6875 STMT_VINFO_REDUC_VECTYPE_IN (reduc_info) = vectype_in; 6876 6877 enum vect_reduction_type v_reduc_type = STMT_VINFO_REDUC_TYPE (phi_info); 6878 STMT_VINFO_REDUC_TYPE (reduc_info) = v_reduc_type; 6879 /* If we have a condition reduction, see if we can simplify it further. */ 6880 if (v_reduc_type == COND_REDUCTION) 6881 { 6882 if (slp_node) 6883 return false; 6884 6885 /* When the condition uses the reduction value in the condition, fail. */ 6886 if (STMT_VINFO_REDUC_IDX (stmt_info) == 0) 6887 { 6888 if (dump_enabled_p ()) 6889 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6890 "condition depends on previous iteration\n"); 6891 return false; 6892 } 6893 6894 if (reduc_chain_length == 1 6895 && direct_internal_fn_supported_p (IFN_FOLD_EXTRACT_LAST, 6896 vectype_in, OPTIMIZE_FOR_SPEED)) 6897 { 6898 if (dump_enabled_p ()) 6899 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 6900 "optimizing condition reduction with" 6901 " FOLD_EXTRACT_LAST.\n"); 6902 STMT_VINFO_REDUC_TYPE (reduc_info) = EXTRACT_LAST_REDUCTION; 6903 } 6904 else if (cond_reduc_dt == vect_induction_def) 6905 { 6906 tree base 6907 = STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED (cond_stmt_vinfo); 6908 tree step = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (cond_stmt_vinfo); 6909 6910 gcc_assert (TREE_CODE (base) == INTEGER_CST 6911 && TREE_CODE (step) == INTEGER_CST); 6912 cond_reduc_val = NULL_TREE; 6913 enum tree_code cond_reduc_op_code = ERROR_MARK; 6914 tree res = PHI_RESULT (STMT_VINFO_STMT (cond_stmt_vinfo)); 6915 if (!types_compatible_p (TREE_TYPE (res), TREE_TYPE (base))) 6916 ; 6917 /* Find a suitable value, for MAX_EXPR below base, for MIN_EXPR 6918 above base; punt if base is the minimum value of the type for 6919 MAX_EXPR or maximum value of the type for MIN_EXPR for now. */ 6920 else if (tree_int_cst_sgn (step) == -1) 6921 { 6922 cond_reduc_op_code = MIN_EXPR; 6923 if (tree_int_cst_sgn (base) == -1) 6924 cond_reduc_val = build_int_cst (TREE_TYPE (base), 0); 6925 else if (tree_int_cst_lt (base, 6926 TYPE_MAX_VALUE (TREE_TYPE (base)))) 6927 cond_reduc_val 6928 = int_const_binop (PLUS_EXPR, base, integer_one_node); 6929 } 6930 else 6931 { 6932 cond_reduc_op_code = MAX_EXPR; 6933 if (tree_int_cst_sgn (base) == 1) 6934 cond_reduc_val = build_int_cst (TREE_TYPE (base), 0); 6935 else if (tree_int_cst_lt (TYPE_MIN_VALUE (TREE_TYPE (base)), 6936 base)) 6937 cond_reduc_val 6938 = int_const_binop (MINUS_EXPR, base, integer_one_node); 6939 } 6940 if (cond_reduc_val) 6941 { 6942 if (dump_enabled_p ()) 6943 dump_printf_loc (MSG_NOTE, vect_location, 6944 "condition expression based on " 6945 "integer induction.\n"); 6946 STMT_VINFO_REDUC_CODE (reduc_info) = cond_reduc_op_code; 6947 STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info) 6948 = cond_reduc_val; 6949 STMT_VINFO_REDUC_TYPE (reduc_info) = INTEGER_INDUC_COND_REDUCTION; 6950 } 6951 } 6952 else if (cond_reduc_dt == vect_constant_def) 6953 { 6954 enum vect_def_type cond_initial_dt; 6955 tree cond_initial_val = vect_phi_initial_value (reduc_def_phi); 6956 vect_is_simple_use (cond_initial_val, loop_vinfo, &cond_initial_dt); 6957 if (cond_initial_dt == vect_constant_def 6958 && types_compatible_p (TREE_TYPE (cond_initial_val), 6959 TREE_TYPE (cond_reduc_val))) 6960 { 6961 tree e = fold_binary (LE_EXPR, boolean_type_node, 6962 cond_initial_val, cond_reduc_val); 6963 if (e && (integer_onep (e) || integer_zerop (e))) 6964 { 6965 if (dump_enabled_p ()) 6966 dump_printf_loc (MSG_NOTE, vect_location, 6967 "condition expression based on " 6968 "compile time constant.\n"); 6969 /* Record reduction code at analysis stage. */ 6970 STMT_VINFO_REDUC_CODE (reduc_info) 6971 = integer_onep (e) ? MAX_EXPR : MIN_EXPR; 6972 STMT_VINFO_REDUC_TYPE (reduc_info) = CONST_COND_REDUCTION; 6973 } 6974 } 6975 } 6976 } 6977 6978 if (STMT_VINFO_LIVE_P (phi_info)) 6979 return false; 6980 6981 if (slp_node) 6982 ncopies = 1; 6983 else 6984 ncopies = vect_get_num_copies (loop_vinfo, vectype_in); 6985 6986 gcc_assert (ncopies >= 1); 6987 6988 poly_uint64 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); 6989 6990 if (nested_cycle) 6991 { 6992 gcc_assert (STMT_VINFO_DEF_TYPE (reduc_info) 6993 == vect_double_reduction_def); 6994 double_reduc = true; 6995 } 6996 6997 /* 4.2. Check support for the epilog operation. 6998 6999 If STMT represents a reduction pattern, then the type of the 7000 reduction variable may be different than the type of the rest 7001 of the arguments. For example, consider the case of accumulation 7002 of shorts into an int accumulator; The original code: 7003 S1: int_a = (int) short_a; 7004 orig_stmt-> S2: int_acc = plus <int_a ,int_acc>; 7005 7006 was replaced with: 7007 STMT: int_acc = widen_sum <short_a, int_acc> 7008 7009 This means that: 7010 1. The tree-code that is used to create the vector operation in the 7011 epilog code (that reduces the partial results) is not the 7012 tree-code of STMT, but is rather the tree-code of the original 7013 stmt from the pattern that STMT is replacing. I.e, in the example 7014 above we want to use 'widen_sum' in the loop, but 'plus' in the 7015 epilog. 7016 2. The type (mode) we use to check available target support 7017 for the vector operation to be created in the *epilog*, is 7018 determined by the type of the reduction variable (in the example 7019 above we'd check this: optab_handler (plus_optab, vect_int_mode])). 7020 However the type (mode) we use to check available target support 7021 for the vector operation to be created *inside the loop*, is 7022 determined by the type of the other arguments to STMT (in the 7023 example we'd check this: optab_handler (widen_sum_optab, 7024 vect_short_mode)). 7025 7026 This is contrary to "regular" reductions, in which the types of all 7027 the arguments are the same as the type of the reduction variable. 7028 For "regular" reductions we can therefore use the same vector type 7029 (and also the same tree-code) when generating the epilog code and 7030 when generating the code inside the loop. */ 7031 7032 code_helper orig_code = STMT_VINFO_REDUC_CODE (phi_info); 7033 STMT_VINFO_REDUC_CODE (reduc_info) = orig_code; 7034 7035 vect_reduction_type reduction_type = STMT_VINFO_REDUC_TYPE (reduc_info); 7036 if (reduction_type == TREE_CODE_REDUCTION) 7037 { 7038 /* Check whether it's ok to change the order of the computation. 7039 Generally, when vectorizing a reduction we change the order of the 7040 computation. This may change the behavior of the program in some 7041 cases, so we need to check that this is ok. One exception is when 7042 vectorizing an outer-loop: the inner-loop is executed sequentially, 7043 and therefore vectorizing reductions in the inner-loop during 7044 outer-loop vectorization is safe. Likewise when we are vectorizing 7045 a series of reductions using SLP and the VF is one the reductions 7046 are performed in scalar order. */ 7047 if (slp_node 7048 && !REDUC_GROUP_FIRST_ELEMENT (stmt_info) 7049 && known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1u)) 7050 ; 7051 else if (needs_fold_left_reduction_p (op.type, orig_code)) 7052 { 7053 /* When vectorizing a reduction chain w/o SLP the reduction PHI 7054 is not directy used in stmt. */ 7055 if (!only_slp_reduc_chain 7056 && reduc_chain_length != 1) 7057 { 7058 if (dump_enabled_p ()) 7059 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7060 "in-order reduction chain without SLP.\n"); 7061 return false; 7062 } 7063 STMT_VINFO_REDUC_TYPE (reduc_info) 7064 = reduction_type = FOLD_LEFT_REDUCTION; 7065 } 7066 else if (!commutative_binary_op_p (orig_code, op.type) 7067 || !associative_binary_op_p (orig_code, op.type)) 7068 { 7069 if (dump_enabled_p ()) 7070 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7071 "reduction: not commutative/associative"); 7072 return false; 7073 } 7074 } 7075 7076 if ((double_reduc || reduction_type != TREE_CODE_REDUCTION) 7077 && ncopies > 1) 7078 { 7079 if (dump_enabled_p ()) 7080 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7081 "multiple types in double reduction or condition " 7082 "reduction or fold-left reduction.\n"); 7083 return false; 7084 } 7085 7086 internal_fn reduc_fn = IFN_LAST; 7087 if (reduction_type == TREE_CODE_REDUCTION 7088 || reduction_type == FOLD_LEFT_REDUCTION 7089 || reduction_type == INTEGER_INDUC_COND_REDUCTION 7090 || reduction_type == CONST_COND_REDUCTION) 7091 { 7092 if (reduction_type == FOLD_LEFT_REDUCTION 7093 ? fold_left_reduction_fn (orig_code, &reduc_fn) 7094 : reduction_fn_for_scalar_code (orig_code, &reduc_fn)) 7095 { 7096 if (reduc_fn != IFN_LAST 7097 && !direct_internal_fn_supported_p (reduc_fn, vectype_out, 7098 OPTIMIZE_FOR_SPEED)) 7099 { 7100 if (dump_enabled_p ()) 7101 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7102 "reduc op not supported by target.\n"); 7103 7104 reduc_fn = IFN_LAST; 7105 } 7106 } 7107 else 7108 { 7109 if (!nested_cycle || double_reduc) 7110 { 7111 if (dump_enabled_p ()) 7112 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7113 "no reduc code for scalar code.\n"); 7114 7115 return false; 7116 } 7117 } 7118 } 7119 else if (reduction_type == COND_REDUCTION) 7120 { 7121 int scalar_precision 7122 = GET_MODE_PRECISION (SCALAR_TYPE_MODE (op.type)); 7123 cr_index_scalar_type = make_unsigned_type (scalar_precision); 7124 cr_index_vector_type = get_same_sized_vectype (cr_index_scalar_type, 7125 vectype_out); 7126 7127 if (direct_internal_fn_supported_p (IFN_REDUC_MAX, cr_index_vector_type, 7128 OPTIMIZE_FOR_SPEED)) 7129 reduc_fn = IFN_REDUC_MAX; 7130 } 7131 STMT_VINFO_REDUC_FN (reduc_info) = reduc_fn; 7132 7133 if (reduction_type != EXTRACT_LAST_REDUCTION 7134 && (!nested_cycle || double_reduc) 7135 && reduc_fn == IFN_LAST 7136 && !nunits_out.is_constant ()) 7137 { 7138 if (dump_enabled_p ()) 7139 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7140 "missing target support for reduction on" 7141 " variable-length vectors.\n"); 7142 return false; 7143 } 7144 7145 /* For SLP reductions, see if there is a neutral value we can use. */ 7146 tree neutral_op = NULL_TREE; 7147 if (slp_node) 7148 { 7149 tree initial_value = NULL_TREE; 7150 if (REDUC_GROUP_FIRST_ELEMENT (stmt_info) != NULL) 7151 initial_value = vect_phi_initial_value (reduc_def_phi); 7152 neutral_op = neutral_op_for_reduction (TREE_TYPE (vectype_out), 7153 orig_code, initial_value); 7154 } 7155 7156 if (double_reduc && reduction_type == FOLD_LEFT_REDUCTION) 7157 { 7158 /* We can't support in-order reductions of code such as this: 7159 7160 for (int i = 0; i < n1; ++i) 7161 for (int j = 0; j < n2; ++j) 7162 l += a[j]; 7163 7164 since GCC effectively transforms the loop when vectorizing: 7165 7166 for (int i = 0; i < n1 / VF; ++i) 7167 for (int j = 0; j < n2; ++j) 7168 for (int k = 0; k < VF; ++k) 7169 l += a[j]; 7170 7171 which is a reassociation of the original operation. */ 7172 if (dump_enabled_p ()) 7173 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7174 "in-order double reduction not supported.\n"); 7175 7176 return false; 7177 } 7178 7179 if (reduction_type == FOLD_LEFT_REDUCTION 7180 && slp_node 7181 && !REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 7182 { 7183 /* We cannot use in-order reductions in this case because there is 7184 an implicit reassociation of the operations involved. */ 7185 if (dump_enabled_p ()) 7186 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7187 "in-order unchained SLP reductions not supported.\n"); 7188 return false; 7189 } 7190 7191 /* For double reductions, and for SLP reductions with a neutral value, 7192 we construct a variable-length initial vector by loading a vector 7193 full of the neutral value and then shift-and-inserting the start 7194 values into the low-numbered elements. */ 7195 if ((double_reduc || neutral_op) 7196 && !nunits_out.is_constant () 7197 && !direct_internal_fn_supported_p (IFN_VEC_SHL_INSERT, 7198 vectype_out, OPTIMIZE_FOR_SPEED)) 7199 { 7200 if (dump_enabled_p ()) 7201 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7202 "reduction on variable-length vectors requires" 7203 " target support for a vector-shift-and-insert" 7204 " operation.\n"); 7205 return false; 7206 } 7207 7208 /* Check extra constraints for variable-length unchained SLP reductions. */ 7209 if (slp_node 7210 && !REDUC_GROUP_FIRST_ELEMENT (stmt_info) 7211 && !nunits_out.is_constant ()) 7212 { 7213 /* We checked above that we could build the initial vector when 7214 there's a neutral element value. Check here for the case in 7215 which each SLP statement has its own initial value and in which 7216 that value needs to be repeated for every instance of the 7217 statement within the initial vector. */ 7218 unsigned int group_size = SLP_TREE_LANES (slp_node); 7219 if (!neutral_op 7220 && !can_duplicate_and_interleave_p (loop_vinfo, group_size, 7221 TREE_TYPE (vectype_out))) 7222 { 7223 if (dump_enabled_p ()) 7224 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7225 "unsupported form of SLP reduction for" 7226 " variable-length vectors: cannot build" 7227 " initial vector.\n"); 7228 return false; 7229 } 7230 /* The epilogue code relies on the number of elements being a multiple 7231 of the group size. The duplicate-and-interleave approach to setting 7232 up the initial vector does too. */ 7233 if (!multiple_p (nunits_out, group_size)) 7234 { 7235 if (dump_enabled_p ()) 7236 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7237 "unsupported form of SLP reduction for" 7238 " variable-length vectors: the vector size" 7239 " is not a multiple of the number of results.\n"); 7240 return false; 7241 } 7242 } 7243 7244 if (reduction_type == COND_REDUCTION) 7245 { 7246 widest_int ni; 7247 7248 if (! max_loop_iterations (loop, &ni)) 7249 { 7250 if (dump_enabled_p ()) 7251 dump_printf_loc (MSG_NOTE, vect_location, 7252 "loop count not known, cannot create cond " 7253 "reduction.\n"); 7254 return false; 7255 } 7256 /* Convert backedges to iterations. */ 7257 ni += 1; 7258 7259 /* The additional index will be the same type as the condition. Check 7260 that the loop can fit into this less one (because we'll use up the 7261 zero slot for when there are no matches). */ 7262 tree max_index = TYPE_MAX_VALUE (cr_index_scalar_type); 7263 if (wi::geu_p (ni, wi::to_widest (max_index))) 7264 { 7265 if (dump_enabled_p ()) 7266 dump_printf_loc (MSG_NOTE, vect_location, 7267 "loop size is greater than data size.\n"); 7268 return false; 7269 } 7270 } 7271 7272 /* In case the vectorization factor (VF) is bigger than the number 7273 of elements that we can fit in a vectype (nunits), we have to generate 7274 more than one vector stmt - i.e - we need to "unroll" the 7275 vector stmt by a factor VF/nunits. For more details see documentation 7276 in vectorizable_operation. */ 7277 7278 /* If the reduction is used in an outer loop we need to generate 7279 VF intermediate results, like so (e.g. for ncopies=2): 7280 r0 = phi (init, r0) 7281 r1 = phi (init, r1) 7282 r0 = x0 + r0; 7283 r1 = x1 + r1; 7284 (i.e. we generate VF results in 2 registers). 7285 In this case we have a separate def-use cycle for each copy, and therefore 7286 for each copy we get the vector def for the reduction variable from the 7287 respective phi node created for this copy. 7288 7289 Otherwise (the reduction is unused in the loop nest), we can combine 7290 together intermediate results, like so (e.g. for ncopies=2): 7291 r = phi (init, r) 7292 r = x0 + r; 7293 r = x1 + r; 7294 (i.e. we generate VF/2 results in a single register). 7295 In this case for each copy we get the vector def for the reduction variable 7296 from the vectorized reduction operation generated in the previous iteration. 7297 7298 This only works when we see both the reduction PHI and its only consumer 7299 in vectorizable_reduction and there are no intermediate stmts 7300 participating. When unrolling we want each unrolled iteration to have its 7301 own reduction accumulator since one of the main goals of unrolling a 7302 reduction is to reduce the aggregate loop-carried latency. */ 7303 if (ncopies > 1 7304 && (STMT_VINFO_RELEVANT (stmt_info) <= vect_used_only_live) 7305 && reduc_chain_length == 1 7306 && loop_vinfo->suggested_unroll_factor == 1) 7307 single_defuse_cycle = true; 7308 7309 if (single_defuse_cycle || lane_reduc_code_p) 7310 { 7311 gcc_assert (op.code != COND_EXPR); 7312 7313 /* 4. Supportable by target? */ 7314 bool ok = true; 7315 7316 /* 4.1. check support for the operation in the loop */ 7317 machine_mode vec_mode = TYPE_MODE (vectype_in); 7318 if (!directly_supported_p (op.code, vectype_in, optab_query_kind)) 7319 { 7320 if (dump_enabled_p ()) 7321 dump_printf (MSG_NOTE, "op not supported by target.\n"); 7322 if (maybe_ne (GET_MODE_SIZE (vec_mode), UNITS_PER_WORD) 7323 || !vect_can_vectorize_without_simd_p (op.code)) 7324 ok = false; 7325 else 7326 if (dump_enabled_p ()) 7327 dump_printf (MSG_NOTE, "proceeding using word mode.\n"); 7328 } 7329 7330 if (vect_emulated_vector_p (vectype_in) 7331 && !vect_can_vectorize_without_simd_p (op.code)) 7332 { 7333 if (dump_enabled_p ()) 7334 dump_printf (MSG_NOTE, "using word mode not possible.\n"); 7335 return false; 7336 } 7337 7338 /* lane-reducing operations have to go through vect_transform_reduction. 7339 For the other cases try without the single cycle optimization. */ 7340 if (!ok) 7341 { 7342 if (lane_reduc_code_p) 7343 return false; 7344 else 7345 single_defuse_cycle = false; 7346 } 7347 } 7348 STMT_VINFO_FORCE_SINGLE_CYCLE (reduc_info) = single_defuse_cycle; 7349 7350 /* If the reduction stmt is one of the patterns that have lane 7351 reduction embedded we cannot handle the case of ! single_defuse_cycle. */ 7352 if ((ncopies > 1 && ! single_defuse_cycle) 7353 && lane_reduc_code_p) 7354 { 7355 if (dump_enabled_p ()) 7356 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7357 "multi def-use cycle not possible for lane-reducing " 7358 "reduction operation\n"); 7359 return false; 7360 } 7361 7362 if (slp_node 7363 && !(!single_defuse_cycle 7364 && !lane_reduc_code_p 7365 && reduction_type != FOLD_LEFT_REDUCTION)) 7366 for (i = 0; i < (int) op.num_ops; i++) 7367 if (!vect_maybe_update_slp_op_vectype (slp_op[i], vectype_op[i])) 7368 { 7369 if (dump_enabled_p ()) 7370 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7371 "incompatible vector types for invariants\n"); 7372 return false; 7373 } 7374 7375 if (slp_node) 7376 vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); 7377 else 7378 vec_num = 1; 7379 7380 vect_model_reduction_cost (loop_vinfo, stmt_info, reduc_fn, 7381 reduction_type, ncopies, cost_vec); 7382 /* Cost the reduction op inside the loop if transformed via 7383 vect_transform_reduction. Otherwise this is costed by the 7384 separate vectorizable_* routines. */ 7385 if (single_defuse_cycle || lane_reduc_code_p) 7386 record_stmt_cost (cost_vec, ncopies, vector_stmt, stmt_info, 0, vect_body); 7387 7388 if (dump_enabled_p () 7389 && reduction_type == FOLD_LEFT_REDUCTION) 7390 dump_printf_loc (MSG_NOTE, vect_location, 7391 "using an in-order (fold-left) reduction.\n"); 7392 STMT_VINFO_TYPE (orig_stmt_of_analysis) = cycle_phi_info_type; 7393 /* All but single defuse-cycle optimized, lane-reducing and fold-left 7394 reductions go through their own vectorizable_* routines. */ 7395 if (!single_defuse_cycle 7396 && !lane_reduc_code_p 7397 && reduction_type != FOLD_LEFT_REDUCTION) 7398 { 7399 stmt_vec_info tem 7400 = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (phi_info)); 7401 if (slp_node && REDUC_GROUP_FIRST_ELEMENT (tem)) 7402 { 7403 gcc_assert (!REDUC_GROUP_NEXT_ELEMENT (tem)); 7404 tem = REDUC_GROUP_FIRST_ELEMENT (tem); 7405 } 7406 STMT_VINFO_DEF_TYPE (vect_orig_stmt (tem)) = vect_internal_def; 7407 STMT_VINFO_DEF_TYPE (tem) = vect_internal_def; 7408 } 7409 else if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) 7410 { 7411 vec_loop_masks *masks = &LOOP_VINFO_MASKS (loop_vinfo); 7412 internal_fn cond_fn = get_conditional_internal_fn (op.code, op.type); 7413 7414 if (reduction_type != FOLD_LEFT_REDUCTION 7415 && !use_mask_by_cond_expr_p (op.code, cond_fn, vectype_in) 7416 && (cond_fn == IFN_LAST 7417 || !direct_internal_fn_supported_p (cond_fn, vectype_in, 7418 OPTIMIZE_FOR_SPEED))) 7419 { 7420 if (dump_enabled_p ()) 7421 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7422 "can't operate on partial vectors because" 7423 " no conditional operation is available.\n"); 7424 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 7425 } 7426 else if (reduction_type == FOLD_LEFT_REDUCTION 7427 && reduc_fn == IFN_LAST 7428 && !expand_vec_cond_expr_p (vectype_in, 7429 truth_type_for (vectype_in), 7430 SSA_NAME)) 7431 { 7432 if (dump_enabled_p ()) 7433 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7434 "can't operate on partial vectors because" 7435 " no conditional operation is available.\n"); 7436 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 7437 } 7438 else 7439 vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, 7440 vectype_in, NULL); 7441 } 7442 return true; 7443 } 7444 7445 /* Transform the definition stmt STMT_INFO of a reduction PHI backedge 7446 value. */ 7447 7448 bool 7449 vect_transform_reduction (loop_vec_info loop_vinfo, 7450 stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, 7451 gimple **vec_stmt, slp_tree slp_node) 7452 { 7453 tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); 7454 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 7455 int i; 7456 int ncopies; 7457 int vec_num; 7458 7459 stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); 7460 gcc_assert (reduc_info->is_reduc_info); 7461 7462 if (nested_in_vect_loop_p (loop, stmt_info)) 7463 { 7464 loop = loop->inner; 7465 gcc_assert (STMT_VINFO_DEF_TYPE (reduc_info) == vect_double_reduction_def); 7466 } 7467 7468 gimple_match_op op; 7469 if (!gimple_extract_op (stmt_info->stmt, &op)) 7470 gcc_unreachable (); 7471 7472 /* All uses but the last are expected to be defined in the loop. 7473 The last use is the reduction variable. In case of nested cycle this 7474 assumption is not true: we use reduc_index to record the index of the 7475 reduction variable. */ 7476 stmt_vec_info phi_info = STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info)); 7477 gphi *reduc_def_phi = as_a <gphi *> (phi_info->stmt); 7478 int reduc_index = STMT_VINFO_REDUC_IDX (stmt_info); 7479 tree vectype_in = STMT_VINFO_REDUC_VECTYPE_IN (reduc_info); 7480 7481 if (slp_node) 7482 { 7483 ncopies = 1; 7484 vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); 7485 } 7486 else 7487 { 7488 ncopies = vect_get_num_copies (loop_vinfo, vectype_in); 7489 vec_num = 1; 7490 } 7491 7492 code_helper code = canonicalize_code (op.code, op.type); 7493 internal_fn cond_fn = get_conditional_internal_fn (code, op.type); 7494 vec_loop_masks *masks = &LOOP_VINFO_MASKS (loop_vinfo); 7495 bool mask_by_cond_expr = use_mask_by_cond_expr_p (code, cond_fn, vectype_in); 7496 7497 /* Transform. */ 7498 tree new_temp = NULL_TREE; 7499 auto_vec<tree> vec_oprnds0; 7500 auto_vec<tree> vec_oprnds1; 7501 auto_vec<tree> vec_oprnds2; 7502 tree def0; 7503 7504 if (dump_enabled_p ()) 7505 dump_printf_loc (MSG_NOTE, vect_location, "transform reduction.\n"); 7506 7507 /* FORNOW: Multiple types are not supported for condition. */ 7508 if (code == COND_EXPR) 7509 gcc_assert (ncopies == 1); 7510 7511 bool masked_loop_p = LOOP_VINFO_FULLY_MASKED_P (loop_vinfo); 7512 7513 vect_reduction_type reduction_type = STMT_VINFO_REDUC_TYPE (reduc_info); 7514 if (reduction_type == FOLD_LEFT_REDUCTION) 7515 { 7516 internal_fn reduc_fn = STMT_VINFO_REDUC_FN (reduc_info); 7517 gcc_assert (code.is_tree_code ()); 7518 return vectorize_fold_left_reduction 7519 (loop_vinfo, stmt_info, gsi, vec_stmt, slp_node, reduc_def_phi, 7520 tree_code (code), reduc_fn, op.ops, vectype_in, reduc_index, masks); 7521 } 7522 7523 bool single_defuse_cycle = STMT_VINFO_FORCE_SINGLE_CYCLE (reduc_info); 7524 gcc_assert (single_defuse_cycle 7525 || code == DOT_PROD_EXPR 7526 || code == WIDEN_SUM_EXPR 7527 || code == SAD_EXPR); 7528 7529 /* Create the destination vector */ 7530 tree scalar_dest = gimple_get_lhs (stmt_info->stmt); 7531 tree vec_dest = vect_create_destination_var (scalar_dest, vectype_out); 7532 7533 vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies, 7534 single_defuse_cycle && reduc_index == 0 7535 ? NULL_TREE : op.ops[0], &vec_oprnds0, 7536 single_defuse_cycle && reduc_index == 1 7537 ? NULL_TREE : op.ops[1], &vec_oprnds1, 7538 op.num_ops == 3 7539 && !(single_defuse_cycle && reduc_index == 2) 7540 ? op.ops[2] : NULL_TREE, &vec_oprnds2); 7541 if (single_defuse_cycle) 7542 { 7543 gcc_assert (!slp_node); 7544 vect_get_vec_defs_for_operand (loop_vinfo, stmt_info, 1, 7545 op.ops[reduc_index], 7546 reduc_index == 0 ? &vec_oprnds0 7547 : (reduc_index == 1 ? &vec_oprnds1 7548 : &vec_oprnds2)); 7549 } 7550 7551 FOR_EACH_VEC_ELT (vec_oprnds0, i, def0) 7552 { 7553 gimple *new_stmt; 7554 tree vop[3] = { def0, vec_oprnds1[i], NULL_TREE }; 7555 if (masked_loop_p && !mask_by_cond_expr) 7556 { 7557 /* Make sure that the reduction accumulator is vop[0]. */ 7558 if (reduc_index == 1) 7559 { 7560 gcc_assert (commutative_binary_op_p (code, op.type)); 7561 std::swap (vop[0], vop[1]); 7562 } 7563 tree mask = vect_get_loop_mask (gsi, masks, vec_num * ncopies, 7564 vectype_in, i); 7565 gcall *call = gimple_build_call_internal (cond_fn, 4, mask, 7566 vop[0], vop[1], vop[0]); 7567 new_temp = make_ssa_name (vec_dest, call); 7568 gimple_call_set_lhs (call, new_temp); 7569 gimple_call_set_nothrow (call, true); 7570 vect_finish_stmt_generation (loop_vinfo, stmt_info, call, gsi); 7571 new_stmt = call; 7572 } 7573 else 7574 { 7575 if (op.num_ops == 3) 7576 vop[2] = vec_oprnds2[i]; 7577 7578 if (masked_loop_p && mask_by_cond_expr) 7579 { 7580 tree mask = vect_get_loop_mask (gsi, masks, vec_num * ncopies, 7581 vectype_in, i); 7582 build_vect_cond_expr (code, vop, mask, gsi); 7583 } 7584 7585 if (code.is_internal_fn ()) 7586 new_stmt = gimple_build_call_internal (internal_fn (code), 7587 op.num_ops, 7588 vop[0], vop[1], vop[2]); 7589 else 7590 new_stmt = gimple_build_assign (vec_dest, tree_code (op.code), 7591 vop[0], vop[1], vop[2]); 7592 new_temp = make_ssa_name (vec_dest, new_stmt); 7593 gimple_set_lhs (new_stmt, new_temp); 7594 vect_finish_stmt_generation (loop_vinfo, stmt_info, new_stmt, gsi); 7595 } 7596 7597 if (slp_node) 7598 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); 7599 else if (single_defuse_cycle 7600 && i < ncopies - 1) 7601 { 7602 if (reduc_index == 0) 7603 vec_oprnds0.safe_push (gimple_get_lhs (new_stmt)); 7604 else if (reduc_index == 1) 7605 vec_oprnds1.safe_push (gimple_get_lhs (new_stmt)); 7606 else if (reduc_index == 2) 7607 vec_oprnds2.safe_push (gimple_get_lhs (new_stmt)); 7608 } 7609 else 7610 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); 7611 } 7612 7613 if (!slp_node) 7614 *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; 7615 7616 return true; 7617 } 7618 7619 /* Transform phase of a cycle PHI. */ 7620 7621 bool 7622 vect_transform_cycle_phi (loop_vec_info loop_vinfo, 7623 stmt_vec_info stmt_info, gimple **vec_stmt, 7624 slp_tree slp_node, slp_instance slp_node_instance) 7625 { 7626 tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); 7627 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 7628 int i; 7629 int ncopies; 7630 int j; 7631 bool nested_cycle = false; 7632 int vec_num; 7633 7634 if (nested_in_vect_loop_p (loop, stmt_info)) 7635 { 7636 loop = loop->inner; 7637 nested_cycle = true; 7638 } 7639 7640 stmt_vec_info reduc_stmt_info = STMT_VINFO_REDUC_DEF (stmt_info); 7641 reduc_stmt_info = vect_stmt_to_vectorize (reduc_stmt_info); 7642 stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); 7643 gcc_assert (reduc_info->is_reduc_info); 7644 7645 if (STMT_VINFO_REDUC_TYPE (reduc_info) == EXTRACT_LAST_REDUCTION 7646 || STMT_VINFO_REDUC_TYPE (reduc_info) == FOLD_LEFT_REDUCTION) 7647 /* Leave the scalar phi in place. */ 7648 return true; 7649 7650 tree vectype_in = STMT_VINFO_REDUC_VECTYPE_IN (reduc_info); 7651 /* For a nested cycle we do not fill the above. */ 7652 if (!vectype_in) 7653 vectype_in = STMT_VINFO_VECTYPE (stmt_info); 7654 gcc_assert (vectype_in); 7655 7656 if (slp_node) 7657 { 7658 /* The size vect_schedule_slp_instance computes is off for us. */ 7659 vec_num = vect_get_num_vectors (LOOP_VINFO_VECT_FACTOR (loop_vinfo) 7660 * SLP_TREE_LANES (slp_node), vectype_in); 7661 ncopies = 1; 7662 } 7663 else 7664 { 7665 vec_num = 1; 7666 ncopies = vect_get_num_copies (loop_vinfo, vectype_in); 7667 } 7668 7669 /* Check whether we should use a single PHI node and accumulate 7670 vectors to one before the backedge. */ 7671 if (STMT_VINFO_FORCE_SINGLE_CYCLE (reduc_info)) 7672 ncopies = 1; 7673 7674 /* Create the destination vector */ 7675 gphi *phi = as_a <gphi *> (stmt_info->stmt); 7676 tree vec_dest = vect_create_destination_var (gimple_phi_result (phi), 7677 vectype_out); 7678 7679 /* Get the loop-entry arguments. */ 7680 tree vec_initial_def = NULL_TREE; 7681 auto_vec<tree> vec_initial_defs; 7682 if (slp_node) 7683 { 7684 vec_initial_defs.reserve (vec_num); 7685 if (nested_cycle) 7686 { 7687 unsigned phi_idx = loop_preheader_edge (loop)->dest_idx; 7688 vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[phi_idx], 7689 &vec_initial_defs); 7690 } 7691 else 7692 { 7693 gcc_assert (slp_node == slp_node_instance->reduc_phis); 7694 vec<tree> &initial_values = reduc_info->reduc_initial_values; 7695 vec<stmt_vec_info> &stmts = SLP_TREE_SCALAR_STMTS (slp_node); 7696 7697 unsigned int num_phis = stmts.length (); 7698 if (REDUC_GROUP_FIRST_ELEMENT (reduc_stmt_info)) 7699 num_phis = 1; 7700 initial_values.reserve (num_phis); 7701 for (unsigned int i = 0; i < num_phis; ++i) 7702 { 7703 gphi *this_phi = as_a<gphi *> (stmts[i]->stmt); 7704 initial_values.quick_push (vect_phi_initial_value (this_phi)); 7705 } 7706 if (vec_num == 1) 7707 vect_find_reusable_accumulator (loop_vinfo, reduc_info); 7708 if (!initial_values.is_empty ()) 7709 { 7710 tree initial_value 7711 = (num_phis == 1 ? initial_values[0] : NULL_TREE); 7712 code_helper code = STMT_VINFO_REDUC_CODE (reduc_info); 7713 tree neutral_op 7714 = neutral_op_for_reduction (TREE_TYPE (vectype_out), 7715 code, initial_value); 7716 get_initial_defs_for_reduction (loop_vinfo, reduc_info, 7717 &vec_initial_defs, vec_num, 7718 stmts.length (), neutral_op); 7719 } 7720 } 7721 } 7722 else 7723 { 7724 /* Get at the scalar def before the loop, that defines the initial 7725 value of the reduction variable. */ 7726 tree initial_def = vect_phi_initial_value (phi); 7727 reduc_info->reduc_initial_values.safe_push (initial_def); 7728 /* Optimize: if initial_def is for REDUC_MAX smaller than the base 7729 and we can't use zero for induc_val, use initial_def. Similarly 7730 for REDUC_MIN and initial_def larger than the base. */ 7731 if (STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION) 7732 { 7733 tree induc_val = STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info); 7734 if (TREE_CODE (initial_def) == INTEGER_CST 7735 && !integer_zerop (induc_val) 7736 && ((STMT_VINFO_REDUC_CODE (reduc_info) == MAX_EXPR 7737 && tree_int_cst_lt (initial_def, induc_val)) 7738 || (STMT_VINFO_REDUC_CODE (reduc_info) == MIN_EXPR 7739 && tree_int_cst_lt (induc_val, initial_def)))) 7740 { 7741 induc_val = initial_def; 7742 /* Communicate we used the initial_def to epilouge 7743 generation. */ 7744 STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info) = NULL_TREE; 7745 } 7746 vec_initial_def = build_vector_from_val (vectype_out, induc_val); 7747 } 7748 else if (nested_cycle) 7749 { 7750 /* Do not use an adjustment def as that case is not supported 7751 correctly if ncopies is not one. */ 7752 vect_get_vec_defs_for_operand (loop_vinfo, reduc_stmt_info, 7753 ncopies, initial_def, 7754 &vec_initial_defs); 7755 } 7756 else if (STMT_VINFO_REDUC_TYPE (reduc_info) == CONST_COND_REDUCTION 7757 || STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION) 7758 /* Fill the initial vector with the initial scalar value. */ 7759 vec_initial_def 7760 = get_initial_def_for_reduction (loop_vinfo, reduc_stmt_info, 7761 initial_def, initial_def); 7762 else 7763 { 7764 if (ncopies == 1) 7765 vect_find_reusable_accumulator (loop_vinfo, reduc_info); 7766 if (!reduc_info->reduc_initial_values.is_empty ()) 7767 { 7768 initial_def = reduc_info->reduc_initial_values[0]; 7769 code_helper code = STMT_VINFO_REDUC_CODE (reduc_info); 7770 tree neutral_op 7771 = neutral_op_for_reduction (TREE_TYPE (initial_def), 7772 code, initial_def); 7773 gcc_assert (neutral_op); 7774 /* Try to simplify the vector initialization by applying an 7775 adjustment after the reduction has been performed. */ 7776 if (!reduc_info->reused_accumulator 7777 && STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def 7778 && !operand_equal_p (neutral_op, initial_def)) 7779 { 7780 STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (reduc_info) 7781 = initial_def; 7782 initial_def = neutral_op; 7783 } 7784 vec_initial_def 7785 = get_initial_def_for_reduction (loop_vinfo, reduc_info, 7786 initial_def, neutral_op); 7787 } 7788 } 7789 } 7790 7791 if (vec_initial_def) 7792 { 7793 vec_initial_defs.create (ncopies); 7794 for (i = 0; i < ncopies; ++i) 7795 vec_initial_defs.quick_push (vec_initial_def); 7796 } 7797 7798 if (auto *accumulator = reduc_info->reused_accumulator) 7799 { 7800 tree def = accumulator->reduc_input; 7801 if (!useless_type_conversion_p (vectype_out, TREE_TYPE (def))) 7802 { 7803 unsigned int nreduc; 7804 bool res = constant_multiple_p (TYPE_VECTOR_SUBPARTS 7805 (TREE_TYPE (def)), 7806 TYPE_VECTOR_SUBPARTS (vectype_out), 7807 &nreduc); 7808 gcc_assert (res); 7809 gimple_seq stmts = NULL; 7810 /* Reduce the single vector to a smaller one. */ 7811 if (nreduc != 1) 7812 { 7813 /* Perform the reduction in the appropriate type. */ 7814 tree rvectype = vectype_out; 7815 if (!useless_type_conversion_p (TREE_TYPE (vectype_out), 7816 TREE_TYPE (TREE_TYPE (def)))) 7817 rvectype = build_vector_type (TREE_TYPE (TREE_TYPE (def)), 7818 TYPE_VECTOR_SUBPARTS 7819 (vectype_out)); 7820 def = vect_create_partial_epilog (def, rvectype, 7821 STMT_VINFO_REDUC_CODE 7822 (reduc_info), 7823 &stmts); 7824 } 7825 /* The epilogue loop might use a different vector mode, like 7826 VNx2DI vs. V2DI. */ 7827 if (TYPE_MODE (vectype_out) != TYPE_MODE (TREE_TYPE (def))) 7828 { 7829 tree reduc_type = build_vector_type_for_mode 7830 (TREE_TYPE (TREE_TYPE (def)), TYPE_MODE (vectype_out)); 7831 def = gimple_convert (&stmts, reduc_type, def); 7832 } 7833 /* Adjust the input so we pick up the partially reduced value 7834 for the skip edge in vect_create_epilog_for_reduction. */ 7835 accumulator->reduc_input = def; 7836 /* And the reduction could be carried out using a different sign. */ 7837 if (!useless_type_conversion_p (vectype_out, TREE_TYPE (def))) 7838 def = gimple_convert (&stmts, vectype_out, def); 7839 if (loop_vinfo->main_loop_edge) 7840 { 7841 /* While we'd like to insert on the edge this will split 7842 blocks and disturb bookkeeping, we also will eventually 7843 need this on the skip edge. Rely on sinking to 7844 fixup optimal placement and insert in the pred. */ 7845 gimple_stmt_iterator gsi 7846 = gsi_last_bb (loop_vinfo->main_loop_edge->src); 7847 /* Insert before a cond that eventually skips the 7848 epilogue. */ 7849 if (!gsi_end_p (gsi) && stmt_ends_bb_p (gsi_stmt (gsi))) 7850 gsi_prev (&gsi); 7851 gsi_insert_seq_after (&gsi, stmts, GSI_CONTINUE_LINKING); 7852 } 7853 else 7854 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), 7855 stmts); 7856 } 7857 if (loop_vinfo->main_loop_edge) 7858 vec_initial_defs[0] 7859 = vect_get_main_loop_result (loop_vinfo, def, 7860 vec_initial_defs[0]); 7861 else 7862 vec_initial_defs.safe_push (def); 7863 } 7864 7865 /* Generate the reduction PHIs upfront. */ 7866 for (i = 0; i < vec_num; i++) 7867 { 7868 tree vec_init_def = vec_initial_defs[i]; 7869 for (j = 0; j < ncopies; j++) 7870 { 7871 /* Create the reduction-phi that defines the reduction 7872 operand. */ 7873 gphi *new_phi = create_phi_node (vec_dest, loop->header); 7874 7875 /* Set the loop-entry arg of the reduction-phi. */ 7876 if (j != 0 && nested_cycle) 7877 vec_init_def = vec_initial_defs[j]; 7878 add_phi_arg (new_phi, vec_init_def, loop_preheader_edge (loop), 7879 UNKNOWN_LOCATION); 7880 7881 /* The loop-latch arg is set in epilogue processing. */ 7882 7883 if (slp_node) 7884 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phi); 7885 else 7886 { 7887 if (j == 0) 7888 *vec_stmt = new_phi; 7889 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_phi); 7890 } 7891 } 7892 } 7893 7894 return true; 7895 } 7896 7897 /* Vectorizes LC PHIs. */ 7898 7899 bool 7900 vectorizable_lc_phi (loop_vec_info loop_vinfo, 7901 stmt_vec_info stmt_info, gimple **vec_stmt, 7902 slp_tree slp_node) 7903 { 7904 if (!loop_vinfo 7905 || !is_a <gphi *> (stmt_info->stmt) 7906 || gimple_phi_num_args (stmt_info->stmt) != 1) 7907 return false; 7908 7909 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def 7910 && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def) 7911 return false; 7912 7913 if (!vec_stmt) /* transformation not required. */ 7914 { 7915 /* Deal with copies from externs or constants that disguise as 7916 loop-closed PHI nodes (PR97886). */ 7917 if (slp_node 7918 && !vect_maybe_update_slp_op_vectype (SLP_TREE_CHILDREN (slp_node)[0], 7919 SLP_TREE_VECTYPE (slp_node))) 7920 { 7921 if (dump_enabled_p ()) 7922 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7923 "incompatible vector types for invariants\n"); 7924 return false; 7925 } 7926 STMT_VINFO_TYPE (stmt_info) = lc_phi_info_type; 7927 return true; 7928 } 7929 7930 tree vectype = STMT_VINFO_VECTYPE (stmt_info); 7931 tree scalar_dest = gimple_phi_result (stmt_info->stmt); 7932 basic_block bb = gimple_bb (stmt_info->stmt); 7933 edge e = single_pred_edge (bb); 7934 tree vec_dest = vect_create_destination_var (scalar_dest, vectype); 7935 auto_vec<tree> vec_oprnds; 7936 vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, 7937 !slp_node ? vect_get_num_copies (loop_vinfo, vectype) : 1, 7938 gimple_phi_arg_def (stmt_info->stmt, 0), &vec_oprnds); 7939 for (unsigned i = 0; i < vec_oprnds.length (); i++) 7940 { 7941 /* Create the vectorized LC PHI node. */ 7942 gphi *new_phi = create_phi_node (vec_dest, bb); 7943 add_phi_arg (new_phi, vec_oprnds[i], e, UNKNOWN_LOCATION); 7944 if (slp_node) 7945 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phi); 7946 else 7947 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_phi); 7948 } 7949 if (!slp_node) 7950 *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; 7951 7952 return true; 7953 } 7954 7955 /* Vectorizes PHIs. */ 7956 7957 bool 7958 vectorizable_phi (vec_info *, 7959 stmt_vec_info stmt_info, gimple **vec_stmt, 7960 slp_tree slp_node, stmt_vector_for_cost *cost_vec) 7961 { 7962 if (!is_a <gphi *> (stmt_info->stmt) || !slp_node) 7963 return false; 7964 7965 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def) 7966 return false; 7967 7968 tree vectype = SLP_TREE_VECTYPE (slp_node); 7969 7970 if (!vec_stmt) /* transformation not required. */ 7971 { 7972 slp_tree child; 7973 unsigned i; 7974 FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (slp_node), i, child) 7975 if (!child) 7976 { 7977 if (dump_enabled_p ()) 7978 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7979 "PHI node with unvectorized backedge def\n"); 7980 return false; 7981 } 7982 else if (!vect_maybe_update_slp_op_vectype (child, vectype)) 7983 { 7984 if (dump_enabled_p ()) 7985 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 7986 "incompatible vector types for invariants\n"); 7987 return false; 7988 } 7989 else if (SLP_TREE_DEF_TYPE (child) == vect_internal_def 7990 && !useless_type_conversion_p (vectype, 7991 SLP_TREE_VECTYPE (child))) 7992 { 7993 /* With bools we can have mask and non-mask precision vectors 7994 or different non-mask precisions. while pattern recog is 7995 supposed to guarantee consistency here bugs in it can cause 7996 mismatches (PR103489 and PR103800 for example). 7997 Deal with them here instead of ICEing later. */ 7998 if (dump_enabled_p ()) 7999 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8000 "incompatible vector type setup from " 8001 "bool pattern detection\n"); 8002 return false; 8003 } 8004 8005 /* For single-argument PHIs assume coalescing which means zero cost 8006 for the scalar and the vector PHIs. This avoids artificially 8007 favoring the vector path (but may pessimize it in some cases). */ 8008 if (gimple_phi_num_args (as_a <gphi *> (stmt_info->stmt)) > 1) 8009 record_stmt_cost (cost_vec, SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node), 8010 vector_stmt, stmt_info, vectype, 0, vect_body); 8011 STMT_VINFO_TYPE (stmt_info) = phi_info_type; 8012 return true; 8013 } 8014 8015 tree scalar_dest = gimple_phi_result (stmt_info->stmt); 8016 basic_block bb = gimple_bb (stmt_info->stmt); 8017 tree vec_dest = vect_create_destination_var (scalar_dest, vectype); 8018 auto_vec<gphi *> new_phis; 8019 for (unsigned i = 0; i < gimple_phi_num_args (stmt_info->stmt); ++i) 8020 { 8021 slp_tree child = SLP_TREE_CHILDREN (slp_node)[i]; 8022 8023 /* Skip not yet vectorized defs. */ 8024 if (SLP_TREE_DEF_TYPE (child) == vect_internal_def 8025 && SLP_TREE_VEC_STMTS (child).is_empty ()) 8026 continue; 8027 8028 auto_vec<tree> vec_oprnds; 8029 vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[i], &vec_oprnds); 8030 if (!new_phis.exists ()) 8031 { 8032 new_phis.create (vec_oprnds.length ()); 8033 for (unsigned j = 0; j < vec_oprnds.length (); j++) 8034 { 8035 /* Create the vectorized LC PHI node. */ 8036 new_phis.quick_push (create_phi_node (vec_dest, bb)); 8037 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phis[j]); 8038 } 8039 } 8040 edge e = gimple_phi_arg_edge (as_a <gphi *> (stmt_info->stmt), i); 8041 for (unsigned j = 0; j < vec_oprnds.length (); j++) 8042 add_phi_arg (new_phis[j], vec_oprnds[j], e, UNKNOWN_LOCATION); 8043 } 8044 /* We should have at least one already vectorized child. */ 8045 gcc_assert (new_phis.exists ()); 8046 8047 return true; 8048 } 8049 8050 /* Return true if VECTYPE represents a vector that requires lowering 8051 by the vector lowering pass. */ 8052 8053 bool 8054 vect_emulated_vector_p (tree vectype) 8055 { 8056 return (!VECTOR_MODE_P (TYPE_MODE (vectype)) 8057 && (!VECTOR_BOOLEAN_TYPE_P (vectype) 8058 || TYPE_PRECISION (TREE_TYPE (vectype)) != 1)); 8059 } 8060 8061 /* Return true if we can emulate CODE on an integer mode representation 8062 of a vector. */ 8063 8064 bool 8065 vect_can_vectorize_without_simd_p (tree_code code) 8066 { 8067 switch (code) 8068 { 8069 case PLUS_EXPR: 8070 case MINUS_EXPR: 8071 case NEGATE_EXPR: 8072 case BIT_AND_EXPR: 8073 case BIT_IOR_EXPR: 8074 case BIT_XOR_EXPR: 8075 case BIT_NOT_EXPR: 8076 return true; 8077 8078 default: 8079 return false; 8080 } 8081 } 8082 8083 /* Likewise, but taking a code_helper. */ 8084 8085 bool 8086 vect_can_vectorize_without_simd_p (code_helper code) 8087 { 8088 return (code.is_tree_code () 8089 && vect_can_vectorize_without_simd_p (tree_code (code))); 8090 } 8091 8092 /* Function vectorizable_induction 8093 8094 Check if STMT_INFO performs an induction computation that can be vectorized. 8095 If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized 8096 phi to replace it, put it in VEC_STMT, and add it to the same basic block. 8097 Return true if STMT_INFO is vectorizable in this way. */ 8098 8099 bool 8100 vectorizable_induction (loop_vec_info loop_vinfo, 8101 stmt_vec_info stmt_info, 8102 gimple **vec_stmt, slp_tree slp_node, 8103 stmt_vector_for_cost *cost_vec) 8104 { 8105 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 8106 unsigned ncopies; 8107 bool nested_in_vect_loop = false; 8108 class loop *iv_loop; 8109 tree vec_def; 8110 edge pe = loop_preheader_edge (loop); 8111 basic_block new_bb; 8112 tree new_vec, vec_init, vec_step, t; 8113 tree new_name; 8114 gimple *new_stmt; 8115 gphi *induction_phi; 8116 tree induc_def, vec_dest; 8117 tree init_expr, step_expr; 8118 poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 8119 unsigned i; 8120 tree expr; 8121 gimple_stmt_iterator si; 8122 8123 gphi *phi = dyn_cast <gphi *> (stmt_info->stmt); 8124 if (!phi) 8125 return false; 8126 8127 if (!STMT_VINFO_RELEVANT_P (stmt_info)) 8128 return false; 8129 8130 /* Make sure it was recognized as induction computation. */ 8131 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def) 8132 return false; 8133 8134 tree vectype = STMT_VINFO_VECTYPE (stmt_info); 8135 poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); 8136 8137 if (slp_node) 8138 ncopies = 1; 8139 else 8140 ncopies = vect_get_num_copies (loop_vinfo, vectype); 8141 gcc_assert (ncopies >= 1); 8142 8143 /* FORNOW. These restrictions should be relaxed. */ 8144 if (nested_in_vect_loop_p (loop, stmt_info)) 8145 { 8146 imm_use_iterator imm_iter; 8147 use_operand_p use_p; 8148 gimple *exit_phi; 8149 edge latch_e; 8150 tree loop_arg; 8151 8152 if (ncopies > 1) 8153 { 8154 if (dump_enabled_p ()) 8155 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8156 "multiple types in nested loop.\n"); 8157 return false; 8158 } 8159 8160 exit_phi = NULL; 8161 latch_e = loop_latch_edge (loop->inner); 8162 loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e); 8163 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg) 8164 { 8165 gimple *use_stmt = USE_STMT (use_p); 8166 if (is_gimple_debug (use_stmt)) 8167 continue; 8168 8169 if (!flow_bb_inside_loop_p (loop->inner, gimple_bb (use_stmt))) 8170 { 8171 exit_phi = use_stmt; 8172 break; 8173 } 8174 } 8175 if (exit_phi) 8176 { 8177 stmt_vec_info exit_phi_vinfo = loop_vinfo->lookup_stmt (exit_phi); 8178 if (!(STMT_VINFO_RELEVANT_P (exit_phi_vinfo) 8179 && !STMT_VINFO_LIVE_P (exit_phi_vinfo))) 8180 { 8181 if (dump_enabled_p ()) 8182 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8183 "inner-loop induction only used outside " 8184 "of the outer vectorized loop.\n"); 8185 return false; 8186 } 8187 } 8188 8189 nested_in_vect_loop = true; 8190 iv_loop = loop->inner; 8191 } 8192 else 8193 iv_loop = loop; 8194 gcc_assert (iv_loop == (gimple_bb (phi))->loop_father); 8195 8196 if (slp_node && !nunits.is_constant ()) 8197 { 8198 /* The current SLP code creates the step value element-by-element. */ 8199 if (dump_enabled_p ()) 8200 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8201 "SLP induction not supported for variable-length" 8202 " vectors.\n"); 8203 return false; 8204 } 8205 8206 if (FLOAT_TYPE_P (vectype) && !param_vect_induction_float) 8207 { 8208 if (dump_enabled_p ()) 8209 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8210 "floating point induction vectorization disabled\n"); 8211 return false; 8212 } 8213 8214 step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info); 8215 gcc_assert (step_expr != NULL_TREE); 8216 if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr)) 8217 && !type_has_mode_precision_p (TREE_TYPE (step_expr))) 8218 { 8219 if (dump_enabled_p ()) 8220 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8221 "bit-precision induction vectorization not " 8222 "supported.\n"); 8223 return false; 8224 } 8225 tree step_vectype = get_same_sized_vectype (TREE_TYPE (step_expr), vectype); 8226 8227 /* Check for backend support of PLUS/MINUS_EXPR. */ 8228 if (!directly_supported_p (PLUS_EXPR, step_vectype) 8229 || !directly_supported_p (MINUS_EXPR, step_vectype)) 8230 return false; 8231 8232 if (!vec_stmt) /* transformation not required. */ 8233 { 8234 unsigned inside_cost = 0, prologue_cost = 0; 8235 if (slp_node) 8236 { 8237 /* We eventually need to set a vector type on invariant 8238 arguments. */ 8239 unsigned j; 8240 slp_tree child; 8241 FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (slp_node), j, child) 8242 if (!vect_maybe_update_slp_op_vectype 8243 (child, SLP_TREE_VECTYPE (slp_node))) 8244 { 8245 if (dump_enabled_p ()) 8246 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8247 "incompatible vector types for " 8248 "invariants\n"); 8249 return false; 8250 } 8251 /* loop cost for vec_loop. */ 8252 inside_cost 8253 = record_stmt_cost (cost_vec, 8254 SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node), 8255 vector_stmt, stmt_info, 0, vect_body); 8256 /* prologue cost for vec_init (if not nested) and step. */ 8257 prologue_cost = record_stmt_cost (cost_vec, 1 + !nested_in_vect_loop, 8258 scalar_to_vec, 8259 stmt_info, 0, vect_prologue); 8260 } 8261 else /* if (!slp_node) */ 8262 { 8263 /* loop cost for vec_loop. */ 8264 inside_cost = record_stmt_cost (cost_vec, ncopies, vector_stmt, 8265 stmt_info, 0, vect_body); 8266 /* prologue cost for vec_init and vec_step. */ 8267 prologue_cost = record_stmt_cost (cost_vec, 2, scalar_to_vec, 8268 stmt_info, 0, vect_prologue); 8269 } 8270 if (dump_enabled_p ()) 8271 dump_printf_loc (MSG_NOTE, vect_location, 8272 "vect_model_induction_cost: inside_cost = %d, " 8273 "prologue_cost = %d .\n", inside_cost, 8274 prologue_cost); 8275 8276 STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type; 8277 DUMP_VECT_SCOPE ("vectorizable_induction"); 8278 return true; 8279 } 8280 8281 /* Transform. */ 8282 8283 /* Compute a vector variable, initialized with the first VF values of 8284 the induction variable. E.g., for an iv with IV_PHI='X' and 8285 evolution S, for a vector of 4 units, we want to compute: 8286 [X, X + S, X + 2*S, X + 3*S]. */ 8287 8288 if (dump_enabled_p ()) 8289 dump_printf_loc (MSG_NOTE, vect_location, "transform induction phi.\n"); 8290 8291 pe = loop_preheader_edge (iv_loop); 8292 /* Find the first insertion point in the BB. */ 8293 basic_block bb = gimple_bb (phi); 8294 si = gsi_after_labels (bb); 8295 8296 /* For SLP induction we have to generate several IVs as for example 8297 with group size 3 we need 8298 [i0, i1, i2, i0 + S0] [i1 + S1, i2 + S2, i0 + 2*S0, i1 + 2*S1] 8299 [i2 + 2*S2, i0 + 3*S0, i1 + 3*S1, i2 + 3*S2]. */ 8300 if (slp_node) 8301 { 8302 /* Enforced above. */ 8303 unsigned int const_nunits = nunits.to_constant (); 8304 8305 /* The initial values are vectorized, but any lanes > group_size 8306 need adjustment. */ 8307 slp_tree init_node 8308 = SLP_TREE_CHILDREN (slp_node)[pe->dest_idx]; 8309 8310 /* Gather steps. Since we do not vectorize inductions as 8311 cycles we have to reconstruct the step from SCEV data. */ 8312 unsigned group_size = SLP_TREE_LANES (slp_node); 8313 tree *steps = XALLOCAVEC (tree, group_size); 8314 tree *inits = XALLOCAVEC (tree, group_size); 8315 stmt_vec_info phi_info; 8316 FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, phi_info) 8317 { 8318 steps[i] = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (phi_info); 8319 if (!init_node) 8320 inits[i] = gimple_phi_arg_def (as_a<gphi *> (phi_info->stmt), 8321 pe->dest_idx); 8322 } 8323 8324 /* Now generate the IVs. */ 8325 unsigned nvects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); 8326 gcc_assert ((const_nunits * nvects) % group_size == 0); 8327 unsigned nivs; 8328 if (nested_in_vect_loop) 8329 nivs = nvects; 8330 else 8331 { 8332 /* Compute the number of distinct IVs we need. First reduce 8333 group_size if it is a multiple of const_nunits so we get 8334 one IV for a group_size of 4 but const_nunits 2. */ 8335 unsigned group_sizep = group_size; 8336 if (group_sizep % const_nunits == 0) 8337 group_sizep = group_sizep / const_nunits; 8338 nivs = least_common_multiple (group_sizep, 8339 const_nunits) / const_nunits; 8340 } 8341 tree stept = TREE_TYPE (step_vectype); 8342 tree lupdate_mul = NULL_TREE; 8343 if (!nested_in_vect_loop) 8344 { 8345 /* The number of iterations covered in one vector iteration. */ 8346 unsigned lup_mul = (nvects * const_nunits) / group_size; 8347 lupdate_mul 8348 = build_vector_from_val (step_vectype, 8349 SCALAR_FLOAT_TYPE_P (stept) 8350 ? build_real_from_wide (stept, lup_mul, 8351 UNSIGNED) 8352 : build_int_cstu (stept, lup_mul)); 8353 } 8354 tree peel_mul = NULL_TREE; 8355 gimple_seq init_stmts = NULL; 8356 if (LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo)) 8357 { 8358 if (SCALAR_FLOAT_TYPE_P (stept)) 8359 peel_mul = gimple_build (&init_stmts, FLOAT_EXPR, stept, 8360 LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo)); 8361 else 8362 peel_mul = gimple_convert (&init_stmts, stept, 8363 LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo)); 8364 peel_mul = gimple_build_vector_from_val (&init_stmts, 8365 step_vectype, peel_mul); 8366 } 8367 unsigned ivn; 8368 auto_vec<tree> vec_steps; 8369 for (ivn = 0; ivn < nivs; ++ivn) 8370 { 8371 tree_vector_builder step_elts (step_vectype, const_nunits, 1); 8372 tree_vector_builder init_elts (vectype, const_nunits, 1); 8373 tree_vector_builder mul_elts (step_vectype, const_nunits, 1); 8374 for (unsigned eltn = 0; eltn < const_nunits; ++eltn) 8375 { 8376 /* The scalar steps of the IVs. */ 8377 tree elt = steps[(ivn*const_nunits + eltn) % group_size]; 8378 elt = gimple_convert (&init_stmts, TREE_TYPE (step_vectype), elt); 8379 step_elts.quick_push (elt); 8380 if (!init_node) 8381 { 8382 /* The scalar inits of the IVs if not vectorized. */ 8383 elt = inits[(ivn*const_nunits + eltn) % group_size]; 8384 if (!useless_type_conversion_p (TREE_TYPE (vectype), 8385 TREE_TYPE (elt))) 8386 elt = gimple_build (&init_stmts, VIEW_CONVERT_EXPR, 8387 TREE_TYPE (vectype), elt); 8388 init_elts.quick_push (elt); 8389 } 8390 /* The number of steps to add to the initial values. */ 8391 unsigned mul_elt = (ivn*const_nunits + eltn) / group_size; 8392 mul_elts.quick_push (SCALAR_FLOAT_TYPE_P (stept) 8393 ? build_real_from_wide (stept, 8394 mul_elt, UNSIGNED) 8395 : build_int_cstu (stept, mul_elt)); 8396 } 8397 vec_step = gimple_build_vector (&init_stmts, &step_elts); 8398 vec_steps.safe_push (vec_step); 8399 tree step_mul = gimple_build_vector (&init_stmts, &mul_elts); 8400 if (peel_mul) 8401 step_mul = gimple_build (&init_stmts, PLUS_EXPR, step_vectype, 8402 step_mul, peel_mul); 8403 if (!init_node) 8404 vec_init = gimple_build_vector (&init_stmts, &init_elts); 8405 8406 /* Create the induction-phi that defines the induction-operand. */ 8407 vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, 8408 "vec_iv_"); 8409 induction_phi = create_phi_node (vec_dest, iv_loop->header); 8410 induc_def = PHI_RESULT (induction_phi); 8411 8412 /* Create the iv update inside the loop */ 8413 tree up = vec_step; 8414 if (lupdate_mul) 8415 up = gimple_build (&init_stmts, MULT_EXPR, step_vectype, 8416 vec_step, lupdate_mul); 8417 gimple_seq stmts = NULL; 8418 vec_def = gimple_convert (&stmts, step_vectype, induc_def); 8419 vec_def = gimple_build (&stmts, 8420 PLUS_EXPR, step_vectype, vec_def, up); 8421 vec_def = gimple_convert (&stmts, vectype, vec_def); 8422 gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); 8423 add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), 8424 UNKNOWN_LOCATION); 8425 8426 if (init_node) 8427 vec_init = vect_get_slp_vect_def (init_node, ivn); 8428 if (!nested_in_vect_loop 8429 && !integer_zerop (step_mul)) 8430 { 8431 vec_def = gimple_convert (&init_stmts, step_vectype, vec_init); 8432 up = gimple_build (&init_stmts, MULT_EXPR, step_vectype, 8433 vec_step, step_mul); 8434 vec_def = gimple_build (&init_stmts, PLUS_EXPR, step_vectype, 8435 vec_def, up); 8436 vec_init = gimple_convert (&init_stmts, vectype, vec_def); 8437 } 8438 8439 /* Set the arguments of the phi node: */ 8440 add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); 8441 8442 SLP_TREE_VEC_STMTS (slp_node).quick_push (induction_phi); 8443 } 8444 if (!nested_in_vect_loop) 8445 { 8446 /* Fill up to the number of vectors we need for the whole group. */ 8447 nivs = least_common_multiple (group_size, 8448 const_nunits) / const_nunits; 8449 vec_steps.reserve (nivs-ivn); 8450 for (; ivn < nivs; ++ivn) 8451 { 8452 SLP_TREE_VEC_STMTS (slp_node) 8453 .quick_push (SLP_TREE_VEC_STMTS (slp_node)[0]); 8454 vec_steps.quick_push (vec_steps[0]); 8455 } 8456 } 8457 8458 /* Re-use IVs when we can. We are generating further vector 8459 stmts by adding VF' * stride to the IVs generated above. */ 8460 if (ivn < nvects) 8461 { 8462 unsigned vfp 8463 = least_common_multiple (group_size, const_nunits) / group_size; 8464 tree lupdate_mul 8465 = build_vector_from_val (step_vectype, 8466 SCALAR_FLOAT_TYPE_P (stept) 8467 ? build_real_from_wide (stept, 8468 vfp, UNSIGNED) 8469 : build_int_cstu (stept, vfp)); 8470 for (; ivn < nvects; ++ivn) 8471 { 8472 gimple *iv = SLP_TREE_VEC_STMTS (slp_node)[ivn - nivs]; 8473 tree def = gimple_get_lhs (iv); 8474 if (ivn < 2*nivs) 8475 vec_steps[ivn - nivs] 8476 = gimple_build (&init_stmts, MULT_EXPR, step_vectype, 8477 vec_steps[ivn - nivs], lupdate_mul); 8478 gimple_seq stmts = NULL; 8479 def = gimple_convert (&stmts, step_vectype, def); 8480 def = gimple_build (&stmts, PLUS_EXPR, step_vectype, 8481 def, vec_steps[ivn % nivs]); 8482 def = gimple_convert (&stmts, vectype, def); 8483 if (gimple_code (iv) == GIMPLE_PHI) 8484 gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); 8485 else 8486 { 8487 gimple_stmt_iterator tgsi = gsi_for_stmt (iv); 8488 gsi_insert_seq_after (&tgsi, stmts, GSI_CONTINUE_LINKING); 8489 } 8490 SLP_TREE_VEC_STMTS (slp_node) 8491 .quick_push (SSA_NAME_DEF_STMT (def)); 8492 } 8493 } 8494 8495 new_bb = gsi_insert_seq_on_edge_immediate (pe, init_stmts); 8496 gcc_assert (!new_bb); 8497 8498 return true; 8499 } 8500 8501 init_expr = vect_phi_initial_value (phi); 8502 8503 gimple_seq stmts = NULL; 8504 if (!nested_in_vect_loop) 8505 { 8506 /* Convert the initial value to the IV update type. */ 8507 tree new_type = TREE_TYPE (step_expr); 8508 init_expr = gimple_convert (&stmts, new_type, init_expr); 8509 8510 /* If we are using the loop mask to "peel" for alignment then we need 8511 to adjust the start value here. */ 8512 tree skip_niters = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo); 8513 if (skip_niters != NULL_TREE) 8514 { 8515 if (FLOAT_TYPE_P (vectype)) 8516 skip_niters = gimple_build (&stmts, FLOAT_EXPR, new_type, 8517 skip_niters); 8518 else 8519 skip_niters = gimple_convert (&stmts, new_type, skip_niters); 8520 tree skip_step = gimple_build (&stmts, MULT_EXPR, new_type, 8521 skip_niters, step_expr); 8522 init_expr = gimple_build (&stmts, MINUS_EXPR, new_type, 8523 init_expr, skip_step); 8524 } 8525 } 8526 8527 if (stmts) 8528 { 8529 new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); 8530 gcc_assert (!new_bb); 8531 } 8532 8533 /* Create the vector that holds the initial_value of the induction. */ 8534 if (nested_in_vect_loop) 8535 { 8536 /* iv_loop is nested in the loop to be vectorized. init_expr had already 8537 been created during vectorization of previous stmts. We obtain it 8538 from the STMT_VINFO_VEC_STMT of the defining stmt. */ 8539 auto_vec<tree> vec_inits; 8540 vect_get_vec_defs_for_operand (loop_vinfo, stmt_info, 1, 8541 init_expr, &vec_inits); 8542 vec_init = vec_inits[0]; 8543 /* If the initial value is not of proper type, convert it. */ 8544 if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init))) 8545 { 8546 new_stmt 8547 = gimple_build_assign (vect_get_new_ssa_name (vectype, 8548 vect_simple_var, 8549 "vec_iv_"), 8550 VIEW_CONVERT_EXPR, 8551 build1 (VIEW_CONVERT_EXPR, vectype, 8552 vec_init)); 8553 vec_init = gimple_assign_lhs (new_stmt); 8554 new_bb = gsi_insert_on_edge_immediate (loop_preheader_edge (iv_loop), 8555 new_stmt); 8556 gcc_assert (!new_bb); 8557 } 8558 } 8559 else 8560 { 8561 /* iv_loop is the loop to be vectorized. Create: 8562 vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ 8563 stmts = NULL; 8564 new_name = gimple_convert (&stmts, TREE_TYPE (step_expr), init_expr); 8565 8566 unsigned HOST_WIDE_INT const_nunits; 8567 if (nunits.is_constant (&const_nunits)) 8568 { 8569 tree_vector_builder elts (step_vectype, const_nunits, 1); 8570 elts.quick_push (new_name); 8571 for (i = 1; i < const_nunits; i++) 8572 { 8573 /* Create: new_name_i = new_name + step_expr */ 8574 new_name = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (new_name), 8575 new_name, step_expr); 8576 elts.quick_push (new_name); 8577 } 8578 /* Create a vector from [new_name_0, new_name_1, ..., 8579 new_name_nunits-1] */ 8580 vec_init = gimple_build_vector (&stmts, &elts); 8581 } 8582 else if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr))) 8583 /* Build the initial value directly from a VEC_SERIES_EXPR. */ 8584 vec_init = gimple_build (&stmts, VEC_SERIES_EXPR, step_vectype, 8585 new_name, step_expr); 8586 else 8587 { 8588 /* Build: 8589 [base, base, base, ...] 8590 + (vectype) [0, 1, 2, ...] * [step, step, step, ...]. */ 8591 gcc_assert (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr))); 8592 gcc_assert (flag_associative_math); 8593 tree index = build_index_vector (step_vectype, 0, 1); 8594 tree base_vec = gimple_build_vector_from_val (&stmts, step_vectype, 8595 new_name); 8596 tree step_vec = gimple_build_vector_from_val (&stmts, step_vectype, 8597 step_expr); 8598 vec_init = gimple_build (&stmts, FLOAT_EXPR, step_vectype, index); 8599 vec_init = gimple_build (&stmts, MULT_EXPR, step_vectype, 8600 vec_init, step_vec); 8601 vec_init = gimple_build (&stmts, PLUS_EXPR, step_vectype, 8602 vec_init, base_vec); 8603 } 8604 vec_init = gimple_convert (&stmts, vectype, vec_init); 8605 8606 if (stmts) 8607 { 8608 new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); 8609 gcc_assert (!new_bb); 8610 } 8611 } 8612 8613 8614 /* Create the vector that holds the step of the induction. */ 8615 if (nested_in_vect_loop) 8616 /* iv_loop is nested in the loop to be vectorized. Generate: 8617 vec_step = [S, S, S, S] */ 8618 new_name = step_expr; 8619 else 8620 { 8621 /* iv_loop is the loop to be vectorized. Generate: 8622 vec_step = [VF*S, VF*S, VF*S, VF*S] */ 8623 gimple_seq seq = NULL; 8624 if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr))) 8625 { 8626 expr = build_int_cst (integer_type_node, vf); 8627 expr = gimple_build (&seq, FLOAT_EXPR, TREE_TYPE (step_expr), expr); 8628 } 8629 else 8630 expr = build_int_cst (TREE_TYPE (step_expr), vf); 8631 new_name = gimple_build (&seq, MULT_EXPR, TREE_TYPE (step_expr), 8632 expr, step_expr); 8633 if (seq) 8634 { 8635 new_bb = gsi_insert_seq_on_edge_immediate (pe, seq); 8636 gcc_assert (!new_bb); 8637 } 8638 } 8639 8640 t = unshare_expr (new_name); 8641 gcc_assert (CONSTANT_CLASS_P (new_name) 8642 || TREE_CODE (new_name) == SSA_NAME); 8643 new_vec = build_vector_from_val (step_vectype, t); 8644 vec_step = vect_init_vector (loop_vinfo, stmt_info, 8645 new_vec, step_vectype, NULL); 8646 8647 8648 /* Create the following def-use cycle: 8649 loop prolog: 8650 vec_init = ... 8651 vec_step = ... 8652 loop: 8653 vec_iv = PHI <vec_init, vec_loop> 8654 ... 8655 STMT 8656 ... 8657 vec_loop = vec_iv + vec_step; */ 8658 8659 /* Create the induction-phi that defines the induction-operand. */ 8660 vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_"); 8661 induction_phi = create_phi_node (vec_dest, iv_loop->header); 8662 induc_def = PHI_RESULT (induction_phi); 8663 8664 /* Create the iv update inside the loop */ 8665 stmts = NULL; 8666 vec_def = gimple_convert (&stmts, step_vectype, induc_def); 8667 vec_def = gimple_build (&stmts, PLUS_EXPR, step_vectype, vec_def, vec_step); 8668 vec_def = gimple_convert (&stmts, vectype, vec_def); 8669 gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); 8670 new_stmt = SSA_NAME_DEF_STMT (vec_def); 8671 8672 /* Set the arguments of the phi node: */ 8673 add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); 8674 add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), 8675 UNKNOWN_LOCATION); 8676 8677 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (induction_phi); 8678 *vec_stmt = induction_phi; 8679 8680 /* In case that vectorization factor (VF) is bigger than the number 8681 of elements that we can fit in a vectype (nunits), we have to generate 8682 more than one vector stmt - i.e - we need to "unroll" the 8683 vector stmt by a factor VF/nunits. For more details see documentation 8684 in vectorizable_operation. */ 8685 8686 if (ncopies > 1) 8687 { 8688 gimple_seq seq = NULL; 8689 /* FORNOW. This restriction should be relaxed. */ 8690 gcc_assert (!nested_in_vect_loop); 8691 8692 /* Create the vector that holds the step of the induction. */ 8693 if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr))) 8694 { 8695 expr = build_int_cst (integer_type_node, nunits); 8696 expr = gimple_build (&seq, FLOAT_EXPR, TREE_TYPE (step_expr), expr); 8697 } 8698 else 8699 expr = build_int_cst (TREE_TYPE (step_expr), nunits); 8700 new_name = gimple_build (&seq, MULT_EXPR, TREE_TYPE (step_expr), 8701 expr, step_expr); 8702 if (seq) 8703 { 8704 new_bb = gsi_insert_seq_on_edge_immediate (pe, seq); 8705 gcc_assert (!new_bb); 8706 } 8707 8708 t = unshare_expr (new_name); 8709 gcc_assert (CONSTANT_CLASS_P (new_name) 8710 || TREE_CODE (new_name) == SSA_NAME); 8711 new_vec = build_vector_from_val (step_vectype, t); 8712 vec_step = vect_init_vector (loop_vinfo, stmt_info, 8713 new_vec, step_vectype, NULL); 8714 8715 vec_def = induc_def; 8716 for (i = 1; i < ncopies; i++) 8717 { 8718 /* vec_i = vec_prev + vec_step */ 8719 gimple_seq stmts = NULL; 8720 vec_def = gimple_convert (&stmts, step_vectype, vec_def); 8721 vec_def = gimple_build (&stmts, 8722 PLUS_EXPR, step_vectype, vec_def, vec_step); 8723 vec_def = gimple_convert (&stmts, vectype, vec_def); 8724 8725 gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); 8726 new_stmt = SSA_NAME_DEF_STMT (vec_def); 8727 STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); 8728 } 8729 } 8730 8731 if (dump_enabled_p ()) 8732 dump_printf_loc (MSG_NOTE, vect_location, 8733 "transform induction: created def-use cycle: %G%G", 8734 induction_phi, SSA_NAME_DEF_STMT (vec_def)); 8735 8736 return true; 8737 } 8738 8739 /* Function vectorizable_live_operation. 8740 8741 STMT_INFO computes a value that is used outside the loop. Check if 8742 it can be supported. */ 8743 8744 bool 8745 vectorizable_live_operation (vec_info *vinfo, 8746 stmt_vec_info stmt_info, 8747 gimple_stmt_iterator *gsi, 8748 slp_tree slp_node, slp_instance slp_node_instance, 8749 int slp_index, bool vec_stmt_p, 8750 stmt_vector_for_cost *cost_vec) 8751 { 8752 loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); 8753 imm_use_iterator imm_iter; 8754 tree lhs, lhs_type, bitsize; 8755 tree vectype = (slp_node 8756 ? SLP_TREE_VECTYPE (slp_node) 8757 : STMT_VINFO_VECTYPE (stmt_info)); 8758 poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); 8759 int ncopies; 8760 gimple *use_stmt; 8761 auto_vec<tree> vec_oprnds; 8762 int vec_entry = 0; 8763 poly_uint64 vec_index = 0; 8764 8765 gcc_assert (STMT_VINFO_LIVE_P (stmt_info)); 8766 8767 /* If a stmt of a reduction is live, vectorize it via 8768 vect_create_epilog_for_reduction. vectorizable_reduction assessed 8769 validity so just trigger the transform here. */ 8770 if (STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info))) 8771 { 8772 if (!vec_stmt_p) 8773 return true; 8774 if (slp_node) 8775 { 8776 /* For reduction chains the meta-info is attached to 8777 the group leader. */ 8778 if (REDUC_GROUP_FIRST_ELEMENT (stmt_info)) 8779 stmt_info = REDUC_GROUP_FIRST_ELEMENT (stmt_info); 8780 /* For SLP reductions we vectorize the epilogue for 8781 all involved stmts together. */ 8782 else if (slp_index != 0) 8783 return true; 8784 } 8785 stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); 8786 gcc_assert (reduc_info->is_reduc_info); 8787 if (STMT_VINFO_REDUC_TYPE (reduc_info) == FOLD_LEFT_REDUCTION 8788 || STMT_VINFO_REDUC_TYPE (reduc_info) == EXTRACT_LAST_REDUCTION) 8789 return true; 8790 vect_create_epilog_for_reduction (loop_vinfo, stmt_info, slp_node, 8791 slp_node_instance); 8792 return true; 8793 } 8794 8795 /* If STMT is not relevant and it is a simple assignment and its inputs are 8796 invariant then it can remain in place, unvectorized. The original last 8797 scalar value that it computes will be used. */ 8798 if (!STMT_VINFO_RELEVANT_P (stmt_info)) 8799 { 8800 gcc_assert (is_simple_and_all_uses_invariant (stmt_info, loop_vinfo)); 8801 if (dump_enabled_p ()) 8802 dump_printf_loc (MSG_NOTE, vect_location, 8803 "statement is simple and uses invariant. Leaving in " 8804 "place.\n"); 8805 return true; 8806 } 8807 8808 if (slp_node) 8809 ncopies = 1; 8810 else 8811 ncopies = vect_get_num_copies (loop_vinfo, vectype); 8812 8813 if (slp_node) 8814 { 8815 gcc_assert (slp_index >= 0); 8816 8817 /* Get the last occurrence of the scalar index from the concatenation of 8818 all the slp vectors. Calculate which slp vector it is and the index 8819 within. */ 8820 int num_scalar = SLP_TREE_LANES (slp_node); 8821 int num_vec = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); 8822 poly_uint64 pos = (num_vec * nunits) - num_scalar + slp_index; 8823 8824 /* Calculate which vector contains the result, and which lane of 8825 that vector we need. */ 8826 if (!can_div_trunc_p (pos, nunits, &vec_entry, &vec_index)) 8827 { 8828 if (dump_enabled_p ()) 8829 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8830 "Cannot determine which vector holds the" 8831 " final result.\n"); 8832 return false; 8833 } 8834 } 8835 8836 if (!vec_stmt_p) 8837 { 8838 /* No transformation required. */ 8839 if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) 8840 { 8841 if (!direct_internal_fn_supported_p (IFN_EXTRACT_LAST, vectype, 8842 OPTIMIZE_FOR_SPEED)) 8843 { 8844 if (dump_enabled_p ()) 8845 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8846 "can't operate on partial vectors " 8847 "because the target doesn't support extract " 8848 "last reduction.\n"); 8849 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 8850 } 8851 else if (slp_node) 8852 { 8853 if (dump_enabled_p ()) 8854 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8855 "can't operate on partial vectors " 8856 "because an SLP statement is live after " 8857 "the loop.\n"); 8858 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 8859 } 8860 else if (ncopies > 1) 8861 { 8862 if (dump_enabled_p ()) 8863 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 8864 "can't operate on partial vectors " 8865 "because ncopies is greater than 1.\n"); 8866 LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; 8867 } 8868 else 8869 { 8870 gcc_assert (ncopies == 1 && !slp_node); 8871 vect_record_loop_mask (loop_vinfo, 8872 &LOOP_VINFO_MASKS (loop_vinfo), 8873 1, vectype, NULL); 8874 } 8875 } 8876 /* ??? Enable for loop costing as well. */ 8877 if (!loop_vinfo) 8878 record_stmt_cost (cost_vec, 1, vec_to_scalar, stmt_info, NULL_TREE, 8879 0, vect_epilogue); 8880 return true; 8881 } 8882 8883 /* Use the lhs of the original scalar statement. */ 8884 gimple *stmt = vect_orig_stmt (stmt_info)->stmt; 8885 if (dump_enabled_p ()) 8886 dump_printf_loc (MSG_NOTE, vect_location, "extracting lane for live " 8887 "stmt %G", stmt); 8888 8889 lhs = gimple_get_lhs (stmt); 8890 lhs_type = TREE_TYPE (lhs); 8891 8892 bitsize = vector_element_bits_tree (vectype); 8893 8894 /* Get the vectorized lhs of STMT and the lane to use (counted in bits). */ 8895 tree vec_lhs, bitstart; 8896 gimple *vec_stmt; 8897 if (slp_node) 8898 { 8899 gcc_assert (!loop_vinfo || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)); 8900 8901 /* Get the correct slp vectorized stmt. */ 8902 vec_stmt = SLP_TREE_VEC_STMTS (slp_node)[vec_entry]; 8903 vec_lhs = gimple_get_lhs (vec_stmt); 8904 8905 /* Get entry to use. */ 8906 bitstart = bitsize_int (vec_index); 8907 bitstart = int_const_binop (MULT_EXPR, bitsize, bitstart); 8908 } 8909 else 8910 { 8911 /* For multiple copies, get the last copy. */ 8912 vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info).last (); 8913 vec_lhs = gimple_get_lhs (vec_stmt); 8914 8915 /* Get the last lane in the vector. */ 8916 bitstart = int_const_binop (MULT_EXPR, bitsize, bitsize_int (nunits - 1)); 8917 } 8918 8919 if (loop_vinfo) 8920 { 8921 /* Ensure the VEC_LHS for lane extraction stmts satisfy loop-closed PHI 8922 requirement, insert one phi node for it. It looks like: 8923 loop; 8924 BB: 8925 # lhs' = PHI <lhs> 8926 ==> 8927 loop; 8928 BB: 8929 # vec_lhs' = PHI <vec_lhs> 8930 new_tree = lane_extract <vec_lhs', ...>; 8931 lhs' = new_tree; */ 8932 8933 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 8934 basic_block exit_bb = single_exit (loop)->dest; 8935 gcc_assert (single_pred_p (exit_bb)); 8936 8937 tree vec_lhs_phi = copy_ssa_name (vec_lhs); 8938 gimple *phi = create_phi_node (vec_lhs_phi, exit_bb); 8939 SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, vec_lhs); 8940 8941 gimple_seq stmts = NULL; 8942 tree new_tree; 8943 if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) 8944 { 8945 /* Emit: 8946 8947 SCALAR_RES = EXTRACT_LAST <VEC_LHS, MASK> 8948 8949 where VEC_LHS is the vectorized live-out result and MASK is 8950 the loop mask for the final iteration. */ 8951 gcc_assert (ncopies == 1 && !slp_node); 8952 tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info)); 8953 tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo), 8954 1, vectype, 0); 8955 tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST, scalar_type, 8956 mask, vec_lhs_phi); 8957 8958 /* Convert the extracted vector element to the scalar type. */ 8959 new_tree = gimple_convert (&stmts, lhs_type, scalar_res); 8960 } 8961 else 8962 { 8963 tree bftype = TREE_TYPE (vectype); 8964 if (VECTOR_BOOLEAN_TYPE_P (vectype)) 8965 bftype = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 1); 8966 new_tree = build3 (BIT_FIELD_REF, bftype, 8967 vec_lhs_phi, bitsize, bitstart); 8968 new_tree = force_gimple_operand (fold_convert (lhs_type, new_tree), 8969 &stmts, true, NULL_TREE); 8970 } 8971 8972 if (stmts) 8973 { 8974 gimple_stmt_iterator exit_gsi = gsi_after_labels (exit_bb); 8975 gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); 8976 8977 /* Remove existing phi from lhs and create one copy from new_tree. */ 8978 tree lhs_phi = NULL_TREE; 8979 gimple_stmt_iterator gsi; 8980 for (gsi = gsi_start_phis (exit_bb); 8981 !gsi_end_p (gsi); gsi_next (&gsi)) 8982 { 8983 gimple *phi = gsi_stmt (gsi); 8984 if ((gimple_phi_arg_def (phi, 0) == lhs)) 8985 { 8986 remove_phi_node (&gsi, false); 8987 lhs_phi = gimple_phi_result (phi); 8988 gimple *copy = gimple_build_assign (lhs_phi, new_tree); 8989 gsi_insert_before (&exit_gsi, copy, GSI_SAME_STMT); 8990 break; 8991 } 8992 } 8993 } 8994 8995 /* Replace use of lhs with newly computed result. If the use stmt is a 8996 single arg PHI, just replace all uses of PHI result. It's necessary 8997 because lcssa PHI defining lhs may be before newly inserted stmt. */ 8998 use_operand_p use_p; 8999 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) 9000 if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) 9001 && !is_gimple_debug (use_stmt)) 9002 { 9003 if (gimple_code (use_stmt) == GIMPLE_PHI 9004 && gimple_phi_num_args (use_stmt) == 1) 9005 { 9006 replace_uses_by (gimple_phi_result (use_stmt), new_tree); 9007 } 9008 else 9009 { 9010 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) 9011 SET_USE (use_p, new_tree); 9012 } 9013 update_stmt (use_stmt); 9014 } 9015 } 9016 else 9017 { 9018 /* For basic-block vectorization simply insert the lane-extraction. */ 9019 tree bftype = TREE_TYPE (vectype); 9020 if (VECTOR_BOOLEAN_TYPE_P (vectype)) 9021 bftype = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 1); 9022 tree new_tree = build3 (BIT_FIELD_REF, bftype, 9023 vec_lhs, bitsize, bitstart); 9024 gimple_seq stmts = NULL; 9025 new_tree = force_gimple_operand (fold_convert (lhs_type, new_tree), 9026 &stmts, true, NULL_TREE); 9027 if (TREE_CODE (new_tree) == SSA_NAME 9028 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) 9029 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_tree) = 1; 9030 if (is_a <gphi *> (vec_stmt)) 9031 { 9032 gimple_stmt_iterator si = gsi_after_labels (gimple_bb (vec_stmt)); 9033 gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); 9034 } 9035 else 9036 { 9037 gimple_stmt_iterator si = gsi_for_stmt (vec_stmt); 9038 gsi_insert_seq_after (&si, stmts, GSI_SAME_STMT); 9039 } 9040 9041 /* Replace use of lhs with newly computed result. If the use stmt is a 9042 single arg PHI, just replace all uses of PHI result. It's necessary 9043 because lcssa PHI defining lhs may be before newly inserted stmt. */ 9044 use_operand_p use_p; 9045 stmt_vec_info use_stmt_info; 9046 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) 9047 if (!is_gimple_debug (use_stmt) 9048 && (!(use_stmt_info = vinfo->lookup_stmt (use_stmt)) 9049 || !PURE_SLP_STMT (vect_stmt_to_vectorize (use_stmt_info)))) 9050 { 9051 /* ??? This can happen when the live lane ends up being 9052 used in a vector construction code-generated by an 9053 external SLP node (and code-generation for that already 9054 happened). See gcc.dg/vect/bb-slp-47.c. 9055 Doing this is what would happen if that vector CTOR 9056 were not code-generated yet so it is not too bad. 9057 ??? In fact we'd likely want to avoid this situation 9058 in the first place. */ 9059 if (TREE_CODE (new_tree) == SSA_NAME 9060 && !SSA_NAME_IS_DEFAULT_DEF (new_tree) 9061 && gimple_code (use_stmt) != GIMPLE_PHI 9062 && !vect_stmt_dominates_stmt_p (SSA_NAME_DEF_STMT (new_tree), 9063 use_stmt)) 9064 { 9065 enum tree_code code = gimple_assign_rhs_code (use_stmt); 9066 gcc_checking_assert (code == SSA_NAME 9067 || code == CONSTRUCTOR 9068 || code == VIEW_CONVERT_EXPR 9069 || CONVERT_EXPR_CODE_P (code)); 9070 if (dump_enabled_p ()) 9071 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 9072 "Using original scalar computation for " 9073 "live lane because use preceeds vector " 9074 "def\n"); 9075 continue; 9076 } 9077 /* ??? It can also happen that we end up pulling a def into 9078 a loop where replacing out-of-loop uses would require 9079 a new LC SSA PHI node. Retain the original scalar in 9080 those cases as well. PR98064. */ 9081 if (TREE_CODE (new_tree) == SSA_NAME 9082 && !SSA_NAME_IS_DEFAULT_DEF (new_tree) 9083 && (gimple_bb (use_stmt)->loop_father 9084 != gimple_bb (vec_stmt)->loop_father) 9085 && !flow_loop_nested_p (gimple_bb (vec_stmt)->loop_father, 9086 gimple_bb (use_stmt)->loop_father)) 9087 { 9088 if (dump_enabled_p ()) 9089 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 9090 "Using original scalar computation for " 9091 "live lane because there is an out-of-loop " 9092 "definition for it\n"); 9093 continue; 9094 } 9095 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) 9096 SET_USE (use_p, new_tree); 9097 update_stmt (use_stmt); 9098 } 9099 } 9100 9101 return true; 9102 } 9103 9104 /* Kill any debug uses outside LOOP of SSA names defined in STMT_INFO. */ 9105 9106 static void 9107 vect_loop_kill_debug_uses (class loop *loop, stmt_vec_info stmt_info) 9108 { 9109 ssa_op_iter op_iter; 9110 imm_use_iterator imm_iter; 9111 def_operand_p def_p; 9112 gimple *ustmt; 9113 9114 FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt_info->stmt, op_iter, SSA_OP_DEF) 9115 { 9116 FOR_EACH_IMM_USE_STMT (ustmt, imm_iter, DEF_FROM_PTR (def_p)) 9117 { 9118 basic_block bb; 9119 9120 if (!is_gimple_debug (ustmt)) 9121 continue; 9122 9123 bb = gimple_bb (ustmt); 9124 9125 if (!flow_bb_inside_loop_p (loop, bb)) 9126 { 9127 if (gimple_debug_bind_p (ustmt)) 9128 { 9129 if (dump_enabled_p ()) 9130 dump_printf_loc (MSG_NOTE, vect_location, 9131 "killing debug use\n"); 9132 9133 gimple_debug_bind_reset_value (ustmt); 9134 update_stmt (ustmt); 9135 } 9136 else 9137 gcc_unreachable (); 9138 } 9139 } 9140 } 9141 } 9142 9143 /* Given loop represented by LOOP_VINFO, return true if computation of 9144 LOOP_VINFO_NITERS (= LOOP_VINFO_NITERSM1 + 1) doesn't overflow, false 9145 otherwise. */ 9146 9147 static bool 9148 loop_niters_no_overflow (loop_vec_info loop_vinfo) 9149 { 9150 /* Constant case. */ 9151 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) 9152 { 9153 tree cst_niters = LOOP_VINFO_NITERS (loop_vinfo); 9154 tree cst_nitersm1 = LOOP_VINFO_NITERSM1 (loop_vinfo); 9155 9156 gcc_assert (TREE_CODE (cst_niters) == INTEGER_CST); 9157 gcc_assert (TREE_CODE (cst_nitersm1) == INTEGER_CST); 9158 if (wi::to_widest (cst_nitersm1) < wi::to_widest (cst_niters)) 9159 return true; 9160 } 9161 9162 widest_int max; 9163 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 9164 /* Check the upper bound of loop niters. */ 9165 if (get_max_loop_iterations (loop, &max)) 9166 { 9167 tree type = TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)); 9168 signop sgn = TYPE_SIGN (type); 9169 widest_int type_max = widest_int::from (wi::max_value (type), sgn); 9170 if (max < type_max) 9171 return true; 9172 } 9173 return false; 9174 } 9175 9176 /* Return a mask type with half the number of elements as OLD_TYPE, 9177 given that it should have mode NEW_MODE. */ 9178 9179 tree 9180 vect_halve_mask_nunits (tree old_type, machine_mode new_mode) 9181 { 9182 poly_uint64 nunits = exact_div (TYPE_VECTOR_SUBPARTS (old_type), 2); 9183 return build_truth_vector_type_for_mode (nunits, new_mode); 9184 } 9185 9186 /* Return a mask type with twice as many elements as OLD_TYPE, 9187 given that it should have mode NEW_MODE. */ 9188 9189 tree 9190 vect_double_mask_nunits (tree old_type, machine_mode new_mode) 9191 { 9192 poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (old_type) * 2; 9193 return build_truth_vector_type_for_mode (nunits, new_mode); 9194 } 9195 9196 /* Record that a fully-masked version of LOOP_VINFO would need MASKS to 9197 contain a sequence of NVECTORS masks that each control a vector of type 9198 VECTYPE. If SCALAR_MASK is nonnull, the fully-masked loop would AND 9199 these vector masks with the vector version of SCALAR_MASK. */ 9200 9201 void 9202 vect_record_loop_mask (loop_vec_info loop_vinfo, vec_loop_masks *masks, 9203 unsigned int nvectors, tree vectype, tree scalar_mask) 9204 { 9205 gcc_assert (nvectors != 0); 9206 if (masks->length () < nvectors) 9207 masks->safe_grow_cleared (nvectors, true); 9208 rgroup_controls *rgm = &(*masks)[nvectors - 1]; 9209 /* The number of scalars per iteration and the number of vectors are 9210 both compile-time constants. */ 9211 unsigned int nscalars_per_iter 9212 = exact_div (nvectors * TYPE_VECTOR_SUBPARTS (vectype), 9213 LOOP_VINFO_VECT_FACTOR (loop_vinfo)).to_constant (); 9214 9215 if (scalar_mask) 9216 { 9217 scalar_cond_masked_key cond (scalar_mask, nvectors); 9218 loop_vinfo->scalar_cond_masked_set.add (cond); 9219 } 9220 9221 if (rgm->max_nscalars_per_iter < nscalars_per_iter) 9222 { 9223 rgm->max_nscalars_per_iter = nscalars_per_iter; 9224 rgm->type = truth_type_for (vectype); 9225 rgm->factor = 1; 9226 } 9227 } 9228 9229 /* Given a complete set of masks MASKS, extract mask number INDEX 9230 for an rgroup that operates on NVECTORS vectors of type VECTYPE, 9231 where 0 <= INDEX < NVECTORS. Insert any set-up statements before GSI. 9232 9233 See the comment above vec_loop_masks for more details about the mask 9234 arrangement. */ 9235 9236 tree 9237 vect_get_loop_mask (gimple_stmt_iterator *gsi, vec_loop_masks *masks, 9238 unsigned int nvectors, tree vectype, unsigned int index) 9239 { 9240 rgroup_controls *rgm = &(*masks)[nvectors - 1]; 9241 tree mask_type = rgm->type; 9242 9243 /* Populate the rgroup's mask array, if this is the first time we've 9244 used it. */ 9245 if (rgm->controls.is_empty ()) 9246 { 9247 rgm->controls.safe_grow_cleared (nvectors, true); 9248 for (unsigned int i = 0; i < nvectors; ++i) 9249 { 9250 tree mask = make_temp_ssa_name (mask_type, NULL, "loop_mask"); 9251 /* Provide a dummy definition until the real one is available. */ 9252 SSA_NAME_DEF_STMT (mask) = gimple_build_nop (); 9253 rgm->controls[i] = mask; 9254 } 9255 } 9256 9257 tree mask = rgm->controls[index]; 9258 if (maybe_ne (TYPE_VECTOR_SUBPARTS (mask_type), 9259 TYPE_VECTOR_SUBPARTS (vectype))) 9260 { 9261 /* A loop mask for data type X can be reused for data type Y 9262 if X has N times more elements than Y and if Y's elements 9263 are N times bigger than X's. In this case each sequence 9264 of N elements in the loop mask will be all-zero or all-one. 9265 We can then view-convert the mask so that each sequence of 9266 N elements is replaced by a single element. */ 9267 gcc_assert (multiple_p (TYPE_VECTOR_SUBPARTS (mask_type), 9268 TYPE_VECTOR_SUBPARTS (vectype))); 9269 gimple_seq seq = NULL; 9270 mask_type = truth_type_for (vectype); 9271 mask = gimple_build (&seq, VIEW_CONVERT_EXPR, mask_type, mask); 9272 if (seq) 9273 gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT); 9274 } 9275 return mask; 9276 } 9277 9278 /* Record that LOOP_VINFO would need LENS to contain a sequence of NVECTORS 9279 lengths for controlling an operation on VECTYPE. The operation splits 9280 each element of VECTYPE into FACTOR separate subelements, measuring the 9281 length as a number of these subelements. */ 9282 9283 void 9284 vect_record_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens, 9285 unsigned int nvectors, tree vectype, unsigned int factor) 9286 { 9287 gcc_assert (nvectors != 0); 9288 if (lens->length () < nvectors) 9289 lens->safe_grow_cleared (nvectors, true); 9290 rgroup_controls *rgl = &(*lens)[nvectors - 1]; 9291 9292 /* The number of scalars per iteration, scalar occupied bytes and 9293 the number of vectors are both compile-time constants. */ 9294 unsigned int nscalars_per_iter 9295 = exact_div (nvectors * TYPE_VECTOR_SUBPARTS (vectype), 9296 LOOP_VINFO_VECT_FACTOR (loop_vinfo)).to_constant (); 9297 9298 if (rgl->max_nscalars_per_iter < nscalars_per_iter) 9299 { 9300 /* For now, we only support cases in which all loads and stores fall back 9301 to VnQI or none do. */ 9302 gcc_assert (!rgl->max_nscalars_per_iter 9303 || (rgl->factor == 1 && factor == 1) 9304 || (rgl->max_nscalars_per_iter * rgl->factor 9305 == nscalars_per_iter * factor)); 9306 rgl->max_nscalars_per_iter = nscalars_per_iter; 9307 rgl->type = vectype; 9308 rgl->factor = factor; 9309 } 9310 } 9311 9312 /* Given a complete set of length LENS, extract length number INDEX for an 9313 rgroup that operates on NVECTORS vectors, where 0 <= INDEX < NVECTORS. */ 9314 9315 tree 9316 vect_get_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens, 9317 unsigned int nvectors, unsigned int index) 9318 { 9319 rgroup_controls *rgl = &(*lens)[nvectors - 1]; 9320 bool use_bias_adjusted_len = 9321 LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo) != 0; 9322 9323 /* Populate the rgroup's len array, if this is the first time we've 9324 used it. */ 9325 if (rgl->controls.is_empty ()) 9326 { 9327 rgl->controls.safe_grow_cleared (nvectors, true); 9328 for (unsigned int i = 0; i < nvectors; ++i) 9329 { 9330 tree len_type = LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo); 9331 gcc_assert (len_type != NULL_TREE); 9332 9333 tree len = make_temp_ssa_name (len_type, NULL, "loop_len"); 9334 9335 /* Provide a dummy definition until the real one is available. */ 9336 SSA_NAME_DEF_STMT (len) = gimple_build_nop (); 9337 rgl->controls[i] = len; 9338 9339 if (use_bias_adjusted_len) 9340 { 9341 gcc_assert (i == 0); 9342 tree adjusted_len = 9343 make_temp_ssa_name (len_type, NULL, "adjusted_loop_len"); 9344 SSA_NAME_DEF_STMT (adjusted_len) = gimple_build_nop (); 9345 rgl->bias_adjusted_ctrl = adjusted_len; 9346 } 9347 } 9348 } 9349 9350 if (use_bias_adjusted_len) 9351 return rgl->bias_adjusted_ctrl; 9352 else 9353 return rgl->controls[index]; 9354 } 9355 9356 /* Scale profiling counters by estimation for LOOP which is vectorized 9357 by factor VF. */ 9358 9359 static void 9360 scale_profile_for_vect_loop (class loop *loop, unsigned vf) 9361 { 9362 edge preheader = loop_preheader_edge (loop); 9363 /* Reduce loop iterations by the vectorization factor. */ 9364 gcov_type new_est_niter = niter_for_unrolled_loop (loop, vf); 9365 profile_count freq_h = loop->header->count, freq_e = preheader->count (); 9366 9367 if (freq_h.nonzero_p ()) 9368 { 9369 profile_probability p; 9370 9371 /* Avoid dropping loop body profile counter to 0 because of zero count 9372 in loop's preheader. */ 9373 if (!(freq_e == profile_count::zero ())) 9374 freq_e = freq_e.force_nonzero (); 9375 p = freq_e.apply_scale (new_est_niter + 1, 1).probability_in (freq_h); 9376 scale_loop_frequencies (loop, p); 9377 } 9378 9379 edge exit_e = single_exit (loop); 9380 exit_e->probability = profile_probability::always () 9381 .apply_scale (1, new_est_niter + 1); 9382 9383 edge exit_l = single_pred_edge (loop->latch); 9384 profile_probability prob = exit_l->probability; 9385 exit_l->probability = exit_e->probability.invert (); 9386 if (prob.initialized_p () && exit_l->probability.initialized_p ()) 9387 scale_bbs_frequencies (&loop->latch, 1, exit_l->probability / prob); 9388 } 9389 9390 /* For a vectorized stmt DEF_STMT_INFO adjust all vectorized PHI 9391 latch edge values originally defined by it. */ 9392 9393 static void 9394 maybe_set_vectorized_backedge_value (loop_vec_info loop_vinfo, 9395 stmt_vec_info def_stmt_info) 9396 { 9397 tree def = gimple_get_lhs (vect_orig_stmt (def_stmt_info)->stmt); 9398 if (!def || TREE_CODE (def) != SSA_NAME) 9399 return; 9400 stmt_vec_info phi_info; 9401 imm_use_iterator iter; 9402 use_operand_p use_p; 9403 FOR_EACH_IMM_USE_FAST (use_p, iter, def) 9404 if (gphi *phi = dyn_cast <gphi *> (USE_STMT (use_p))) 9405 if (gimple_bb (phi)->loop_father->header == gimple_bb (phi) 9406 && (phi_info = loop_vinfo->lookup_stmt (phi)) 9407 && STMT_VINFO_RELEVANT_P (phi_info) 9408 && VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (phi_info)) 9409 && STMT_VINFO_REDUC_TYPE (phi_info) != FOLD_LEFT_REDUCTION 9410 && STMT_VINFO_REDUC_TYPE (phi_info) != EXTRACT_LAST_REDUCTION) 9411 { 9412 loop_p loop = gimple_bb (phi)->loop_father; 9413 edge e = loop_latch_edge (loop); 9414 if (PHI_ARG_DEF_FROM_EDGE (phi, e) == def) 9415 { 9416 vec<gimple *> &phi_defs = STMT_VINFO_VEC_STMTS (phi_info); 9417 vec<gimple *> &latch_defs = STMT_VINFO_VEC_STMTS (def_stmt_info); 9418 gcc_assert (phi_defs.length () == latch_defs.length ()); 9419 for (unsigned i = 0; i < phi_defs.length (); ++i) 9420 add_phi_arg (as_a <gphi *> (phi_defs[i]), 9421 gimple_get_lhs (latch_defs[i]), e, 9422 gimple_phi_arg_location (phi, e->dest_idx)); 9423 } 9424 } 9425 } 9426 9427 /* Vectorize STMT_INFO if relevant, inserting any new instructions before GSI. 9428 When vectorizing STMT_INFO as a store, set *SEEN_STORE to its 9429 stmt_vec_info. */ 9430 9431 static bool 9432 vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info, 9433 gimple_stmt_iterator *gsi, stmt_vec_info *seen_store) 9434 { 9435 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 9436 poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 9437 9438 if (dump_enabled_p ()) 9439 dump_printf_loc (MSG_NOTE, vect_location, 9440 "------>vectorizing statement: %G", stmt_info->stmt); 9441 9442 if (MAY_HAVE_DEBUG_BIND_STMTS && !STMT_VINFO_LIVE_P (stmt_info)) 9443 vect_loop_kill_debug_uses (loop, stmt_info); 9444 9445 if (!STMT_VINFO_RELEVANT_P (stmt_info) 9446 && !STMT_VINFO_LIVE_P (stmt_info)) 9447 return false; 9448 9449 if (STMT_VINFO_VECTYPE (stmt_info)) 9450 { 9451 poly_uint64 nunits 9452 = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)); 9453 if (!STMT_SLP_TYPE (stmt_info) 9454 && maybe_ne (nunits, vf) 9455 && dump_enabled_p ()) 9456 /* For SLP VF is set according to unrolling factor, and not 9457 to vector size, hence for SLP this print is not valid. */ 9458 dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.\n"); 9459 } 9460 9461 /* Pure SLP statements have already been vectorized. We still need 9462 to apply loop vectorization to hybrid SLP statements. */ 9463 if (PURE_SLP_STMT (stmt_info)) 9464 return false; 9465 9466 if (dump_enabled_p ()) 9467 dump_printf_loc (MSG_NOTE, vect_location, "transform statement.\n"); 9468 9469 if (vect_transform_stmt (loop_vinfo, stmt_info, gsi, NULL, NULL)) 9470 *seen_store = stmt_info; 9471 9472 return true; 9473 } 9474 9475 /* Helper function to pass to simplify_replace_tree to enable replacing tree's 9476 in the hash_map with its corresponding values. */ 9477 9478 static tree 9479 find_in_mapping (tree t, void *context) 9480 { 9481 hash_map<tree,tree>* mapping = (hash_map<tree, tree>*) context; 9482 9483 tree *value = mapping->get (t); 9484 return value ? *value : t; 9485 } 9486 9487 /* Update EPILOGUE's loop_vec_info. EPILOGUE was constructed as a copy of the 9488 original loop that has now been vectorized. 9489 9490 The inits of the data_references need to be advanced with the number of 9491 iterations of the main loop. This has been computed in vect_do_peeling and 9492 is stored in parameter ADVANCE. We first restore the data_references 9493 initial offset with the values recored in ORIG_DRS_INIT. 9494 9495 Since the loop_vec_info of this EPILOGUE was constructed for the original 9496 loop, its stmt_vec_infos all point to the original statements. These need 9497 to be updated to point to their corresponding copies as well as the SSA_NAMES 9498 in their PATTERN_DEF_SEQs and RELATED_STMTs. 9499 9500 The data_reference's connections also need to be updated. Their 9501 corresponding dr_vec_info need to be reconnected to the EPILOGUE's 9502 stmt_vec_infos, their statements need to point to their corresponding copy, 9503 if they are gather loads or scatter stores then their reference needs to be 9504 updated to point to its corresponding copy. */ 9505 9506 static void 9507 update_epilogue_loop_vinfo (class loop *epilogue, tree advance) 9508 { 9509 loop_vec_info epilogue_vinfo = loop_vec_info_for_loop (epilogue); 9510 auto_vec<gimple *> stmt_worklist; 9511 hash_map<tree,tree> mapping; 9512 gimple *orig_stmt, *new_stmt; 9513 gimple_stmt_iterator epilogue_gsi; 9514 gphi_iterator epilogue_phi_gsi; 9515 stmt_vec_info stmt_vinfo = NULL, related_vinfo; 9516 basic_block *epilogue_bbs = get_loop_body (epilogue); 9517 unsigned i; 9518 9519 free (LOOP_VINFO_BBS (epilogue_vinfo)); 9520 LOOP_VINFO_BBS (epilogue_vinfo) = epilogue_bbs; 9521 9522 /* Advance data_reference's with the number of iterations of the previous 9523 loop and its prologue. */ 9524 vect_update_inits_of_drs (epilogue_vinfo, advance, PLUS_EXPR); 9525 9526 9527 /* The EPILOGUE loop is a copy of the original loop so they share the same 9528 gimple UIDs. In this loop we update the loop_vec_info of the EPILOGUE to 9529 point to the copied statements. We also create a mapping of all LHS' in 9530 the original loop and all the LHS' in the EPILOGUE and create worklists to 9531 update teh STMT_VINFO_PATTERN_DEF_SEQs and STMT_VINFO_RELATED_STMTs. */ 9532 for (unsigned i = 0; i < epilogue->num_nodes; ++i) 9533 { 9534 for (epilogue_phi_gsi = gsi_start_phis (epilogue_bbs[i]); 9535 !gsi_end_p (epilogue_phi_gsi); gsi_next (&epilogue_phi_gsi)) 9536 { 9537 new_stmt = epilogue_phi_gsi.phi (); 9538 9539 gcc_assert (gimple_uid (new_stmt) > 0); 9540 stmt_vinfo 9541 = epilogue_vinfo->stmt_vec_infos[gimple_uid (new_stmt) - 1]; 9542 9543 orig_stmt = STMT_VINFO_STMT (stmt_vinfo); 9544 STMT_VINFO_STMT (stmt_vinfo) = new_stmt; 9545 9546 mapping.put (gimple_phi_result (orig_stmt), 9547 gimple_phi_result (new_stmt)); 9548 /* PHI nodes can not have patterns or related statements. */ 9549 gcc_assert (STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) == NULL 9550 && STMT_VINFO_RELATED_STMT (stmt_vinfo) == NULL); 9551 } 9552 9553 for (epilogue_gsi = gsi_start_bb (epilogue_bbs[i]); 9554 !gsi_end_p (epilogue_gsi); gsi_next (&epilogue_gsi)) 9555 { 9556 new_stmt = gsi_stmt (epilogue_gsi); 9557 if (is_gimple_debug (new_stmt)) 9558 continue; 9559 9560 gcc_assert (gimple_uid (new_stmt) > 0); 9561 stmt_vinfo 9562 = epilogue_vinfo->stmt_vec_infos[gimple_uid (new_stmt) - 1]; 9563 9564 orig_stmt = STMT_VINFO_STMT (stmt_vinfo); 9565 STMT_VINFO_STMT (stmt_vinfo) = new_stmt; 9566 9567 if (tree old_lhs = gimple_get_lhs (orig_stmt)) 9568 mapping.put (old_lhs, gimple_get_lhs (new_stmt)); 9569 9570 if (STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo)) 9571 { 9572 gimple_seq seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo); 9573 for (gimple_stmt_iterator gsi = gsi_start (seq); 9574 !gsi_end_p (gsi); gsi_next (&gsi)) 9575 stmt_worklist.safe_push (gsi_stmt (gsi)); 9576 } 9577 9578 related_vinfo = STMT_VINFO_RELATED_STMT (stmt_vinfo); 9579 if (related_vinfo != NULL && related_vinfo != stmt_vinfo) 9580 { 9581 gimple *stmt = STMT_VINFO_STMT (related_vinfo); 9582 stmt_worklist.safe_push (stmt); 9583 /* Set BB such that the assert in 9584 'get_initial_def_for_reduction' is able to determine that 9585 the BB of the related stmt is inside this loop. */ 9586 gimple_set_bb (stmt, 9587 gimple_bb (new_stmt)); 9588 related_vinfo = STMT_VINFO_RELATED_STMT (related_vinfo); 9589 gcc_assert (related_vinfo == NULL 9590 || related_vinfo == stmt_vinfo); 9591 } 9592 } 9593 } 9594 9595 /* The PATTERN_DEF_SEQs and RELATED_STMTs in the epilogue were constructed 9596 using the original main loop and thus need to be updated to refer to the 9597 cloned variables used in the epilogue. */ 9598 for (unsigned i = 0; i < stmt_worklist.length (); ++i) 9599 { 9600 gimple *stmt = stmt_worklist[i]; 9601 tree *new_op; 9602 9603 for (unsigned j = 1; j < gimple_num_ops (stmt); ++j) 9604 { 9605 tree op = gimple_op (stmt, j); 9606 if ((new_op = mapping.get(op))) 9607 gimple_set_op (stmt, j, *new_op); 9608 else 9609 { 9610 /* PR92429: The last argument of simplify_replace_tree disables 9611 folding when replacing arguments. This is required as 9612 otherwise you might end up with different statements than the 9613 ones analyzed in vect_loop_analyze, leading to different 9614 vectorization. */ 9615 op = simplify_replace_tree (op, NULL_TREE, NULL_TREE, 9616 &find_in_mapping, &mapping, false); 9617 gimple_set_op (stmt, j, op); 9618 } 9619 } 9620 } 9621 9622 struct data_reference *dr; 9623 vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (epilogue_vinfo); 9624 FOR_EACH_VEC_ELT (datarefs, i, dr) 9625 { 9626 orig_stmt = DR_STMT (dr); 9627 gcc_assert (gimple_uid (orig_stmt) > 0); 9628 stmt_vinfo = epilogue_vinfo->stmt_vec_infos[gimple_uid (orig_stmt) - 1]; 9629 /* Data references for gather loads and scatter stores do not use the 9630 updated offset we set using ADVANCE. Instead we have to make sure the 9631 reference in the data references point to the corresponding copy of 9632 the original in the epilogue. */ 9633 if (STMT_VINFO_MEMORY_ACCESS_TYPE (vect_stmt_to_vectorize (stmt_vinfo)) 9634 == VMAT_GATHER_SCATTER) 9635 { 9636 DR_REF (dr) 9637 = simplify_replace_tree (DR_REF (dr), NULL_TREE, NULL_TREE, 9638 &find_in_mapping, &mapping); 9639 DR_BASE_ADDRESS (dr) 9640 = simplify_replace_tree (DR_BASE_ADDRESS (dr), NULL_TREE, NULL_TREE, 9641 &find_in_mapping, &mapping); 9642 } 9643 DR_STMT (dr) = STMT_VINFO_STMT (stmt_vinfo); 9644 stmt_vinfo->dr_aux.stmt = stmt_vinfo; 9645 } 9646 9647 epilogue_vinfo->shared->datarefs_copy.release (); 9648 epilogue_vinfo->shared->save_datarefs (); 9649 } 9650 9651 /* Function vect_transform_loop. 9652 9653 The analysis phase has determined that the loop is vectorizable. 9654 Vectorize the loop - created vectorized stmts to replace the scalar 9655 stmts in the loop, and update the loop exit condition. 9656 Returns scalar epilogue loop if any. */ 9657 9658 class loop * 9659 vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) 9660 { 9661 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 9662 class loop *epilogue = NULL; 9663 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); 9664 int nbbs = loop->num_nodes; 9665 int i; 9666 tree niters_vector = NULL_TREE; 9667 tree step_vector = NULL_TREE; 9668 tree niters_vector_mult_vf = NULL_TREE; 9669 poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 9670 unsigned int lowest_vf = constant_lower_bound (vf); 9671 gimple *stmt; 9672 bool check_profitability = false; 9673 unsigned int th; 9674 9675 DUMP_VECT_SCOPE ("vec_transform_loop"); 9676 9677 loop_vinfo->shared->check_datarefs (); 9678 9679 /* Use the more conservative vectorization threshold. If the number 9680 of iterations is constant assume the cost check has been performed 9681 by our caller. If the threshold makes all loops profitable that 9682 run at least the (estimated) vectorization factor number of times 9683 checking is pointless, too. */ 9684 th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo); 9685 if (vect_apply_runtime_profitability_check_p (loop_vinfo)) 9686 { 9687 if (dump_enabled_p ()) 9688 dump_printf_loc (MSG_NOTE, vect_location, 9689 "Profitability threshold is %d loop iterations.\n", 9690 th); 9691 check_profitability = true; 9692 } 9693 9694 /* Make sure there exists a single-predecessor exit bb. Do this before 9695 versioning. */ 9696 edge e = single_exit (loop); 9697 if (! single_pred_p (e->dest)) 9698 { 9699 split_loop_exit_edge (e, true); 9700 if (dump_enabled_p ()) 9701 dump_printf (MSG_NOTE, "split exit edge\n"); 9702 } 9703 9704 /* Version the loop first, if required, so the profitability check 9705 comes first. */ 9706 9707 if (LOOP_REQUIRES_VERSIONING (loop_vinfo)) 9708 { 9709 class loop *sloop 9710 = vect_loop_versioning (loop_vinfo, loop_vectorized_call); 9711 sloop->force_vectorize = false; 9712 check_profitability = false; 9713 } 9714 9715 /* Make sure there exists a single-predecessor exit bb also on the 9716 scalar loop copy. Do this after versioning but before peeling 9717 so CFG structure is fine for both scalar and if-converted loop 9718 to make slpeel_duplicate_current_defs_from_edges face matched 9719 loop closed PHI nodes on the exit. */ 9720 if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)) 9721 { 9722 e = single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)); 9723 if (! single_pred_p (e->dest)) 9724 { 9725 split_loop_exit_edge (e, true); 9726 if (dump_enabled_p ()) 9727 dump_printf (MSG_NOTE, "split exit edge of scalar loop\n"); 9728 } 9729 } 9730 9731 tree niters = vect_build_loop_niters (loop_vinfo); 9732 LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = niters; 9733 tree nitersm1 = unshare_expr (LOOP_VINFO_NITERSM1 (loop_vinfo)); 9734 bool niters_no_overflow = loop_niters_no_overflow (loop_vinfo); 9735 tree advance; 9736 drs_init_vec orig_drs_init; 9737 9738 epilogue = vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector, 9739 &step_vector, &niters_vector_mult_vf, th, 9740 check_profitability, niters_no_overflow, 9741 &advance); 9742 9743 if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo) 9744 && LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo).initialized_p ()) 9745 scale_loop_frequencies (LOOP_VINFO_SCALAR_LOOP (loop_vinfo), 9746 LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo)); 9747 9748 if (niters_vector == NULL_TREE) 9749 { 9750 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 9751 && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) 9752 && known_eq (lowest_vf, vf)) 9753 { 9754 niters_vector 9755 = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)), 9756 LOOP_VINFO_INT_NITERS (loop_vinfo) / lowest_vf); 9757 step_vector = build_one_cst (TREE_TYPE (niters)); 9758 } 9759 else if (vect_use_loop_mask_for_alignment_p (loop_vinfo)) 9760 vect_gen_vector_loop_niters (loop_vinfo, niters, &niters_vector, 9761 &step_vector, niters_no_overflow); 9762 else 9763 /* vect_do_peeling subtracted the number of peeled prologue 9764 iterations from LOOP_VINFO_NITERS. */ 9765 vect_gen_vector_loop_niters (loop_vinfo, LOOP_VINFO_NITERS (loop_vinfo), 9766 &niters_vector, &step_vector, 9767 niters_no_overflow); 9768 } 9769 9770 /* 1) Make sure the loop header has exactly two entries 9771 2) Make sure we have a preheader basic block. */ 9772 9773 gcc_assert (EDGE_COUNT (loop->header->preds) == 2); 9774 9775 split_edge (loop_preheader_edge (loop)); 9776 9777 if (vect_use_loop_mask_for_alignment_p (loop_vinfo)) 9778 /* This will deal with any possible peeling. */ 9779 vect_prepare_for_masked_peels (loop_vinfo); 9780 9781 /* Schedule the SLP instances first, then handle loop vectorization 9782 below. */ 9783 if (!loop_vinfo->slp_instances.is_empty ()) 9784 { 9785 DUMP_VECT_SCOPE ("scheduling SLP instances"); 9786 vect_schedule_slp (loop_vinfo, LOOP_VINFO_SLP_INSTANCES (loop_vinfo)); 9787 } 9788 9789 /* FORNOW: the vectorizer supports only loops which body consist 9790 of one basic block (header + empty latch). When the vectorizer will 9791 support more involved loop forms, the order by which the BBs are 9792 traversed need to be reconsidered. */ 9793 9794 for (i = 0; i < nbbs; i++) 9795 { 9796 basic_block bb = bbs[i]; 9797 stmt_vec_info stmt_info; 9798 9799 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); 9800 gsi_next (&si)) 9801 { 9802 gphi *phi = si.phi (); 9803 if (dump_enabled_p ()) 9804 dump_printf_loc (MSG_NOTE, vect_location, 9805 "------>vectorizing phi: %G", phi); 9806 stmt_info = loop_vinfo->lookup_stmt (phi); 9807 if (!stmt_info) 9808 continue; 9809 9810 if (MAY_HAVE_DEBUG_BIND_STMTS && !STMT_VINFO_LIVE_P (stmt_info)) 9811 vect_loop_kill_debug_uses (loop, stmt_info); 9812 9813 if (!STMT_VINFO_RELEVANT_P (stmt_info) 9814 && !STMT_VINFO_LIVE_P (stmt_info)) 9815 continue; 9816 9817 if (STMT_VINFO_VECTYPE (stmt_info) 9818 && (maybe_ne 9819 (TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)), vf)) 9820 && dump_enabled_p ()) 9821 dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.\n"); 9822 9823 if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def 9824 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def 9825 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def 9826 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle 9827 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def) 9828 && ! PURE_SLP_STMT (stmt_info)) 9829 { 9830 if (dump_enabled_p ()) 9831 dump_printf_loc (MSG_NOTE, vect_location, "transform phi.\n"); 9832 vect_transform_stmt (loop_vinfo, stmt_info, NULL, NULL, NULL); 9833 } 9834 } 9835 9836 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); 9837 gsi_next (&si)) 9838 { 9839 gphi *phi = si.phi (); 9840 stmt_info = loop_vinfo->lookup_stmt (phi); 9841 if (!stmt_info) 9842 continue; 9843 9844 if (!STMT_VINFO_RELEVANT_P (stmt_info) 9845 && !STMT_VINFO_LIVE_P (stmt_info)) 9846 continue; 9847 9848 if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def 9849 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def 9850 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def 9851 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle 9852 || STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def) 9853 && ! PURE_SLP_STMT (stmt_info)) 9854 maybe_set_vectorized_backedge_value (loop_vinfo, stmt_info); 9855 } 9856 9857 for (gimple_stmt_iterator si = gsi_start_bb (bb); 9858 !gsi_end_p (si);) 9859 { 9860 stmt = gsi_stmt (si); 9861 /* During vectorization remove existing clobber stmts. */ 9862 if (gimple_clobber_p (stmt)) 9863 { 9864 unlink_stmt_vdef (stmt); 9865 gsi_remove (&si, true); 9866 release_defs (stmt); 9867 } 9868 else 9869 { 9870 /* Ignore vector stmts created in the outer loop. */ 9871 stmt_info = loop_vinfo->lookup_stmt (stmt); 9872 9873 /* vector stmts created in the outer-loop during vectorization of 9874 stmts in an inner-loop may not have a stmt_info, and do not 9875 need to be vectorized. */ 9876 stmt_vec_info seen_store = NULL; 9877 if (stmt_info) 9878 { 9879 if (STMT_VINFO_IN_PATTERN_P (stmt_info)) 9880 { 9881 gimple *def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info); 9882 for (gimple_stmt_iterator subsi = gsi_start (def_seq); 9883 !gsi_end_p (subsi); gsi_next (&subsi)) 9884 { 9885 stmt_vec_info pat_stmt_info 9886 = loop_vinfo->lookup_stmt (gsi_stmt (subsi)); 9887 vect_transform_loop_stmt (loop_vinfo, pat_stmt_info, 9888 &si, &seen_store); 9889 } 9890 stmt_vec_info pat_stmt_info 9891 = STMT_VINFO_RELATED_STMT (stmt_info); 9892 if (vect_transform_loop_stmt (loop_vinfo, pat_stmt_info, 9893 &si, &seen_store)) 9894 maybe_set_vectorized_backedge_value (loop_vinfo, 9895 pat_stmt_info); 9896 } 9897 else 9898 { 9899 if (vect_transform_loop_stmt (loop_vinfo, stmt_info, &si, 9900 &seen_store)) 9901 maybe_set_vectorized_backedge_value (loop_vinfo, 9902 stmt_info); 9903 } 9904 } 9905 gsi_next (&si); 9906 if (seen_store) 9907 { 9908 if (STMT_VINFO_GROUPED_ACCESS (seen_store)) 9909 /* Interleaving. If IS_STORE is TRUE, the 9910 vectorization of the interleaving chain was 9911 completed - free all the stores in the chain. */ 9912 vect_remove_stores (loop_vinfo, 9913 DR_GROUP_FIRST_ELEMENT (seen_store)); 9914 else 9915 /* Free the attached stmt_vec_info and remove the stmt. */ 9916 loop_vinfo->remove_stmt (stmt_info); 9917 } 9918 } 9919 } 9920 9921 /* Stub out scalar statements that must not survive vectorization. 9922 Doing this here helps with grouped statements, or statements that 9923 are involved in patterns. */ 9924 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); 9925 !gsi_end_p (gsi); gsi_next (&gsi)) 9926 { 9927 gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi)); 9928 if (!call || !gimple_call_internal_p (call)) 9929 continue; 9930 internal_fn ifn = gimple_call_internal_fn (call); 9931 if (ifn == IFN_MASK_LOAD) 9932 { 9933 tree lhs = gimple_get_lhs (call); 9934 if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) 9935 { 9936 tree zero = build_zero_cst (TREE_TYPE (lhs)); 9937 gimple *new_stmt = gimple_build_assign (lhs, zero); 9938 gsi_replace (&gsi, new_stmt, true); 9939 } 9940 } 9941 else if (conditional_internal_fn_code (ifn) != ERROR_MARK) 9942 { 9943 tree lhs = gimple_get_lhs (call); 9944 if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) 9945 { 9946 tree else_arg 9947 = gimple_call_arg (call, gimple_call_num_args (call) - 1); 9948 gimple *new_stmt = gimple_build_assign (lhs, else_arg); 9949 gsi_replace (&gsi, new_stmt, true); 9950 } 9951 } 9952 } 9953 } /* BBs in loop */ 9954 9955 /* The vectorization factor is always > 1, so if we use an IV increment of 1. 9956 a zero NITERS becomes a nonzero NITERS_VECTOR. */ 9957 if (integer_onep (step_vector)) 9958 niters_no_overflow = true; 9959 vect_set_loop_condition (loop, loop_vinfo, niters_vector, step_vector, 9960 niters_vector_mult_vf, !niters_no_overflow); 9961 9962 unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo); 9963 scale_profile_for_vect_loop (loop, assumed_vf); 9964 9965 /* True if the final iteration might not handle a full vector's 9966 worth of scalar iterations. */ 9967 bool final_iter_may_be_partial 9968 = LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo); 9969 /* The minimum number of iterations performed by the epilogue. This 9970 is 1 when peeling for gaps because we always need a final scalar 9971 iteration. */ 9972 int min_epilogue_iters = LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) ? 1 : 0; 9973 /* +1 to convert latch counts to loop iteration counts, 9974 -min_epilogue_iters to remove iterations that cannot be performed 9975 by the vector code. */ 9976 int bias_for_lowest = 1 - min_epilogue_iters; 9977 int bias_for_assumed = bias_for_lowest; 9978 int alignment_npeels = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); 9979 if (alignment_npeels && LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) 9980 { 9981 /* When the amount of peeling is known at compile time, the first 9982 iteration will have exactly alignment_npeels active elements. 9983 In the worst case it will have at least one. */ 9984 int min_first_active = (alignment_npeels > 0 ? alignment_npeels : 1); 9985 bias_for_lowest += lowest_vf - min_first_active; 9986 bias_for_assumed += assumed_vf - min_first_active; 9987 } 9988 /* In these calculations the "- 1" converts loop iteration counts 9989 back to latch counts. */ 9990 if (loop->any_upper_bound) 9991 { 9992 loop_vec_info main_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); 9993 loop->nb_iterations_upper_bound 9994 = (final_iter_may_be_partial 9995 ? wi::udiv_ceil (loop->nb_iterations_upper_bound + bias_for_lowest, 9996 lowest_vf) - 1 9997 : wi::udiv_floor (loop->nb_iterations_upper_bound + bias_for_lowest, 9998 lowest_vf) - 1); 9999 if (main_vinfo 10000 /* Both peeling for alignment and peeling for gaps can end up 10001 with the scalar epilogue running for more than VF-1 iterations. */ 10002 && !main_vinfo->peeling_for_alignment 10003 && !main_vinfo->peeling_for_gaps) 10004 { 10005 unsigned int bound; 10006 poly_uint64 main_iters 10007 = upper_bound (LOOP_VINFO_VECT_FACTOR (main_vinfo), 10008 LOOP_VINFO_COST_MODEL_THRESHOLD (main_vinfo)); 10009 main_iters 10010 = upper_bound (main_iters, 10011 LOOP_VINFO_VERSIONING_THRESHOLD (main_vinfo)); 10012 if (can_div_away_from_zero_p (main_iters, 10013 LOOP_VINFO_VECT_FACTOR (loop_vinfo), 10014 &bound)) 10015 loop->nb_iterations_upper_bound 10016 = wi::umin ((widest_int) (bound - 1), 10017 loop->nb_iterations_upper_bound); 10018 } 10019 } 10020 if (loop->any_likely_upper_bound) 10021 loop->nb_iterations_likely_upper_bound 10022 = (final_iter_may_be_partial 10023 ? wi::udiv_ceil (loop->nb_iterations_likely_upper_bound 10024 + bias_for_lowest, lowest_vf) - 1 10025 : wi::udiv_floor (loop->nb_iterations_likely_upper_bound 10026 + bias_for_lowest, lowest_vf) - 1); 10027 if (loop->any_estimate) 10028 loop->nb_iterations_estimate 10029 = (final_iter_may_be_partial 10030 ? wi::udiv_ceil (loop->nb_iterations_estimate + bias_for_assumed, 10031 assumed_vf) - 1 10032 : wi::udiv_floor (loop->nb_iterations_estimate + bias_for_assumed, 10033 assumed_vf) - 1); 10034 10035 if (dump_enabled_p ()) 10036 { 10037 if (!LOOP_VINFO_EPILOGUE_P (loop_vinfo)) 10038 { 10039 dump_printf_loc (MSG_NOTE, vect_location, 10040 "LOOP VECTORIZED\n"); 10041 if (loop->inner) 10042 dump_printf_loc (MSG_NOTE, vect_location, 10043 "OUTER LOOP VECTORIZED\n"); 10044 dump_printf (MSG_NOTE, "\n"); 10045 } 10046 else 10047 dump_printf_loc (MSG_NOTE, vect_location, 10048 "LOOP EPILOGUE VECTORIZED (MODE=%s)\n", 10049 GET_MODE_NAME (loop_vinfo->vector_mode)); 10050 } 10051 10052 /* Loops vectorized with a variable factor won't benefit from 10053 unrolling/peeling. */ 10054 if (!vf.is_constant ()) 10055 { 10056 loop->unroll = 1; 10057 if (dump_enabled_p ()) 10058 dump_printf_loc (MSG_NOTE, vect_location, "Disabling unrolling due to" 10059 " variable-length vectorization factor\n"); 10060 } 10061 /* Free SLP instances here because otherwise stmt reference counting 10062 won't work. */ 10063 slp_instance instance; 10064 FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance) 10065 vect_free_slp_instance (instance); 10066 LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release (); 10067 /* Clear-up safelen field since its value is invalid after vectorization 10068 since vectorized loop can have loop-carried dependencies. */ 10069 loop->safelen = 0; 10070 10071 if (epilogue) 10072 { 10073 update_epilogue_loop_vinfo (epilogue, advance); 10074 10075 epilogue->simduid = loop->simduid; 10076 epilogue->force_vectorize = loop->force_vectorize; 10077 epilogue->dont_vectorize = false; 10078 } 10079 10080 return epilogue; 10081 } 10082 10083 /* The code below is trying to perform simple optimization - revert 10084 if-conversion for masked stores, i.e. if the mask of a store is zero 10085 do not perform it and all stored value producers also if possible. 10086 For example, 10087 for (i=0; i<n; i++) 10088 if (c[i]) 10089 { 10090 p1[i] += 1; 10091 p2[i] = p3[i] +2; 10092 } 10093 this transformation will produce the following semi-hammock: 10094 10095 if (!mask__ifc__42.18_165 == { 0, 0, 0, 0, 0, 0, 0, 0 }) 10096 { 10097 vect__11.19_170 = MASK_LOAD (vectp_p1.20_168, 0B, mask__ifc__42.18_165); 10098 vect__12.22_172 = vect__11.19_170 + vect_cst__171; 10099 MASK_STORE (vectp_p1.23_175, 0B, mask__ifc__42.18_165, vect__12.22_172); 10100 vect__18.25_182 = MASK_LOAD (vectp_p3.26_180, 0B, mask__ifc__42.18_165); 10101 vect__19.28_184 = vect__18.25_182 + vect_cst__183; 10102 MASK_STORE (vectp_p2.29_187, 0B, mask__ifc__42.18_165, vect__19.28_184); 10103 } 10104 */ 10105 10106 void 10107 optimize_mask_stores (class loop *loop) 10108 { 10109 basic_block *bbs = get_loop_body (loop); 10110 unsigned nbbs = loop->num_nodes; 10111 unsigned i; 10112 basic_block bb; 10113 class loop *bb_loop; 10114 gimple_stmt_iterator gsi; 10115 gimple *stmt; 10116 auto_vec<gimple *> worklist; 10117 auto_purge_vect_location sentinel; 10118 10119 vect_location = find_loop_location (loop); 10120 /* Pick up all masked stores in loop if any. */ 10121 for (i = 0; i < nbbs; i++) 10122 { 10123 bb = bbs[i]; 10124 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); 10125 gsi_next (&gsi)) 10126 { 10127 stmt = gsi_stmt (gsi); 10128 if (gimple_call_internal_p (stmt, IFN_MASK_STORE)) 10129 worklist.safe_push (stmt); 10130 } 10131 } 10132 10133 free (bbs); 10134 if (worklist.is_empty ()) 10135 return; 10136 10137 /* Loop has masked stores. */ 10138 while (!worklist.is_empty ()) 10139 { 10140 gimple *last, *last_store; 10141 edge e, efalse; 10142 tree mask; 10143 basic_block store_bb, join_bb; 10144 gimple_stmt_iterator gsi_to; 10145 tree vdef, new_vdef; 10146 gphi *phi; 10147 tree vectype; 10148 tree zero; 10149 10150 last = worklist.pop (); 10151 mask = gimple_call_arg (last, 2); 10152 bb = gimple_bb (last); 10153 /* Create then_bb and if-then structure in CFG, then_bb belongs to 10154 the same loop as if_bb. It could be different to LOOP when two 10155 level loop-nest is vectorized and mask_store belongs to the inner 10156 one. */ 10157 e = split_block (bb, last); 10158 bb_loop = bb->loop_father; 10159 gcc_assert (loop == bb_loop || flow_loop_nested_p (loop, bb_loop)); 10160 join_bb = e->dest; 10161 store_bb = create_empty_bb (bb); 10162 add_bb_to_loop (store_bb, bb_loop); 10163 e->flags = EDGE_TRUE_VALUE; 10164 efalse = make_edge (bb, store_bb, EDGE_FALSE_VALUE); 10165 /* Put STORE_BB to likely part. */ 10166 efalse->probability = profile_probability::unlikely (); 10167 store_bb->count = efalse->count (); 10168 make_single_succ_edge (store_bb, join_bb, EDGE_FALLTHRU); 10169 if (dom_info_available_p (CDI_DOMINATORS)) 10170 set_immediate_dominator (CDI_DOMINATORS, store_bb, bb); 10171 if (dump_enabled_p ()) 10172 dump_printf_loc (MSG_NOTE, vect_location, 10173 "Create new block %d to sink mask stores.", 10174 store_bb->index); 10175 /* Create vector comparison with boolean result. */ 10176 vectype = TREE_TYPE (mask); 10177 zero = build_zero_cst (vectype); 10178 stmt = gimple_build_cond (EQ_EXPR, mask, zero, NULL_TREE, NULL_TREE); 10179 gsi = gsi_last_bb (bb); 10180 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); 10181 /* Create new PHI node for vdef of the last masked store: 10182 .MEM_2 = VDEF <.MEM_1> 10183 will be converted to 10184 .MEM.3 = VDEF <.MEM_1> 10185 and new PHI node will be created in join bb 10186 .MEM_2 = PHI <.MEM_1, .MEM_3> 10187 */ 10188 vdef = gimple_vdef (last); 10189 new_vdef = make_ssa_name (gimple_vop (cfun), last); 10190 gimple_set_vdef (last, new_vdef); 10191 phi = create_phi_node (vdef, join_bb); 10192 add_phi_arg (phi, new_vdef, EDGE_SUCC (store_bb, 0), UNKNOWN_LOCATION); 10193 10194 /* Put all masked stores with the same mask to STORE_BB if possible. */ 10195 while (true) 10196 { 10197 gimple_stmt_iterator gsi_from; 10198 gimple *stmt1 = NULL; 10199 10200 /* Move masked store to STORE_BB. */ 10201 last_store = last; 10202 gsi = gsi_for_stmt (last); 10203 gsi_from = gsi; 10204 /* Shift GSI to the previous stmt for further traversal. */ 10205 gsi_prev (&gsi); 10206 gsi_to = gsi_start_bb (store_bb); 10207 gsi_move_before (&gsi_from, &gsi_to); 10208 /* Setup GSI_TO to the non-empty block start. */ 10209 gsi_to = gsi_start_bb (store_bb); 10210 if (dump_enabled_p ()) 10211 dump_printf_loc (MSG_NOTE, vect_location, 10212 "Move stmt to created bb\n%G", last); 10213 /* Move all stored value producers if possible. */ 10214 while (!gsi_end_p (gsi)) 10215 { 10216 tree lhs; 10217 imm_use_iterator imm_iter; 10218 use_operand_p use_p; 10219 bool res; 10220 10221 /* Skip debug statements. */ 10222 if (is_gimple_debug (gsi_stmt (gsi))) 10223 { 10224 gsi_prev (&gsi); 10225 continue; 10226 } 10227 stmt1 = gsi_stmt (gsi); 10228 /* Do not consider statements writing to memory or having 10229 volatile operand. */ 10230 if (gimple_vdef (stmt1) 10231 || gimple_has_volatile_ops (stmt1)) 10232 break; 10233 gsi_from = gsi; 10234 gsi_prev (&gsi); 10235 lhs = gimple_get_lhs (stmt1); 10236 if (!lhs) 10237 break; 10238 10239 /* LHS of vectorized stmt must be SSA_NAME. */ 10240 if (TREE_CODE (lhs) != SSA_NAME) 10241 break; 10242 10243 if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) 10244 { 10245 /* Remove dead scalar statement. */ 10246 if (has_zero_uses (lhs)) 10247 { 10248 gsi_remove (&gsi_from, true); 10249 continue; 10250 } 10251 } 10252 10253 /* Check that LHS does not have uses outside of STORE_BB. */ 10254 res = true; 10255 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) 10256 { 10257 gimple *use_stmt; 10258 use_stmt = USE_STMT (use_p); 10259 if (is_gimple_debug (use_stmt)) 10260 continue; 10261 if (gimple_bb (use_stmt) != store_bb) 10262 { 10263 res = false; 10264 break; 10265 } 10266 } 10267 if (!res) 10268 break; 10269 10270 if (gimple_vuse (stmt1) 10271 && gimple_vuse (stmt1) != gimple_vuse (last_store)) 10272 break; 10273 10274 /* Can move STMT1 to STORE_BB. */ 10275 if (dump_enabled_p ()) 10276 dump_printf_loc (MSG_NOTE, vect_location, 10277 "Move stmt to created bb\n%G", stmt1); 10278 gsi_move_before (&gsi_from, &gsi_to); 10279 /* Shift GSI_TO for further insertion. */ 10280 gsi_prev (&gsi_to); 10281 } 10282 /* Put other masked stores with the same mask to STORE_BB. */ 10283 if (worklist.is_empty () 10284 || gimple_call_arg (worklist.last (), 2) != mask 10285 || worklist.last () != stmt1) 10286 break; 10287 last = worklist.pop (); 10288 } 10289 add_phi_arg (phi, gimple_vuse (last_store), e, UNKNOWN_LOCATION); 10290 } 10291 } 10292 10293 /* Decide whether it is possible to use a zero-based induction variable 10294 when vectorizing LOOP_VINFO with partial vectors. If it is, return 10295 the value that the induction variable must be able to hold in order 10296 to ensure that the rgroups eventually have no active vector elements. 10297 Return -1 otherwise. */ 10298 10299 widest_int 10300 vect_iv_limit_for_partial_vectors (loop_vec_info loop_vinfo) 10301 { 10302 tree niters_skip = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo); 10303 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 10304 unsigned HOST_WIDE_INT max_vf = vect_max_vf (loop_vinfo); 10305 10306 /* Calculate the value that the induction variable must be able 10307 to hit in order to ensure that we end the loop with an all-false mask. 10308 This involves adding the maximum number of inactive trailing scalar 10309 iterations. */ 10310 widest_int iv_limit = -1; 10311 if (max_loop_iterations (loop, &iv_limit)) 10312 { 10313 if (niters_skip) 10314 { 10315 /* Add the maximum number of skipped iterations to the 10316 maximum iteration count. */ 10317 if (TREE_CODE (niters_skip) == INTEGER_CST) 10318 iv_limit += wi::to_widest (niters_skip); 10319 else 10320 iv_limit += max_vf - 1; 10321 } 10322 else if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)) 10323 /* Make a conservatively-correct assumption. */ 10324 iv_limit += max_vf - 1; 10325 10326 /* IV_LIMIT is the maximum number of latch iterations, which is also 10327 the maximum in-range IV value. Round this value down to the previous 10328 vector alignment boundary and then add an extra full iteration. */ 10329 poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); 10330 iv_limit = (iv_limit & -(int) known_alignment (vf)) + max_vf; 10331 } 10332 return iv_limit; 10333 } 10334 10335 /* For the given rgroup_controls RGC, check whether an induction variable 10336 would ever hit a value that produces a set of all-false masks or zero 10337 lengths before wrapping around. Return true if it's possible to wrap 10338 around before hitting the desirable value, otherwise return false. */ 10339 10340 bool 10341 vect_rgroup_iv_might_wrap_p (loop_vec_info loop_vinfo, rgroup_controls *rgc) 10342 { 10343 widest_int iv_limit = vect_iv_limit_for_partial_vectors (loop_vinfo); 10344 10345 if (iv_limit == -1) 10346 return true; 10347 10348 tree compare_type = LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo); 10349 unsigned int compare_precision = TYPE_PRECISION (compare_type); 10350 unsigned nitems = rgc->max_nscalars_per_iter * rgc->factor; 10351 10352 if (wi::min_precision (iv_limit * nitems, UNSIGNED) > compare_precision) 10353 return true; 10354 10355 return false; 10356 } 10357