2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Dorit Naishlos <dorit@il.ibm.com> and
5 Ira Rosen <irar@il.ibm.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "basic-block.h"
30 #include "tree-pretty-print.h"
31 #include "gimple-pretty-print.h"
32 #include "tree-flow.h"
33 #include "tree-dump.h"
35 #include "cfglayout.h"
40 #include "diagnostic-core.h"
41 #include "tree-chrec.h"
42 #include "tree-scalar-evolution.h"
43 #include "tree-vectorizer.h"
46 /* Loop Vectorization Pass.
48 This pass tries to vectorize loops.
50 For example, the vectorizer transforms the following simple loop:
52 short a[N]; short b[N]; short c[N]; int i;
58 as if it was manually vectorized by rewriting the source code into:
60 typedef int __attribute__((mode(V8HI))) v8hi;
61 short a[N]; short b[N]; short c[N]; int i;
62 v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
65 for (i=0; i<N/8; i++){
72 The main entry to this pass is vectorize_loops(), in which
73 the vectorizer applies a set of analyses on a given set of loops,
74 followed by the actual vectorization transformation for the loops that
75 had successfully passed the analysis phase.
76 Throughout this pass we make a distinction between two types of
77 data: scalars (which are represented by SSA_NAMES), and memory references
78 ("data-refs"). These two types of data require different handling both
79 during analysis and transformation. The types of data-refs that the
80 vectorizer currently supports are ARRAY_REFS which base is an array DECL
81 (not a pointer), and INDIRECT_REFS through pointers; both array and pointer
82 accesses are required to have a simple (consecutive) access pattern.
86 The driver for the analysis phase is vect_analyze_loop().
87 It applies a set of analyses, some of which rely on the scalar evolution
88 analyzer (scev) developed by Sebastian Pop.
90 During the analysis phase the vectorizer records some information
91 per stmt in a "stmt_vec_info" struct which is attached to each stmt in the
92 loop, as well as general information about the loop as a whole, which is
93 recorded in a "loop_vec_info" struct attached to each loop.
97 The loop transformation phase scans all the stmts in the loop, and
98 creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
99 the loop that needs to be vectorized. It inserts the vector code sequence
100 just before the scalar stmt S, and records a pointer to the vector code
101 in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct
102 attached to S). This pointer will be used for the vectorization of following
103 stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
104 otherwise, we rely on dead code elimination for removing it.
106 For example, say stmt S1 was vectorized into stmt VS1:
109 S1: b = x[i]; STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
112 To vectorize stmt S2, the vectorizer first finds the stmt that defines
113 the operand 'b' (S1), and gets the relevant vector def 'vb' from the
114 vector stmt VS1 pointed to by STMT_VINFO_VEC_STMT (stmt_info (S1)). The
115 resulting sequence would be:
118 S1: b = x[i]; STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
120 S2: a = b; STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
122 Operands that are not SSA_NAMEs, are data-refs that appear in
123 load/store operations (like 'x[i]' in S1), and are handled differently.
127 Currently the only target specific information that is used is the
128 size of the vector (in bytes) - "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD".
129 Targets that can support different sizes of vectors, for now will need
130 to specify one value for "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD". More
131 flexibility will be added in the future.
133 Since we only vectorize operations which vector form can be
134 expressed using existing tree codes, to verify that an operation is
135 supported, the vectorizer checks the relevant optab at the relevant
136 machine_mode (e.g, optab_handler (add_optab, V8HImode)). If
137 the value found is CODE_FOR_nothing, then there's no target support, and
138 we can't vectorize the stmt.
140 For additional information on this project see:
141 http://gcc.gnu.org/projects/tree-ssa/vectorization.html
144 /* Function vect_determine_vectorization_factor
146 Determine the vectorization factor (VF). VF is the number of data elements
147 that are operated upon in parallel in a single iteration of the vectorized
148 loop. For example, when vectorizing a loop that operates on 4byte elements,
149 on a target with vector size (VS) 16byte, the VF is set to 4, since 4
150 elements can fit in a single vector register.
152 We currently support vectorization of loops in which all types operated upon
153 are of the same size. Therefore this function currently sets VF according to
154 the size of the types operated upon, and fails if there are multiple sizes
157 VF is also the factor by which the loop iterations are strip-mined, e.g.:
164 for (i=0; i<N; i+=VF){
165 a[i:VF] = b[i:VF] + c[i:VF];
170 vect_determine_vectorization_factor (loop_vec_info loop_vinfo
)
172 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
173 basic_block
*bbs
= LOOP_VINFO_BBS (loop_vinfo
);
174 int nbbs
= loop
->num_nodes
;
175 gimple_stmt_iterator si
;
176 unsigned int vectorization_factor
= 0;
181 stmt_vec_info stmt_info
;
185 if (vect_print_dump_info (REPORT_DETAILS
))
186 fprintf (vect_dump
, "=== vect_determine_vectorization_factor ===");
188 for (i
= 0; i
< nbbs
; i
++)
190 basic_block bb
= bbs
[i
];
192 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
195 stmt_info
= vinfo_for_stmt (phi
);
196 if (vect_print_dump_info (REPORT_DETAILS
))
198 fprintf (vect_dump
, "==> examining phi: ");
199 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
202 gcc_assert (stmt_info
);
204 if (STMT_VINFO_RELEVANT_P (stmt_info
))
206 gcc_assert (!STMT_VINFO_VECTYPE (stmt_info
));
207 scalar_type
= TREE_TYPE (PHI_RESULT (phi
));
209 if (vect_print_dump_info (REPORT_DETAILS
))
211 fprintf (vect_dump
, "get vectype for scalar type: ");
212 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
215 vectype
= get_vectype_for_scalar_type (scalar_type
);
218 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
221 "not vectorized: unsupported data-type ");
222 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
226 STMT_VINFO_VECTYPE (stmt_info
) = vectype
;
228 if (vect_print_dump_info (REPORT_DETAILS
))
230 fprintf (vect_dump
, "vectype: ");
231 print_generic_expr (vect_dump
, vectype
, TDF_SLIM
);
234 nunits
= TYPE_VECTOR_SUBPARTS (vectype
);
235 if (vect_print_dump_info (REPORT_DETAILS
))
236 fprintf (vect_dump
, "nunits = %d", nunits
);
238 if (!vectorization_factor
239 || (nunits
> vectorization_factor
))
240 vectorization_factor
= nunits
;
244 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
247 gimple stmt
= gsi_stmt (si
);
248 stmt_info
= vinfo_for_stmt (stmt
);
250 if (vect_print_dump_info (REPORT_DETAILS
))
252 fprintf (vect_dump
, "==> examining statement: ");
253 print_gimple_stmt (vect_dump
, stmt
, 0, TDF_SLIM
);
256 gcc_assert (stmt_info
);
258 /* skip stmts which do not need to be vectorized. */
259 if (!STMT_VINFO_RELEVANT_P (stmt_info
)
260 && !STMT_VINFO_LIVE_P (stmt_info
))
262 if (vect_print_dump_info (REPORT_DETAILS
))
263 fprintf (vect_dump
, "skip.");
267 if (gimple_get_lhs (stmt
) == NULL_TREE
)
269 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
271 fprintf (vect_dump
, "not vectorized: irregular stmt.");
272 print_gimple_stmt (vect_dump
, stmt
, 0, TDF_SLIM
);
277 if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt
))))
279 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
281 fprintf (vect_dump
, "not vectorized: vector stmt in loop:");
282 print_gimple_stmt (vect_dump
, stmt
, 0, TDF_SLIM
);
287 if (STMT_VINFO_VECTYPE (stmt_info
))
289 /* The only case when a vectype had been already set is for stmts
290 that contain a dataref, or for "pattern-stmts" (stmts generated
291 by the vectorizer to represent/replace a certain idiom). */
292 gcc_assert (STMT_VINFO_DATA_REF (stmt_info
)
293 || is_pattern_stmt_p (stmt_info
));
294 vectype
= STMT_VINFO_VECTYPE (stmt_info
);
298 gcc_assert (!STMT_VINFO_DATA_REF (stmt_info
)
299 && !is_pattern_stmt_p (stmt_info
));
301 scalar_type
= TREE_TYPE (gimple_get_lhs (stmt
));
302 if (vect_print_dump_info (REPORT_DETAILS
))
304 fprintf (vect_dump
, "get vectype for scalar type: ");
305 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
307 vectype
= get_vectype_for_scalar_type (scalar_type
);
310 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
313 "not vectorized: unsupported data-type ");
314 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
319 STMT_VINFO_VECTYPE (stmt_info
) = vectype
;
322 /* The vectorization factor is according to the smallest
323 scalar type (or the largest vector size, but we only
324 support one vector size per loop). */
325 scalar_type
= vect_get_smallest_scalar_type (stmt
, &dummy
,
327 if (vect_print_dump_info (REPORT_DETAILS
))
329 fprintf (vect_dump
, "get vectype for scalar type: ");
330 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
332 vf_vectype
= get_vectype_for_scalar_type (scalar_type
);
335 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
338 "not vectorized: unsupported data-type ");
339 print_generic_expr (vect_dump
, scalar_type
, TDF_SLIM
);
344 if ((GET_MODE_SIZE (TYPE_MODE (vectype
))
345 != GET_MODE_SIZE (TYPE_MODE (vf_vectype
))))
347 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
350 "not vectorized: different sized vector "
351 "types in statement, ");
352 print_generic_expr (vect_dump
, vectype
, TDF_SLIM
);
353 fprintf (vect_dump
, " and ");
354 print_generic_expr (vect_dump
, vf_vectype
, TDF_SLIM
);
359 if (vect_print_dump_info (REPORT_DETAILS
))
361 fprintf (vect_dump
, "vectype: ");
362 print_generic_expr (vect_dump
, vf_vectype
, TDF_SLIM
);
365 nunits
= TYPE_VECTOR_SUBPARTS (vf_vectype
);
366 if (vect_print_dump_info (REPORT_DETAILS
))
367 fprintf (vect_dump
, "nunits = %d", nunits
);
369 if (!vectorization_factor
370 || (nunits
> vectorization_factor
))
371 vectorization_factor
= nunits
;
375 /* TODO: Analyze cost. Decide if worth while to vectorize. */
376 if (vect_print_dump_info (REPORT_DETAILS
))
377 fprintf (vect_dump
, "vectorization factor = %d", vectorization_factor
);
378 if (vectorization_factor
<= 1)
380 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
381 fprintf (vect_dump
, "not vectorized: unsupported data-type");
384 LOOP_VINFO_VECT_FACTOR (loop_vinfo
) = vectorization_factor
;
390 /* Function vect_is_simple_iv_evolution.
392 FORNOW: A simple evolution of an induction variables in the loop is
393 considered a polynomial evolution with constant step. */
396 vect_is_simple_iv_evolution (unsigned loop_nb
, tree access_fn
, tree
* init
,
401 tree evolution_part
= evolution_part_in_loop_num (access_fn
, loop_nb
);
403 /* When there is no evolution in this loop, the evolution function
405 if (evolution_part
== NULL_TREE
)
408 /* When the evolution is a polynomial of degree >= 2
409 the evolution function is not "simple". */
410 if (tree_is_chrec (evolution_part
))
413 step_expr
= evolution_part
;
414 init_expr
= unshare_expr (initial_condition_in_loop_num (access_fn
, loop_nb
));
416 if (vect_print_dump_info (REPORT_DETAILS
))
418 fprintf (vect_dump
, "step: ");
419 print_generic_expr (vect_dump
, step_expr
, TDF_SLIM
);
420 fprintf (vect_dump
, ", init: ");
421 print_generic_expr (vect_dump
, init_expr
, TDF_SLIM
);
427 if (TREE_CODE (step_expr
) != INTEGER_CST
)
429 if (vect_print_dump_info (REPORT_DETAILS
))
430 fprintf (vect_dump
, "step unknown.");
437 /* Function vect_analyze_scalar_cycles_1.
439 Examine the cross iteration def-use cycles of scalar variables
440 in LOOP. LOOP_VINFO represents the loop that is now being
441 considered for vectorization (can be LOOP, or an outer-loop
445 vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo
, struct loop
*loop
)
447 basic_block bb
= loop
->header
;
449 VEC(gimple
,heap
) *worklist
= VEC_alloc (gimple
, heap
, 64);
450 gimple_stmt_iterator gsi
;
453 if (vect_print_dump_info (REPORT_DETAILS
))
454 fprintf (vect_dump
, "=== vect_analyze_scalar_cycles ===");
456 /* First - identify all inductions. Reduction detection assumes that all the
457 inductions have been identified, therefore, this order must not be
459 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
461 gimple phi
= gsi_stmt (gsi
);
462 tree access_fn
= NULL
;
463 tree def
= PHI_RESULT (phi
);
464 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (phi
);
466 if (vect_print_dump_info (REPORT_DETAILS
))
468 fprintf (vect_dump
, "Analyze phi: ");
469 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
472 /* Skip virtual phi's. The data dependences that are associated with
473 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */
474 if (!is_gimple_reg (SSA_NAME_VAR (def
)))
477 STMT_VINFO_DEF_TYPE (stmt_vinfo
) = vect_unknown_def_type
;
479 /* Analyze the evolution function. */
480 access_fn
= analyze_scalar_evolution (loop
, def
);
482 STRIP_NOPS (access_fn
);
483 if (access_fn
&& vect_print_dump_info (REPORT_DETAILS
))
485 fprintf (vect_dump
, "Access function of PHI: ");
486 print_generic_expr (vect_dump
, access_fn
, TDF_SLIM
);
490 || !vect_is_simple_iv_evolution (loop
->num
, access_fn
, &dumy
, &dumy
))
492 VEC_safe_push (gimple
, heap
, worklist
, phi
);
496 if (vect_print_dump_info (REPORT_DETAILS
))
497 fprintf (vect_dump
, "Detected induction.");
498 STMT_VINFO_DEF_TYPE (stmt_vinfo
) = vect_induction_def
;
502 /* Second - identify all reductions and nested cycles. */
503 while (VEC_length (gimple
, worklist
) > 0)
505 gimple phi
= VEC_pop (gimple
, worklist
);
506 tree def
= PHI_RESULT (phi
);
507 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (phi
);
511 if (vect_print_dump_info (REPORT_DETAILS
))
513 fprintf (vect_dump
, "Analyze phi: ");
514 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
517 gcc_assert (is_gimple_reg (SSA_NAME_VAR (def
)));
518 gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo
) == vect_unknown_def_type
);
520 nested_cycle
= (loop
!= LOOP_VINFO_LOOP (loop_vinfo
));
521 reduc_stmt
= vect_force_simple_reduction (loop_vinfo
, phi
, !nested_cycle
,
527 if (vect_print_dump_info (REPORT_DETAILS
))
528 fprintf (vect_dump
, "Detected double reduction.");
530 STMT_VINFO_DEF_TYPE (stmt_vinfo
) = vect_double_reduction_def
;
531 STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt
)) =
532 vect_double_reduction_def
;
538 if (vect_print_dump_info (REPORT_DETAILS
))
539 fprintf (vect_dump
, "Detected vectorizable nested cycle.");
541 STMT_VINFO_DEF_TYPE (stmt_vinfo
) = vect_nested_cycle
;
542 STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt
)) =
547 if (vect_print_dump_info (REPORT_DETAILS
))
548 fprintf (vect_dump
, "Detected reduction.");
550 STMT_VINFO_DEF_TYPE (stmt_vinfo
) = vect_reduction_def
;
551 STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt
)) =
553 /* Store the reduction cycles for possible vectorization in
555 VEC_safe_push (gimple
, heap
,
556 LOOP_VINFO_REDUCTIONS (loop_vinfo
),
562 if (vect_print_dump_info (REPORT_DETAILS
))
563 fprintf (vect_dump
, "Unknown def-use cycle pattern.");
566 VEC_free (gimple
, heap
, worklist
);
570 /* Function vect_analyze_scalar_cycles.
572 Examine the cross iteration def-use cycles of scalar variables, by
573 analyzing the loop-header PHIs of scalar variables. Classify each
574 cycle as one of the following: invariant, induction, reduction, unknown.
575 We do that for the loop represented by LOOP_VINFO, and also to its
576 inner-loop, if exists.
577 Examples for scalar cycles:
592 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo
)
594 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
596 vect_analyze_scalar_cycles_1 (loop_vinfo
, loop
);
598 /* When vectorizing an outer-loop, the inner-loop is executed sequentially.
599 Reductions in such inner-loop therefore have different properties than
600 the reductions in the nest that gets vectorized:
601 1. When vectorized, they are executed in the same order as in the original
602 scalar loop, so we can't change the order of computation when
604 2. FIXME: Inner-loop reductions can be used in the inner-loop, so the
605 current checks are too strict. */
608 vect_analyze_scalar_cycles_1 (loop_vinfo
, loop
->inner
);
611 /* Function vect_get_loop_niters.
613 Determine how many iterations the loop is executed.
614 If an expression that represents the number of iterations
615 can be constructed, place it in NUMBER_OF_ITERATIONS.
616 Return the loop exit condition. */
619 vect_get_loop_niters (struct loop
*loop
, tree
*number_of_iterations
)
623 if (vect_print_dump_info (REPORT_DETAILS
))
624 fprintf (vect_dump
, "=== get_loop_niters ===");
626 niters
= number_of_exit_cond_executions (loop
);
628 if (niters
!= NULL_TREE
629 && niters
!= chrec_dont_know
)
631 *number_of_iterations
= niters
;
633 if (vect_print_dump_info (REPORT_DETAILS
))
635 fprintf (vect_dump
, "==> get_loop_niters:" );
636 print_generic_expr (vect_dump
, *number_of_iterations
, TDF_SLIM
);
640 return get_loop_exit_condition (loop
);
644 /* Function bb_in_loop_p
646 Used as predicate for dfs order traversal of the loop bbs. */
649 bb_in_loop_p (const_basic_block bb
, const void *data
)
651 const struct loop
*const loop
= (const struct loop
*)data
;
652 if (flow_bb_inside_loop_p (loop
, bb
))
658 /* Function new_loop_vec_info.
660 Create and initialize a new loop_vec_info struct for LOOP, as well as
661 stmt_vec_info structs for all the stmts in LOOP. */
664 new_loop_vec_info (struct loop
*loop
)
668 gimple_stmt_iterator si
;
669 unsigned int i
, nbbs
;
671 res
= (loop_vec_info
) xcalloc (1, sizeof (struct _loop_vec_info
));
672 LOOP_VINFO_LOOP (res
) = loop
;
674 bbs
= get_loop_body (loop
);
676 /* Create/Update stmt_info for all stmts in the loop. */
677 for (i
= 0; i
< loop
->num_nodes
; i
++)
679 basic_block bb
= bbs
[i
];
681 /* BBs in a nested inner-loop will have been already processed (because
682 we will have called vect_analyze_loop_form for any nested inner-loop).
683 Therefore, for stmts in an inner-loop we just want to update the
684 STMT_VINFO_LOOP_VINFO field of their stmt_info to point to the new
685 loop_info of the outer-loop we are currently considering to vectorize
686 (instead of the loop_info of the inner-loop).
687 For stmts in other BBs we need to create a stmt_info from scratch. */
688 if (bb
->loop_father
!= loop
)
691 gcc_assert (loop
->inner
&& bb
->loop_father
== loop
->inner
);
692 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
694 gimple phi
= gsi_stmt (si
);
695 stmt_vec_info stmt_info
= vinfo_for_stmt (phi
);
696 loop_vec_info inner_loop_vinfo
=
697 STMT_VINFO_LOOP_VINFO (stmt_info
);
698 gcc_assert (loop
->inner
== LOOP_VINFO_LOOP (inner_loop_vinfo
));
699 STMT_VINFO_LOOP_VINFO (stmt_info
) = res
;
701 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
703 gimple stmt
= gsi_stmt (si
);
704 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
705 loop_vec_info inner_loop_vinfo
=
706 STMT_VINFO_LOOP_VINFO (stmt_info
);
707 gcc_assert (loop
->inner
== LOOP_VINFO_LOOP (inner_loop_vinfo
));
708 STMT_VINFO_LOOP_VINFO (stmt_info
) = res
;
713 /* bb in current nest. */
714 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
716 gimple phi
= gsi_stmt (si
);
717 gimple_set_uid (phi
, 0);
718 set_vinfo_for_stmt (phi
, new_stmt_vec_info (phi
, res
, NULL
));
721 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
723 gimple stmt
= gsi_stmt (si
);
724 gimple_set_uid (stmt
, 0);
725 set_vinfo_for_stmt (stmt
, new_stmt_vec_info (stmt
, res
, NULL
));
730 /* CHECKME: We want to visit all BBs before their successors (except for
731 latch blocks, for which this assertion wouldn't hold). In the simple
732 case of the loop forms we allow, a dfs order of the BBs would the same
733 as reversed postorder traversal, so we are safe. */
736 bbs
= XCNEWVEC (basic_block
, loop
->num_nodes
);
737 nbbs
= dfs_enumerate_from (loop
->header
, 0, bb_in_loop_p
,
738 bbs
, loop
->num_nodes
, loop
);
739 gcc_assert (nbbs
== loop
->num_nodes
);
741 LOOP_VINFO_BBS (res
) = bbs
;
742 LOOP_VINFO_NITERS (res
) = NULL
;
743 LOOP_VINFO_NITERS_UNCHANGED (res
) = NULL
;
744 LOOP_VINFO_COST_MODEL_MIN_ITERS (res
) = 0;
745 LOOP_VINFO_VECTORIZABLE_P (res
) = 0;
746 LOOP_PEELING_FOR_ALIGNMENT (res
) = 0;
747 LOOP_VINFO_VECT_FACTOR (res
) = 0;
748 LOOP_VINFO_LOOP_NEST (res
) = VEC_alloc (loop_p
, heap
, 3);
749 LOOP_VINFO_DATAREFS (res
) = VEC_alloc (data_reference_p
, heap
, 10);
750 LOOP_VINFO_DDRS (res
) = VEC_alloc (ddr_p
, heap
, 10 * 10);
751 LOOP_VINFO_UNALIGNED_DR (res
) = NULL
;
752 LOOP_VINFO_MAY_MISALIGN_STMTS (res
) =
753 VEC_alloc (gimple
, heap
,
754 PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS
));
755 LOOP_VINFO_MAY_ALIAS_DDRS (res
) =
756 VEC_alloc (ddr_p
, heap
,
757 PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS
));
758 LOOP_VINFO_STRIDED_STORES (res
) = VEC_alloc (gimple
, heap
, 10);
759 LOOP_VINFO_REDUCTIONS (res
) = VEC_alloc (gimple
, heap
, 10);
760 LOOP_VINFO_SLP_INSTANCES (res
) = VEC_alloc (slp_instance
, heap
, 10);
761 LOOP_VINFO_SLP_UNROLLING_FACTOR (res
) = 1;
762 LOOP_VINFO_PEELING_HTAB (res
) = NULL
;
763 LOOP_VINFO_PEELING_FOR_GAPS (res
) = false;
769 /* Function destroy_loop_vec_info.
771 Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the
772 stmts in the loop. */
775 destroy_loop_vec_info (loop_vec_info loop_vinfo
, bool clean_stmts
)
780 gimple_stmt_iterator si
;
782 VEC (slp_instance
, heap
) *slp_instances
;
783 slp_instance instance
;
788 loop
= LOOP_VINFO_LOOP (loop_vinfo
);
790 bbs
= LOOP_VINFO_BBS (loop_vinfo
);
791 nbbs
= loop
->num_nodes
;
795 free (LOOP_VINFO_BBS (loop_vinfo
));
796 free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo
));
797 free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo
));
798 VEC_free (loop_p
, heap
, LOOP_VINFO_LOOP_NEST (loop_vinfo
));
799 VEC_free (gimple
, heap
, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo
));
800 VEC_free (ddr_p
, heap
, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo
));
807 for (j
= 0; j
< nbbs
; j
++)
809 basic_block bb
= bbs
[j
];
810 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
811 free_stmt_vec_info (gsi_stmt (si
));
813 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); )
815 gimple stmt
= gsi_stmt (si
);
816 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
820 /* Check if this is a "pattern stmt" (introduced by the
821 vectorizer during the pattern recognition pass). */
822 bool remove_stmt_p
= false;
823 gimple orig_stmt
= STMT_VINFO_RELATED_STMT (stmt_info
);
826 stmt_vec_info orig_stmt_info
= vinfo_for_stmt (orig_stmt
);
828 && STMT_VINFO_IN_PATTERN_P (orig_stmt_info
))
829 remove_stmt_p
= true;
832 /* Free stmt_vec_info. */
833 free_stmt_vec_info (stmt
);
835 /* Remove dead "pattern stmts". */
837 gsi_remove (&si
, true);
843 free (LOOP_VINFO_BBS (loop_vinfo
));
844 free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo
));
845 free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo
));
846 VEC_free (loop_p
, heap
, LOOP_VINFO_LOOP_NEST (loop_vinfo
));
847 VEC_free (gimple
, heap
, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo
));
848 VEC_free (ddr_p
, heap
, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo
));
849 slp_instances
= LOOP_VINFO_SLP_INSTANCES (loop_vinfo
);
850 FOR_EACH_VEC_ELT (slp_instance
, slp_instances
, j
, instance
)
851 vect_free_slp_instance (instance
);
853 VEC_free (slp_instance
, heap
, LOOP_VINFO_SLP_INSTANCES (loop_vinfo
));
854 VEC_free (gimple
, heap
, LOOP_VINFO_STRIDED_STORES (loop_vinfo
));
855 VEC_free (gimple
, heap
, LOOP_VINFO_REDUCTIONS (loop_vinfo
));
857 if (LOOP_VINFO_PEELING_HTAB (loop_vinfo
))
858 htab_delete (LOOP_VINFO_PEELING_HTAB (loop_vinfo
));
865 /* Function vect_analyze_loop_1.
867 Apply a set of analyses on LOOP, and create a loop_vec_info struct
868 for it. The different analyses will record information in the
869 loop_vec_info struct. This is a subset of the analyses applied in
870 vect_analyze_loop, to be applied on an inner-loop nested in the loop
871 that is now considered for (outer-loop) vectorization. */
874 vect_analyze_loop_1 (struct loop
*loop
)
876 loop_vec_info loop_vinfo
;
878 if (vect_print_dump_info (REPORT_DETAILS
))
879 fprintf (vect_dump
, "===== analyze_loop_nest_1 =====");
881 /* Check the CFG characteristics of the loop (nesting, entry/exit, etc. */
883 loop_vinfo
= vect_analyze_loop_form (loop
);
886 if (vect_print_dump_info (REPORT_DETAILS
))
887 fprintf (vect_dump
, "bad inner-loop form.");
895 /* Function vect_analyze_loop_form.
897 Verify that certain CFG restrictions hold, including:
898 - the loop has a pre-header
899 - the loop has a single entry and exit
900 - the loop exit condition is simple enough, and the number of iterations
901 can be analyzed (a countable loop). */
904 vect_analyze_loop_form (struct loop
*loop
)
906 loop_vec_info loop_vinfo
;
908 tree number_of_iterations
= NULL
;
909 loop_vec_info inner_loop_vinfo
= NULL
;
911 if (vect_print_dump_info (REPORT_DETAILS
))
912 fprintf (vect_dump
, "=== vect_analyze_loop_form ===");
914 /* Different restrictions apply when we are considering an inner-most loop,
915 vs. an outer (nested) loop.
916 (FORNOW. May want to relax some of these restrictions in the future). */
920 /* Inner-most loop. We currently require that the number of BBs is
921 exactly 2 (the header and latch). Vectorizable inner-most loops
932 if (loop
->num_nodes
!= 2)
934 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
935 fprintf (vect_dump
, "not vectorized: control flow in loop.");
939 if (empty_block_p (loop
->header
))
941 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
942 fprintf (vect_dump
, "not vectorized: empty loop.");
948 struct loop
*innerloop
= loop
->inner
;
951 /* Nested loop. We currently require that the loop is doubly-nested,
952 contains a single inner loop, and the number of BBs is exactly 5.
953 Vectorizable outer-loops look like this:
965 The inner-loop has the properties expected of inner-most loops
966 as described above. */
968 if ((loop
->inner
)->inner
|| (loop
->inner
)->next
)
970 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
971 fprintf (vect_dump
, "not vectorized: multiple nested loops.");
975 /* Analyze the inner-loop. */
976 inner_loop_vinfo
= vect_analyze_loop_1 (loop
->inner
);
977 if (!inner_loop_vinfo
)
979 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
980 fprintf (vect_dump
, "not vectorized: Bad inner loop.");
984 if (!expr_invariant_in_loop_p (loop
,
985 LOOP_VINFO_NITERS (inner_loop_vinfo
)))
987 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
989 "not vectorized: inner-loop count not invariant.");
990 destroy_loop_vec_info (inner_loop_vinfo
, true);
994 if (loop
->num_nodes
!= 5)
996 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
997 fprintf (vect_dump
, "not vectorized: control flow in loop.");
998 destroy_loop_vec_info (inner_loop_vinfo
, true);
1002 gcc_assert (EDGE_COUNT (innerloop
->header
->preds
) == 2);
1003 entryedge
= EDGE_PRED (innerloop
->header
, 0);
1004 if (EDGE_PRED (innerloop
->header
, 0)->src
== innerloop
->latch
)
1005 entryedge
= EDGE_PRED (innerloop
->header
, 1);
1007 if (entryedge
->src
!= loop
->header
1008 || !single_exit (innerloop
)
1009 || single_exit (innerloop
)->dest
!= EDGE_PRED (loop
->latch
, 0)->src
)
1011 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1012 fprintf (vect_dump
, "not vectorized: unsupported outerloop form.");
1013 destroy_loop_vec_info (inner_loop_vinfo
, true);
1017 if (vect_print_dump_info (REPORT_DETAILS
))
1018 fprintf (vect_dump
, "Considering outer-loop vectorization.");
1021 if (!single_exit (loop
)
1022 || EDGE_COUNT (loop
->header
->preds
) != 2)
1024 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1026 if (!single_exit (loop
))
1027 fprintf (vect_dump
, "not vectorized: multiple exits.");
1028 else if (EDGE_COUNT (loop
->header
->preds
) != 2)
1029 fprintf (vect_dump
, "not vectorized: too many incoming edges.");
1031 if (inner_loop_vinfo
)
1032 destroy_loop_vec_info (inner_loop_vinfo
, true);
1036 /* We assume that the loop exit condition is at the end of the loop. i.e,
1037 that the loop is represented as a do-while (with a proper if-guard
1038 before the loop if needed), where the loop header contains all the
1039 executable statements, and the latch is empty. */
1040 if (!empty_block_p (loop
->latch
)
1041 || !gimple_seq_empty_p (phi_nodes (loop
->latch
)))
1043 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1044 fprintf (vect_dump
, "not vectorized: unexpected loop form.");
1045 if (inner_loop_vinfo
)
1046 destroy_loop_vec_info (inner_loop_vinfo
, true);
1050 /* Make sure there exists a single-predecessor exit bb: */
1051 if (!single_pred_p (single_exit (loop
)->dest
))
1053 edge e
= single_exit (loop
);
1054 if (!(e
->flags
& EDGE_ABNORMAL
))
1056 split_loop_exit_edge (e
);
1057 if (vect_print_dump_info (REPORT_DETAILS
))
1058 fprintf (vect_dump
, "split exit edge.");
1062 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1063 fprintf (vect_dump
, "not vectorized: abnormal loop exit edge.");
1064 if (inner_loop_vinfo
)
1065 destroy_loop_vec_info (inner_loop_vinfo
, true);
1070 loop_cond
= vect_get_loop_niters (loop
, &number_of_iterations
);
1073 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1074 fprintf (vect_dump
, "not vectorized: complicated exit condition.");
1075 if (inner_loop_vinfo
)
1076 destroy_loop_vec_info (inner_loop_vinfo
, true);
1080 if (!number_of_iterations
)
1082 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1084 "not vectorized: number of iterations cannot be computed.");
1085 if (inner_loop_vinfo
)
1086 destroy_loop_vec_info (inner_loop_vinfo
, true);
1090 if (chrec_contains_undetermined (number_of_iterations
))
1092 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS
))
1093 fprintf (vect_dump
, "Infinite number of iterations.");
1094 if (inner_loop_vinfo
)
1095 destroy_loop_vec_info (inner_loop_vinfo
, true);
1099 if (!NITERS_KNOWN_P (number_of_iterations
))
1101 if (vect_print_dump_info (REPORT_DETAILS
))
1103 fprintf (vect_dump
, "Symbolic number of iterations is ");
1104 print_generic_expr (vect_dump
, number_of_iterations
, TDF_DETAILS
);
1107 else if (TREE_INT_CST_LOW (number_of_iterations
) == 0)
1109 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1110 fprintf (vect_dump
, "not vectorized: number of iterations = 0.");
1111 if (inner_loop_vinfo
)
1112 destroy_loop_vec_info (inner_loop_vinfo
, false);
1116 loop_vinfo
= new_loop_vec_info (loop
);
1117 LOOP_VINFO_NITERS (loop_vinfo
) = number_of_iterations
;
1118 LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo
) = number_of_iterations
;
1120 STMT_VINFO_TYPE (vinfo_for_stmt (loop_cond
)) = loop_exit_ctrl_vec_info_type
;
1122 /* CHECKME: May want to keep it around it in the future. */
1123 if (inner_loop_vinfo
)
1124 destroy_loop_vec_info (inner_loop_vinfo
, false);
1126 gcc_assert (!loop
->aux
);
1127 loop
->aux
= loop_vinfo
;
1132 /* Get cost by calling cost target builtin. */
1135 vect_get_cost (enum vect_cost_for_stmt type_of_cost
)
1137 tree dummy_type
= NULL
;
1140 return targetm
.vectorize
.builtin_vectorization_cost (type_of_cost
,
1145 /* Function vect_analyze_loop_operations.
1147 Scan the loop stmts and make sure they are all vectorizable. */
1150 vect_analyze_loop_operations (loop_vec_info loop_vinfo
)
1152 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
1153 basic_block
*bbs
= LOOP_VINFO_BBS (loop_vinfo
);
1154 int nbbs
= loop
->num_nodes
;
1155 gimple_stmt_iterator si
;
1156 unsigned int vectorization_factor
= 0;
1159 stmt_vec_info stmt_info
;
1160 bool need_to_vectorize
= false;
1161 int min_profitable_iters
;
1162 int min_scalar_loop_bound
;
1164 bool only_slp_in_loop
= true, ok
;
1166 if (vect_print_dump_info (REPORT_DETAILS
))
1167 fprintf (vect_dump
, "=== vect_analyze_loop_operations ===");
1169 gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo
));
1170 vectorization_factor
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
);
1172 for (i
= 0; i
< nbbs
; i
++)
1174 basic_block bb
= bbs
[i
];
1176 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
1178 phi
= gsi_stmt (si
);
1181 stmt_info
= vinfo_for_stmt (phi
);
1182 if (vect_print_dump_info (REPORT_DETAILS
))
1184 fprintf (vect_dump
, "examining phi: ");
1185 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
1188 if (! is_loop_header_bb_p (bb
))
1190 /* inner-loop loop-closed exit phi in outer-loop vectorization
1191 (i.e. a phi in the tail of the outer-loop).
1192 FORNOW: we currently don't support the case that these phis
1193 are not used in the outerloop (unless it is double reduction,
1194 i.e., this phi is vect_reduction_def), cause this case
1195 requires to actually do something here. */
1196 if ((!STMT_VINFO_RELEVANT_P (stmt_info
)
1197 || STMT_VINFO_LIVE_P (stmt_info
))
1198 && STMT_VINFO_DEF_TYPE (stmt_info
)
1199 != vect_double_reduction_def
)
1201 if (vect_print_dump_info (REPORT_DETAILS
))
1203 "Unsupported loop-closed phi in outer-loop.");
1209 gcc_assert (stmt_info
);
1211 if (STMT_VINFO_LIVE_P (stmt_info
))
1213 /* FORNOW: not yet supported. */
1214 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1215 fprintf (vect_dump
, "not vectorized: value used after loop.");
1219 if (STMT_VINFO_RELEVANT (stmt_info
) == vect_used_in_scope
1220 && STMT_VINFO_DEF_TYPE (stmt_info
) != vect_induction_def
)
1222 /* A scalar-dependence cycle that we don't support. */
1223 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1224 fprintf (vect_dump
, "not vectorized: scalar dependence cycle.");
1228 if (STMT_VINFO_RELEVANT_P (stmt_info
))
1230 need_to_vectorize
= true;
1231 if (STMT_VINFO_DEF_TYPE (stmt_info
) == vect_induction_def
)
1232 ok
= vectorizable_induction (phi
, NULL
, NULL
);
1237 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1240 "not vectorized: relevant phi not supported: ");
1241 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
1247 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
1249 gimple stmt
= gsi_stmt (si
);
1250 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
1252 gcc_assert (stmt_info
);
1254 if (!vect_analyze_stmt (stmt
, &need_to_vectorize
, NULL
))
1257 if ((STMT_VINFO_RELEVANT_P (stmt_info
)
1258 || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info
)))
1259 && !PURE_SLP_STMT (stmt_info
))
1260 /* STMT needs both SLP and loop-based vectorization. */
1261 only_slp_in_loop
= false;
1265 /* All operations in the loop are either irrelevant (deal with loop
1266 control, or dead), or only used outside the loop and can be moved
1267 out of the loop (e.g. invariants, inductions). The loop can be
1268 optimized away by scalar optimizations. We're better off not
1269 touching this loop. */
1270 if (!need_to_vectorize
)
1272 if (vect_print_dump_info (REPORT_DETAILS
))
1274 "All the computation can be taken out of the loop.");
1275 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1277 "not vectorized: redundant loop. no profit to vectorize.");
1281 /* If all the stmts in the loop can be SLPed, we perform only SLP, and
1282 vectorization factor of the loop is the unrolling factor required by the
1283 SLP instances. If that unrolling factor is 1, we say, that we perform
1284 pure SLP on loop - cross iteration parallelism is not exploited. */
1285 if (only_slp_in_loop
)
1286 vectorization_factor
= LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo
);
1288 vectorization_factor
= least_common_multiple (vectorization_factor
,
1289 LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo
));
1291 LOOP_VINFO_VECT_FACTOR (loop_vinfo
) = vectorization_factor
;
1293 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
1294 && vect_print_dump_info (REPORT_DETAILS
))
1296 "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC
,
1297 vectorization_factor
, LOOP_VINFO_INT_NITERS (loop_vinfo
));
1299 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
1300 && (LOOP_VINFO_INT_NITERS (loop_vinfo
) < vectorization_factor
))
1302 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1303 fprintf (vect_dump
, "not vectorized: iteration count too small.");
1304 if (vect_print_dump_info (REPORT_DETAILS
))
1305 fprintf (vect_dump
,"not vectorized: iteration count smaller than "
1306 "vectorization factor.");
1310 /* Analyze cost. Decide if worth while to vectorize. */
1312 /* Once VF is set, SLP costs should be updated since the number of created
1313 vector stmts depends on VF. */
1314 vect_update_slp_costs_according_to_vf (loop_vinfo
);
1316 min_profitable_iters
= vect_estimate_min_profitable_iters (loop_vinfo
);
1317 LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo
) = min_profitable_iters
;
1319 if (min_profitable_iters
< 0)
1321 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1322 fprintf (vect_dump
, "not vectorized: vectorization not profitable.");
1323 if (vect_print_dump_info (REPORT_DETAILS
))
1324 fprintf (vect_dump
, "not vectorized: vector version will never be "
1329 min_scalar_loop_bound
= ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND
)
1330 * vectorization_factor
) - 1);
1332 /* Use the cost model only if it is more conservative than user specified
1335 th
= (unsigned) min_scalar_loop_bound
;
1336 if (min_profitable_iters
1337 && (!min_scalar_loop_bound
1338 || min_profitable_iters
> min_scalar_loop_bound
))
1339 th
= (unsigned) min_profitable_iters
;
1341 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
1342 && LOOP_VINFO_INT_NITERS (loop_vinfo
) <= th
)
1344 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1345 fprintf (vect_dump
, "not vectorized: vectorization not "
1347 if (vect_print_dump_info (REPORT_DETAILS
))
1348 fprintf (vect_dump
, "not vectorized: iteration count smaller than "
1349 "user specified loop bound parameter or minimum "
1350 "profitable iterations (whichever is more conservative).");
1354 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
1355 || LOOP_VINFO_INT_NITERS (loop_vinfo
) % vectorization_factor
!= 0
1356 || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo
))
1358 if (vect_print_dump_info (REPORT_DETAILS
))
1359 fprintf (vect_dump
, "epilog loop required.");
1360 if (!vect_can_advance_ivs_p (loop_vinfo
))
1362 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1364 "not vectorized: can't create epilog loop 1.");
1367 if (!slpeel_can_duplicate_loop_p (loop
, single_exit (loop
)))
1369 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS
))
1371 "not vectorized: can't create epilog loop 2.");
1380 /* Function vect_analyze_loop_2.
1382 Apply a set of analyses on LOOP, and create a loop_vec_info struct
1383 for it. The different analyses will record information in the
1384 loop_vec_info struct. */
1386 vect_analyze_loop_2 (loop_vec_info loop_vinfo
)
1389 int max_vf
= MAX_VECTORIZATION_FACTOR
;
1392 /* Find all data references in the loop (which correspond to vdefs/vuses)
1393 and analyze their evolution in the loop. Also adjust the minimal
1394 vectorization factor according to the loads and stores.
1396 FORNOW: Handle only simple, array references, which
1397 alignment can be forced, and aligned pointer-references. */
1399 ok
= vect_analyze_data_refs (loop_vinfo
, NULL
, &min_vf
);
1402 if (vect_print_dump_info (REPORT_DETAILS
))
1403 fprintf (vect_dump
, "bad data references.");
1407 /* Classify all cross-iteration scalar data-flow cycles.
1408 Cross-iteration cycles caused by virtual phis are analyzed separately. */
1410 vect_analyze_scalar_cycles (loop_vinfo
);
1412 vect_pattern_recog (loop_vinfo
);
1414 /* Data-flow analysis to detect stmts that do not need to be vectorized. */
1416 ok
= vect_mark_stmts_to_be_vectorized (loop_vinfo
);
1419 if (vect_print_dump_info (REPORT_DETAILS
))
1420 fprintf (vect_dump
, "unexpected pattern.");
1424 /* Analyze data dependences between the data-refs in the loop
1425 and adjust the maximum vectorization factor according to
1427 FORNOW: fail at the first data dependence that we encounter. */
1429 ok
= vect_analyze_data_ref_dependences (loop_vinfo
, NULL
, &max_vf
, &dummy
);
1433 if (vect_print_dump_info (REPORT_DETAILS
))
1434 fprintf (vect_dump
, "bad data dependence.");
1438 ok
= vect_determine_vectorization_factor (loop_vinfo
);
1441 if (vect_print_dump_info (REPORT_DETAILS
))
1442 fprintf (vect_dump
, "can't determine vectorization factor.");
1445 if (max_vf
< LOOP_VINFO_VECT_FACTOR (loop_vinfo
))
1447 if (vect_print_dump_info (REPORT_DETAILS
))
1448 fprintf (vect_dump
, "bad data dependence.");
1452 /* Analyze the alignment of the data-refs in the loop.
1453 Fail if a data reference is found that cannot be vectorized. */
1455 ok
= vect_analyze_data_refs_alignment (loop_vinfo
, NULL
);
1458 if (vect_print_dump_info (REPORT_DETAILS
))
1459 fprintf (vect_dump
, "bad data alignment.");
1463 /* Analyze the access patterns of the data-refs in the loop (consecutive,
1464 complex, etc.). FORNOW: Only handle consecutive access pattern. */
1466 ok
= vect_analyze_data_ref_accesses (loop_vinfo
, NULL
);
1469 if (vect_print_dump_info (REPORT_DETAILS
))
1470 fprintf (vect_dump
, "bad data access.");
1474 /* Prune the list of ddrs to be tested at run-time by versioning for alias.
1475 It is important to call pruning after vect_analyze_data_ref_accesses,
1476 since we use grouping information gathered by interleaving analysis. */
1477 ok
= vect_prune_runtime_alias_test_list (loop_vinfo
);
1480 if (vect_print_dump_info (REPORT_DETAILS
))
1481 fprintf (vect_dump
, "too long list of versioning for alias "
1486 /* This pass will decide on using loop versioning and/or loop peeling in
1487 order to enhance the alignment of data references in the loop. */
1489 ok
= vect_enhance_data_refs_alignment (loop_vinfo
);
1492 if (vect_print_dump_info (REPORT_DETAILS
))
1493 fprintf (vect_dump
, "bad data alignment.");
1497 /* Check the SLP opportunities in the loop, analyze and build SLP trees. */
1498 ok
= vect_analyze_slp (loop_vinfo
, NULL
);
1501 /* Decide which possible SLP instances to SLP. */
1502 vect_make_slp_decision (loop_vinfo
);
1504 /* Find stmts that need to be both vectorized and SLPed. */
1505 vect_detect_hybrid_slp (loop_vinfo
);
1508 /* Scan all the operations in the loop and make sure they are
1511 ok
= vect_analyze_loop_operations (loop_vinfo
);
1514 if (vect_print_dump_info (REPORT_DETAILS
))
1515 fprintf (vect_dump
, "bad operation or unsupported loop bound.");
1522 /* Function vect_analyze_loop.
1524 Apply a set of analyses on LOOP, and create a loop_vec_info struct
1525 for it. The different analyses will record information in the
1526 loop_vec_info struct. */
1528 vect_analyze_loop (struct loop
*loop
)
1530 loop_vec_info loop_vinfo
;
1531 unsigned int vector_sizes
;
1533 /* Autodetect first vector size we try. */
1534 current_vector_size
= 0;
1535 vector_sizes
= targetm
.vectorize
.autovectorize_vector_sizes ();
1537 if (vect_print_dump_info (REPORT_DETAILS
))
1538 fprintf (vect_dump
, "===== analyze_loop_nest =====");
1540 if (loop_outer (loop
)
1541 && loop_vec_info_for_loop (loop_outer (loop
))
1542 && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop
))))
1544 if (vect_print_dump_info (REPORT_DETAILS
))
1545 fprintf (vect_dump
, "outer-loop already vectorized.");
1551 /* Check the CFG characteristics of the loop (nesting, entry/exit). */
1552 loop_vinfo
= vect_analyze_loop_form (loop
);
1555 if (vect_print_dump_info (REPORT_DETAILS
))
1556 fprintf (vect_dump
, "bad loop form.");
1560 if (vect_analyze_loop_2 (loop_vinfo
))
1562 LOOP_VINFO_VECTORIZABLE_P (loop_vinfo
) = 1;
1567 destroy_loop_vec_info (loop_vinfo
, true);
1569 vector_sizes
&= ~current_vector_size
;
1570 if (vector_sizes
== 0
1571 || current_vector_size
== 0)
1574 /* Try the next biggest vector size. */
1575 current_vector_size
= 1 << floor_log2 (vector_sizes
);
1576 if (vect_print_dump_info (REPORT_DETAILS
))
1577 fprintf (vect_dump
, "***** Re-trying analysis with "
1578 "vector size %d\n", current_vector_size
);
1583 /* Function reduction_code_for_scalar_code
1586 CODE - tree_code of a reduction operations.
1589 REDUC_CODE - the corresponding tree-code to be used to reduce the
1590 vector of partial results into a single scalar result (which
1591 will also reside in a vector) or ERROR_MARK if the operation is
1592 a supported reduction operation, but does not have such tree-code.
1594 Return FALSE if CODE currently cannot be vectorized as reduction. */
1597 reduction_code_for_scalar_code (enum tree_code code
,
1598 enum tree_code
*reduc_code
)
1603 *reduc_code
= REDUC_MAX_EXPR
;
1607 *reduc_code
= REDUC_MIN_EXPR
;
1611 *reduc_code
= REDUC_PLUS_EXPR
;
1619 *reduc_code
= ERROR_MARK
;
1628 /* Error reporting helper for vect_is_simple_reduction below. GIMPLE statement
1629 STMT is printed with a message MSG. */
1632 report_vect_op (gimple stmt
, const char *msg
)
1634 fprintf (vect_dump
, "%s", msg
);
1635 print_gimple_stmt (vect_dump
, stmt
, 0, TDF_SLIM
);
1639 /* Function vect_is_simple_reduction_1
1641 (1) Detect a cross-iteration def-use cycle that represents a simple
1642 reduction computation. We look for the following pattern:
1647 a2 = operation (a3, a1)
1650 1. operation is commutative and associative and it is safe to
1651 change the order of the computation (if CHECK_REDUCTION is true)
1652 2. no uses for a2 in the loop (a2 is used out of the loop)
1653 3. no uses of a1 in the loop besides the reduction operation
1654 4. no uses of a1 outside the loop.
1656 Conditions 1,4 are tested here.
1657 Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized.
1659 (2) Detect a cross-iteration def-use cycle in nested loops, i.e.,
1660 nested cycles, if CHECK_REDUCTION is false.
1662 (3) Detect cycles of phi nodes in outer-loop vectorization, i.e., double
1666 inner loop (def of a3)
1669 If MODIFY is true it tries also to rework the code in-place to enable
1670 detection of more reduction patterns. For the time being we rewrite
1671 "res -= RHS" into "rhs += -RHS" when it seems worthwhile.
1675 vect_is_simple_reduction_1 (loop_vec_info loop_info
, gimple phi
,
1676 bool check_reduction
, bool *double_reduc
,
1679 struct loop
*loop
= (gimple_bb (phi
))->loop_father
;
1680 struct loop
*vect_loop
= LOOP_VINFO_LOOP (loop_info
);
1681 edge latch_e
= loop_latch_edge (loop
);
1682 tree loop_arg
= PHI_ARG_DEF_FROM_EDGE (phi
, latch_e
);
1683 gimple def_stmt
, def1
= NULL
, def2
= NULL
;
1684 enum tree_code orig_code
, code
;
1685 tree op1
, op2
, op3
= NULL_TREE
, op4
= NULL_TREE
;
1689 imm_use_iterator imm_iter
;
1690 use_operand_p use_p
;
1693 *double_reduc
= false;
1695 /* If CHECK_REDUCTION is true, we assume inner-most loop vectorization,
1696 otherwise, we assume outer loop vectorization. */
1697 gcc_assert ((check_reduction
&& loop
== vect_loop
)
1698 || (!check_reduction
&& flow_loop_nested_p (vect_loop
, loop
)));
1700 name
= PHI_RESULT (phi
);
1702 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, name
)
1704 gimple use_stmt
= USE_STMT (use_p
);
1705 if (is_gimple_debug (use_stmt
))
1708 if (!flow_bb_inside_loop_p (loop
, gimple_bb (use_stmt
)))
1710 if (vect_print_dump_info (REPORT_DETAILS
))
1711 fprintf (vect_dump
, "intermediate value used outside loop.");
1716 if (vinfo_for_stmt (use_stmt
)
1717 && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt
)))
1721 if (vect_print_dump_info (REPORT_DETAILS
))
1722 fprintf (vect_dump
, "reduction used in loop.");
1727 if (TREE_CODE (loop_arg
) != SSA_NAME
)
1729 if (vect_print_dump_info (REPORT_DETAILS
))
1731 fprintf (vect_dump
, "reduction: not ssa_name: ");
1732 print_generic_expr (vect_dump
, loop_arg
, TDF_SLIM
);
1737 def_stmt
= SSA_NAME_DEF_STMT (loop_arg
);
1740 if (vect_print_dump_info (REPORT_DETAILS
))
1741 fprintf (vect_dump
, "reduction: no def_stmt.");
1745 if (!is_gimple_assign (def_stmt
) && gimple_code (def_stmt
) != GIMPLE_PHI
)
1747 if (vect_print_dump_info (REPORT_DETAILS
))
1748 print_gimple_stmt (vect_dump
, def_stmt
, 0, TDF_SLIM
);
1752 if (is_gimple_assign (def_stmt
))
1754 name
= gimple_assign_lhs (def_stmt
);
1759 name
= PHI_RESULT (def_stmt
);
1764 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, name
)
1766 gimple use_stmt
= USE_STMT (use_p
);
1767 if (is_gimple_debug (use_stmt
))
1769 if (flow_bb_inside_loop_p (loop
, gimple_bb (use_stmt
))
1770 && vinfo_for_stmt (use_stmt
)
1771 && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt
)))
1775 if (vect_print_dump_info (REPORT_DETAILS
))
1776 fprintf (vect_dump
, "reduction used in loop.");
1781 /* If DEF_STMT is a phi node itself, we expect it to have a single argument
1782 defined in the inner loop. */
1785 op1
= PHI_ARG_DEF (def_stmt
, 0);
1787 if (gimple_phi_num_args (def_stmt
) != 1
1788 || TREE_CODE (op1
) != SSA_NAME
)
1790 if (vect_print_dump_info (REPORT_DETAILS
))
1791 fprintf (vect_dump
, "unsupported phi node definition.");
1796 def1
= SSA_NAME_DEF_STMT (op1
);
1797 if (flow_bb_inside_loop_p (loop
, gimple_bb (def_stmt
))
1799 && flow_bb_inside_loop_p (loop
->inner
, gimple_bb (def1
))
1800 && is_gimple_assign (def1
))
1802 if (vect_print_dump_info (REPORT_DETAILS
))
1803 report_vect_op (def_stmt
, "detected double reduction: ");
1805 *double_reduc
= true;
1812 code
= orig_code
= gimple_assign_rhs_code (def_stmt
);
1814 /* We can handle "res -= x[i]", which is non-associative by
1815 simply rewriting this into "res += -x[i]". Avoid changing
1816 gimple instruction for the first simple tests and only do this
1817 if we're allowed to change code at all. */
1818 if (code
== MINUS_EXPR
1820 && (op1
= gimple_assign_rhs1 (def_stmt
))
1821 && TREE_CODE (op1
) == SSA_NAME
1822 && SSA_NAME_DEF_STMT (op1
) == phi
)
1826 && (!commutative_tree_code (code
) || !associative_tree_code (code
)))
1828 if (vect_print_dump_info (REPORT_DETAILS
))
1829 report_vect_op (def_stmt
, "reduction: not commutative/associative: ");
1833 if (get_gimple_rhs_class (code
) != GIMPLE_BINARY_RHS
)
1835 if (code
!= COND_EXPR
)
1837 if (vect_print_dump_info (REPORT_DETAILS
))
1838 report_vect_op (def_stmt
, "reduction: not binary operation: ");
1843 op3
= TREE_OPERAND (gimple_assign_rhs1 (def_stmt
), 0);
1844 if (COMPARISON_CLASS_P (op3
))
1846 op4
= TREE_OPERAND (op3
, 1);
1847 op3
= TREE_OPERAND (op3
, 0);
1850 op1
= TREE_OPERAND (gimple_assign_rhs1 (def_stmt
), 1);
1851 op2
= TREE_OPERAND (gimple_assign_rhs1 (def_stmt
), 2);
1853 if (TREE_CODE (op1
) != SSA_NAME
&& TREE_CODE (op2
) != SSA_NAME
)
1855 if (vect_print_dump_info (REPORT_DETAILS
))
1856 report_vect_op (def_stmt
, "reduction: uses not ssa_names: ");
1863 op1
= gimple_assign_rhs1 (def_stmt
);
1864 op2
= gimple_assign_rhs2 (def_stmt
);
1866 if (TREE_CODE (op1
) != SSA_NAME
|| TREE_CODE (op2
) != SSA_NAME
)
1868 if (vect_print_dump_info (REPORT_DETAILS
))
1869 report_vect_op (def_stmt
, "reduction: uses not ssa_names: ");
1875 type
= TREE_TYPE (gimple_assign_lhs (def_stmt
));
1876 if ((TREE_CODE (op1
) == SSA_NAME
1877 && !types_compatible_p (type
,TREE_TYPE (op1
)))
1878 || (TREE_CODE (op2
) == SSA_NAME
1879 && !types_compatible_p (type
, TREE_TYPE (op2
)))
1880 || (op3
&& TREE_CODE (op3
) == SSA_NAME
1881 && !types_compatible_p (type
, TREE_TYPE (op3
)))
1882 || (op4
&& TREE_CODE (op4
) == SSA_NAME
1883 && !types_compatible_p (type
, TREE_TYPE (op4
))))
1885 if (vect_print_dump_info (REPORT_DETAILS
))
1887 fprintf (vect_dump
, "reduction: multiple types: operation type: ");
1888 print_generic_expr (vect_dump
, type
, TDF_SLIM
);
1889 fprintf (vect_dump
, ", operands types: ");
1890 print_generic_expr (vect_dump
, TREE_TYPE (op1
), TDF_SLIM
);
1891 fprintf (vect_dump
, ",");
1892 print_generic_expr (vect_dump
, TREE_TYPE (op2
), TDF_SLIM
);
1895 fprintf (vect_dump
, ",");
1896 print_generic_expr (vect_dump
, TREE_TYPE (op3
), TDF_SLIM
);
1901 fprintf (vect_dump
, ",");
1902 print_generic_expr (vect_dump
, TREE_TYPE (op4
), TDF_SLIM
);
1909 /* Check that it's ok to change the order of the computation.
1910 Generally, when vectorizing a reduction we change the order of the
1911 computation. This may change the behavior of the program in some
1912 cases, so we need to check that this is ok. One exception is when
1913 vectorizing an outer-loop: the inner-loop is executed sequentially,
1914 and therefore vectorizing reductions in the inner-loop during
1915 outer-loop vectorization is safe. */
1917 /* CHECKME: check for !flag_finite_math_only too? */
1918 if (SCALAR_FLOAT_TYPE_P (type
) && !flag_associative_math
1921 /* Changing the order of operations changes the semantics. */
1922 if (vect_print_dump_info (REPORT_DETAILS
))
1923 report_vect_op (def_stmt
, "reduction: unsafe fp math optimization: ");
1926 else if (INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
)
1929 /* Changing the order of operations changes the semantics. */
1930 if (vect_print_dump_info (REPORT_DETAILS
))
1931 report_vect_op (def_stmt
, "reduction: unsafe int math optimization: ");
1934 else if (SAT_FIXED_POINT_TYPE_P (type
) && check_reduction
)
1936 /* Changing the order of operations changes the semantics. */
1937 if (vect_print_dump_info (REPORT_DETAILS
))
1938 report_vect_op (def_stmt
,
1939 "reduction: unsafe fixed-point math optimization: ");
1943 /* If we detected "res -= x[i]" earlier, rewrite it into
1944 "res += -x[i]" now. If this turns out to be useless reassoc
1945 will clean it up again. */
1946 if (orig_code
== MINUS_EXPR
)
1948 tree rhs
= gimple_assign_rhs2 (def_stmt
);
1949 tree negrhs
= make_ssa_name (SSA_NAME_VAR (rhs
), NULL
);
1950 gimple negate_stmt
= gimple_build_assign_with_ops (NEGATE_EXPR
, negrhs
,
1952 gimple_stmt_iterator gsi
= gsi_for_stmt (def_stmt
);
1953 set_vinfo_for_stmt (negate_stmt
, new_stmt_vec_info (negate_stmt
,
1955 gsi_insert_before (&gsi
, negate_stmt
, GSI_NEW_STMT
);
1956 gimple_assign_set_rhs2 (def_stmt
, negrhs
);
1957 gimple_assign_set_rhs_code (def_stmt
, PLUS_EXPR
);
1958 update_stmt (def_stmt
);
1961 /* Reduction is safe. We're dealing with one of the following:
1962 1) integer arithmetic and no trapv
1963 2) floating point arithmetic, and special flags permit this optimization
1964 3) nested cycle (i.e., outer loop vectorization). */
1965 if (TREE_CODE (op1
) == SSA_NAME
)
1966 def1
= SSA_NAME_DEF_STMT (op1
);
1968 if (TREE_CODE (op2
) == SSA_NAME
)
1969 def2
= SSA_NAME_DEF_STMT (op2
);
1971 if (code
!= COND_EXPR
1972 && (!def1
|| !def2
|| gimple_nop_p (def1
) || gimple_nop_p (def2
)))
1974 if (vect_print_dump_info (REPORT_DETAILS
))
1975 report_vect_op (def_stmt
, "reduction: no defs for operands: ");
1979 /* Check that one def is the reduction def, defined by PHI,
1980 the other def is either defined in the loop ("vect_internal_def"),
1981 or it's an induction (defined by a loop-header phi-node). */
1983 if (def2
&& def2
== phi
1984 && (code
== COND_EXPR
1985 || (def1
&& flow_bb_inside_loop_p (loop
, gimple_bb (def1
))
1986 && (is_gimple_assign (def1
)
1987 || is_gimple_call (def1
)
1988 || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1
))
1989 == vect_induction_def
1990 || (gimple_code (def1
) == GIMPLE_PHI
1991 && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1
))
1992 == vect_internal_def
1993 && !is_loop_header_bb_p (gimple_bb (def1
)))))))
1995 if (vect_print_dump_info (REPORT_DETAILS
))
1996 report_vect_op (def_stmt
, "detected reduction: ");
1999 else if (def1
&& def1
== phi
2000 && (code
== COND_EXPR
2001 || (def2
&& flow_bb_inside_loop_p (loop
, gimple_bb (def2
))
2002 && (is_gimple_assign (def2
)
2003 || is_gimple_call (def2
)
2004 || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2
))
2005 == vect_induction_def
2006 || (gimple_code (def2
) == GIMPLE_PHI
2007 && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2
))
2008 == vect_internal_def
2009 && !is_loop_header_bb_p (gimple_bb (def2
)))))))
2011 if (check_reduction
)
2013 /* Swap operands (just for simplicity - so that the rest of the code
2014 can assume that the reduction variable is always the last (second)
2016 if (vect_print_dump_info (REPORT_DETAILS
))
2017 report_vect_op (def_stmt
,
2018 "detected reduction: need to swap operands: ");
2020 swap_tree_operands (def_stmt
, gimple_assign_rhs1_ptr (def_stmt
),
2021 gimple_assign_rhs2_ptr (def_stmt
));
2025 if (vect_print_dump_info (REPORT_DETAILS
))
2026 report_vect_op (def_stmt
, "detected reduction: ");
2033 if (vect_print_dump_info (REPORT_DETAILS
))
2034 report_vect_op (def_stmt
, "reduction: unknown pattern: ");
2040 /* Wrapper around vect_is_simple_reduction_1, that won't modify code
2041 in-place. Arguments as there. */
2044 vect_is_simple_reduction (loop_vec_info loop_info
, gimple phi
,
2045 bool check_reduction
, bool *double_reduc
)
2047 return vect_is_simple_reduction_1 (loop_info
, phi
, check_reduction
,
2048 double_reduc
, false);
2051 /* Wrapper around vect_is_simple_reduction_1, which will modify code
2052 in-place if it enables detection of more reductions. Arguments
2056 vect_force_simple_reduction (loop_vec_info loop_info
, gimple phi
,
2057 bool check_reduction
, bool *double_reduc
)
2059 return vect_is_simple_reduction_1 (loop_info
, phi
, check_reduction
,
2060 double_reduc
, true);
2063 /* Calculate the cost of one scalar iteration of the loop. */
2065 vect_get_single_scalar_iteraion_cost (loop_vec_info loop_vinfo
)
2067 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
2068 basic_block
*bbs
= LOOP_VINFO_BBS (loop_vinfo
);
2069 int nbbs
= loop
->num_nodes
, factor
, scalar_single_iter_cost
= 0;
2070 int innerloop_iters
, i
, stmt_cost
;
2072 /* Count statements in scalar loop. Using this as scalar cost for a single
2075 TODO: Add outer loop support.
2077 TODO: Consider assigning different costs to different scalar
2081 innerloop_iters
= 1;
2083 innerloop_iters
= 50; /* FIXME */
2085 for (i
= 0; i
< nbbs
; i
++)
2087 gimple_stmt_iterator si
;
2088 basic_block bb
= bbs
[i
];
2090 if (bb
->loop_father
== loop
->inner
)
2091 factor
= innerloop_iters
;
2095 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
2097 gimple stmt
= gsi_stmt (si
);
2098 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
2100 if (!is_gimple_assign (stmt
) && !is_gimple_call (stmt
))
2103 /* Skip stmts that are not vectorized inside the loop. */
2105 && !STMT_VINFO_RELEVANT_P (stmt_info
)
2106 && (!STMT_VINFO_LIVE_P (stmt_info
)
2107 || STMT_VINFO_DEF_TYPE (stmt_info
) != vect_reduction_def
))
2110 if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt
)))
2112 if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt
))))
2113 stmt_cost
= vect_get_cost (scalar_load
);
2115 stmt_cost
= vect_get_cost (scalar_store
);
2118 stmt_cost
= vect_get_cost (scalar_stmt
);
2120 scalar_single_iter_cost
+= stmt_cost
* factor
;
2123 return scalar_single_iter_cost
;
2126 /* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times. */
2128 vect_get_known_peeling_cost (loop_vec_info loop_vinfo
, int peel_iters_prologue
,
2129 int *peel_iters_epilogue
,
2130 int scalar_single_iter_cost
)
2132 int peel_guard_costs
= 0;
2133 int vf
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
);
2135 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
))
2137 *peel_iters_epilogue
= vf
/2;
2138 if (vect_print_dump_info (REPORT_COST
))
2139 fprintf (vect_dump
, "cost model: "
2140 "epilogue peel iters set to vf/2 because "
2141 "loop iterations are unknown .");
2143 /* If peeled iterations are known but number of scalar loop
2144 iterations are unknown, count a taken branch per peeled loop. */
2145 peel_guard_costs
= 2 * vect_get_cost (cond_branch_taken
);
2149 int niters
= LOOP_VINFO_INT_NITERS (loop_vinfo
);
2150 peel_iters_prologue
= niters
< peel_iters_prologue
?
2151 niters
: peel_iters_prologue
;
2152 *peel_iters_epilogue
= (niters
- peel_iters_prologue
) % vf
;
2153 /* If we need to peel for gaps, but no peeling is required, we have to
2154 peel VF iterations. */
2155 if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo
) && !*peel_iters_epilogue
)
2156 *peel_iters_epilogue
= vf
;
2159 return (peel_iters_prologue
* scalar_single_iter_cost
)
2160 + (*peel_iters_epilogue
* scalar_single_iter_cost
)
2164 /* Function vect_estimate_min_profitable_iters
2166 Return the number of iterations required for the vector version of the
2167 loop to be profitable relative to the cost of the scalar version of the
2170 TODO: Take profile info into account before making vectorization
2171 decisions, if available. */
2174 vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo
)
2177 int min_profitable_iters
;
2178 int peel_iters_prologue
;
2179 int peel_iters_epilogue
;
2180 int vec_inside_cost
= 0;
2181 int vec_outside_cost
= 0;
2182 int scalar_single_iter_cost
= 0;
2183 int scalar_outside_cost
= 0;
2184 int vf
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
);
2185 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
2186 basic_block
*bbs
= LOOP_VINFO_BBS (loop_vinfo
);
2187 int nbbs
= loop
->num_nodes
;
2188 int npeel
= LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo
);
2189 int peel_guard_costs
= 0;
2190 int innerloop_iters
= 0, factor
;
2191 VEC (slp_instance
, heap
) *slp_instances
;
2192 slp_instance instance
;
2194 /* Cost model disabled. */
2195 if (!flag_vect_cost_model
)
2197 if (vect_print_dump_info (REPORT_COST
))
2198 fprintf (vect_dump
, "cost model disabled.");
2202 /* Requires loop versioning tests to handle misalignment. */
2203 if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo
))
2205 /* FIXME: Make cost depend on complexity of individual check. */
2207 VEC_length (gimple
, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo
));
2208 if (vect_print_dump_info (REPORT_COST
))
2209 fprintf (vect_dump
, "cost model: Adding cost of checks for loop "
2210 "versioning to treat misalignment.\n");
2213 /* Requires loop versioning with alias checks. */
2214 if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo
))
2216 /* FIXME: Make cost depend on complexity of individual check. */
2218 VEC_length (ddr_p
, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo
));
2219 if (vect_print_dump_info (REPORT_COST
))
2220 fprintf (vect_dump
, "cost model: Adding cost of checks for loop "
2221 "versioning aliasing.\n");
2224 if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo
)
2225 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo
))
2226 vec_outside_cost
+= vect_get_cost (cond_branch_taken
);
2228 /* Count statements in scalar loop. Using this as scalar cost for a single
2231 TODO: Add outer loop support.
2233 TODO: Consider assigning different costs to different scalar
2238 innerloop_iters
= 50; /* FIXME */
2240 for (i
= 0; i
< nbbs
; i
++)
2242 gimple_stmt_iterator si
;
2243 basic_block bb
= bbs
[i
];
2245 if (bb
->loop_father
== loop
->inner
)
2246 factor
= innerloop_iters
;
2250 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
2252 gimple stmt
= gsi_stmt (si
);
2253 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
2254 /* Skip stmts that are not vectorized inside the loop. */
2255 if (!STMT_VINFO_RELEVANT_P (stmt_info
)
2256 && (!STMT_VINFO_LIVE_P (stmt_info
)
2257 || STMT_VINFO_DEF_TYPE (stmt_info
) != vect_reduction_def
))
2259 vec_inside_cost
+= STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info
) * factor
;
2260 /* FIXME: for stmts in the inner-loop in outer-loop vectorization,
2261 some of the "outside" costs are generated inside the outer-loop. */
2262 vec_outside_cost
+= STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info
);
2266 scalar_single_iter_cost
= vect_get_single_scalar_iteraion_cost (loop_vinfo
);
2268 /* Add additional cost for the peeled instructions in prologue and epilogue
2271 FORNOW: If we don't know the value of peel_iters for prologue or epilogue
2272 at compile-time - we assume it's vf/2 (the worst would be vf-1).
2274 TODO: Build an expression that represents peel_iters for prologue and
2275 epilogue to be used in a run-time test. */
2279 peel_iters_prologue
= vf
/2;
2280 if (vect_print_dump_info (REPORT_COST
))
2281 fprintf (vect_dump
, "cost model: "
2282 "prologue peel iters set to vf/2.");
2284 /* If peeling for alignment is unknown, loop bound of main loop becomes
2286 peel_iters_epilogue
= vf
/2;
2287 if (vect_print_dump_info (REPORT_COST
))
2288 fprintf (vect_dump
, "cost model: "
2289 "epilogue peel iters set to vf/2 because "
2290 "peeling for alignment is unknown .");
2292 /* If peeled iterations are unknown, count a taken branch and a not taken
2293 branch per peeled loop. Even if scalar loop iterations are known,
2294 vector iterations are not known since peeled prologue iterations are
2295 not known. Hence guards remain the same. */
2296 peel_guard_costs
+= 2 * (vect_get_cost (cond_branch_taken
)
2297 + vect_get_cost (cond_branch_not_taken
));
2298 vec_outside_cost
+= (peel_iters_prologue
* scalar_single_iter_cost
)
2299 + (peel_iters_epilogue
* scalar_single_iter_cost
)
2304 peel_iters_prologue
= npeel
;
2305 vec_outside_cost
+= vect_get_known_peeling_cost (loop_vinfo
,
2306 peel_iters_prologue
, &peel_iters_epilogue
,
2307 scalar_single_iter_cost
);
2310 /* FORNOW: The scalar outside cost is incremented in one of the
2313 1. The vectorizer checks for alignment and aliasing and generates
2314 a condition that allows dynamic vectorization. A cost model
2315 check is ANDED with the versioning condition. Hence scalar code
2316 path now has the added cost of the versioning check.
2318 if (cost > th & versioning_check)
2321 Hence run-time scalar is incremented by not-taken branch cost.
2323 2. The vectorizer then checks if a prologue is required. If the
2324 cost model check was not done before during versioning, it has to
2325 be done before the prologue check.
2328 prologue = scalar_iters
2333 if (prologue == num_iters)
2336 Hence the run-time scalar cost is incremented by a taken branch,
2337 plus a not-taken branch, plus a taken branch cost.
2339 3. The vectorizer then checks if an epilogue is required. If the
2340 cost model check was not done before during prologue check, it
2341 has to be done with the epilogue check.
2347 if (prologue == num_iters)
2350 if ((cost <= th) | (scalar_iters-prologue-epilogue == 0))
2353 Hence the run-time scalar cost should be incremented by 2 taken
2356 TODO: The back end may reorder the BBS's differently and reverse
2357 conditions/branch directions. Change the estimates below to
2358 something more reasonable. */
2360 /* If the number of iterations is known and we do not do versioning, we can
2361 decide whether to vectorize at compile time. Hence the scalar version
2362 do not carry cost model guard costs. */
2363 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
2364 || LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo
)
2365 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo
))
2367 /* Cost model check occurs at versioning. */
2368 if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo
)
2369 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo
))
2370 scalar_outside_cost
+= vect_get_cost (cond_branch_not_taken
);
2373 /* Cost model check occurs at prologue generation. */
2374 if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo
) < 0)
2375 scalar_outside_cost
+= 2 * vect_get_cost (cond_branch_taken
)
2376 + vect_get_cost (cond_branch_not_taken
);
2377 /* Cost model check occurs at epilogue generation. */
2379 scalar_outside_cost
+= 2 * vect_get_cost (cond_branch_taken
);
2383 /* Add SLP costs. */
2384 slp_instances
= LOOP_VINFO_SLP_INSTANCES (loop_vinfo
);
2385 FOR_EACH_VEC_ELT (slp_instance
, slp_instances
, i
, instance
)
2387 vec_outside_cost
+= SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (instance
);
2388 vec_inside_cost
+= SLP_INSTANCE_INSIDE_OF_LOOP_COST (instance
);
2391 /* Calculate number of iterations required to make the vector version
2392 profitable, relative to the loop bodies only. The following condition
2394 SIC * niters + SOC > VIC * ((niters-PL_ITERS-EP_ITERS)/VF) + VOC
2396 SIC = scalar iteration cost, VIC = vector iteration cost,
2397 VOC = vector outside cost, VF = vectorization factor,
2398 PL_ITERS = prologue iterations, EP_ITERS= epilogue iterations
2399 SOC = scalar outside cost for run time cost model check. */
2401 if ((scalar_single_iter_cost
* vf
) > vec_inside_cost
)
2403 if (vec_outside_cost
<= 0)
2404 min_profitable_iters
= 1;
2407 min_profitable_iters
= ((vec_outside_cost
- scalar_outside_cost
) * vf
2408 - vec_inside_cost
* peel_iters_prologue
2409 - vec_inside_cost
* peel_iters_epilogue
)
2410 / ((scalar_single_iter_cost
* vf
)
2413 if ((scalar_single_iter_cost
* vf
* min_profitable_iters
)
2414 <= ((vec_inside_cost
* min_profitable_iters
)
2415 + ((vec_outside_cost
- scalar_outside_cost
) * vf
)))
2416 min_profitable_iters
++;
2419 /* vector version will never be profitable. */
2422 if (vect_print_dump_info (REPORT_COST
))
2423 fprintf (vect_dump
, "cost model: the vector iteration cost = %d "
2424 "divided by the scalar iteration cost = %d "
2425 "is greater or equal to the vectorization factor = %d.",
2426 vec_inside_cost
, scalar_single_iter_cost
, vf
);
2430 if (vect_print_dump_info (REPORT_COST
))
2432 fprintf (vect_dump
, "Cost model analysis: \n");
2433 fprintf (vect_dump
, " Vector inside of loop cost: %d\n",
2435 fprintf (vect_dump
, " Vector outside of loop cost: %d\n",
2437 fprintf (vect_dump
, " Scalar iteration cost: %d\n",
2438 scalar_single_iter_cost
);
2439 fprintf (vect_dump
, " Scalar outside cost: %d\n", scalar_outside_cost
);
2440 fprintf (vect_dump
, " prologue iterations: %d\n",
2441 peel_iters_prologue
);
2442 fprintf (vect_dump
, " epilogue iterations: %d\n",
2443 peel_iters_epilogue
);
2444 fprintf (vect_dump
, " Calculated minimum iters for profitability: %d\n",
2445 min_profitable_iters
);
2448 min_profitable_iters
=
2449 min_profitable_iters
< vf
? vf
: min_profitable_iters
;
2451 /* Because the condition we create is:
2452 if (niters <= min_profitable_iters)
2453 then skip the vectorized loop. */
2454 min_profitable_iters
--;
2456 if (vect_print_dump_info (REPORT_COST
))
2457 fprintf (vect_dump
, " Profitability threshold = %d\n",
2458 min_profitable_iters
);
2460 return min_profitable_iters
;
2464 /* TODO: Close dependency between vect_model_*_cost and vectorizable_*
2465 functions. Design better to avoid maintenance issues. */
2467 /* Function vect_model_reduction_cost.
2469 Models cost for a reduction operation, including the vector ops
2470 generated within the strip-mine loop, the initial definition before
2471 the loop, and the epilogue code that must be generated. */
2474 vect_model_reduction_cost (stmt_vec_info stmt_info
, enum tree_code reduc_code
,
2478 enum tree_code code
;
2481 gimple stmt
, orig_stmt
;
2483 enum machine_mode mode
;
2484 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_info
);
2485 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
2488 /* Cost of reduction op inside loop. */
2489 STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info
)
2490 += ncopies
* vect_get_cost (vector_stmt
);
2492 stmt
= STMT_VINFO_STMT (stmt_info
);
2494 switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt
)))
2496 case GIMPLE_SINGLE_RHS
:
2497 gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt
)) == ternary_op
);
2498 reduction_op
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 2);
2500 case GIMPLE_UNARY_RHS
:
2501 reduction_op
= gimple_assign_rhs1 (stmt
);
2503 case GIMPLE_BINARY_RHS
:
2504 reduction_op
= gimple_assign_rhs2 (stmt
);
2510 vectype
= get_vectype_for_scalar_type (TREE_TYPE (reduction_op
));
2513 if (vect_print_dump_info (REPORT_COST
))
2515 fprintf (vect_dump
, "unsupported data-type ");
2516 print_generic_expr (vect_dump
, TREE_TYPE (reduction_op
), TDF_SLIM
);
2521 mode
= TYPE_MODE (vectype
);
2522 orig_stmt
= STMT_VINFO_RELATED_STMT (stmt_info
);
2525 orig_stmt
= STMT_VINFO_STMT (stmt_info
);
2527 code
= gimple_assign_rhs_code (orig_stmt
);
2529 /* Add in cost for initial definition. */
2530 outer_cost
+= vect_get_cost (scalar_to_vec
);
2532 /* Determine cost of epilogue code.
2534 We have a reduction operator that will reduce the vector in one statement.
2535 Also requires scalar extract. */
2537 if (!nested_in_vect_loop_p (loop
, orig_stmt
))
2539 if (reduc_code
!= ERROR_MARK
)
2540 outer_cost
+= vect_get_cost (vector_stmt
)
2541 + vect_get_cost (vec_to_scalar
);
2544 int vec_size_in_bits
= tree_low_cst (TYPE_SIZE (vectype
), 1);
2546 TYPE_SIZE (TREE_TYPE (gimple_assign_lhs (orig_stmt
)));
2547 int element_bitsize
= tree_low_cst (bitsize
, 1);
2548 int nelements
= vec_size_in_bits
/ element_bitsize
;
2550 optab
= optab_for_tree_code (code
, vectype
, optab_default
);
2552 /* We have a whole vector shift available. */
2553 if (VECTOR_MODE_P (mode
)
2554 && optab_handler (optab
, mode
) != CODE_FOR_nothing
2555 && optab_handler (vec_shr_optab
, mode
) != CODE_FOR_nothing
)
2556 /* Final reduction via vector shifts and the reduction operator. Also
2557 requires scalar extract. */
2558 outer_cost
+= ((exact_log2(nelements
) * 2)
2559 * vect_get_cost (vector_stmt
)
2560 + vect_get_cost (vec_to_scalar
));
2562 /* Use extracts and reduction op for final reduction. For N elements,
2563 we have N extracts and N-1 reduction ops. */
2564 outer_cost
+= ((nelements
+ nelements
- 1)
2565 * vect_get_cost (vector_stmt
));
2569 STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info
) = outer_cost
;
2571 if (vect_print_dump_info (REPORT_COST
))
2572 fprintf (vect_dump
, "vect_model_reduction_cost: inside_cost = %d, "
2573 "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info
),
2574 STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info
));
2580 /* Function vect_model_induction_cost.
2582 Models cost for induction operations. */
2585 vect_model_induction_cost (stmt_vec_info stmt_info
, int ncopies
)
2587 /* loop cost for vec_loop. */
2588 STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info
)
2589 = ncopies
* vect_get_cost (vector_stmt
);
2590 /* prologue cost for vec_init and vec_step. */
2591 STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info
)
2592 = 2 * vect_get_cost (scalar_to_vec
);
2594 if (vect_print_dump_info (REPORT_COST
))
2595 fprintf (vect_dump
, "vect_model_induction_cost: inside_cost = %d, "
2596 "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info
),
2597 STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info
));
2601 /* Function get_initial_def_for_induction
2604 STMT - a stmt that performs an induction operation in the loop.
2605 IV_PHI - the initial value of the induction variable
2608 Return a vector variable, initialized with the first VF values of
2609 the induction variable. E.g., for an iv with IV_PHI='X' and
2610 evolution S, for a vector of 4 units, we want to return:
2611 [X, X + S, X + 2*S, X + 3*S]. */
2614 get_initial_def_for_induction (gimple iv_phi
)
2616 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (iv_phi
);
2617 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_vinfo
);
2618 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
2622 edge pe
= loop_preheader_edge (loop
);
2623 struct loop
*iv_loop
;
2625 tree vec
, vec_init
, vec_step
, t
;
2629 gimple init_stmt
, induction_phi
, new_stmt
;
2630 tree induc_def
, vec_def
, vec_dest
;
2631 tree init_expr
, step_expr
;
2632 int vf
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
);
2637 stmt_vec_info phi_info
= vinfo_for_stmt (iv_phi
);
2638 bool nested_in_vect_loop
= false;
2639 gimple_seq stmts
= NULL
;
2640 imm_use_iterator imm_iter
;
2641 use_operand_p use_p
;
2645 gimple_stmt_iterator si
;
2646 basic_block bb
= gimple_bb (iv_phi
);
2650 /* Is phi in an inner-loop, while vectorizing an enclosing outer-loop? */
2651 if (nested_in_vect_loop_p (loop
, iv_phi
))
2653 nested_in_vect_loop
= true;
2654 iv_loop
= loop
->inner
;
2658 gcc_assert (iv_loop
== (gimple_bb (iv_phi
))->loop_father
);
2660 latch_e
= loop_latch_edge (iv_loop
);
2661 loop_arg
= PHI_ARG_DEF_FROM_EDGE (iv_phi
, latch_e
);
2663 access_fn
= analyze_scalar_evolution (iv_loop
, PHI_RESULT (iv_phi
));
2664 gcc_assert (access_fn
);
2665 STRIP_NOPS (access_fn
);
2666 ok
= vect_is_simple_iv_evolution (iv_loop
->num
, access_fn
,
2667 &init_expr
, &step_expr
);
2669 pe
= loop_preheader_edge (iv_loop
);
2671 scalar_type
= TREE_TYPE (init_expr
);
2672 vectype
= get_vectype_for_scalar_type (scalar_type
);
2673 resvectype
= get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi
)));
2674 gcc_assert (vectype
);
2675 nunits
= TYPE_VECTOR_SUBPARTS (vectype
);
2676 ncopies
= vf
/ nunits
;
2678 gcc_assert (phi_info
);
2679 gcc_assert (ncopies
>= 1);
2681 /* Find the first insertion point in the BB. */
2682 si
= gsi_after_labels (bb
);
2684 /* Create the vector that holds the initial_value of the induction. */
2685 if (nested_in_vect_loop
)
2687 /* iv_loop is nested in the loop to be vectorized. init_expr had already
2688 been created during vectorization of previous stmts. We obtain it
2689 from the STMT_VINFO_VEC_STMT of the defining stmt. */
2690 tree iv_def
= PHI_ARG_DEF_FROM_EDGE (iv_phi
,
2691 loop_preheader_edge (iv_loop
));
2692 vec_init
= vect_get_vec_def_for_operand (iv_def
, iv_phi
, NULL
);
2696 /* iv_loop is the loop to be vectorized. Create:
2697 vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */
2698 new_var
= vect_get_new_vect_var (scalar_type
, vect_scalar_var
, "var_");
2699 add_referenced_var (new_var
);
2701 new_name
= force_gimple_operand (init_expr
, &stmts
, false, new_var
);
2704 new_bb
= gsi_insert_seq_on_edge_immediate (pe
, stmts
);
2705 gcc_assert (!new_bb
);
2709 t
= tree_cons (NULL_TREE
, new_name
, t
);
2710 for (i
= 1; i
< nunits
; i
++)
2712 /* Create: new_name_i = new_name + step_expr */
2713 enum tree_code code
= POINTER_TYPE_P (scalar_type
)
2714 ? POINTER_PLUS_EXPR
: PLUS_EXPR
;
2715 init_stmt
= gimple_build_assign_with_ops (code
, new_var
,
2716 new_name
, step_expr
);
2717 new_name
= make_ssa_name (new_var
, init_stmt
);
2718 gimple_assign_set_lhs (init_stmt
, new_name
);
2720 new_bb
= gsi_insert_on_edge_immediate (pe
, init_stmt
);
2721 gcc_assert (!new_bb
);
2723 if (vect_print_dump_info (REPORT_DETAILS
))
2725 fprintf (vect_dump
, "created new init_stmt: ");
2726 print_gimple_stmt (vect_dump
, init_stmt
, 0, TDF_SLIM
);
2728 t
= tree_cons (NULL_TREE
, new_name
, t
);
2730 /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1] */
2731 vec
= build_constructor_from_list (vectype
, nreverse (t
));
2732 vec_init
= vect_init_vector (iv_phi
, vec
, vectype
, NULL
);
2736 /* Create the vector that holds the step of the induction. */
2737 if (nested_in_vect_loop
)
2738 /* iv_loop is nested in the loop to be vectorized. Generate:
2739 vec_step = [S, S, S, S] */
2740 new_name
= step_expr
;
2743 /* iv_loop is the loop to be vectorized. Generate:
2744 vec_step = [VF*S, VF*S, VF*S, VF*S] */
2745 expr
= build_int_cst (TREE_TYPE (step_expr
), vf
);
2746 new_name
= fold_build2 (MULT_EXPR
, TREE_TYPE (step_expr
),
2750 t
= unshare_expr (new_name
);
2751 gcc_assert (CONSTANT_CLASS_P (new_name
));
2752 stepvectype
= get_vectype_for_scalar_type (TREE_TYPE (new_name
));
2753 gcc_assert (stepvectype
);
2754 vec
= build_vector_from_val (stepvectype
, t
);
2755 vec_step
= vect_init_vector (iv_phi
, vec
, stepvectype
, NULL
);
2758 /* Create the following def-use cycle:
2763 vec_iv = PHI <vec_init, vec_loop>
2767 vec_loop = vec_iv + vec_step; */
2769 /* Create the induction-phi that defines the induction-operand. */
2770 vec_dest
= vect_get_new_vect_var (vectype
, vect_simple_var
, "vec_iv_");
2771 add_referenced_var (vec_dest
);
2772 induction_phi
= create_phi_node (vec_dest
, iv_loop
->header
);
2773 set_vinfo_for_stmt (induction_phi
,
2774 new_stmt_vec_info (induction_phi
, loop_vinfo
, NULL
));
2775 induc_def
= PHI_RESULT (induction_phi
);
2777 /* Create the iv update inside the loop */
2778 new_stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, vec_dest
,
2779 induc_def
, vec_step
);
2780 vec_def
= make_ssa_name (vec_dest
, new_stmt
);
2781 gimple_assign_set_lhs (new_stmt
, vec_def
);
2782 gsi_insert_before (&si
, new_stmt
, GSI_SAME_STMT
);
2783 set_vinfo_for_stmt (new_stmt
, new_stmt_vec_info (new_stmt
, loop_vinfo
,
2786 /* Set the arguments of the phi node: */
2787 add_phi_arg (induction_phi
, vec_init
, pe
, UNKNOWN_LOCATION
);
2788 add_phi_arg (induction_phi
, vec_def
, loop_latch_edge (iv_loop
),
2792 /* In case that vectorization factor (VF) is bigger than the number
2793 of elements that we can fit in a vectype (nunits), we have to generate
2794 more than one vector stmt - i.e - we need to "unroll" the
2795 vector stmt by a factor VF/nunits. For more details see documentation
2796 in vectorizable_operation. */
2800 stmt_vec_info prev_stmt_vinfo
;
2801 /* FORNOW. This restriction should be relaxed. */
2802 gcc_assert (!nested_in_vect_loop
);
2804 /* Create the vector that holds the step of the induction. */
2805 expr
= build_int_cst (TREE_TYPE (step_expr
), nunits
);
2806 new_name
= fold_build2 (MULT_EXPR
, TREE_TYPE (step_expr
),
2808 t
= unshare_expr (new_name
);
2809 gcc_assert (CONSTANT_CLASS_P (new_name
));
2810 vec
= build_vector_from_val (stepvectype
, t
);
2811 vec_step
= vect_init_vector (iv_phi
, vec
, stepvectype
, NULL
);
2813 vec_def
= induc_def
;
2814 prev_stmt_vinfo
= vinfo_for_stmt (induction_phi
);
2815 for (i
= 1; i
< ncopies
; i
++)
2817 /* vec_i = vec_prev + vec_step */
2818 new_stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, vec_dest
,
2820 vec_def
= make_ssa_name (vec_dest
, new_stmt
);
2821 gimple_assign_set_lhs (new_stmt
, vec_def
);
2823 gsi_insert_before (&si
, new_stmt
, GSI_SAME_STMT
);
2824 if (!useless_type_conversion_p (resvectype
, vectype
))
2826 new_stmt
= gimple_build_assign_with_ops
2828 vect_get_new_vect_var (resvectype
, vect_simple_var
,
2830 build1 (VIEW_CONVERT_EXPR
, resvectype
,
2831 gimple_assign_lhs (new_stmt
)), NULL_TREE
);
2832 gimple_assign_set_lhs (new_stmt
,
2834 (gimple_assign_lhs (new_stmt
), new_stmt
));
2835 gsi_insert_before (&si
, new_stmt
, GSI_SAME_STMT
);
2837 set_vinfo_for_stmt (new_stmt
,
2838 new_stmt_vec_info (new_stmt
, loop_vinfo
, NULL
));
2839 STMT_VINFO_RELATED_STMT (prev_stmt_vinfo
) = new_stmt
;
2840 prev_stmt_vinfo
= vinfo_for_stmt (new_stmt
);
2844 if (nested_in_vect_loop
)
2846 /* Find the loop-closed exit-phi of the induction, and record
2847 the final vector of induction results: */
2849 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, loop_arg
)
2851 if (!flow_bb_inside_loop_p (iv_loop
, gimple_bb (USE_STMT (use_p
))))
2853 exit_phi
= USE_STMT (use_p
);
2859 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (exit_phi
);
2860 /* FORNOW. Currently not supporting the case that an inner-loop induction
2861 is not used in the outer-loop (i.e. only outside the outer-loop). */
2862 gcc_assert (STMT_VINFO_RELEVANT_P (stmt_vinfo
)
2863 && !STMT_VINFO_LIVE_P (stmt_vinfo
));
2865 STMT_VINFO_VEC_STMT (stmt_vinfo
) = new_stmt
;
2866 if (vect_print_dump_info (REPORT_DETAILS
))
2868 fprintf (vect_dump
, "vector of inductions after inner-loop:");
2869 print_gimple_stmt (vect_dump
, new_stmt
, 0, TDF_SLIM
);
2875 if (vect_print_dump_info (REPORT_DETAILS
))
2877 fprintf (vect_dump
, "transform induction: created def-use cycle: ");
2878 print_gimple_stmt (vect_dump
, induction_phi
, 0, TDF_SLIM
);
2879 fprintf (vect_dump
, "\n");
2880 print_gimple_stmt (vect_dump
, SSA_NAME_DEF_STMT (vec_def
), 0, TDF_SLIM
);
2883 STMT_VINFO_VEC_STMT (phi_info
) = induction_phi
;
2884 if (!useless_type_conversion_p (resvectype
, vectype
))
2886 new_stmt
= gimple_build_assign_with_ops
2888 vect_get_new_vect_var (resvectype
, vect_simple_var
, "vec_iv_"),
2889 build1 (VIEW_CONVERT_EXPR
, resvectype
, induc_def
), NULL_TREE
);
2890 induc_def
= make_ssa_name (gimple_assign_lhs (new_stmt
), new_stmt
);
2891 gimple_assign_set_lhs (new_stmt
, induc_def
);
2892 si
= gsi_start_bb (bb
);
2893 gsi_insert_before (&si
, new_stmt
, GSI_SAME_STMT
);
2894 set_vinfo_for_stmt (new_stmt
,
2895 new_stmt_vec_info (new_stmt
, loop_vinfo
, NULL
));
2896 STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_stmt
))
2897 = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (induction_phi
));
2904 /* Function get_initial_def_for_reduction
2907 STMT - a stmt that performs a reduction operation in the loop.
2908 INIT_VAL - the initial value of the reduction variable
2911 ADJUSTMENT_DEF - a tree that holds a value to be added to the final result
2912 of the reduction (used for adjusting the epilog - see below).
2913 Return a vector variable, initialized according to the operation that STMT
2914 performs. This vector will be used as the initial value of the
2915 vector of partial results.
2917 Option1 (adjust in epilog): Initialize the vector as follows:
2918 add/bit or/xor: [0,0,...,0,0]
2919 mult/bit and: [1,1,...,1,1]
2920 min/max/cond_expr: [init_val,init_val,..,init_val,init_val]
2921 and when necessary (e.g. add/mult case) let the caller know
2922 that it needs to adjust the result by init_val.
2924 Option2: Initialize the vector as follows:
2925 add/bit or/xor: [init_val,0,0,...,0]
2926 mult/bit and: [init_val,1,1,...,1]
2927 min/max/cond_expr: [init_val,init_val,...,init_val]
2928 and no adjustments are needed.
2930 For example, for the following code:
2936 STMT is 's = s + a[i]', and the reduction variable is 's'.
2937 For a vector of 4 units, we want to return either [0,0,0,init_val],
2938 or [0,0,0,0] and let the caller know that it needs to adjust
2939 the result at the end by 'init_val'.
2941 FORNOW, we are using the 'adjust in epilog' scheme, because this way the
2942 initialization vector is simpler (same element in all entries), if
2943 ADJUSTMENT_DEF is not NULL, and Option2 otherwise.
2945 A cost model should help decide between these two schemes. */
2948 get_initial_def_for_reduction (gimple stmt
, tree init_val
,
2949 tree
*adjustment_def
)
2951 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (stmt
);
2952 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_vinfo
);
2953 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
2954 tree scalar_type
= TREE_TYPE (init_val
);
2955 tree vectype
= get_vectype_for_scalar_type (scalar_type
);
2957 enum tree_code code
= gimple_assign_rhs_code (stmt
);
2962 bool nested_in_vect_loop
= false;
2964 REAL_VALUE_TYPE real_init_val
= dconst0
;
2965 int int_init_val
= 0;
2966 gimple def_stmt
= NULL
;
2968 gcc_assert (vectype
);
2969 nunits
= TYPE_VECTOR_SUBPARTS (vectype
);
2971 gcc_assert (POINTER_TYPE_P (scalar_type
) || INTEGRAL_TYPE_P (scalar_type
)
2972 || SCALAR_FLOAT_TYPE_P (scalar_type
));
2974 if (nested_in_vect_loop_p (loop
, stmt
))
2975 nested_in_vect_loop
= true;
2977 gcc_assert (loop
== (gimple_bb (stmt
))->loop_father
);
2979 /* In case of double reduction we only create a vector variable to be put
2980 in the reduction phi node. The actual statement creation is done in
2981 vect_create_epilog_for_reduction. */
2982 if (adjustment_def
&& nested_in_vect_loop
2983 && TREE_CODE (init_val
) == SSA_NAME
2984 && (def_stmt
= SSA_NAME_DEF_STMT (init_val
))
2985 && gimple_code (def_stmt
) == GIMPLE_PHI
2986 && flow_bb_inside_loop_p (loop
, gimple_bb (def_stmt
))
2987 && vinfo_for_stmt (def_stmt
)
2988 && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt
))
2989 == vect_double_reduction_def
)
2991 *adjustment_def
= NULL
;
2992 return vect_create_destination_var (init_val
, vectype
);
2995 if (TREE_CONSTANT (init_val
))
2997 if (SCALAR_FLOAT_TYPE_P (scalar_type
))
2998 init_value
= build_real (scalar_type
, TREE_REAL_CST (init_val
));
3000 init_value
= build_int_cst (scalar_type
, TREE_INT_CST_LOW (init_val
));
3003 init_value
= init_val
;
3007 case WIDEN_SUM_EXPR
:
3015 /* ADJUSMENT_DEF is NULL when called from
3016 vect_create_epilog_for_reduction to vectorize double reduction. */
3019 if (nested_in_vect_loop
)
3020 *adjustment_def
= vect_get_vec_def_for_operand (init_val
, stmt
,
3023 *adjustment_def
= init_val
;
3026 if (code
== MULT_EXPR
)
3028 real_init_val
= dconst1
;
3032 if (code
== BIT_AND_EXPR
)
3035 if (SCALAR_FLOAT_TYPE_P (scalar_type
))
3036 def_for_init
= build_real (scalar_type
, real_init_val
);
3038 def_for_init
= build_int_cst (scalar_type
, int_init_val
);
3040 /* Create a vector of '0' or '1' except the first element. */
3041 for (i
= nunits
- 2; i
>= 0; --i
)
3042 t
= tree_cons (NULL_TREE
, def_for_init
, t
);
3044 /* Option1: the first element is '0' or '1' as well. */
3047 t
= tree_cons (NULL_TREE
, def_for_init
, t
);
3048 init_def
= build_vector (vectype
, t
);
3052 /* Option2: the first element is INIT_VAL. */
3053 t
= tree_cons (NULL_TREE
, init_value
, t
);
3054 if (TREE_CONSTANT (init_val
))
3055 init_def
= build_vector (vectype
, t
);
3057 init_def
= build_constructor_from_list (vectype
, t
);
3066 *adjustment_def
= NULL_TREE
;
3067 init_def
= vect_get_vec_def_for_operand (init_val
, stmt
, NULL
);
3071 init_def
= build_vector_from_val (vectype
, init_value
);
3082 /* Function vect_create_epilog_for_reduction
3084 Create code at the loop-epilog to finalize the result of a reduction
3087 VECT_DEFS is list of vector of partial results, i.e., the lhs's of vector
3088 reduction statements.
3089 STMT is the scalar reduction stmt that is being vectorized.
3090 NCOPIES is > 1 in case the vectorization factor (VF) is bigger than the
3091 number of elements that we can fit in a vectype (nunits). In this case
3092 we have to generate more than one vector stmt - i.e - we need to "unroll"
3093 the vector stmt by a factor VF/nunits. For more details see documentation
3094 in vectorizable_operation.
3095 REDUC_CODE is the tree-code for the epilog reduction.
3096 REDUCTION_PHIS is a list of the phi-nodes that carry the reduction
3098 REDUC_INDEX is the index of the operand in the right hand side of the
3099 statement that is defined by REDUCTION_PHI.
3100 DOUBLE_REDUC is TRUE if double reduction phi nodes should be handled.
3101 SLP_NODE is an SLP node containing a group of reduction statements. The
3102 first one in this group is STMT.
3105 1. Creates the reduction def-use cycles: sets the arguments for
3107 The loop-entry argument is the vectorized initial-value of the reduction.
3108 The loop-latch argument is taken from VECT_DEFS - the vector of partial
3110 2. "Reduces" each vector of partial results VECT_DEFS into a single result,
3111 by applying the operation specified by REDUC_CODE if available, or by
3112 other means (whole-vector shifts or a scalar loop).
3113 The function also creates a new phi node at the loop exit to preserve
3114 loop-closed form, as illustrated below.
3116 The flow at the entry to this function:
3119 vec_def = phi <null, null> # REDUCTION_PHI
3120 VECT_DEF = vector_stmt # vectorized form of STMT
3121 s_loop = scalar_stmt # (scalar) STMT
3123 s_out0 = phi <s_loop> # (scalar) EXIT_PHI
3127 The above is transformed by this function into:
3130 vec_def = phi <vec_init, VECT_DEF> # REDUCTION_PHI
3131 VECT_DEF = vector_stmt # vectorized form of STMT
3132 s_loop = scalar_stmt # (scalar) STMT
3134 s_out0 = phi <s_loop> # (scalar) EXIT_PHI
3135 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI
3136 v_out2 = reduce <v_out1>
3137 s_out3 = extract_field <v_out2, 0>
3138 s_out4 = adjust_result <s_out3>
3144 vect_create_epilog_for_reduction (VEC (tree
, heap
) *vect_defs
, gimple stmt
,
3145 int ncopies
, enum tree_code reduc_code
,
3146 VEC (gimple
, heap
) *reduction_phis
,
3147 int reduc_index
, bool double_reduc
,
3150 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
3151 stmt_vec_info prev_phi_info
;
3153 enum machine_mode mode
;
3154 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_info
);
3155 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
), *outer_loop
= NULL
;
3156 basic_block exit_bb
;
3159 gimple new_phi
= NULL
, phi
;
3160 gimple_stmt_iterator exit_gsi
;
3162 tree new_temp
= NULL_TREE
, new_dest
, new_name
, new_scalar_dest
;
3163 gimple epilog_stmt
= NULL
;
3164 enum tree_code code
= gimple_assign_rhs_code (stmt
);
3166 tree bitsize
, bitpos
;
3167 tree adjustment_def
= NULL
;
3168 tree vec_initial_def
= NULL
;
3169 tree reduction_op
, expr
, def
;
3170 tree orig_name
, scalar_result
;
3171 imm_use_iterator imm_iter
, phi_imm_iter
;
3172 use_operand_p use_p
, phi_use_p
;
3173 bool extract_scalar_result
= false;
3174 gimple use_stmt
, orig_stmt
, reduction_phi
= NULL
;
3175 bool nested_in_vect_loop
= false;
3176 VEC (gimple
, heap
) *new_phis
= NULL
;
3177 enum vect_def_type dt
= vect_unknown_def_type
;
3179 VEC (tree
, heap
) *scalar_results
= NULL
;
3180 unsigned int group_size
= 1, k
, ratio
;
3181 VEC (tree
, heap
) *vec_initial_defs
= NULL
;
3182 VEC (gimple
, heap
) *phis
;
3185 group_size
= VEC_length (gimple
, SLP_TREE_SCALAR_STMTS (slp_node
));
3187 if (nested_in_vect_loop_p (loop
, stmt
))
3191 nested_in_vect_loop
= true;
3192 gcc_assert (!slp_node
);
3195 switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt
)))
3197 case GIMPLE_SINGLE_RHS
:
3198 gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt
))
3200 reduction_op
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), reduc_index
);
3202 case GIMPLE_UNARY_RHS
:
3203 reduction_op
= gimple_assign_rhs1 (stmt
);
3205 case GIMPLE_BINARY_RHS
:
3206 reduction_op
= reduc_index
?
3207 gimple_assign_rhs2 (stmt
) : gimple_assign_rhs1 (stmt
);
3213 vectype
= get_vectype_for_scalar_type (TREE_TYPE (reduction_op
));
3214 gcc_assert (vectype
);
3215 mode
= TYPE_MODE (vectype
);
3217 /* 1. Create the reduction def-use cycle:
3218 Set the arguments of REDUCTION_PHIS, i.e., transform
3221 vec_def = phi <null, null> # REDUCTION_PHI
3222 VECT_DEF = vector_stmt # vectorized form of STMT
3228 vec_def = phi <vec_init, VECT_DEF> # REDUCTION_PHI
3229 VECT_DEF = vector_stmt # vectorized form of STMT
3232 (in case of SLP, do it for all the phis). */
3234 /* Get the loop-entry arguments. */
3236 vect_get_slp_defs (reduction_op
, NULL_TREE
, slp_node
, &vec_initial_defs
,
3240 vec_initial_defs
= VEC_alloc (tree
, heap
, 1);
3241 /* For the case of reduction, vect_get_vec_def_for_operand returns
3242 the scalar def before the loop, that defines the initial value
3243 of the reduction variable. */
3244 vec_initial_def
= vect_get_vec_def_for_operand (reduction_op
, stmt
,
3246 VEC_quick_push (tree
, vec_initial_defs
, vec_initial_def
);
3249 /* Set phi nodes arguments. */
3250 FOR_EACH_VEC_ELT (gimple
, reduction_phis
, i
, phi
)
3252 tree vec_init_def
= VEC_index (tree
, vec_initial_defs
, i
);
3253 tree def
= VEC_index (tree
, vect_defs
, i
);
3254 for (j
= 0; j
< ncopies
; j
++)
3256 /* Set the loop-entry arg of the reduction-phi. */
3257 add_phi_arg (phi
, vec_init_def
, loop_preheader_edge (loop
),
3260 /* Set the loop-latch arg for the reduction-phi. */
3262 def
= vect_get_vec_def_for_stmt_copy (vect_unknown_def_type
, def
);
3264 add_phi_arg (phi
, def
, loop_latch_edge (loop
), UNKNOWN_LOCATION
);
3266 if (vect_print_dump_info (REPORT_DETAILS
))
3268 fprintf (vect_dump
, "transform reduction: created def-use"
3270 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
3271 fprintf (vect_dump
, "\n");
3272 print_gimple_stmt (vect_dump
, SSA_NAME_DEF_STMT (def
), 0,
3276 phi
= STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi
));
3280 VEC_free (tree
, heap
, vec_initial_defs
);
3282 /* 2. Create epilog code.
3283 The reduction epilog code operates across the elements of the vector
3284 of partial results computed by the vectorized loop.
3285 The reduction epilog code consists of:
3287 step 1: compute the scalar result in a vector (v_out2)
3288 step 2: extract the scalar result (s_out3) from the vector (v_out2)
3289 step 3: adjust the scalar result (s_out3) if needed.
3291 Step 1 can be accomplished using one the following three schemes:
3292 (scheme 1) using reduc_code, if available.
3293 (scheme 2) using whole-vector shifts, if available.
3294 (scheme 3) using a scalar loop. In this case steps 1+2 above are
3297 The overall epilog code looks like this:
3299 s_out0 = phi <s_loop> # original EXIT_PHI
3300 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI
3301 v_out2 = reduce <v_out1> # step 1
3302 s_out3 = extract_field <v_out2, 0> # step 2
3303 s_out4 = adjust_result <s_out3> # step 3
3305 (step 3 is optional, and steps 1 and 2 may be combined).
3306 Lastly, the uses of s_out0 are replaced by s_out4. */
3309 /* 2.1 Create new loop-exit-phis to preserve loop-closed form:
3310 v_out1 = phi <VECT_DEF>
3311 Store them in NEW_PHIS. */
3313 exit_bb
= single_exit (loop
)->dest
;
3314 prev_phi_info
= NULL
;
3315 new_phis
= VEC_alloc (gimple
, heap
, VEC_length (tree
, vect_defs
));
3316 FOR_EACH_VEC_ELT (tree
, vect_defs
, i
, def
)
3318 for (j
= 0; j
< ncopies
; j
++)
3320 phi
= create_phi_node (SSA_NAME_VAR (def
), exit_bb
);
3321 set_vinfo_for_stmt (phi
, new_stmt_vec_info (phi
, loop_vinfo
, NULL
));
3323 VEC_quick_push (gimple
, new_phis
, phi
);
3326 def
= vect_get_vec_def_for_stmt_copy (dt
, def
);
3327 STMT_VINFO_RELATED_STMT (prev_phi_info
) = phi
;
3330 SET_PHI_ARG_DEF (phi
, single_exit (loop
)->dest_idx
, def
);
3331 prev_phi_info
= vinfo_for_stmt (phi
);
3335 /* The epilogue is created for the outer-loop, i.e., for the loop being
3340 exit_bb
= single_exit (loop
)->dest
;
3343 exit_gsi
= gsi_after_labels (exit_bb
);
3345 /* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3
3346 (i.e. when reduc_code is not available) and in the final adjustment
3347 code (if needed). Also get the original scalar reduction variable as
3348 defined in the loop. In case STMT is a "pattern-stmt" (i.e. - it
3349 represents a reduction pattern), the tree-code and scalar-def are
3350 taken from the original stmt that the pattern-stmt (STMT) replaces.
3351 Otherwise (it is a regular reduction) - the tree-code and scalar-def
3352 are taken from STMT. */
3354 orig_stmt
= STMT_VINFO_RELATED_STMT (stmt_info
);
3357 /* Regular reduction */
3362 /* Reduction pattern */
3363 stmt_vec_info stmt_vinfo
= vinfo_for_stmt (orig_stmt
);
3364 gcc_assert (STMT_VINFO_IN_PATTERN_P (stmt_vinfo
));
3365 gcc_assert (STMT_VINFO_RELATED_STMT (stmt_vinfo
) == stmt
);
3368 code
= gimple_assign_rhs_code (orig_stmt
);
3369 /* For MINUS_EXPR the initial vector is [init_val,0,...,0], therefore,
3370 partial results are added and not subtracted. */
3371 if (code
== MINUS_EXPR
)
3374 scalar_dest
= gimple_assign_lhs (orig_stmt
);
3375 scalar_type
= TREE_TYPE (scalar_dest
);
3376 scalar_results
= VEC_alloc (tree
, heap
, group_size
);
3377 new_scalar_dest
= vect_create_destination_var (scalar_dest
, NULL
);
3378 bitsize
= TYPE_SIZE (scalar_type
);
3380 /* In case this is a reduction in an inner-loop while vectorizing an outer
3381 loop - we don't need to extract a single scalar result at the end of the
3382 inner-loop (unless it is double reduction, i.e., the use of reduction is
3383 outside the outer-loop). The final vector of partial results will be used
3384 in the vectorized outer-loop, or reduced to a scalar result at the end of
3386 if (nested_in_vect_loop
&& !double_reduc
)
3387 goto vect_finalize_reduction
;
3389 /* 2.3 Create the reduction code, using one of the three schemes described
3390 above. In SLP we simply need to extract all the elements from the
3391 vector (without reducing them), so we use scalar shifts. */
3392 if (reduc_code
!= ERROR_MARK
&& !slp_node
)
3396 /*** Case 1: Create:
3397 v_out2 = reduc_expr <v_out1> */
3399 if (vect_print_dump_info (REPORT_DETAILS
))
3400 fprintf (vect_dump
, "Reduce using direct vector reduction.");
3402 vec_dest
= vect_create_destination_var (scalar_dest
, vectype
);
3403 new_phi
= VEC_index (gimple
, new_phis
, 0);
3404 tmp
= build1 (reduc_code
, vectype
, PHI_RESULT (new_phi
));
3405 epilog_stmt
= gimple_build_assign (vec_dest
, tmp
);
3406 new_temp
= make_ssa_name (vec_dest
, epilog_stmt
);
3407 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3408 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3410 extract_scalar_result
= true;
3414 enum tree_code shift_code
= ERROR_MARK
;
3415 bool have_whole_vector_shift
= true;
3417 int element_bitsize
= tree_low_cst (bitsize
, 1);
3418 int vec_size_in_bits
= tree_low_cst (TYPE_SIZE (vectype
), 1);
3421 if (optab_handler (vec_shr_optab
, mode
) != CODE_FOR_nothing
)
3422 shift_code
= VEC_RSHIFT_EXPR
;
3424 have_whole_vector_shift
= false;
3426 /* Regardless of whether we have a whole vector shift, if we're
3427 emulating the operation via tree-vect-generic, we don't want
3428 to use it. Only the first round of the reduction is likely
3429 to still be profitable via emulation. */
3430 /* ??? It might be better to emit a reduction tree code here, so that
3431 tree-vect-generic can expand the first round via bit tricks. */
3432 if (!VECTOR_MODE_P (mode
))
3433 have_whole_vector_shift
= false;
3436 optab optab
= optab_for_tree_code (code
, vectype
, optab_default
);
3437 if (optab_handler (optab
, mode
) == CODE_FOR_nothing
)
3438 have_whole_vector_shift
= false;
3441 if (have_whole_vector_shift
&& !slp_node
)
3443 /*** Case 2: Create:
3444 for (offset = VS/2; offset >= element_size; offset/=2)
3446 Create: va' = vec_shift <va, offset>
3447 Create: va = vop <va, va'>
3450 if (vect_print_dump_info (REPORT_DETAILS
))
3451 fprintf (vect_dump
, "Reduce using vector shifts");
3453 vec_dest
= vect_create_destination_var (scalar_dest
, vectype
);
3454 new_phi
= VEC_index (gimple
, new_phis
, 0);
3455 new_temp
= PHI_RESULT (new_phi
);
3456 for (bit_offset
= vec_size_in_bits
/2;
3457 bit_offset
>= element_bitsize
;
3460 tree bitpos
= size_int (bit_offset
);
3462 epilog_stmt
= gimple_build_assign_with_ops (shift_code
,
3463 vec_dest
, new_temp
, bitpos
);
3464 new_name
= make_ssa_name (vec_dest
, epilog_stmt
);
3465 gimple_assign_set_lhs (epilog_stmt
, new_name
);
3466 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3468 epilog_stmt
= gimple_build_assign_with_ops (code
, vec_dest
,
3469 new_name
, new_temp
);
3470 new_temp
= make_ssa_name (vec_dest
, epilog_stmt
);
3471 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3472 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3475 extract_scalar_result
= true;
3481 /*** Case 3: Create:
3482 s = extract_field <v_out2, 0>
3483 for (offset = element_size;
3484 offset < vector_size;
3485 offset += element_size;)
3487 Create: s' = extract_field <v_out2, offset>
3488 Create: s = op <s, s'> // For non SLP cases
3491 if (vect_print_dump_info (REPORT_DETAILS
))
3492 fprintf (vect_dump
, "Reduce using scalar code. ");
3494 vec_size_in_bits
= tree_low_cst (TYPE_SIZE (vectype
), 1);
3495 FOR_EACH_VEC_ELT (gimple
, new_phis
, i
, new_phi
)
3497 vec_temp
= PHI_RESULT (new_phi
);
3498 rhs
= build3 (BIT_FIELD_REF
, scalar_type
, vec_temp
, bitsize
,
3500 epilog_stmt
= gimple_build_assign (new_scalar_dest
, rhs
);
3501 new_temp
= make_ssa_name (new_scalar_dest
, epilog_stmt
);
3502 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3503 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3505 /* In SLP we don't need to apply reduction operation, so we just
3506 collect s' values in SCALAR_RESULTS. */
3508 VEC_safe_push (tree
, heap
, scalar_results
, new_temp
);
3510 for (bit_offset
= element_bitsize
;
3511 bit_offset
< vec_size_in_bits
;
3512 bit_offset
+= element_bitsize
)
3514 tree bitpos
= bitsize_int (bit_offset
);
3515 tree rhs
= build3 (BIT_FIELD_REF
, scalar_type
, vec_temp
,
3518 epilog_stmt
= gimple_build_assign (new_scalar_dest
, rhs
);
3519 new_name
= make_ssa_name (new_scalar_dest
, epilog_stmt
);
3520 gimple_assign_set_lhs (epilog_stmt
, new_name
);
3521 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3525 /* In SLP we don't need to apply reduction operation, so
3526 we just collect s' values in SCALAR_RESULTS. */
3527 new_temp
= new_name
;
3528 VEC_safe_push (tree
, heap
, scalar_results
, new_name
);
3532 epilog_stmt
= gimple_build_assign_with_ops (code
,
3533 new_scalar_dest
, new_name
, new_temp
);
3534 new_temp
= make_ssa_name (new_scalar_dest
, epilog_stmt
);
3535 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3536 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3541 /* The only case where we need to reduce scalar results in SLP, is
3542 unrolling. If the size of SCALAR_RESULTS is greater than
3543 GROUP_SIZE, we reduce them combining elements modulo
3547 tree res
, first_res
, new_res
;
3550 /* Reduce multiple scalar results in case of SLP unrolling. */
3551 for (j
= group_size
; VEC_iterate (tree
, scalar_results
, j
, res
);
3554 first_res
= VEC_index (tree
, scalar_results
, j
% group_size
);
3555 new_stmt
= gimple_build_assign_with_ops (code
,
3556 new_scalar_dest
, first_res
, res
);
3557 new_res
= make_ssa_name (new_scalar_dest
, new_stmt
);
3558 gimple_assign_set_lhs (new_stmt
, new_res
);
3559 gsi_insert_before (&exit_gsi
, new_stmt
, GSI_SAME_STMT
);
3560 VEC_replace (tree
, scalar_results
, j
% group_size
, new_res
);
3564 /* Not SLP - we have one scalar to keep in SCALAR_RESULTS. */
3565 VEC_safe_push (tree
, heap
, scalar_results
, new_temp
);
3567 extract_scalar_result
= false;
3571 /* 2.4 Extract the final scalar result. Create:
3572 s_out3 = extract_field <v_out2, bitpos> */
3574 if (extract_scalar_result
)
3578 if (vect_print_dump_info (REPORT_DETAILS
))
3579 fprintf (vect_dump
, "extract scalar result");
3581 if (BYTES_BIG_ENDIAN
)
3582 bitpos
= size_binop (MULT_EXPR
,
3583 bitsize_int (TYPE_VECTOR_SUBPARTS (vectype
) - 1),
3584 TYPE_SIZE (scalar_type
));
3586 bitpos
= bitsize_zero_node
;
3588 rhs
= build3 (BIT_FIELD_REF
, scalar_type
, new_temp
, bitsize
, bitpos
);
3589 epilog_stmt
= gimple_build_assign (new_scalar_dest
, rhs
);
3590 new_temp
= make_ssa_name (new_scalar_dest
, epilog_stmt
);
3591 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3592 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3593 VEC_safe_push (tree
, heap
, scalar_results
, new_temp
);
3596 vect_finalize_reduction
:
3601 /* 2.5 Adjust the final result by the initial value of the reduction
3602 variable. (When such adjustment is not needed, then
3603 'adjustment_def' is zero). For example, if code is PLUS we create:
3604 new_temp = loop_exit_def + adjustment_def */
3608 gcc_assert (!slp_node
);
3609 if (nested_in_vect_loop
)
3611 new_phi
= VEC_index (gimple
, new_phis
, 0);
3612 gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def
)) == VECTOR_TYPE
);
3613 expr
= build2 (code
, vectype
, PHI_RESULT (new_phi
), adjustment_def
);
3614 new_dest
= vect_create_destination_var (scalar_dest
, vectype
);
3618 new_temp
= VEC_index (tree
, scalar_results
, 0);
3619 gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def
)) != VECTOR_TYPE
);
3620 expr
= build2 (code
, scalar_type
, new_temp
, adjustment_def
);
3621 new_dest
= vect_create_destination_var (scalar_dest
, scalar_type
);
3624 epilog_stmt
= gimple_build_assign (new_dest
, expr
);
3625 new_temp
= make_ssa_name (new_dest
, epilog_stmt
);
3626 gimple_assign_set_lhs (epilog_stmt
, new_temp
);
3627 SSA_NAME_DEF_STMT (new_temp
) = epilog_stmt
;
3628 gsi_insert_before (&exit_gsi
, epilog_stmt
, GSI_SAME_STMT
);
3629 if (nested_in_vect_loop
)
3631 set_vinfo_for_stmt (epilog_stmt
,
3632 new_stmt_vec_info (epilog_stmt
, loop_vinfo
,
3634 STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt
)) =
3635 STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi
));
3638 VEC_quick_push (tree
, scalar_results
, new_temp
);
3640 VEC_replace (tree
, scalar_results
, 0, new_temp
);
3643 VEC_replace (tree
, scalar_results
, 0, new_temp
);
3645 VEC_replace (gimple
, new_phis
, 0, epilog_stmt
);
3648 /* 2.6 Handle the loop-exit phis. Replace the uses of scalar loop-exit
3649 phis with new adjusted scalar results, i.e., replace use <s_out0>
3654 s_out0 = phi <s_loop> # (scalar) EXIT_PHI
3655 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI
3656 v_out2 = reduce <v_out1>
3657 s_out3 = extract_field <v_out2, 0>
3658 s_out4 = adjust_result <s_out3>
3665 s_out0 = phi <s_loop> # (scalar) EXIT_PHI
3666 v_out1 = phi <VECT_DEF> # NEW_EXIT_PHI
3667 v_out2 = reduce <v_out1>
3668 s_out3 = extract_field <v_out2, 0>
3669 s_out4 = adjust_result <s_out3>
3673 /* In SLP we may have several statements in NEW_PHIS and REDUCTION_PHIS (in
3674 case that GROUP_SIZE is greater than vectorization factor). Therefore, we
3675 need to match SCALAR_RESULTS with corresponding statements. The first
3676 (GROUP_SIZE / number of new vector stmts) scalar results correspond to
3677 the first vector stmt, etc.
3678 (RATIO is equal to (GROUP_SIZE / number of new vector stmts)). */
3679 if (group_size
> VEC_length (gimple
, new_phis
))
3681 ratio
= group_size
/ VEC_length (gimple
, new_phis
);
3682 gcc_assert (!(group_size
% VEC_length (gimple
, new_phis
)));
3687 for (k
= 0; k
< group_size
; k
++)
3691 epilog_stmt
= VEC_index (gimple
, new_phis
, k
/ ratio
);
3692 reduction_phi
= VEC_index (gimple
, reduction_phis
, k
/ ratio
);
3697 gimple current_stmt
= VEC_index (gimple
,
3698 SLP_TREE_SCALAR_STMTS (slp_node
), k
);
3700 orig_stmt
= STMT_VINFO_RELATED_STMT (vinfo_for_stmt (current_stmt
));
3701 /* SLP statements can't participate in patterns. */
3702 gcc_assert (!orig_stmt
);
3703 scalar_dest
= gimple_assign_lhs (current_stmt
);
3706 phis
= VEC_alloc (gimple
, heap
, 3);
3707 /* Find the loop-closed-use at the loop exit of the original scalar
3708 result. (The reduction result is expected to have two immediate uses -
3709 one at the latch block, and one at the loop exit). */
3710 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, scalar_dest
)
3711 if (!flow_bb_inside_loop_p (loop
, gimple_bb (USE_STMT (use_p
))))
3712 VEC_safe_push (gimple
, heap
, phis
, USE_STMT (use_p
));
3714 /* We expect to have found an exit_phi because of loop-closed-ssa
3716 gcc_assert (!VEC_empty (gimple
, phis
));
3718 FOR_EACH_VEC_ELT (gimple
, phis
, i
, exit_phi
)
3722 stmt_vec_info exit_phi_vinfo
= vinfo_for_stmt (exit_phi
);
3725 /* FORNOW. Currently not supporting the case that an inner-loop
3726 reduction is not used in the outer-loop (but only outside the
3727 outer-loop), unless it is double reduction. */
3728 gcc_assert ((STMT_VINFO_RELEVANT_P (exit_phi_vinfo
)
3729 && !STMT_VINFO_LIVE_P (exit_phi_vinfo
))
3732 STMT_VINFO_VEC_STMT (exit_phi_vinfo
) = epilog_stmt
;
3734 || STMT_VINFO_DEF_TYPE (exit_phi_vinfo
)
3735 != vect_double_reduction_def
)
3738 /* Handle double reduction:
3740 stmt1: s1 = phi <s0, s2> - double reduction phi (outer loop)
3741 stmt2: s3 = phi <s1, s4> - (regular) reduc phi (inner loop)
3742 stmt3: s4 = use (s3) - (regular) reduc stmt (inner loop)
3743 stmt4: s2 = phi <s4> - double reduction stmt (outer loop)
3745 At that point the regular reduction (stmt2 and stmt3) is
3746 already vectorized, as well as the exit phi node, stmt4.
3747 Here we vectorize the phi node of double reduction, stmt1, and
3748 update all relevant statements. */
3750 /* Go through all the uses of s2 to find double reduction phi
3751 node, i.e., stmt1 above. */
3752 orig_name
= PHI_RESULT (exit_phi
);
3753 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, orig_name
)
3755 stmt_vec_info use_stmt_vinfo
= vinfo_for_stmt (use_stmt
);
3756 stmt_vec_info new_phi_vinfo
;
3757 tree vect_phi_init
, preheader_arg
, vect_phi_res
, init_def
;
3758 basic_block bb
= gimple_bb (use_stmt
);
3761 /* Check that USE_STMT is really double reduction phi
3763 if (gimple_code (use_stmt
) != GIMPLE_PHI
3764 || gimple_phi_num_args (use_stmt
) != 2
3766 || STMT_VINFO_DEF_TYPE (use_stmt_vinfo
)
3767 != vect_double_reduction_def
3768 || bb
->loop_father
!= outer_loop
)
3771 /* Create vector phi node for double reduction:
3772 vs1 = phi <vs0, vs2>
3773 vs1 was created previously in this function by a call to
3774 vect_get_vec_def_for_operand and is stored in
3776 vs2 is defined by EPILOG_STMT, the vectorized EXIT_PHI;
3777 vs0 is created here. */
3779 /* Create vector phi node. */
3780 vect_phi
= create_phi_node (vec_initial_def
, bb
);
3781 new_phi_vinfo
= new_stmt_vec_info (vect_phi
,
3782 loop_vec_info_for_loop (outer_loop
), NULL
);
3783 set_vinfo_for_stmt (vect_phi
, new_phi_vinfo
);
3785 /* Create vs0 - initial def of the double reduction phi. */
3786 preheader_arg
= PHI_ARG_DEF_FROM_EDGE (use_stmt
,
3787 loop_preheader_edge (outer_loop
));
3788 init_def
= get_initial_def_for_reduction (stmt
,
3789 preheader_arg
, NULL
);
3790 vect_phi_init
= vect_init_vector (use_stmt
, init_def
,
3793 /* Update phi node arguments with vs0 and vs2. */
3794 add_phi_arg (vect_phi
, vect_phi_init
,
3795 loop_preheader_edge (outer_loop
),
3797 add_phi_arg (vect_phi
, PHI_RESULT (epilog_stmt
),
3798 loop_latch_edge (outer_loop
), UNKNOWN_LOCATION
);
3799 if (vect_print_dump_info (REPORT_DETAILS
))
3801 fprintf (vect_dump
, "created double reduction phi "
3803 print_gimple_stmt (vect_dump
, vect_phi
, 0, TDF_SLIM
);
3806 vect_phi_res
= PHI_RESULT (vect_phi
);
3808 /* Replace the use, i.e., set the correct vs1 in the regular
3809 reduction phi node. FORNOW, NCOPIES is always 1, so the
3810 loop is redundant. */
3811 use
= reduction_phi
;
3812 for (j
= 0; j
< ncopies
; j
++)
3814 edge pr_edge
= loop_preheader_edge (loop
);
3815 SET_PHI_ARG_DEF (use
, pr_edge
->dest_idx
, vect_phi_res
);
3816 use
= STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use
));
3822 VEC_free (gimple
, heap
, phis
);
3823 if (nested_in_vect_loop
)
3831 phis
= VEC_alloc (gimple
, heap
, 3);
3832 /* Find the loop-closed-use at the loop exit of the original scalar
3833 result. (The reduction result is expected to have two immediate uses,
3834 one at the latch block, and one at the loop exit). For double
3835 reductions we are looking for exit phis of the outer loop. */
3836 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, scalar_dest
)
3838 if (!flow_bb_inside_loop_p (loop
, gimple_bb (USE_STMT (use_p
))))
3839 VEC_safe_push (gimple
, heap
, phis
, USE_STMT (use_p
));
3842 if (double_reduc
&& gimple_code (USE_STMT (use_p
)) == GIMPLE_PHI
)
3844 tree phi_res
= PHI_RESULT (USE_STMT (use_p
));
3846 FOR_EACH_IMM_USE_FAST (phi_use_p
, phi_imm_iter
, phi_res
)
3848 if (!flow_bb_inside_loop_p (loop
,
3849 gimple_bb (USE_STMT (phi_use_p
))))
3850 VEC_safe_push (gimple
, heap
, phis
,
3851 USE_STMT (phi_use_p
));
3857 FOR_EACH_VEC_ELT (gimple
, phis
, i
, exit_phi
)
3859 /* Replace the uses: */
3860 orig_name
= PHI_RESULT (exit_phi
);
3861 scalar_result
= VEC_index (tree
, scalar_results
, k
);
3862 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, orig_name
)
3863 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
3864 SET_USE (use_p
, scalar_result
);
3867 VEC_free (gimple
, heap
, phis
);
3870 VEC_free (tree
, heap
, scalar_results
);
3871 VEC_free (gimple
, heap
, new_phis
);
3875 /* Function vectorizable_reduction.
3877 Check if STMT performs a reduction operation that can be vectorized.
3878 If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3879 stmt to replace it, put it in VEC_STMT, and insert it at GSI.
3880 Return FALSE if not a vectorizable STMT, TRUE otherwise.
3882 This function also handles reduction idioms (patterns) that have been
3883 recognized in advance during vect_pattern_recog. In this case, STMT may be
3885 X = pattern_expr (arg0, arg1, ..., X)
3886 and it's STMT_VINFO_RELATED_STMT points to the last stmt in the original
3887 sequence that had been detected and replaced by the pattern-stmt (STMT).
3889 In some cases of reduction patterns, the type of the reduction variable X is
3890 different than the type of the other arguments of STMT.
3891 In such cases, the vectype that is used when transforming STMT into a vector
3892 stmt is different than the vectype that is used to determine the
3893 vectorization factor, because it consists of a different number of elements
3894 than the actual number of elements that are being operated upon in parallel.
3896 For example, consider an accumulation of shorts into an int accumulator.
3897 On some targets it's possible to vectorize this pattern operating on 8
3898 shorts at a time (hence, the vectype for purposes of determining the
3899 vectorization factor should be V8HI); on the other hand, the vectype that
3900 is used to create the vector form is actually V4SI (the type of the result).
3902 Upon entry to this function, STMT_VINFO_VECTYPE records the vectype that
3903 indicates what is the actual level of parallelism (V8HI in the example), so
3904 that the right vectorization factor would be derived. This vectype
3905 corresponds to the type of arguments to the reduction stmt, and should *NOT*
3906 be used to create the vectorized stmt. The right vectype for the vectorized
3907 stmt is obtained from the type of the result X:
3908 get_vectype_for_scalar_type (TREE_TYPE (X))
3910 This means that, contrary to "regular" reductions (or "regular" stmts in
3911 general), the following equation:
3912 STMT_VINFO_VECTYPE == get_vectype_for_scalar_type (TREE_TYPE (X))
3913 does *NOT* necessarily hold for reduction patterns. */
3916 vectorizable_reduction (gimple stmt
, gimple_stmt_iterator
*gsi
,
3917 gimple
*vec_stmt
, slp_tree slp_node
)
3921 tree loop_vec_def0
= NULL_TREE
, loop_vec_def1
= NULL_TREE
;
3922 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
3923 tree vectype_out
= STMT_VINFO_VECTYPE (stmt_info
);
3924 tree vectype_in
= NULL_TREE
;
3925 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_info
);
3926 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
3927 enum tree_code code
, orig_code
, epilog_reduc_code
;
3928 enum machine_mode vec_mode
;
3930 optab optab
, reduc_optab
;
3931 tree new_temp
= NULL_TREE
;
3934 enum vect_def_type dt
;
3935 gimple new_phi
= NULL
;
3939 stmt_vec_info orig_stmt_info
;
3940 tree expr
= NULL_TREE
;
3944 stmt_vec_info prev_stmt_info
, prev_phi_info
;
3945 bool single_defuse_cycle
= false;
3946 tree reduc_def
= NULL_TREE
;
3947 gimple new_stmt
= NULL
;
3950 bool nested_cycle
= false, found_nested_cycle_def
= false;
3951 gimple reduc_def_stmt
= NULL
;
3952 /* The default is that the reduction variable is the last in statement. */
3953 int reduc_index
= 2;
3954 bool double_reduc
= false, dummy
;
3956 struct loop
* def_stmt_loop
, *outer_loop
= NULL
;
3958 gimple def_arg_stmt
;
3959 VEC (tree
, heap
) *vec_oprnds0
= NULL
, *vec_oprnds1
= NULL
, *vect_defs
= NULL
;
3960 VEC (gimple
, heap
) *phis
= NULL
;
3962 tree def0
, def1
, tem
;
3964 if (nested_in_vect_loop_p (loop
, stmt
))
3968 nested_cycle
= true;
3971 /* 1. Is vectorizable reduction? */
3972 /* Not supportable if the reduction variable is used in the loop. */
3973 if (STMT_VINFO_RELEVANT (stmt_info
) > vect_used_in_outer
)
3976 /* Reductions that are not used even in an enclosing outer-loop,
3977 are expected to be "live" (used out of the loop). */
3978 if (STMT_VINFO_RELEVANT (stmt_info
) == vect_unused_in_scope
3979 && !STMT_VINFO_LIVE_P (stmt_info
))
3982 /* Make sure it was already recognized as a reduction computation. */
3983 if (STMT_VINFO_DEF_TYPE (stmt_info
) != vect_reduction_def
3984 && STMT_VINFO_DEF_TYPE (stmt_info
) != vect_nested_cycle
)
3987 /* 2. Has this been recognized as a reduction pattern?
3989 Check if STMT represents a pattern that has been recognized
3990 in earlier analysis stages. For stmts that represent a pattern,
3991 the STMT_VINFO_RELATED_STMT field records the last stmt in
3992 the original sequence that constitutes the pattern. */
3994 orig_stmt
= STMT_VINFO_RELATED_STMT (stmt_info
);
3997 orig_stmt_info
= vinfo_for_stmt (orig_stmt
);
3998 gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info
) == stmt
);
3999 gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info
));
4000 gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info
));
4003 /* 3. Check the operands of the operation. The first operands are defined
4004 inside the loop body. The last operand is the reduction variable,
4005 which is defined by the loop-header-phi. */
4007 gcc_assert (is_gimple_assign (stmt
));
4010 switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt
)))
4012 case GIMPLE_SINGLE_RHS
:
4013 op_type
= TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt
));
4014 if (op_type
== ternary_op
)
4016 tree rhs
= gimple_assign_rhs1 (stmt
);
4017 ops
[0] = TREE_OPERAND (rhs
, 0);
4018 ops
[1] = TREE_OPERAND (rhs
, 1);
4019 ops
[2] = TREE_OPERAND (rhs
, 2);
4020 code
= TREE_CODE (rhs
);
4026 case GIMPLE_BINARY_RHS
:
4027 code
= gimple_assign_rhs_code (stmt
);
4028 op_type
= TREE_CODE_LENGTH (code
);
4029 gcc_assert (op_type
== binary_op
);
4030 ops
[0] = gimple_assign_rhs1 (stmt
);
4031 ops
[1] = gimple_assign_rhs2 (stmt
);
4034 case GIMPLE_UNARY_RHS
:
4041 scalar_dest
= gimple_assign_lhs (stmt
);
4042 scalar_type
= TREE_TYPE (scalar_dest
);
4043 if (!POINTER_TYPE_P (scalar_type
) && !INTEGRAL_TYPE_P (scalar_type
)
4044 && !SCALAR_FLOAT_TYPE_P (scalar_type
))
4047 /* All uses but the last are expected to be defined in the loop.
4048 The last use is the reduction variable. In case of nested cycle this
4049 assumption is not true: we use reduc_index to record the index of the
4050 reduction variable. */
4051 for (i
= 0; i
< op_type
-1; i
++)
4053 /* The condition of COND_EXPR is checked in vectorizable_condition(). */
4054 if (i
== 0 && code
== COND_EXPR
)
4057 is_simple_use
= vect_is_simple_use_1 (ops
[i
], loop_vinfo
, NULL
,
4058 &def_stmt
, &def
, &dt
, &tem
);
4061 gcc_assert (is_simple_use
);
4062 if (dt
!= vect_internal_def
4063 && dt
!= vect_external_def
4064 && dt
!= vect_constant_def
4065 && dt
!= vect_induction_def
4066 && !(dt
== vect_nested_cycle
&& nested_cycle
))
4069 if (dt
== vect_nested_cycle
)
4071 found_nested_cycle_def
= true;
4072 reduc_def_stmt
= def_stmt
;
4077 is_simple_use
= vect_is_simple_use_1 (ops
[i
], loop_vinfo
, NULL
, &def_stmt
,
4081 gcc_assert (is_simple_use
);
4082 gcc_assert (dt
== vect_reduction_def
4083 || dt
== vect_nested_cycle
4084 || ((dt
== vect_internal_def
|| dt
== vect_external_def
4085 || dt
== vect_constant_def
|| dt
== vect_induction_def
)
4086 && nested_cycle
&& found_nested_cycle_def
));
4087 if (!found_nested_cycle_def
)
4088 reduc_def_stmt
= def_stmt
;
4090 gcc_assert (gimple_code (reduc_def_stmt
) == GIMPLE_PHI
);
4092 gcc_assert (orig_stmt
== vect_is_simple_reduction (loop_vinfo
,
4097 gcc_assert (stmt
== vect_is_simple_reduction (loop_vinfo
, reduc_def_stmt
,
4098 !nested_cycle
, &dummy
));
4100 if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt
)))
4106 ncopies
= (LOOP_VINFO_VECT_FACTOR (loop_vinfo
)
4107 / TYPE_VECTOR_SUBPARTS (vectype_in
));
4109 gcc_assert (ncopies
>= 1);
4111 vec_mode
= TYPE_MODE (vectype_in
);
4113 if (code
== COND_EXPR
)
4115 if (!vectorizable_condition (stmt
, gsi
, NULL
, ops
[reduc_index
], 0))
4117 if (vect_print_dump_info (REPORT_DETAILS
))
4118 fprintf (vect_dump
, "unsupported condition in reduction");
4125 /* 4. Supportable by target? */
4127 /* 4.1. check support for the operation in the loop */
4128 optab
= optab_for_tree_code (code
, vectype_in
, optab_default
);
4131 if (vect_print_dump_info (REPORT_DETAILS
))
4132 fprintf (vect_dump
, "no optab.");
4137 if (optab_handler (optab
, vec_mode
) == CODE_FOR_nothing
)
4139 if (vect_print_dump_info (REPORT_DETAILS
))
4140 fprintf (vect_dump
, "op not supported by target.");
4142 if (GET_MODE_SIZE (vec_mode
) != UNITS_PER_WORD
4143 || LOOP_VINFO_VECT_FACTOR (loop_vinfo
)
4144 < vect_min_worthwhile_factor (code
))
4147 if (vect_print_dump_info (REPORT_DETAILS
))
4148 fprintf (vect_dump
, "proceeding using word mode.");
4151 /* Worthwhile without SIMD support? */
4152 if (!VECTOR_MODE_P (TYPE_MODE (vectype_in
))
4153 && LOOP_VINFO_VECT_FACTOR (loop_vinfo
)
4154 < vect_min_worthwhile_factor (code
))
4156 if (vect_print_dump_info (REPORT_DETAILS
))
4157 fprintf (vect_dump
, "not worthwhile without SIMD support.");
4163 /* 4.2. Check support for the epilog operation.
4165 If STMT represents a reduction pattern, then the type of the
4166 reduction variable may be different than the type of the rest
4167 of the arguments. For example, consider the case of accumulation
4168 of shorts into an int accumulator; The original code:
4169 S1: int_a = (int) short_a;
4170 orig_stmt-> S2: int_acc = plus <int_a ,int_acc>;
4173 STMT: int_acc = widen_sum <short_a, int_acc>
4176 1. The tree-code that is used to create the vector operation in the
4177 epilog code (that reduces the partial results) is not the
4178 tree-code of STMT, but is rather the tree-code of the original
4179 stmt from the pattern that STMT is replacing. I.e, in the example
4180 above we want to use 'widen_sum' in the loop, but 'plus' in the
4182 2. The type (mode) we use to check available target support
4183 for the vector operation to be created in the *epilog*, is
4184 determined by the type of the reduction variable (in the example
4185 above we'd check this: optab_handler (plus_optab, vect_int_mode])).
4186 However the type (mode) we use to check available target support
4187 for the vector operation to be created *inside the loop*, is
4188 determined by the type of the other arguments to STMT (in the
4189 example we'd check this: optab_handler (widen_sum_optab,
4192 This is contrary to "regular" reductions, in which the types of all
4193 the arguments are the same as the type of the reduction variable.
4194 For "regular" reductions we can therefore use the same vector type
4195 (and also the same tree-code) when generating the epilog code and
4196 when generating the code inside the loop. */
4200 /* This is a reduction pattern: get the vectype from the type of the
4201 reduction variable, and get the tree-code from orig_stmt. */
4202 orig_code
= gimple_assign_rhs_code (orig_stmt
);
4203 gcc_assert (vectype_out
);
4204 vec_mode
= TYPE_MODE (vectype_out
);
4208 /* Regular reduction: use the same vectype and tree-code as used for
4209 the vector code inside the loop can be used for the epilog code. */
4215 def_bb
= gimple_bb (reduc_def_stmt
);
4216 def_stmt_loop
= def_bb
->loop_father
;
4217 def_arg
= PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt
,
4218 loop_preheader_edge (def_stmt_loop
));
4219 if (TREE_CODE (def_arg
) == SSA_NAME
4220 && (def_arg_stmt
= SSA_NAME_DEF_STMT (def_arg
))
4221 && gimple_code (def_arg_stmt
) == GIMPLE_PHI
4222 && flow_bb_inside_loop_p (outer_loop
, gimple_bb (def_arg_stmt
))
4223 && vinfo_for_stmt (def_arg_stmt
)
4224 && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_arg_stmt
))
4225 == vect_double_reduction_def
)
4226 double_reduc
= true;
4229 epilog_reduc_code
= ERROR_MARK
;
4230 if (reduction_code_for_scalar_code (orig_code
, &epilog_reduc_code
))
4232 reduc_optab
= optab_for_tree_code (epilog_reduc_code
, vectype_out
,
4236 if (vect_print_dump_info (REPORT_DETAILS
))
4237 fprintf (vect_dump
, "no optab for reduction.");
4239 epilog_reduc_code
= ERROR_MARK
;
4243 && optab_handler (reduc_optab
, vec_mode
) == CODE_FOR_nothing
)
4245 if (vect_print_dump_info (REPORT_DETAILS
))
4246 fprintf (vect_dump
, "reduc op not supported by target.");
4248 epilog_reduc_code
= ERROR_MARK
;
4253 if (!nested_cycle
|| double_reduc
)
4255 if (vect_print_dump_info (REPORT_DETAILS
))
4256 fprintf (vect_dump
, "no reduc code for scalar code.");
4262 if (double_reduc
&& ncopies
> 1)
4264 if (vect_print_dump_info (REPORT_DETAILS
))
4265 fprintf (vect_dump
, "multiple types in double reduction");
4270 if (!vec_stmt
) /* transformation not required. */
4272 STMT_VINFO_TYPE (stmt_info
) = reduc_vec_info_type
;
4273 if (!vect_model_reduction_cost (stmt_info
, epilog_reduc_code
, ncopies
))
4280 if (vect_print_dump_info (REPORT_DETAILS
))
4281 fprintf (vect_dump
, "transform reduction.");
4283 /* FORNOW: Multiple types are not supported for condition. */
4284 if (code
== COND_EXPR
)
4285 gcc_assert (ncopies
== 1);
4287 /* Create the destination vector */
4288 vec_dest
= vect_create_destination_var (scalar_dest
, vectype_out
);
4290 /* In case the vectorization factor (VF) is bigger than the number
4291 of elements that we can fit in a vectype (nunits), we have to generate
4292 more than one vector stmt - i.e - we need to "unroll" the
4293 vector stmt by a factor VF/nunits. For more details see documentation
4294 in vectorizable_operation. */
4296 /* If the reduction is used in an outer loop we need to generate
4297 VF intermediate results, like so (e.g. for ncopies=2):
4302 (i.e. we generate VF results in 2 registers).
4303 In this case we have a separate def-use cycle for each copy, and therefore
4304 for each copy we get the vector def for the reduction variable from the
4305 respective phi node created for this copy.
4307 Otherwise (the reduction is unused in the loop nest), we can combine
4308 together intermediate results, like so (e.g. for ncopies=2):
4312 (i.e. we generate VF/2 results in a single register).
4313 In this case for each copy we get the vector def for the reduction variable
4314 from the vectorized reduction operation generated in the previous iteration.
4317 if (STMT_VINFO_RELEVANT (stmt_info
) == vect_unused_in_scope
)
4319 single_defuse_cycle
= true;
4323 epilog_copies
= ncopies
;
4325 prev_stmt_info
= NULL
;
4326 prev_phi_info
= NULL
;
4329 vec_num
= SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node
);
4330 gcc_assert (TYPE_VECTOR_SUBPARTS (vectype_out
)
4331 == TYPE_VECTOR_SUBPARTS (vectype_in
));
4336 vec_oprnds0
= VEC_alloc (tree
, heap
, 1);
4337 if (op_type
== ternary_op
)
4338 vec_oprnds1
= VEC_alloc (tree
, heap
, 1);
4341 phis
= VEC_alloc (gimple
, heap
, vec_num
);
4342 vect_defs
= VEC_alloc (tree
, heap
, vec_num
);
4344 VEC_quick_push (tree
, vect_defs
, NULL_TREE
);
4346 for (j
= 0; j
< ncopies
; j
++)
4348 if (j
== 0 || !single_defuse_cycle
)
4350 for (i
= 0; i
< vec_num
; i
++)
4352 /* Create the reduction-phi that defines the reduction
4354 new_phi
= create_phi_node (vec_dest
, loop
->header
);
4355 set_vinfo_for_stmt (new_phi
,
4356 new_stmt_vec_info (new_phi
, loop_vinfo
,
4358 if (j
== 0 || slp_node
)
4359 VEC_quick_push (gimple
, phis
, new_phi
);
4363 if (code
== COND_EXPR
)
4365 gcc_assert (!slp_node
);
4366 vectorizable_condition (stmt
, gsi
, vec_stmt
,
4367 PHI_RESULT (VEC_index (gimple
, phis
, 0)),
4369 /* Multiple types are not supported for condition. */
4376 tree op0
, op1
= NULL_TREE
;
4378 op0
= ops
[!reduc_index
];
4379 if (op_type
== ternary_op
)
4381 if (reduc_index
== 0)
4388 vect_get_slp_defs (op0
, op1
, slp_node
, &vec_oprnds0
, &vec_oprnds1
,
4392 loop_vec_def0
= vect_get_vec_def_for_operand (ops
[!reduc_index
],
4394 VEC_quick_push (tree
, vec_oprnds0
, loop_vec_def0
);
4395 if (op_type
== ternary_op
)
4397 loop_vec_def1
= vect_get_vec_def_for_operand (op1
, stmt
,
4399 VEC_quick_push (tree
, vec_oprnds1
, loop_vec_def1
);
4407 enum vect_def_type dt
= vect_unknown_def_type
; /* Dummy */
4408 loop_vec_def0
= vect_get_vec_def_for_stmt_copy (dt
, loop_vec_def0
);
4409 VEC_replace (tree
, vec_oprnds0
, 0, loop_vec_def0
);
4410 if (op_type
== ternary_op
)
4412 loop_vec_def1
= vect_get_vec_def_for_stmt_copy (dt
,
4414 VEC_replace (tree
, vec_oprnds1
, 0, loop_vec_def1
);
4418 if (single_defuse_cycle
)
4419 reduc_def
= gimple_assign_lhs (new_stmt
);
4421 STMT_VINFO_RELATED_STMT (prev_phi_info
) = new_phi
;
4424 FOR_EACH_VEC_ELT (tree
, vec_oprnds0
, i
, def0
)
4427 reduc_def
= PHI_RESULT (VEC_index (gimple
, phis
, i
));
4430 if (!single_defuse_cycle
|| j
== 0)
4431 reduc_def
= PHI_RESULT (new_phi
);
4434 def1
= ((op_type
== ternary_op
)
4435 ? VEC_index (tree
, vec_oprnds1
, i
) : NULL
);
4436 if (op_type
== binary_op
)
4438 if (reduc_index
== 0)
4439 expr
= build2 (code
, vectype_out
, reduc_def
, def0
);
4441 expr
= build2 (code
, vectype_out
, def0
, reduc_def
);
4445 if (reduc_index
== 0)
4446 expr
= build3 (code
, vectype_out
, reduc_def
, def0
, def1
);
4449 if (reduc_index
== 1)
4450 expr
= build3 (code
, vectype_out
, def0
, reduc_def
, def1
);
4452 expr
= build3 (code
, vectype_out
, def0
, def1
, reduc_def
);
4456 new_stmt
= gimple_build_assign (vec_dest
, expr
);
4457 new_temp
= make_ssa_name (vec_dest
, new_stmt
);
4458 gimple_assign_set_lhs (new_stmt
, new_temp
);
4459 vect_finish_stmt_generation (stmt
, new_stmt
, gsi
);
4462 VEC_quick_push (gimple
, SLP_TREE_VEC_STMTS (slp_node
), new_stmt
);
4463 VEC_quick_push (tree
, vect_defs
, new_temp
);
4466 VEC_replace (tree
, vect_defs
, 0, new_temp
);
4473 STMT_VINFO_VEC_STMT (stmt_info
) = *vec_stmt
= new_stmt
;
4475 STMT_VINFO_RELATED_STMT (prev_stmt_info
) = new_stmt
;
4477 prev_stmt_info
= vinfo_for_stmt (new_stmt
);
4478 prev_phi_info
= vinfo_for_stmt (new_phi
);
4481 /* Finalize the reduction-phi (set its arguments) and create the
4482 epilog reduction code. */
4483 if ((!single_defuse_cycle
|| code
== COND_EXPR
) && !slp_node
)
4485 new_temp
= gimple_assign_lhs (*vec_stmt
);
4486 VEC_replace (tree
, vect_defs
, 0, new_temp
);
4489 vect_create_epilog_for_reduction (vect_defs
, stmt
, epilog_copies
,
4490 epilog_reduc_code
, phis
, reduc_index
,
4491 double_reduc
, slp_node
);
4493 VEC_free (gimple
, heap
, phis
);
4494 VEC_free (tree
, heap
, vec_oprnds0
);
4496 VEC_free (tree
, heap
, vec_oprnds1
);
4501 /* Function vect_min_worthwhile_factor.
4503 For a loop where we could vectorize the operation indicated by CODE,
4504 return the minimum vectorization factor that makes it worthwhile
4505 to use generic vectors. */
4507 vect_min_worthwhile_factor (enum tree_code code
)
4528 /* Function vectorizable_induction
4530 Check if PHI performs an induction computation that can be vectorized.
4531 If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized
4532 phi to replace it, put it in VEC_STMT, and add it to the same basic block.
4533 Return FALSE if not a vectorizable STMT, TRUE otherwise. */
4536 vectorizable_induction (gimple phi
, gimple_stmt_iterator
*gsi ATTRIBUTE_UNUSED
,
4539 stmt_vec_info stmt_info
= vinfo_for_stmt (phi
);
4540 tree vectype
= STMT_VINFO_VECTYPE (stmt_info
);
4541 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_info
);
4542 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
4543 int nunits
= TYPE_VECTOR_SUBPARTS (vectype
);
4544 int ncopies
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
) / nunits
;
4547 gcc_assert (ncopies
>= 1);
4548 /* FORNOW. This restriction should be relaxed. */
4549 if (nested_in_vect_loop_p (loop
, phi
) && ncopies
> 1)
4551 if (vect_print_dump_info (REPORT_DETAILS
))
4552 fprintf (vect_dump
, "multiple types in nested loop.");
4556 if (!STMT_VINFO_RELEVANT_P (stmt_info
))
4559 /* FORNOW: SLP not supported. */
4560 if (STMT_SLP_TYPE (stmt_info
))
4563 gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info
) == vect_induction_def
);
4565 if (gimple_code (phi
) != GIMPLE_PHI
)
4568 if (!vec_stmt
) /* transformation not required. */
4570 STMT_VINFO_TYPE (stmt_info
) = induc_vec_info_type
;
4571 if (vect_print_dump_info (REPORT_DETAILS
))
4572 fprintf (vect_dump
, "=== vectorizable_induction ===");
4573 vect_model_induction_cost (stmt_info
, ncopies
);
4579 if (vect_print_dump_info (REPORT_DETAILS
))
4580 fprintf (vect_dump
, "transform induction phi.");
4582 vec_def
= get_initial_def_for_induction (phi
);
4583 *vec_stmt
= SSA_NAME_DEF_STMT (vec_def
);
4587 /* Function vectorizable_live_operation.
4589 STMT computes a value that is used outside the loop. Check if
4590 it can be supported. */
4593 vectorizable_live_operation (gimple stmt
,
4594 gimple_stmt_iterator
*gsi ATTRIBUTE_UNUSED
,
4595 gimple
*vec_stmt ATTRIBUTE_UNUSED
)
4597 stmt_vec_info stmt_info
= vinfo_for_stmt (stmt
);
4598 loop_vec_info loop_vinfo
= STMT_VINFO_LOOP_VINFO (stmt_info
);
4599 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
4605 enum vect_def_type dt
;
4606 enum tree_code code
;
4607 enum gimple_rhs_class rhs_class
;
4609 gcc_assert (STMT_VINFO_LIVE_P (stmt_info
));
4611 if (STMT_VINFO_DEF_TYPE (stmt_info
) == vect_reduction_def
)
4614 if (!is_gimple_assign (stmt
))
4617 if (TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
4620 /* FORNOW. CHECKME. */
4621 if (nested_in_vect_loop_p (loop
, stmt
))
4624 code
= gimple_assign_rhs_code (stmt
);
4625 op_type
= TREE_CODE_LENGTH (code
);
4626 rhs_class
= get_gimple_rhs_class (code
);
4627 gcc_assert (rhs_class
!= GIMPLE_UNARY_RHS
|| op_type
== unary_op
);
4628 gcc_assert (rhs_class
!= GIMPLE_BINARY_RHS
|| op_type
== binary_op
);
4630 /* FORNOW: support only if all uses are invariant. This means
4631 that the scalar operations can remain in place, unvectorized.
4632 The original last scalar value that they compute will be used. */
4634 for (i
= 0; i
< op_type
; i
++)
4636 if (rhs_class
== GIMPLE_SINGLE_RHS
)
4637 op
= TREE_OPERAND (gimple_op (stmt
, 1), i
);
4639 op
= gimple_op (stmt
, i
+ 1);
4641 && !vect_is_simple_use (op
, loop_vinfo
, NULL
, &def_stmt
, &def
, &dt
))
4643 if (vect_print_dump_info (REPORT_DETAILS
))
4644 fprintf (vect_dump
, "use not simple.");
4648 if (dt
!= vect_external_def
&& dt
!= vect_constant_def
)
4652 /* No transformation is required for the cases we currently support. */
4656 /* Kill any debug uses outside LOOP of SSA names defined in STMT. */
4659 vect_loop_kill_debug_uses (struct loop
*loop
, gimple stmt
)
4661 ssa_op_iter op_iter
;
4662 imm_use_iterator imm_iter
;
4663 def_operand_p def_p
;
4666 FOR_EACH_PHI_OR_STMT_DEF (def_p
, stmt
, op_iter
, SSA_OP_DEF
)
4668 FOR_EACH_IMM_USE_STMT (ustmt
, imm_iter
, DEF_FROM_PTR (def_p
))
4672 if (!is_gimple_debug (ustmt
))
4675 bb
= gimple_bb (ustmt
);
4677 if (!flow_bb_inside_loop_p (loop
, bb
))
4679 if (gimple_debug_bind_p (ustmt
))
4681 if (vect_print_dump_info (REPORT_DETAILS
))
4682 fprintf (vect_dump
, "killing debug use");
4684 gimple_debug_bind_reset_value (ustmt
);
4685 update_stmt (ustmt
);
4694 /* Function vect_transform_loop.
4696 The analysis phase has determined that the loop is vectorizable.
4697 Vectorize the loop - created vectorized stmts to replace the scalar
4698 stmts in the loop, and update the loop exit condition. */
4701 vect_transform_loop (loop_vec_info loop_vinfo
)
4703 struct loop
*loop
= LOOP_VINFO_LOOP (loop_vinfo
);
4704 basic_block
*bbs
= LOOP_VINFO_BBS (loop_vinfo
);
4705 int nbbs
= loop
->num_nodes
;
4706 gimple_stmt_iterator si
;
4709 int vectorization_factor
= LOOP_VINFO_VECT_FACTOR (loop_vinfo
);
4711 bool slp_scheduled
= false;
4712 unsigned int nunits
;
4713 tree cond_expr
= NULL_TREE
;
4714 gimple_seq cond_expr_stmt_list
= NULL
;
4715 bool do_peeling_for_loop_bound
;
4717 if (vect_print_dump_info (REPORT_DETAILS
))
4718 fprintf (vect_dump
, "=== vec_transform_loop ===");
4720 /* Peel the loop if there are data refs with unknown alignment.
4721 Only one data ref with unknown store is allowed. */
4723 if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo
))
4724 vect_do_peeling_for_alignment (loop_vinfo
);
4726 do_peeling_for_loop_bound
4727 = (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
4728 || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo
)
4729 && LOOP_VINFO_INT_NITERS (loop_vinfo
) % vectorization_factor
!= 0)
4730 || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo
));
4732 if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo
)
4733 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo
))
4734 vect_loop_versioning (loop_vinfo
,
4735 !do_peeling_for_loop_bound
,
4736 &cond_expr
, &cond_expr_stmt_list
);
4738 /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
4739 compile time constant), or it is a constant that doesn't divide by the
4740 vectorization factor, then an epilog loop needs to be created.
4741 We therefore duplicate the loop: the original loop will be vectorized,
4742 and will compute the first (n/VF) iterations. The second copy of the loop
4743 will remain scalar and will compute the remaining (n%VF) iterations.
4744 (VF is the vectorization factor). */
4746 if (do_peeling_for_loop_bound
)
4747 vect_do_peeling_for_loop_bound (loop_vinfo
, &ratio
,
4748 cond_expr
, cond_expr_stmt_list
);
4750 ratio
= build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo
)),
4751 LOOP_VINFO_INT_NITERS (loop_vinfo
) / vectorization_factor
);
4753 /* 1) Make sure the loop header has exactly two entries
4754 2) Make sure we have a preheader basic block. */
4756 gcc_assert (EDGE_COUNT (loop
->header
->preds
) == 2);
4758 split_edge (loop_preheader_edge (loop
));
4760 /* FORNOW: the vectorizer supports only loops which body consist
4761 of one basic block (header + empty latch). When the vectorizer will
4762 support more involved loop forms, the order by which the BBs are
4763 traversed need to be reconsidered. */
4765 for (i
= 0; i
< nbbs
; i
++)
4767 basic_block bb
= bbs
[i
];
4768 stmt_vec_info stmt_info
;
4771 for (si
= gsi_start_phis (bb
); !gsi_end_p (si
); gsi_next (&si
))
4773 phi
= gsi_stmt (si
);
4774 if (vect_print_dump_info (REPORT_DETAILS
))
4776 fprintf (vect_dump
, "------>vectorizing phi: ");
4777 print_gimple_stmt (vect_dump
, phi
, 0, TDF_SLIM
);
4779 stmt_info
= vinfo_for_stmt (phi
);
4783 if (MAY_HAVE_DEBUG_STMTS
&& !STMT_VINFO_LIVE_P (stmt_info
))
4784 vect_loop_kill_debug_uses (loop
, phi
);
4786 if (!STMT_VINFO_RELEVANT_P (stmt_info
)
4787 && !STMT_VINFO_LIVE_P (stmt_info
))
4790 if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info
))
4791 != (unsigned HOST_WIDE_INT
) vectorization_factor
)
4792 && vect_print_dump_info (REPORT_DETAILS
))
4793 fprintf (vect_dump
, "multiple-types.");
4795 if (STMT_VINFO_DEF_TYPE (stmt_info
) == vect_induction_def
)
4797 if (vect_print_dump_info (REPORT_DETAILS
))
4798 fprintf (vect_dump
, "transform phi.");
4799 vect_transform_stmt (phi
, NULL
, NULL
, NULL
, NULL
);
4803 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
);)
4805 gimple stmt
= gsi_stmt (si
);
4808 if (vect_print_dump_info (REPORT_DETAILS
))
4810 fprintf (vect_dump
, "------>vectorizing statement: ");
4811 print_gimple_stmt (vect_dump
, stmt
, 0, TDF_SLIM
);
4814 stmt_info
= vinfo_for_stmt (stmt
);
4816 /* vector stmts created in the outer-loop during vectorization of
4817 stmts in an inner-loop may not have a stmt_info, and do not
4818 need to be vectorized. */
4825 if (MAY_HAVE_DEBUG_STMTS
&& !STMT_VINFO_LIVE_P (stmt_info
))
4826 vect_loop_kill_debug_uses (loop
, stmt
);
4828 if (!STMT_VINFO_RELEVANT_P (stmt_info
)
4829 && !STMT_VINFO_LIVE_P (stmt_info
))
4835 gcc_assert (STMT_VINFO_VECTYPE (stmt_info
));
4837 (unsigned int) TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info
));
4838 if (!STMT_SLP_TYPE (stmt_info
)
4839 && nunits
!= (unsigned int) vectorization_factor
4840 && vect_print_dump_info (REPORT_DETAILS
))
4841 /* For SLP VF is set according to unrolling factor, and not to
4842 vector size, hence for SLP this print is not valid. */
4843 fprintf (vect_dump
, "multiple-types.");
4845 /* SLP. Schedule all the SLP instances when the first SLP stmt is
4847 if (STMT_SLP_TYPE (stmt_info
))
4851 slp_scheduled
= true;
4853 if (vect_print_dump_info (REPORT_DETAILS
))
4854 fprintf (vect_dump
, "=== scheduling SLP instances ===");
4856 vect_schedule_slp (loop_vinfo
, NULL
);
4859 /* Hybrid SLP stmts must be vectorized in addition to SLP. */
4860 if (!vinfo_for_stmt (stmt
) || PURE_SLP_STMT (stmt_info
))
4867 /* -------- vectorize statement ------------ */
4868 if (vect_print_dump_info (REPORT_DETAILS
))
4869 fprintf (vect_dump
, "transform statement.");
4871 strided_store
= false;
4872 is_store
= vect_transform_stmt (stmt
, &si
, &strided_store
, NULL
, NULL
);
4875 if (STMT_VINFO_STRIDED_ACCESS (stmt_info
))
4877 /* Interleaving. If IS_STORE is TRUE, the vectorization of the
4878 interleaving chain was completed - free all the stores in
4880 vect_remove_stores (DR_GROUP_FIRST_DR (stmt_info
));
4881 gsi_remove (&si
, true);
4886 /* Free the attached stmt_vec_info and remove the stmt. */
4887 free_stmt_vec_info (stmt
);
4888 gsi_remove (&si
, true);
4896 slpeel_make_loop_iterate_ntimes (loop
, ratio
);
4898 /* The memory tags and pointers in vectorized statements need to
4899 have their SSA forms updated. FIXME, why can't this be delayed
4900 until all the loops have been transformed? */
4901 update_ssa (TODO_update_ssa
);
4903 if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS
))
4904 fprintf (vect_dump
, "LOOP VECTORIZED.");
4905 if (loop
->inner
&& vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS
))
4906 fprintf (vect_dump
, "OUTER LOOP VECTORIZED.");