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