OSDN Git Service

* tree-vectorizer.h (LOC): New type.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vectorizer.c
1 /* Loop Vectorization
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Dorit Naishlos <dorit@il.ibm.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /* Loop Vectorization Pass.
23
24    This pass tries to vectorize loops. This first implementation focuses on
25    simple inner-most loops, with no conditional control flow, and a set of
26    simple operations which vector form can be expressed using existing
27    tree codes (PLUS, MULT etc).
28
29    For example, the vectorizer transforms the following simple loop:
30
31         short a[N]; short b[N]; short c[N]; int i;
32
33         for (i=0; i<N; i++){
34           a[i] = b[i] + c[i];
35         }
36
37    as if it was manually vectorized by rewriting the source code into:
38
39         typedef int __attribute__((mode(V8HI))) v8hi;
40         short a[N];  short b[N]; short c[N];   int i;
41         v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
42         v8hi va, vb, vc;
43
44         for (i=0; i<N/8; i++){
45           vb = pb[i];
46           vc = pc[i];
47           va = vb + vc;
48           pa[i] = va;
49         }
50
51         The main entry to this pass is vectorize_loops(), in which
52    the vectorizer applies a set of analyses on a given set of loops,
53    followed by the actual vectorization transformation for the loops that
54    had successfully passed the analysis phase.
55
56         Throughout this pass we make a distinction between two types of
57    data: scalars (which are represented by SSA_NAMES), and memory references
58    ("data-refs"). These two types of data require different handling both 
59    during analysis and transformation. The types of data-refs that the 
60    vectorizer currently supports are ARRAY_REFS which base is an array DECL 
61    (not a pointer), and INDIRECT_REFS through pointers; both array and pointer
62    accesses are required to have a  simple (consecutive) access pattern.
63
64    Analysis phase:
65    ===============
66         The driver for the analysis phase is vect_analyze_loop_nest().
67    It applies a set of analyses, some of which rely on the scalar evolution 
68    analyzer (scev) developed by Sebastian Pop.
69
70         During the analysis phase the vectorizer records some information
71    per stmt in a "stmt_vec_info" struct which is attached to each stmt in the 
72    loop, as well as general information about the loop as a whole, which is
73    recorded in a "loop_vec_info" struct attached to each loop.
74
75    Transformation phase:
76    =====================
77         The loop transformation phase scans all the stmts in the loop, and
78    creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
79    the loop that needs to be vectorized. It insert the vector code sequence
80    just before the scalar stmt S, and records a pointer to the vector code
81    in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct 
82    attached to S). This pointer will be used for the vectorization of following
83    stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
84    otherwise, we rely on dead code elimination for removing it.
85
86         For example, say stmt S1 was vectorized into stmt VS1:
87
88    VS1: vb = px[i];
89    S1:  b = x[i];    STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
90    S2:  a = b;
91
92    To vectorize stmt S2, the vectorizer first finds the stmt that defines
93    the operand 'b' (S1), and gets the relevant vector def 'vb' from the
94    vector stmt VS1 pointed by STMT_VINFO_VEC_STMT (stmt_info (S1)). The
95    resulting sequence would be:
96
97    VS1: vb = px[i];
98    S1:  b = x[i];       STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
99    VS2: va = vb;
100    S2:  a = b;          STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
101
102         Operands that are not SSA_NAMEs, are data-refs that appear in 
103    load/store operations (like 'x[i]' in S1), and are handled differently.
104
105    Target modeling:
106    =================
107         Currently the only target specific information that is used is the
108    size of the vector (in bytes) - "UNITS_PER_SIMD_WORD". Targets that can 
109    support different sizes of vectors, for now will need to specify one value 
110    for "UNITS_PER_SIMD_WORD". More flexibility will be added in the future.
111
112         Since we only vectorize operations which vector form can be
113    expressed using existing tree codes, to verify that an operation is
114    supported, the vectorizer checks the relevant optab at the relevant
115    machine_mode (e.g, add_optab->handlers[(int) V8HImode].insn_code). If
116    the value found is CODE_FOR_nothing, then there's no target support, and
117    we can't vectorize the stmt.
118
119    For additional information on this project see:
120    http://gcc.gnu.org/projects/tree-ssa/vectorization.html
121 */
122
123 #include "config.h"
124 #include "system.h"
125 #include "coretypes.h"
126 #include "tm.h"
127 #include "errors.h"
128 #include "ggc.h"
129 #include "tree.h"
130 #include "target.h"
131
132 #include "rtl.h"
133 #include "basic-block.h"
134 #include "diagnostic.h"
135 #include "tree-flow.h"
136 #include "tree-dump.h"
137 #include "timevar.h"
138 #include "cfgloop.h"
139 #include "cfglayout.h"
140 #include "expr.h"
141 #include "optabs.h"
142 #include "toplev.h"
143 #include "tree-chrec.h"
144 #include "tree-data-ref.h"
145 #include "tree-scalar-evolution.h"
146 #include "input.h"
147 #include "tree-vectorizer.h"
148 #include "tree-pass.h"
149 #include "langhooks.h"
150
151
152 /*************************************************************************
153   Simple Loop Peeling Utilities
154  *************************************************************************/
155    
156 /* Entry point for peeling of simple loops.
157    Peel the first/last iterations of a loop.
158    It can be used outside of the vectorizer for loops that are simple enough
159    (see function documentation).  In the vectorizer it is used to peel the
160    last few iterations when the loop bound is unknown or does not evenly
161    divide by the vectorization factor, and to peel the first few iterations
162    to force the alignment of data references in the loop.  */
163 struct loop *slpeel_tree_peel_loop_to_edge 
164   (struct loop *, struct loops *, edge, tree, tree, bool);
165 static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg 
166   (struct loop *, struct loops *, edge);
167 static void slpeel_update_phis_for_duplicate_loop 
168   (struct loop *, struct loop *, bool after);
169 static void slpeel_update_phi_nodes_for_guard (edge, struct loop *, bool, bool);
170 static void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
171 static edge slpeel_add_loop_guard (basic_block, tree, basic_block, basic_block);
172 static bool slpeel_can_duplicate_loop_p (struct loop *, edge);
173 static void allocate_new_names (bitmap);
174 static void rename_use_op (use_operand_p);
175 static void rename_def_op (def_operand_p, tree);
176 static void rename_variables_in_bb (basic_block);
177 static void free_new_names (bitmap);
178 static void rename_variables_in_loop (struct loop *);
179 #ifdef ENABLE_CHECKING
180 static void slpeel_verify_cfg_after_peeling (struct loop *, struct loop *);
181 #endif
182 static LOC find_loop_location (struct loop *);
183
184
185 /*************************************************************************
186   Vectorization Utilities. 
187  *************************************************************************/
188
189 /* Main analysis functions.  */
190 static loop_vec_info vect_analyze_loop (struct loop *);
191 static loop_vec_info vect_analyze_loop_form (struct loop *);
192 static bool vect_analyze_data_refs (loop_vec_info);
193 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
194 static bool vect_analyze_scalar_cycles (loop_vec_info);
195 static bool vect_analyze_data_ref_accesses (loop_vec_info);
196 static bool vect_analyze_data_ref_dependence
197   (struct data_reference *, struct data_reference *, loop_vec_info);
198 static bool vect_analyze_data_ref_dependences (loop_vec_info);
199 static bool vect_analyze_data_refs_alignment (loop_vec_info);
200 static bool vect_compute_data_refs_alignment (loop_vec_info);
201 static bool vect_analyze_operations (loop_vec_info);
202
203 /* Main code transformation functions.  */
204 static void vect_transform_loop (loop_vec_info, struct loops *);
205 static bool vect_transform_stmt (tree, block_stmt_iterator *);
206 static bool vectorizable_load (tree, block_stmt_iterator *, tree *);
207 static bool vectorizable_store (tree, block_stmt_iterator *, tree *);
208 static bool vectorizable_operation (tree, block_stmt_iterator *, tree *);
209 static bool vectorizable_assignment (tree, block_stmt_iterator *, tree *);
210 static enum dr_alignment_support vect_supportable_dr_alignment
211   (struct data_reference *);
212 static void vect_align_data_ref (tree);
213 static void vect_enhance_data_refs_alignment (loop_vec_info);
214
215 /* Utility functions for the analyses.  */
216 static bool vect_is_simple_use (tree , loop_vec_info, tree *);
217 static bool exist_non_indexing_operands_for_use_p (tree, tree);
218 static bool vect_is_simple_iv_evolution (unsigned, tree, tree *, tree *, bool);
219 static void vect_mark_relevant (varray_type *, tree);
220 static bool vect_stmt_relevant_p (tree, loop_vec_info);
221 static tree vect_get_loop_niters (struct loop *, tree *);
222 static bool vect_compute_data_ref_alignment (struct data_reference *);
223 static bool vect_analyze_data_ref_access (struct data_reference *);
224 static bool vect_can_force_dr_alignment_p (tree, unsigned int);
225 static struct data_reference * vect_analyze_pointer_ref_access 
226   (tree, tree, bool);
227 static bool vect_can_advance_ivs_p (loop_vec_info);
228 static tree vect_get_base_and_offset (struct data_reference *, tree, tree, 
229                                       loop_vec_info, tree *, tree *, tree *,
230                                       bool*);
231 static struct data_reference * vect_analyze_pointer_ref_access
232   (tree, tree, bool);
233 static tree vect_get_ptr_offset (tree, tree, tree *);
234 static tree vect_get_memtag_and_dr
235   (tree, tree, bool, loop_vec_info, tree, struct data_reference **);
236 static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, 
237                                       tree *, tree *);
238 static tree vect_strip_conversion (tree);
239
240 /* Utility functions for the code transformation.  */
241 static tree vect_create_destination_var (tree, tree);
242 static tree vect_create_data_ref_ptr 
243   (tree, block_stmt_iterator *, tree, tree *, bool); 
244 static tree vect_create_index_for_vector_ref (loop_vec_info);
245 static tree vect_create_addr_base_for_vector_ref (tree, tree *, tree);
246 static tree get_vectype_for_scalar_type (tree);
247 static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
248 static tree vect_get_vec_def_for_operand (tree, tree);
249 static tree vect_init_vector (tree, tree);
250 static void vect_finish_stmt_generation 
251   (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
252
253 /* Utility function dealing with loop peeling (not peeling itself).  */
254 static void vect_generate_tmps_on_preheader 
255   (loop_vec_info, tree *, tree *, tree *);
256 static tree vect_build_loop_niters (loop_vec_info);
257 static void vect_update_ivs_after_vectorizer (loop_vec_info, tree, edge); 
258 static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
259 static void vect_update_inits_of_dr (struct data_reference *, tree niters);
260 static void vect_update_inits_of_drs (loop_vec_info, tree);
261 static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
262 static void vect_do_peeling_for_loop_bound 
263   (loop_vec_info, tree *, struct loops *);
264
265 /* Utilities for creation and deletion of vec_info structs.  */
266 loop_vec_info new_loop_vec_info (struct loop *loop);
267 void destroy_loop_vec_info (loop_vec_info);
268 stmt_vec_info new_stmt_vec_info (tree, loop_vec_info);
269
270 /*************************************************************************
271   Vectorization Debug Information.
272  *************************************************************************/
273
274 /* Utilities for output formatting. */
275 static bool vect_debug_stats (LOC);
276 static bool vect_debug_details (LOC);
277
278 \f
279 /*************************************************************************
280   Simple Loop Peeling Utilities
281
282   Utilities to support loop peeling for vectorization purposes.
283  *************************************************************************/
284
285
286 /* For each definition in DEFINITIONS this function allocates 
287    new ssa name.  */
288
289 static void
290 allocate_new_names (bitmap definitions)
291 {
292   unsigned ver;
293   bitmap_iterator bi;
294
295   EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
296     {
297       tree def = ssa_name (ver);
298       tree *new_name_ptr = xmalloc (sizeof (tree));
299
300       bool abnormal = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def);
301
302       *new_name_ptr = duplicate_ssa_name (def, SSA_NAME_DEF_STMT (def));
303       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*new_name_ptr) = abnormal;
304
305       SSA_NAME_AUX (def) = new_name_ptr;
306     }
307 }
308
309
310 /* Renames the use *OP_P.  */
311
312 static void
313 rename_use_op (use_operand_p op_p)
314 {
315   tree *new_name_ptr;
316
317   if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
318     return;
319
320   new_name_ptr = SSA_NAME_AUX (USE_FROM_PTR (op_p));
321
322   /* Something defined outside of the loop.  */
323   if (!new_name_ptr)
324     return;
325
326   /* An ordinary ssa name defined in the loop.  */
327
328   SET_USE (op_p, *new_name_ptr);
329 }
330
331
332 /* Renames the def *OP_P in statement STMT.  */
333
334 static void
335 rename_def_op (def_operand_p op_p, tree stmt)
336 {
337   tree *new_name_ptr;
338
339   if (TREE_CODE (DEF_FROM_PTR (op_p)) != SSA_NAME)
340     return;
341
342   new_name_ptr = SSA_NAME_AUX (DEF_FROM_PTR (op_p));
343
344   /* Something defined outside of the loop.  */
345   if (!new_name_ptr)
346     return;
347
348   /* An ordinary ssa name defined in the loop.  */
349
350   SET_DEF (op_p, *new_name_ptr);
351   SSA_NAME_DEF_STMT (DEF_FROM_PTR (op_p)) = stmt;
352 }
353
354
355 /* Renames the variables in basic block BB.  */
356
357 static void
358 rename_variables_in_bb (basic_block bb)
359 {
360   tree phi;
361   block_stmt_iterator bsi;
362   tree stmt;
363   stmt_ann_t ann;
364   use_optype uses;
365   vuse_optype vuses;
366   def_optype defs;
367   v_may_def_optype v_may_defs;
368   v_must_def_optype v_must_defs;
369   unsigned i;
370   edge e;
371   edge_iterator ei;
372   struct loop *loop = bb->loop_father;
373
374   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
375     rename_def_op (PHI_RESULT_PTR (phi), phi);
376
377   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
378     {
379       stmt = bsi_stmt (bsi);
380       get_stmt_operands (stmt);
381       ann = stmt_ann (stmt);
382
383       uses = USE_OPS (ann);
384       for (i = 0; i < NUM_USES (uses); i++)
385         rename_use_op (USE_OP_PTR (uses, i));
386
387       defs = DEF_OPS (ann);
388       for (i = 0; i < NUM_DEFS (defs); i++)
389         rename_def_op (DEF_OP_PTR (defs, i), stmt);
390
391       vuses = VUSE_OPS (ann);
392       for (i = 0; i < NUM_VUSES (vuses); i++)
393         rename_use_op (VUSE_OP_PTR (vuses, i));
394
395       v_may_defs = V_MAY_DEF_OPS (ann);
396       for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
397         {
398           rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
399           rename_def_op (V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt);
400         }
401
402       v_must_defs = V_MUST_DEF_OPS (ann);
403       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
404         {
405           rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
406           rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
407         }
408     }
409
410   FOR_EACH_EDGE (e, ei, bb->succs)
411     {
412       if (!flow_bb_inside_loop_p (loop, e->dest))
413         continue;
414       for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
415         rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e));
416     }
417 }
418
419
420 /* Releases the structures holding the new ssa names.  */
421
422 static void
423 free_new_names (bitmap definitions)
424 {
425   unsigned ver;
426   bitmap_iterator bi;
427
428   EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
429     {
430       tree def = ssa_name (ver);
431
432       if (SSA_NAME_AUX (def))
433         {
434           free (SSA_NAME_AUX (def));
435           SSA_NAME_AUX (def) = NULL;
436         }
437     }
438 }
439
440
441 /* Renames variables in new generated LOOP.  */
442
443 static void
444 rename_variables_in_loop (struct loop *loop)
445 {
446   unsigned i;
447   basic_block *bbs;
448
449   bbs = get_loop_body (loop);
450
451   for (i = 0; i < loop->num_nodes; i++)
452     rename_variables_in_bb (bbs[i]);
453
454   free (bbs);
455 }
456
457
458 /* Update the PHI nodes of NEW_LOOP.
459
460    NEW_LOOP is a duplicate of ORIG_LOOP.
461    AFTER indicates whether NEW_LOOP executes before or after ORIG_LOOP:
462    AFTER is true if NEW_LOOP executes after ORIG_LOOP, and false if it
463    executes before it.  */
464
465 static void
466 slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
467                                        struct loop *new_loop, bool after)
468 {
469   tree *new_name_ptr, new_ssa_name;
470   tree phi_new, phi_orig;
471   tree def;
472   edge orig_loop_latch = loop_latch_edge (orig_loop);
473   edge orig_entry_e = loop_preheader_edge (orig_loop);
474   edge new_loop_exit_e = new_loop->exit_edges[0];
475   edge new_loop_entry_e = loop_preheader_edge (new_loop);
476   edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
477
478   /*
479      step 1. For each loop-header-phi:
480              Add the first phi argument for the phi in NEW_LOOP
481             (the one associated with the entry of NEW_LOOP)
482
483      step 2. For each loop-header-phi:
484              Add the second phi argument for the phi in NEW_LOOP
485             (the one associated with the latch of NEW_LOOP)
486
487      step 3. Update the phis in the successor block of NEW_LOOP.
488
489         case 1: NEW_LOOP was placed before ORIG_LOOP:
490                 The successor block of NEW_LOOP is the header of ORIG_LOOP.
491                 Updating the phis in the successor block can therefore be done
492                 along with the scanning of the loop header phis, because the
493                 header blocks of ORIG_LOOP and NEW_LOOP have exactly the same
494                 phi nodes, organized in the same order.
495
496         case 2: NEW_LOOP was placed after ORIG_LOOP:
497                 The successor block of NEW_LOOP is the original exit block of 
498                 ORIG_LOOP - the phis to be updated are the loop-closed-ssa phis.
499                 We postpone updating these phis to a later stage (when
500                 loop guards are added).
501    */
502
503
504   /* Scan the phis in the headers of the old and new loops
505      (they are organized in exactly the same order).  */
506
507   for (phi_new = phi_nodes (new_loop->header),
508        phi_orig = phi_nodes (orig_loop->header);
509        phi_new && phi_orig;
510        phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
511     {
512       /* step 1.  */
513       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
514       add_phi_arg (phi_new, def, new_loop_entry_e);
515
516       /* step 2.  */
517       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
518       if (TREE_CODE (def) != SSA_NAME)
519         continue;
520
521       new_name_ptr = SSA_NAME_AUX (def);
522       if (!new_name_ptr)
523         /* Something defined outside of the loop.  */
524         continue;
525
526       /* An ordinary ssa name defined in the loop.  */
527       new_ssa_name = *new_name_ptr;
528       add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
529
530       /* step 3 (case 1).  */
531       if (!after)
532         {
533           gcc_assert (new_loop_exit_e == orig_entry_e);
534           SET_PHI_ARG_DEF (phi_orig,
535                            new_loop_exit_e->dest_idx,
536                            new_ssa_name);
537         }
538     }
539 }
540
541
542 /* Update PHI nodes for a guard of the LOOP.
543
544    Input:
545    - LOOP, GUARD_EDGE: LOOP is a loop for which we added guard code that
546         controls whether LOOP is to be executed.  GUARD_EDGE is the edge that
547         originates from the guard-bb, skips LOOP and reaches the (unique) exit
548         bb of LOOP.  This loop-exit-bb is an empty bb with one successor.
549         We denote this bb NEW_MERGE_BB because it had a single predecessor (the
550         LOOP header) before the guard code was added, and now it became a merge
551         point of two paths - the path that ends with the LOOP exit-edge, and
552         the path that ends with GUARD_EDGE.
553
554         This function creates and updates the relevant phi nodes to account for
555         the new incoming edge (GUARD_EDGE) into NEW_MERGE_BB:
556         1. Create phi nodes at NEW_MERGE_BB.
557         2. Update the phi nodes at the successor of NEW_MERGE_BB (denoted
558            UPDATE_BB).  UPDATE_BB was the exit-bb of LOOP before NEW_MERGE_BB
559            was added:
560
561         ===> The CFG before the guard-code was added:
562         LOOP_header_bb:
563           if (exit_loop) goto update_bb : LOOP_header_bb
564         update_bb:
565
566         ==> The CFG after the guard-code was added:
567         guard_bb: 
568           if (LOOP_guard_condition) goto new_merge_bb : LOOP_header_bb
569         LOOP_header_bb:
570           if (exit_loop_condition) goto new_merge_bb : LOOP_header_bb
571         new_merge_bb:
572           goto update_bb
573         update_bb:
574
575    - ENTRY_PHIS: If ENTRY_PHIS is TRUE, this indicates that the phis in 
576         UPDATE_BB are loop entry phis, like the phis in the LOOP header,
577         organized in the same order. 
578         If ENTRY_PHIs is FALSE, this indicates that the phis in UPDATE_BB are
579         loop exit phis.
580
581    - IS_NEW_LOOP: TRUE if LOOP is a new loop (a duplicated copy of another
582         "original" loop).  FALSE if LOOP is an original loop (not a newly 
583         created copy).  The SSA_NAME_AUX fields of the defs in the original
584         loop are the corresponding new ssa-names used in the new duplicated
585         loop copy.  IS_NEW_LOOP indicates which of the two args of the phi 
586         nodes in UPDATE_BB takes the original ssa-name, and which takes the 
587         new name: If IS_NEW_LOOP is TRUE, the phi-arg that is associated with
588         the LOOP-exit-edge takes the new-name, and the phi-arg that is 
589         associated with GUARD_EDGE takes the original name.  If IS_NEW_LOOP is
590         FALSE, it's the other way around.
591   */
592
593 static void
594 slpeel_update_phi_nodes_for_guard (edge guard_edge, 
595                                    struct loop *loop,
596                                    bool entry_phis,
597                                    bool is_new_loop)
598 {
599   tree orig_phi, new_phi, update_phi;
600   tree guard_arg, loop_arg;
601   basic_block new_merge_bb = guard_edge->dest;
602   edge e = EDGE_SUCC (new_merge_bb, 0);
603   basic_block update_bb = e->dest;
604   basic_block orig_bb = (entry_phis ? loop->header : update_bb);
605
606   for (orig_phi = phi_nodes (orig_bb), update_phi = phi_nodes (update_bb);
607        orig_phi && update_phi;
608        orig_phi = PHI_CHAIN (orig_phi), update_phi = PHI_CHAIN (update_phi))
609     {
610       /* 1. Generate new phi node in NEW_MERGE_BB:  */
611       new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
612                                  new_merge_bb);
613
614       /* 2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
615             of LOOP. Set the two phi args in NEW_PHI for these edges:  */
616       if (entry_phis)
617         {
618           loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi,
619                                             EDGE_SUCC (loop->latch, 0));
620           guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop->entry_edges[0]);
621         }
622       else /* exit phis */
623         {
624           tree orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
625           tree *new_name_ptr = SSA_NAME_AUX (orig_def);
626           tree new_name;
627
628           if (new_name_ptr)
629             new_name = *new_name_ptr;
630           else
631             /* Something defined outside of the loop  */
632             new_name = orig_def;
633
634           if (is_new_loop)
635             {
636               guard_arg = orig_def;
637               loop_arg = new_name;
638             }
639           else
640             {
641               guard_arg = new_name;
642               loop_arg = orig_def;
643             }
644         }
645       add_phi_arg (new_phi, loop_arg, loop->exit_edges[0]);
646       add_phi_arg (new_phi, guard_arg, guard_edge);
647
648       /* 3. Update phi in successor block.  */
649       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
650                   || PHI_ARG_DEF_FROM_EDGE (update_phi, e) == guard_arg);
651       SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
652     }
653
654   set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
655 }
656
657
658 /* Make the LOOP iterate NITERS times. This is done by adding a new IV
659    that starts at zero, increases by one and its limit is NITERS.
660
661    Assumption: the exit-condition of LOOP is the last stmt in the loop.  */
662
663 static void
664 slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
665 {
666   tree indx_before_incr, indx_after_incr, cond_stmt, cond;
667   tree orig_cond;
668   edge exit_edge = loop->exit_edges[0];
669   block_stmt_iterator loop_cond_bsi;
670   block_stmt_iterator incr_bsi;
671   bool insert_after;
672   tree begin_label = tree_block_label (loop->latch);
673   tree exit_label = tree_block_label (loop->single_exit->dest);
674   tree init = build_int_cst (TREE_TYPE (niters), 0);
675   tree step = build_int_cst (TREE_TYPE (niters), 1);
676   tree then_label;
677   tree else_label;
678   LOC loop_loc;
679
680   orig_cond = get_loop_exit_condition (loop);
681 #ifdef ENABLE_CHECKING
682   gcc_assert (orig_cond);
683 #endif
684   loop_cond_bsi = bsi_for_stmt (orig_cond);
685
686   standard_iv_increment_position (loop, &incr_bsi, &insert_after);
687   create_iv (init, step, NULL_TREE, loop,
688              &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
689
690   if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop.  */
691     {
692       cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
693       then_label = build1 (GOTO_EXPR, void_type_node, exit_label);
694       else_label = build1 (GOTO_EXPR, void_type_node, begin_label);
695     }
696   else /* 'then' edge loops back.  */
697     {
698       cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
699       then_label = build1 (GOTO_EXPR, void_type_node, begin_label);
700       else_label = build1 (GOTO_EXPR, void_type_node, exit_label);
701     }
702
703   cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
704                      then_label, else_label);
705   bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
706
707   /* Remove old loop exit test:  */
708   bsi_remove (&loop_cond_bsi);
709
710   loop_loc = find_loop_location (loop);
711   if (vect_debug_details (loop_loc))
712     print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
713
714   loop->nb_iterations = niters;
715 }
716
717
718 /* Given LOOP this function generates a new copy of it and puts it 
719    on E which is either the entry or exit of LOOP.  */
720
721 static struct loop *
722 slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops, 
723                                         edge e)
724 {
725   struct loop *new_loop;
726   basic_block *new_bbs, *bbs;
727   bool at_exit;
728   bool was_imm_dom;
729   basic_block exit_dest; 
730   tree phi, phi_arg;
731
732   at_exit = (e == loop->exit_edges[0]); 
733   if (!at_exit && e != loop_preheader_edge (loop))
734     return NULL;
735
736   bbs = get_loop_body (loop);
737
738   /* Check whether duplication is possible.  */
739   if (!can_copy_bbs_p (bbs, loop->num_nodes))
740     {
741       free (bbs);
742       return NULL;
743     }
744
745   /* Generate new loop structure.  */
746   new_loop = duplicate_loop (loops, loop, loop->outer);
747   if (!new_loop)
748     {
749       free (bbs);
750       return NULL;
751     }
752
753   exit_dest = loop->exit_edges[0]->dest;
754   was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS, 
755                                           exit_dest) == loop->header ? 
756                  true : false);
757
758   new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
759
760   copy_bbs (bbs, loop->num_nodes, new_bbs, NULL, 0, NULL, NULL);
761
762   /* Duplicating phi args at exit bbs as coming 
763      also from exit of duplicated loop.  */
764   for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
765     {
766       phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->exit_edges[0]);
767       if (phi_arg)
768         {
769           edge new_loop_exit_edge;
770
771           if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
772             new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
773           else
774             new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
775   
776           add_phi_arg (phi, phi_arg, new_loop_exit_edge);       
777         }
778     }    
779    
780   if (at_exit) /* Add the loop copy at exit.  */
781     {
782       redirect_edge_and_branch_force (e, new_loop->header);
783       set_immediate_dominator (CDI_DOMINATORS, new_loop->header, e->src);
784       if (was_imm_dom)
785         set_immediate_dominator (CDI_DOMINATORS, exit_dest, new_loop->header);
786     }
787   else /* Add the copy at entry.  */
788     {
789       edge new_exit_e;
790       edge entry_e = loop_preheader_edge (loop);
791       basic_block preheader = entry_e->src;
792            
793       if (!flow_bb_inside_loop_p (new_loop, 
794                                   EDGE_SUCC (new_loop->header, 0)->dest))
795         new_exit_e = EDGE_SUCC (new_loop->header, 0);
796       else
797         new_exit_e = EDGE_SUCC (new_loop->header, 1); 
798
799       redirect_edge_and_branch_force (new_exit_e, loop->header);
800       set_immediate_dominator (CDI_DOMINATORS, loop->header,
801                                new_exit_e->src);
802
803       /* We have to add phi args to the loop->header here as coming 
804          from new_exit_e edge.  */
805       for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
806         {
807           phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
808           if (phi_arg)
809             add_phi_arg (phi, phi_arg, new_exit_e);     
810         }    
811
812       redirect_edge_and_branch_force (entry_e, new_loop->header);
813       set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
814     }
815
816   flow_loop_scan (new_loop, LOOP_ALL);
817   flow_loop_scan (loop, LOOP_ALL);  
818   free (new_bbs);
819   free (bbs);
820
821   return new_loop;
822 }
823
824
825 /* Given the condition statement COND, put it as the last statement
826    of GUARD_BB; EXIT_BB is the basic block to skip the loop;
827    Assumes that this is the single exit of the guarded loop.  
828    Returns the skip edge.  */
829
830 static edge
831 slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
832                         basic_block dom_bb)
833 {
834   block_stmt_iterator bsi;
835   edge new_e, enter_e;
836   tree cond_stmt, then_label, else_label;
837
838   enter_e = EDGE_SUCC (guard_bb, 0);
839   enter_e->flags &= ~EDGE_FALLTHRU;
840   enter_e->flags |= EDGE_FALSE_VALUE;
841   bsi = bsi_last (guard_bb);
842
843   then_label = build1 (GOTO_EXPR, void_type_node,
844                        tree_block_label (exit_bb));
845   else_label = build1 (GOTO_EXPR, void_type_node,
846                        tree_block_label (enter_e->dest));
847   cond_stmt = build3 (COND_EXPR, void_type_node, cond,
848                      then_label, else_label);
849   bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
850   /* Add new edge to connect entry block to the second loop.  */
851   new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
852   set_immediate_dominator (CDI_DOMINATORS, exit_bb, dom_bb);
853   return new_e;
854 }
855
856
857 /* This function verifies that the following restrictions apply to LOOP:
858    (1) it is innermost
859    (2) it consists of exactly 2 basic blocks - header, and an empty latch.
860    (3) it is single entry, single exit
861    (4) its exit condition is the last stmt in the header
862    (5) E is the entry/exit edge of LOOP.
863  */
864
865 static bool
866 slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
867 {
868   edge exit_e = loop->exit_edges [0];
869   edge entry_e = loop_preheader_edge (loop);
870   tree orig_cond = get_loop_exit_condition (loop);
871   block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
872
873   if (any_marked_for_rewrite_p ())
874     return false;
875
876   if (loop->inner
877       /* All loops have an outer scope; the only case loop->outer is NULL is for
878          the function itself.  */
879       || !loop->outer
880       || loop->num_nodes != 2
881       || !empty_block_p (loop->latch)
882       || loop->num_exits != 1
883       || loop->num_entries != 1
884       /* Verify that new loop exit condition can be trivially modified.  */
885       || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
886       || (e != exit_e && e != entry_e))
887     return false;
888
889   return true;
890 }
891
892 #ifdef ENABLE_CHECKING
893 static void
894 slpeel_verify_cfg_after_peeling (struct loop *first_loop,
895                                  struct loop *second_loop)
896 {
897   basic_block loop1_exit_bb = first_loop->exit_edges[0]->dest;
898   basic_block loop2_entry_bb = second_loop->pre_header;
899   basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
900
901   /* A guard that controls whether the second_loop is to be executed or skipped
902      is placed in first_loop->exit.  first_loopt->exit therefore has two
903      successors - one is the preheader of second_loop, and the other is a bb
904      after second_loop.
905    */
906   gcc_assert (EDGE_COUNT (loop1_exit_bb->succs) == 2);
907    
908    
909   /* 1. Verify that one of the successors of first_loopt->exit is the preheader
910         of second_loop.  */
911    
912   /* The preheader of new_loop is expected to have two predessors:
913      first_loop->exit and the block that precedes first_loop.  */
914
915   gcc_assert (EDGE_COUNT (loop2_entry_bb->preds) == 2 
916               && ((EDGE_PRED (loop2_entry_bb, 0)->src == loop1_exit_bb
917                    && EDGE_PRED (loop2_entry_bb, 1)->src == loop1_entry_bb)
918                || (EDGE_PRED (loop2_entry_bb, 1)->src ==  loop1_exit_bb
919                    && EDGE_PRED (loop2_entry_bb, 0)->src == loop1_entry_bb)));
920   
921   /* Verify that the other successor of first_loopt->exit is after the
922      second_loop.  */
923   /* TODO */
924 }
925 #endif
926
927 /* Function slpeel_tree_peel_loop_to_edge.
928
929    Peel the first (last) iterations of LOOP into a new prolog (epilog) loop
930    that is placed on the entry (exit) edge E of LOOP. After this transformation
931    we have two loops one after the other - first-loop iterates FIRST_NITERS
932    times, and second-loop iterates the remainder NITERS - FIRST_NITERS times.
933
934    Input:
935    - LOOP: the loop to be peeled.
936    - E: the exit or entry edge of LOOP.
937         If it is the entry edge, we peel the first iterations of LOOP. In this
938         case first-loop is LOOP, and second-loop is the newly created loop.
939         If it is the exit edge, we peel the last iterations of LOOP. In this
940         case, first-loop is the newly created loop, and second-loop is LOOP.
941    - NITERS: the number of iterations that LOOP iterates.
942    - FIRST_NITERS: the number of iterations that the first-loop should iterate.
943    - UPDATE_FIRST_LOOP_COUNT:  specified whether this function is responsible
944         for updating the loop bound of the first-loop to FIRST_NITERS.  If it
945         is false, the caller of this function may want to take care of this
946         (this can be useful if we don't want new stmts added to first-loop).
947
948    Output:
949    The function returns a pointer to the new loop-copy, or NULL if it failed
950    to perform the transformation.
951
952    The function generates two if-then-else guards: one before the first loop,
953    and the other before the second loop:
954    The first guard is:
955      if (FIRST_NITERS == 0) then skip the first loop,
956      and go directly to the second loop.
957    The second guard is:
958      if (FIRST_NITERS == NITERS) then skip the second loop.
959
960    FORNOW only simple loops are supported (see slpeel_can_duplicate_loop_p).
961    FORNOW the resulting code will not be in loop-closed-ssa form.
962 */
963
964 struct loop*
965 slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, 
966                                edge e, tree first_niters, 
967                                tree niters, bool update_first_loop_count)
968 {
969   struct loop *new_loop = NULL, *first_loop, *second_loop;
970   edge skip_e;
971   tree pre_condition;
972   bitmap definitions;
973   basic_block bb_before_second_loop, bb_after_second_loop;
974   basic_block bb_before_first_loop;
975   basic_block bb_between_loops;
976   edge exit_e = loop->exit_edges [0];
977   LOC loop_loc;
978   
979   if (!slpeel_can_duplicate_loop_p (loop, e))
980     return NULL;
981   
982   /* We have to initialize cfg_hooks. Then, when calling
983    cfg_hooks->split_edge, the function tree_split_edge 
984    is actually called and, when calling cfg_hooks->duplicate_block,
985    the function tree_duplicate_bb is called.  */
986   tree_register_cfg_hooks ();
987
988
989   /* 1. Generate a copy of LOOP and put it on E (E is the entry/exit of LOOP).
990         Resulting CFG would be:
991
992         first_loop:
993         do {
994         } while ...
995
996         second_loop:
997         do {
998         } while ...
999
1000         orig_exit_bb:
1001    */
1002   
1003   if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
1004     {
1005       loop_loc = find_loop_location (loop);
1006       if (vect_debug_stats (loop_loc)
1007           || vect_debug_details (loop_loc))
1008         fprintf (dump_file, "tree_duplicate_loop_to_edge_cfg failed.\n");
1009       return NULL;
1010     }
1011   
1012   if (e == exit_e)
1013     {
1014       /* NEW_LOOP was placed after LOOP.  */
1015       first_loop = loop;
1016       second_loop = new_loop;
1017     }
1018   else
1019     {
1020       /* NEW_LOOP was placed before LOOP.  */
1021       first_loop = new_loop;
1022       second_loop = loop;
1023     }
1024
1025   definitions = marked_ssa_names ();
1026   allocate_new_names (definitions);
1027   slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
1028   rename_variables_in_loop (new_loop);
1029
1030
1031   /* 2. Add the guard that controls whether the first loop is executed.
1032         Resulting CFG would be:
1033
1034         bb_before_first_loop:
1035         if (FIRST_NITERS == 0) GOTO bb_before_second_loop
1036                                GOTO first-loop
1037
1038         first_loop:
1039         do {
1040         } while ...
1041
1042         bb_before_second_loop:
1043
1044         second_loop:
1045         do {
1046         } while ...
1047
1048         orig_exit_bb:
1049    */
1050
1051   bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
1052   add_bb_to_loop (bb_before_first_loop, first_loop->outer);
1053   bb_before_second_loop = split_edge (first_loop->exit_edges[0]);
1054   add_bb_to_loop (bb_before_second_loop, first_loop->outer);
1055   flow_loop_scan (first_loop, LOOP_ALL);
1056   flow_loop_scan (second_loop, LOOP_ALL);
1057
1058   pre_condition =
1059         build2 (LE_EXPR, boolean_type_node, first_niters, integer_zero_node);
1060   skip_e = slpeel_add_loop_guard (bb_before_first_loop, pre_condition,
1061                                   bb_before_second_loop, bb_before_first_loop);
1062   slpeel_update_phi_nodes_for_guard (skip_e, first_loop, true /* entry-phis */,
1063                                      first_loop == new_loop);
1064
1065
1066   /* 3. Add the guard that controls whether the second loop is executed.
1067         Resulting CFG would be:
1068
1069         bb_before_first_loop:
1070         if (FIRST_NITERS == 0) GOTO bb_before_second_loop (skip first loop)
1071                                GOTO first-loop
1072
1073         first_loop:
1074         do {
1075         } while ...
1076
1077         bb_between_loops:
1078         if (FIRST_NITERS == NITERS) GOTO bb_after_second_loop (skip second loop)
1079                                     GOTO bb_before_second_loop
1080
1081         bb_before_second_loop:
1082
1083         second_loop:
1084         do {
1085         } while ...
1086
1087         bb_after_second_loop:
1088
1089         orig_exit_bb:
1090    */
1091
1092   bb_between_loops = split_edge (first_loop->exit_edges[0]);
1093   add_bb_to_loop (bb_between_loops, first_loop->outer);
1094   bb_after_second_loop = split_edge (second_loop->exit_edges[0]);
1095   add_bb_to_loop (bb_after_second_loop, second_loop->outer);
1096   flow_loop_scan (first_loop, LOOP_ALL);
1097   flow_loop_scan (second_loop, LOOP_ALL);
1098
1099   pre_condition = build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
1100   skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition,
1101                                   bb_after_second_loop, bb_before_first_loop);
1102   slpeel_update_phi_nodes_for_guard (skip_e, second_loop, false /* exit-phis */,
1103                                      second_loop == new_loop);
1104
1105   /* Flow loop scan does not update loop->single_exit field.  */
1106   first_loop->single_exit = first_loop->exit_edges[0];
1107   second_loop->single_exit = second_loop->exit_edges[0];
1108
1109   /* 4. Make first-loop iterate FIRST_NITERS times, if requested.
1110    */
1111   if (update_first_loop_count)
1112     slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
1113
1114   free_new_names (definitions);
1115   BITMAP_XFREE (definitions);
1116   unmark_all_for_rewrite ();
1117
1118   return new_loop;
1119 }
1120
1121 /* Function vect_get_loop_location.
1122
1123    Extract the location of the loop in the source code.
1124    If the loop is not well formed for vectorization, an estimated
1125    location is calculated.
1126    Return the loop location if succeed and NULL if not.  */
1127
1128 static LOC
1129 find_loop_location (struct loop *loop)
1130 {
1131   tree node = NULL_TREE;
1132   basic_block bb;
1133   block_stmt_iterator si;
1134
1135   if (!loop)
1136     return UNKNOWN_LOC;
1137
1138   node = get_loop_exit_condition (loop);
1139
1140   if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node)
1141       && EXPR_FILENAME (node) && EXPR_LINENO (node))
1142     return EXPR_LOC (node);
1143
1144   /* If we got here the loop is probably not "well formed",
1145      try to estimate the loop location */
1146
1147   if (!loop->header)
1148     return UNKNOWN_LOC;
1149
1150   bb = loop->header;
1151
1152   for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1153     {
1154       node = bsi_stmt (si);
1155       if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node))
1156         return EXPR_LOC (node);
1157     }
1158
1159   return UNKNOWN_LOC;
1160 }
1161
1162
1163 \f
1164 /* Here the proper Vectorizer starts.  */
1165
1166 /*************************************************************************
1167   Vectorization Utilities.
1168  *************************************************************************/
1169
1170 /* Function new_stmt_vec_info.
1171
1172    Create and initialize a new stmt_vec_info struct for STMT.  */
1173
1174 stmt_vec_info
1175 new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
1176 {
1177   stmt_vec_info res;
1178   res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
1179
1180   STMT_VINFO_TYPE (res) = undef_vec_info_type;
1181   STMT_VINFO_STMT (res) = stmt;
1182   STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
1183   STMT_VINFO_RELEVANT_P (res) = 0;
1184   STMT_VINFO_VECTYPE (res) = NULL;
1185   STMT_VINFO_VEC_STMT (res) = NULL;
1186   STMT_VINFO_DATA_REF (res) = NULL;
1187   STMT_VINFO_MEMTAG (res) = NULL;
1188   STMT_VINFO_VECT_DR_BASE (res) = NULL;
1189   STMT_VINFO_VECT_INIT_OFFSET (res) = NULL_TREE;
1190   STMT_VINFO_VECT_STEP (res) = NULL_TREE;
1191   STMT_VINFO_VECT_BASE_ALIGNED_P (res) = false;
1192   STMT_VINFO_VECT_MISALIGNMENT (res) = NULL_TREE;
1193
1194   return res;
1195 }
1196
1197
1198 /* Function new_loop_vec_info.
1199
1200    Create and initialize a new loop_vec_info struct for LOOP, as well as
1201    stmt_vec_info structs for all the stmts in LOOP.  */
1202
1203 loop_vec_info
1204 new_loop_vec_info (struct loop *loop)
1205 {
1206   loop_vec_info res;
1207   basic_block *bbs;
1208   block_stmt_iterator si;
1209   unsigned int i;
1210
1211   res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
1212
1213   bbs = get_loop_body (loop);
1214
1215   /* Create stmt_info for all stmts in the loop.  */
1216   for (i = 0; i < loop->num_nodes; i++)
1217     {
1218       basic_block bb = bbs[i];
1219       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1220         {
1221           tree stmt = bsi_stmt (si);
1222           stmt_ann_t ann;
1223
1224           get_stmt_operands (stmt);
1225           ann = stmt_ann (stmt);
1226           set_stmt_info (ann, new_stmt_vec_info (stmt, res));
1227         }
1228     }
1229
1230   LOOP_VINFO_LOOP (res) = loop;
1231   LOOP_VINFO_BBS (res) = bbs;
1232   LOOP_VINFO_EXIT_COND (res) = NULL;
1233   LOOP_VINFO_NITERS (res) = NULL;
1234   LOOP_VINFO_VECTORIZABLE_P (res) = 0;
1235   LOOP_DO_PEELING_FOR_ALIGNMENT (res) = false;
1236   LOOP_VINFO_VECT_FACTOR (res) = 0;
1237   VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_WRITES (res), 20,
1238                            "loop_write_datarefs");
1239   VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_READS (res), 20,
1240                            "loop_read_datarefs");
1241   LOOP_VINFO_UNALIGNED_DR (res) = NULL;
1242   LOOP_VINFO_LOC (res) = UNKNOWN_LOC;
1243
1244   return res;
1245 }
1246
1247
1248 /* Function destroy_loop_vec_info.
1249  
1250    Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the 
1251    stmts in the loop.  */
1252
1253 void
1254 destroy_loop_vec_info (loop_vec_info loop_vinfo)
1255 {
1256   struct loop *loop;
1257   basic_block *bbs;
1258   int nbbs;
1259   block_stmt_iterator si;
1260   int j;
1261
1262   if (!loop_vinfo)
1263     return;
1264
1265   loop = LOOP_VINFO_LOOP (loop_vinfo);
1266
1267   bbs = LOOP_VINFO_BBS (loop_vinfo);
1268   nbbs = loop->num_nodes;
1269
1270   for (j = 0; j < nbbs; j++)
1271     {
1272       basic_block bb = bbs[j];
1273       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1274         {
1275           tree stmt = bsi_stmt (si);
1276           stmt_ann_t ann = stmt_ann (stmt);
1277           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1278           free (stmt_info);
1279           set_stmt_info (ann, NULL);
1280         }
1281     }
1282
1283   free (LOOP_VINFO_BBS (loop_vinfo));
1284   varray_clear (LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
1285   varray_clear (LOOP_VINFO_DATAREF_READS (loop_vinfo));
1286
1287   free (loop_vinfo);
1288 }
1289
1290
1291 /* Function debug_loop_stats.
1292
1293    For vectorization statistics dumps.  */
1294
1295 static bool
1296 vect_debug_stats (LOC loc)
1297 {
1298   if (!dump_file || !(dump_flags & TDF_STATS))
1299     return false;
1300
1301   if (loc == UNKNOWN_LOC)
1302     fprintf (dump_file, "\n");
1303   else
1304     fprintf (dump_file, "\nloop at %s:%d: ",
1305              LOC_FILE (loc), LOC_LINE (loc));
1306
1307   return true;
1308 }
1309
1310
1311 /* Function debug_loop_details.
1312
1313    For vectorization debug dumps.  */
1314
1315 static bool
1316 vect_debug_details (LOC loc)
1317 {
1318   if (!dump_file || !(dump_flags & TDF_DETAILS))
1319     return false;
1320    
1321   if (loc == UNKNOWN_LOC)
1322     fprintf (dump_file, "\n");
1323   else
1324     fprintf (dump_file, "\nloop at %s:%d: ",
1325              LOC_FILE (loc), LOC_LINE (loc));
1326     
1327   return true;
1328 }
1329
1330
1331 /* Function vect_get_ptr_offset
1332
1333    Compute the OFFSET modulo vector-type alignment of pointer REF in bits.  */
1334
1335 static tree 
1336 vect_get_ptr_offset (tree ref ATTRIBUTE_UNUSED, 
1337                      tree vectype ATTRIBUTE_UNUSED, 
1338                      tree *offset ATTRIBUTE_UNUSED)
1339 {
1340   /* TODO: Use alignment information.  */
1341   return NULL_TREE; 
1342 }
1343
1344
1345 /* Function vect_strip_conversions
1346
1347    Strip conversions that don't narrow the mode.  */
1348
1349 static tree 
1350 vect_strip_conversion (tree expr)
1351 {
1352   tree to, ti, oprnd0;
1353   
1354   while (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
1355     {
1356       to = TREE_TYPE (expr);
1357       oprnd0 = TREE_OPERAND (expr, 0);
1358       ti = TREE_TYPE (oprnd0);
1359  
1360       if (!INTEGRAL_TYPE_P (to) || !INTEGRAL_TYPE_P (ti))
1361         return NULL_TREE;
1362       if (GET_MODE_SIZE (TYPE_MODE (to)) < GET_MODE_SIZE (TYPE_MODE (ti)))
1363         return NULL_TREE;
1364       
1365       expr = oprnd0;
1366     }
1367   return expr; 
1368 }
1369
1370
1371 /* Function vect_analyze_offset_expr
1372
1373    Given an offset expression EXPR received from get_inner_reference, analyze
1374    it and create an expression for INITIAL_OFFSET by substituting the variables 
1375    of EXPR with initial_condition of the corresponding access_fn in the loop. 
1376    E.g., 
1377       for i
1378          for (j = 3; j < N; j++)
1379             a[j].b[i][j] = 0;
1380          
1381    For a[j].b[i][j], EXPR will be 'i * C_i + j * C_j + C'. 'i' cannot be 
1382    substituted, since its access_fn in the inner loop is i. 'j' will be 
1383    substituted with 3. An INITIAL_OFFSET will be 'i * C_i + C`', where
1384    C` =  3 * C_j + C.
1385
1386    Compute MISALIGN (the misalignment of the data reference initial access from
1387    its base) if possible. Misalignment can be calculated only if all the
1388    variables can be substituted with constants, or if a variable is multiplied
1389    by a multiple of VECTYPE_ALIGNMENT. In the above example, since 'i' cannot
1390    be substituted, MISALIGN will be NULL_TREE in case that C_i is not a multiple
1391    of VECTYPE_ALIGNMENT, and C` otherwise. (We perform MISALIGN modulo 
1392    VECTYPE_ALIGNMENT computation in the caller of this function).
1393
1394    STEP is an evolution of the data reference in this loop in bytes.
1395    In the above example, STEP is C_j.
1396
1397    Return FALSE, if the analysis fails, e.g., there is no access_fn for a 
1398    variable. In this case, all the outputs (INITIAL_OFFSET, MISALIGN and STEP) 
1399    are NULL_TREEs. Otherwise, return TRUE.
1400
1401 */
1402
1403 static bool
1404 vect_analyze_offset_expr (tree expr, 
1405                           struct loop *loop, 
1406                           tree vectype_alignment,
1407                           tree *initial_offset,
1408                           tree *misalign,
1409                           tree *step)
1410 {
1411   tree oprnd0;
1412   tree oprnd1;
1413   tree left_offset = ssize_int (0);
1414   tree right_offset = ssize_int (0);
1415   tree left_misalign = ssize_int (0);
1416   tree right_misalign = ssize_int (0);
1417   tree left_step = ssize_int (0);
1418   tree right_step = ssize_int (0);
1419   enum tree_code code;
1420   tree init, evolution;
1421
1422   *step = NULL_TREE;
1423   *misalign = NULL_TREE;
1424   *initial_offset = NULL_TREE;
1425
1426   /* Strip conversions that don't narrow the mode.  */
1427   expr = vect_strip_conversion (expr);
1428   if (!expr)
1429     return false;
1430
1431   /* Stop conditions:
1432      1. Constant.  */
1433   if (TREE_CODE (expr) == INTEGER_CST)
1434     {
1435       *initial_offset = fold_convert (ssizetype, expr);
1436       *misalign = fold_convert (ssizetype, expr);      
1437       *step = ssize_int (0);
1438       return true;
1439     }
1440
1441   /* 2. Variable. Try to substitute with initial_condition of the corresponding
1442      access_fn in the current loop.  */
1443   if (SSA_VAR_P (expr))
1444     {
1445       tree access_fn = analyze_scalar_evolution (loop, expr);
1446
1447       if (access_fn == chrec_dont_know)
1448         /* No access_fn.  */
1449         return false;
1450
1451       init = initial_condition_in_loop_num (access_fn, loop->num);
1452       if (init == expr && !expr_invariant_in_loop_p (loop, init))
1453         /* Not enough information: may be not loop invariant.  
1454            E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its 
1455            initial_condition is D, but it depends on i - loop's induction
1456            variable.  */          
1457         return false;
1458
1459       evolution = evolution_part_in_loop_num (access_fn, loop->num);
1460       if (evolution && TREE_CODE (evolution) != INTEGER_CST)
1461         /* Evolution is not constant.  */
1462         return false;
1463
1464       if (TREE_CODE (init) == INTEGER_CST)
1465         *misalign = fold_convert (ssizetype, init);
1466       else
1467         /* Not constant, misalignment cannot be calculated.  */
1468         *misalign = NULL_TREE;
1469
1470       *initial_offset = fold_convert (ssizetype, init); 
1471
1472       *step = evolution ? fold_convert (ssizetype, evolution) : ssize_int (0);
1473       return true;      
1474     }
1475
1476   /* Recursive computation.  */
1477   if (!BINARY_CLASS_P (expr))
1478     {
1479       /* We expect to get binary expressions (PLUS/MINUS and MULT).  */
1480       if (vect_debug_details (UNKNOWN_LOC))
1481         {
1482           fprintf (dump_file, "Not binary expression ");
1483           print_generic_expr (dump_file, expr, TDF_SLIM);
1484         }
1485       return false;
1486     }
1487   oprnd0 = TREE_OPERAND (expr, 0);
1488   oprnd1 = TREE_OPERAND (expr, 1);
1489
1490   if (!vect_analyze_offset_expr (oprnd0, loop, vectype_alignment, &left_offset, 
1491                                 &left_misalign, &left_step)
1492       || !vect_analyze_offset_expr (oprnd1, loop, vectype_alignment, 
1493                                    &right_offset, &right_misalign, &right_step))
1494     return false;
1495
1496   /* The type of the operation: plus, minus or mult.  */
1497   code = TREE_CODE (expr);
1498   switch (code)
1499     {
1500     case MULT_EXPR:
1501       if (TREE_CODE (right_offset) != INTEGER_CST)
1502         /* RIGHT_OFFSET can be not constant. For example, for arrays of variable 
1503            sized types. 
1504            FORNOW: We don't support such cases.  */
1505         return false;
1506
1507       /* Strip conversions that don't narrow the mode.  */
1508       left_offset = vect_strip_conversion (left_offset);      
1509       if (!left_offset)
1510         return false;      
1511       /* Misalignment computation.  */
1512       if (SSA_VAR_P (left_offset))
1513         {
1514           /* If the left side contains variables that can't be substituted with 
1515              constants, we check if the right side is a multiple of ALIGNMENT.
1516            */
1517           if (integer_zerop (size_binop (TRUNC_MOD_EXPR, right_offset, 
1518                                   fold_convert (ssizetype, vectype_alignment))))
1519             *misalign = ssize_int (0);
1520           else
1521             /* If the remainder is not zero or the right side isn't constant,
1522                we can't compute  misalignment.  */
1523             *misalign = NULL_TREE;
1524         }
1525       else 
1526         {
1527           /* The left operand was successfully substituted with constant.  */     
1528           if (left_misalign)
1529             /* In case of EXPR '(i * C1 + j) * C2', LEFT_MISALIGN is 
1530                NULL_TREE.  */
1531             *misalign  = size_binop (code, left_misalign, right_misalign);
1532           else
1533             *misalign = NULL_TREE; 
1534         }
1535
1536       /* Step calculation.  */
1537       /* Multiply the step by the right operand.  */
1538       *step  = size_binop (MULT_EXPR, left_step, right_offset);
1539       break;
1540    
1541     case PLUS_EXPR:
1542     case MINUS_EXPR:
1543       /* Combine the recursive calculations for step and misalignment.  */
1544       *step = size_binop (code, left_step, right_step);
1545    
1546       if (left_misalign && right_misalign)
1547         *misalign  = size_binop (code, left_misalign, right_misalign);
1548       else
1549         *misalign = NULL_TREE;
1550     
1551       break;
1552
1553     default:
1554       gcc_unreachable ();
1555     }
1556
1557   /* Compute offset.  */
1558   *initial_offset = fold_convert (ssizetype, 
1559                                   fold (build2 (code, TREE_TYPE (left_offset), 
1560                                                 left_offset, 
1561                                                 right_offset)));
1562   return true;
1563 }
1564
1565
1566 /* Function vect_get_base_and_offset
1567
1568    Return the BASE of the data reference EXPR.
1569    If VECTYPE is given, also compute the INITIAL_OFFSET from BASE, MISALIGN and 
1570    STEP.
1571    E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset  
1572    'a.b[i] + 4B' from a (can be an expression), MISALIGN is an OFFSET 
1573    instantiated with initial_conditions of access_functions of variables, 
1574    modulo alignment, and STEP is the evolution of the DR_REF in this loop.
1575
1576    Function get_inner_reference is used for the above in case of ARRAY_REF and
1577    COMPONENT_REF.
1578
1579    Input:
1580    EXPR - the memory reference that is being analyzed
1581    DR - the data_reference struct of the _original_ memory reference
1582         (Note: DR_REF (DR) is not necessarily EXPR)
1583    VECTYPE - the type that defines the alignment (i.e, we compute
1584              alignment relative to TYPE_ALIGN(VECTYPE))
1585    
1586    Output:
1587    BASE (returned value) - the base of the data reference EXPR.
1588                            E.g, if EXPR is a.b[k].c[i][j] the returned
1589                            base is a.
1590    INITIAL_OFFSET - initial offset of EXPR from BASE (an expression)
1591    MISALIGN - offset of EXPR from BASE in bytes (a constant) or NULL_TREE if the
1592               computation is impossible
1593    STEP - evolution of the DR_REF in the loop
1594    BASE_ALIGNED_P - indicates if BASE is aligned
1595  
1596    If something unexpected is encountered (an unsupported form of data-ref),
1597    then NULL_TREE is returned.  */
1598
1599 static tree 
1600 vect_get_base_and_offset (struct data_reference *dr, 
1601                           tree expr, 
1602                           tree vectype, 
1603                           loop_vec_info loop_vinfo,
1604                           tree *initial_offset,
1605                           tree *misalign,
1606                           tree *step,
1607                           bool *base_aligned_p)
1608 {
1609   tree this_offset = ssize_int (0);
1610   tree this_misalign = ssize_int (0);
1611   tree this_step = ssize_int (0);
1612   tree base = NULL_TREE;
1613   tree next_ref;
1614   tree oprnd0, oprnd1;
1615   enum tree_code code = TREE_CODE (expr);
1616   HOST_WIDE_INT pbitsize;
1617   HOST_WIDE_INT pbitpos;
1618   tree poffset;
1619   enum machine_mode pmode;
1620   int punsignedp, pvolatilep;
1621   tree bit_pos_in_bytes;
1622   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1623
1624   *base_aligned_p = false;
1625
1626   switch (code)
1627     {
1628     /* These cases end the recursion:  */
1629     case VAR_DECL:
1630     case PARM_DECL:
1631       *initial_offset = ssize_int (0);
1632       *step = ssize_int (0);
1633       *misalign = ssize_int (0);
1634       if (DECL_ALIGN (expr) >= TYPE_ALIGN (vectype))
1635         *base_aligned_p = true;
1636       return expr;
1637
1638     case SSA_NAME:
1639       if (TREE_CODE (TREE_TYPE (expr)) != POINTER_TYPE)
1640         return NULL_TREE;
1641       
1642       if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))) < TYPE_ALIGN (vectype)) 
1643         {
1644           base = vect_get_ptr_offset (expr, vectype, misalign);
1645           if (base)
1646             *base_aligned_p = true;
1647         }
1648       else
1649         {         
1650           *base_aligned_p = true;
1651           *misalign = ssize_int (0);
1652         }
1653       *initial_offset = ssize_int (0);
1654       *step = ssize_int (0);
1655       return expr;
1656       
1657     case INTEGER_CST:      
1658       *initial_offset = fold_convert (ssizetype, expr);
1659       *misalign = fold_convert (ssizetype, expr);
1660       *step = ssize_int (0);
1661       return expr;
1662
1663     /* These cases continue the recursion:  */
1664     case ADDR_EXPR:
1665       oprnd0 = TREE_OPERAND (expr, 0);
1666       next_ref = oprnd0;
1667       break;
1668
1669     case INDIRECT_REF:
1670       oprnd0 = TREE_OPERAND (expr, 0);
1671       next_ref = oprnd0;
1672       break;
1673
1674     case PLUS_EXPR:
1675     case MINUS_EXPR:
1676       oprnd0 = TREE_OPERAND (expr, 0);
1677       oprnd1 = TREE_OPERAND (expr, 1);
1678
1679       /* In case we have a PLUS_EXPR of the form
1680          (oprnd0 + oprnd1), we assume that only oprnd0 determines the base.  
1681          This is verified in vect_get_memtag_and_dr.  */
1682       base = vect_get_base_and_offset (dr, oprnd1, vectype, loop_vinfo, 
1683                                        &this_offset, &this_misalign, 
1684                                        &this_step, base_aligned_p);  
1685       /* Offset was already computed in vect_analyze_pointer_ref_access.  */
1686       this_offset = ssize_int (0);
1687
1688       if (!base) 
1689         this_misalign = NULL_TREE;
1690       else
1691         this_misalign = size_binop (TREE_CODE (expr), ssize_int (0),
1692                                     this_misalign);
1693       next_ref = oprnd0;
1694       break;
1695
1696     default:
1697       if (!handled_component_p (expr))
1698         /* Unsupported expression.  */
1699         return NULL_TREE;
1700
1701       /* Find the base and the offset from it.  */
1702       next_ref = get_inner_reference (expr, &pbitsize, &pbitpos, &poffset,
1703                                       &pmode, &punsignedp, &pvolatilep, false);
1704       if (!next_ref)
1705         return NULL_TREE;
1706
1707       if (poffset 
1708           && !vect_analyze_offset_expr (poffset, loop, TYPE_SIZE_UNIT (vectype), 
1709                                         &this_offset, &this_misalign, 
1710                                         &this_step))
1711         {
1712           /* Failed to compute offset or step.  */
1713           *step = NULL_TREE;
1714           *initial_offset = NULL_TREE;
1715           *misalign = NULL_TREE;
1716           return NULL_TREE;
1717         }
1718
1719       /* Add bit position to OFFSET and MISALIGN.  */
1720
1721       bit_pos_in_bytes = ssize_int (pbitpos/BITS_PER_UNIT);
1722       /* Check that there is no remainder in bits.  */
1723       if (pbitpos%BITS_PER_UNIT)
1724         {
1725           if (vect_debug_details (UNKNOWN_LOC))
1726             fprintf (dump_file, "bit offset alignment.");
1727           return NULL_TREE;
1728         }
1729       this_offset = size_binop (PLUS_EXPR, bit_pos_in_bytes, 
1730                                 fold_convert (ssizetype, this_offset));     
1731       if (this_misalign) 
1732         this_misalign = size_binop (PLUS_EXPR, this_misalign, bit_pos_in_bytes); 
1733
1734       /* Continue the recursion to refine the base (get_inner_reference returns 
1735          &a for &a[i], and not a).  */
1736       break;
1737     }
1738
1739   base = vect_get_base_and_offset (dr, next_ref, vectype, loop_vinfo, 
1740                                    initial_offset, misalign, step, 
1741                                    base_aligned_p);  
1742   if (base)
1743     {
1744       /* Combine the results.  */
1745       if (this_misalign && *misalign)
1746         *misalign = size_binop (PLUS_EXPR, *misalign, this_misalign);
1747       else 
1748         *misalign = NULL_TREE;
1749
1750       *step = size_binop (PLUS_EXPR, *step, this_step);
1751
1752       *initial_offset = size_binop (PLUS_EXPR, *initial_offset, this_offset);
1753
1754       if (vect_debug_details (UNKNOWN_LOC))
1755         {
1756           print_generic_expr (dump_file, expr, TDF_SLIM);
1757           fprintf (dump_file, "\n --> total offset for ref: ");
1758           print_generic_expr (dump_file, *initial_offset, TDF_SLIM);
1759           fprintf (dump_file, "\n --> total misalign for ref: ");
1760           print_generic_expr (dump_file, *misalign, TDF_SLIM);
1761           fprintf (dump_file, "\n --> total step for ref: ");
1762           print_generic_expr (dump_file, *step, TDF_SLIM);
1763         }
1764     }    
1765   return base;
1766 }
1767
1768
1769 /* Function vect_force_dr_alignment_p.
1770
1771    Returns whether the alignment of a DECL can be forced to be aligned
1772    on ALIGNMENT bit boundary.  */
1773
1774 static bool 
1775 vect_can_force_dr_alignment_p (tree decl, unsigned int alignment)
1776 {
1777   if (TREE_CODE (decl) != VAR_DECL)
1778     return false;
1779
1780   if (DECL_EXTERNAL (decl))
1781     return false;
1782
1783   if (TREE_ASM_WRITTEN (decl))
1784     return false;
1785
1786   if (TREE_STATIC (decl))
1787     return (alignment <= MAX_OFILE_ALIGNMENT);
1788   else
1789     /* This is not 100% correct.  The absolute correct stack alignment
1790        is STACK_BOUNDARY.  We're supposed to hope, but not assume, that
1791        PREFERRED_STACK_BOUNDARY is honored by all translation units.
1792        However, until someone implements forced stack alignment, SSE
1793        isn't really usable without this.  */  
1794     return (alignment <= PREFERRED_STACK_BOUNDARY); 
1795 }
1796
1797
1798 /* Function vect_get_new_vect_var.
1799
1800    Returns a name for a new variable. The current naming scheme appends the 
1801    prefix "vect_" or "vect_p" (depending on the value of VAR_KIND) to 
1802    the name of vectorizer generated variables, and appends that to NAME if 
1803    provided.  */
1804
1805 static tree
1806 vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
1807 {
1808   const char *prefix;
1809   int prefix_len;
1810   tree new_vect_var;
1811
1812   if (var_kind == vect_simple_var)
1813     prefix = "vect_"; 
1814   else
1815     prefix = "vect_p";
1816
1817   prefix_len = strlen (prefix);
1818
1819   if (name)
1820     new_vect_var = create_tmp_var (type, concat (prefix, name, NULL));
1821   else
1822     new_vect_var = create_tmp_var (type, prefix);
1823
1824   return new_vect_var;
1825 }
1826
1827
1828 /* Function vect_create_index_for_vector_ref.
1829
1830    Create (and return) an index variable, along with it's update chain in the
1831    loop. This variable will be used to access a memory location in a vector
1832    operation.
1833
1834    Input:
1835    LOOP: The loop being vectorized.
1836    BSI: The block_stmt_iterator where STMT is. Any new stmts created by this
1837         function can be added here, or in the loop pre-header.
1838
1839    Output:
1840    Return an index that will be used to index a vector array.  It is expected
1841    that a pointer to the first vector will be used as the base address for the
1842    indexed reference.
1843
1844    FORNOW: we are not trying to be efficient, just creating a new index each
1845    time from scratch.  At this time all vector references could use the same
1846    index.
1847
1848    TODO: create only one index to be used by all vector references.  Record
1849    the index in the LOOP_VINFO the first time this procedure is called and
1850    return it on subsequent calls.  The increment of this index must be placed
1851    just before the conditional expression that ends the single block loop.  */
1852
1853 static tree
1854 vect_create_index_for_vector_ref (loop_vec_info loop_vinfo)
1855 {
1856   tree init, step;
1857   block_stmt_iterator incr_bsi;
1858   bool insert_after;
1859   tree indx_before_incr, indx_after_incr;
1860   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1861   tree incr;
1862
1863   /* It is assumed that the base pointer used for vectorized access contains
1864      the address of the first vector.  Therefore the index used for vectorized
1865      access must be initialized to zero and incremented by 1.  */
1866
1867   init = integer_zero_node;
1868   step = integer_one_node;
1869
1870   standard_iv_increment_position (loop, &incr_bsi, &insert_after);
1871   create_iv (init, step, NULL_TREE, loop, &incr_bsi, insert_after,
1872         &indx_before_incr, &indx_after_incr);
1873   incr = bsi_stmt (incr_bsi);
1874   get_stmt_operands (incr);
1875   set_stmt_info (stmt_ann (incr), new_stmt_vec_info (incr, loop_vinfo));
1876
1877   return indx_before_incr;
1878 }
1879
1880
1881 /* Function vect_create_addr_base_for_vector_ref.
1882
1883    Create an expression that computes the address of the first memory location
1884    that will be accessed for a data reference.
1885
1886    Input:
1887    STMT: The statement containing the data reference.
1888    NEW_STMT_LIST: Must be initialized to NULL_TREE or a statement list.
1889    OFFSET: Optional. If supplied, it is be added to the initial address.
1890
1891    Output:
1892    1. Return an SSA_NAME whose value is the address of the memory location of 
1893       the first vector of the data reference.
1894    2. If new_stmt_list is not NULL_TREE after return then the caller must insert
1895       these statement(s) which define the returned SSA_NAME.
1896
1897    FORNOW: We are only handling array accesses with step 1.  */
1898
1899 static tree
1900 vect_create_addr_base_for_vector_ref (tree stmt,
1901                                       tree *new_stmt_list,
1902                                       tree offset)
1903 {
1904   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1905   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1906   tree data_ref_base = unshare_expr (STMT_VINFO_VECT_DR_BASE (stmt_info));
1907   tree base_name = unshare_expr (DR_BASE_NAME (dr));
1908   tree ref = DR_REF (dr);
1909   tree scalar_type = TREE_TYPE (ref);
1910   tree scalar_ptr_type = build_pointer_type (scalar_type);
1911   tree vec_stmt;
1912   tree new_temp;
1913   tree addr_base, addr_expr;
1914   tree dest, new_stmt;
1915   tree base_offset = unshare_expr (STMT_VINFO_VECT_INIT_OFFSET (stmt_info));
1916
1917   if (TREE_CODE (TREE_TYPE (data_ref_base)) != POINTER_TYPE)
1918     /* After the analysis stage, we expect to get here only with RECORD_TYPE
1919        and ARRAY_TYPE. */
1920     /* Add '&' to ref_base.  */
1921     data_ref_base = build_fold_addr_expr (data_ref_base);
1922   else
1923     {
1924       /* Create '(scalar_type*) base' for pointers.  */
1925       tree dest, new_stmt, new_temp, vec_stmt, tmp_base;
1926       tree scalar_array_type = build_array_type (scalar_type, 0);
1927       tree scalar_array_ptr_type = build_pointer_type (scalar_array_type);
1928       tree array_ptr = create_tmp_var (scalar_array_ptr_type, "array_ptr");
1929       add_referenced_tmp_var (array_ptr);
1930
1931       dest = create_tmp_var (TREE_TYPE (data_ref_base), "dataref");
1932       add_referenced_tmp_var (dest);
1933       tmp_base = force_gimple_operand (data_ref_base, &new_stmt, false, dest);  
1934       append_to_statement_list_force (new_stmt,  new_stmt_list);
1935       
1936       vec_stmt = fold_convert (scalar_array_ptr_type, tmp_base);
1937       vec_stmt = build2 (MODIFY_EXPR, void_type_node, array_ptr, vec_stmt);
1938       new_temp = make_ssa_name (array_ptr, vec_stmt);
1939       TREE_OPERAND (vec_stmt, 0) = new_temp;
1940       append_to_statement_list_force (vec_stmt,  new_stmt_list);
1941       data_ref_base = new_temp;
1942     }
1943
1944   /* Create base_offset */
1945   dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
1946   add_referenced_tmp_var (dest);
1947   base_offset = force_gimple_operand (base_offset, &new_stmt, false, dest);  
1948   append_to_statement_list_force (new_stmt, new_stmt_list);
1949
1950   if (offset)
1951     {
1952       tree tmp = create_tmp_var (TREE_TYPE (base_offset), "offset");
1953       add_referenced_tmp_var (tmp);
1954       offset = fold (build2 (MULT_EXPR, TREE_TYPE (offset), offset, 
1955                              STMT_VINFO_VECT_STEP (stmt_info)));
1956       base_offset = fold (build2 (PLUS_EXPR, TREE_TYPE (base_offset), 
1957                                   base_offset, offset));
1958       base_offset = force_gimple_operand (base_offset, &new_stmt, false, tmp);  
1959       append_to_statement_list_force (new_stmt, new_stmt_list);
1960     }
1961   
1962   /* base + base_offset */
1963   addr_base = fold (build2 (PLUS_EXPR, TREE_TYPE (data_ref_base), data_ref_base, 
1964                             base_offset));
1965
1966   /* addr_expr = addr_base */
1967   addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var,
1968                                      get_name (base_name));
1969   add_referenced_tmp_var (addr_expr);
1970   vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, addr_base);
1971   new_temp = make_ssa_name (addr_expr, vec_stmt);
1972   TREE_OPERAND (vec_stmt, 0) = new_temp;
1973   append_to_statement_list_force (vec_stmt, new_stmt_list);
1974
1975   if (vect_debug_details (UNKNOWN_LOC))
1976     {
1977       fprintf (dump_file, "created ");
1978       print_generic_expr (dump_file, vec_stmt, TDF_SLIM);
1979       fprintf (dump_file, "\n");
1980     }
1981   return new_temp;
1982 }
1983
1984
1985 /* Function get_vectype_for_scalar_type.
1986
1987    Returns the vector type corresponding to SCALAR_TYPE as supported
1988    by the target.  */
1989
1990 static tree
1991 get_vectype_for_scalar_type (tree scalar_type)
1992 {
1993   enum machine_mode inner_mode = TYPE_MODE (scalar_type);
1994   int nbytes = GET_MODE_SIZE (inner_mode);
1995   int nunits;
1996   tree vectype;
1997
1998   if (nbytes == 0)
1999     return NULL_TREE;
2000
2001   /* FORNOW: Only a single vector size per target (UNITS_PER_SIMD_WORD)
2002      is expected.  */
2003   nunits = UNITS_PER_SIMD_WORD / nbytes;
2004
2005   vectype = build_vector_type (scalar_type, nunits);
2006   if (vect_debug_details (UNKNOWN_LOC))
2007     {
2008       fprintf (dump_file, "get vectype with %d units of type ", nunits);
2009       print_generic_expr (dump_file, scalar_type, TDF_SLIM);
2010     }
2011
2012   if (!vectype)
2013     return NULL_TREE;
2014
2015   if (vect_debug_details (UNKNOWN_LOC))
2016     {
2017       fprintf (dump_file, "vectype: ");
2018       print_generic_expr (dump_file, vectype, TDF_SLIM);
2019     }
2020
2021   if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
2022     {
2023       /* TODO: tree-complex.c sometimes can parallelize operations
2024          on generic vectors.  We can vectorize the loop in that case,
2025          but then we should re-run the lowering pass.  */
2026       if (vect_debug_details (UNKNOWN_LOC))
2027         fprintf (dump_file, "mode not supported by target.");
2028       return NULL_TREE;
2029     }
2030
2031   return vectype;
2032 }
2033
2034
2035 /* Function vect_align_data_ref.
2036
2037    Handle mislignment of a memory accesses.
2038
2039    FORNOW: Can't handle misaligned accesses. 
2040    Make sure that the dataref is aligned.  */
2041
2042 static void
2043 vect_align_data_ref (tree stmt)
2044 {
2045   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2046   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2047
2048   /* FORNOW: can't handle misaligned accesses; 
2049              all accesses expected to be aligned.  */
2050   gcc_assert (aligned_access_p (dr));
2051 }
2052
2053
2054 /* Function vect_create_data_ref_ptr.
2055
2056    Create a memory reference expression for vector access, to be used in a
2057    vector load/store stmt. The reference is based on a new pointer to vector
2058    type (vp).
2059
2060    Input:
2061    1. STMT: a stmt that references memory. Expected to be of the form
2062          MODIFY_EXPR <name, data-ref> or MODIFY_EXPR <data-ref, name>.
2063    2. BSI: block_stmt_iterator where new stmts can be added.
2064    3. OFFSET (optional): an offset to be added to the initial address accessed
2065         by the data-ref in STMT.
2066    4. ONLY_INIT: indicate if vp is to be updated in the loop, or remain
2067         pointing to the initial address.
2068
2069    Output:
2070    1. Declare a new ptr to vector_type, and have it point to the base of the
2071       data reference (initial addressed accessed by the data reference).
2072       For example, for vector of type V8HI, the following code is generated:
2073
2074       v8hi *vp;
2075       vp = (v8hi *)initial_address;
2076
2077       if OFFSET is not supplied:
2078          initial_address = &a[init];
2079       if OFFSET is supplied:
2080          initial_address = &a[init + OFFSET];
2081
2082       Return the initial_address in INITIAL_ADDRESS.
2083
2084    2. Create a data-reference in the loop based on the new vector pointer vp,
2085       and using a new index variable 'idx' as follows:
2086
2087       vp' = vp + update
2088
2089       where if ONLY_INIT is true:
2090          update = zero
2091       and otherwise
2092          update = idx + vector_type_size
2093
2094       Return the pointer vp'.
2095
2096
2097    FORNOW: handle only aligned and consecutive accesses.  */
2098
2099 static tree
2100 vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
2101                           tree *initial_address, bool only_init)
2102 {
2103   tree base_name;
2104   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2105   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2106   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2107   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2108   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2109   tree vect_ptr_type;
2110   tree vect_ptr;
2111   tree tag;
2112   v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
2113   v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
2114   vuse_optype vuses = STMT_VUSE_OPS (stmt);
2115   int nvuses, nv_may_defs, nv_must_defs;
2116   int i;
2117   tree new_temp;
2118   tree vec_stmt;
2119   tree new_stmt_list = NULL_TREE;
2120   tree idx;
2121   edge pe = loop_preheader_edge (loop);
2122   basic_block new_bb;
2123   tree vect_ptr_init;
2124   tree vectype_size;
2125   tree ptr_update;
2126   tree data_ref_ptr;
2127   tree type, tmp, size;
2128
2129   base_name = unshare_expr (DR_BASE_NAME (dr));
2130   if (vect_debug_details (UNKNOWN_LOC))
2131     {
2132       tree data_ref_base = base_name;
2133       fprintf (dump_file, "create array_ref of type: ");
2134       print_generic_expr (dump_file, vectype, TDF_SLIM);
2135       if (TREE_CODE (data_ref_base) == VAR_DECL)
2136         fprintf (dump_file, "\nvectorizing a one dimensional array ref: ");
2137       else if (TREE_CODE (data_ref_base) == ARRAY_REF)
2138         fprintf (dump_file, "\nvectorizing a multidimensional array ref: ");
2139       else if (TREE_CODE (data_ref_base) == COMPONENT_REF)
2140         fprintf (dump_file, "\nvectorizing a record based array ref: ");
2141       else if (TREE_CODE (data_ref_base) == SSA_NAME)
2142         fprintf (dump_file, "\nvectorizing a pointer ref: ");
2143       print_generic_expr (dump_file, base_name, TDF_SLIM);
2144     }
2145
2146   /** (1) Create the new vector-pointer variable:  **/
2147
2148   vect_ptr_type = build_pointer_type (vectype);
2149   vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
2150                                     get_name (base_name));
2151   add_referenced_tmp_var (vect_ptr);
2152   
2153   
2154   /** (2) Handle aliasing information of the new vector-pointer:  **/
2155   
2156   tag = STMT_VINFO_MEMTAG (stmt_info);
2157   gcc_assert (tag);
2158   get_var_ann (vect_ptr)->type_mem_tag = tag;
2159   
2160   /* Mark for renaming all aliased variables
2161      (i.e, the may-aliases of the type-mem-tag).  */
2162   nvuses = NUM_VUSES (vuses);
2163   nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
2164   nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
2165   for (i = 0; i < nvuses; i++)
2166     {
2167       tree use = VUSE_OP (vuses, i);
2168       if (TREE_CODE (use) == SSA_NAME)
2169         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
2170     }
2171   for (i = 0; i < nv_may_defs; i++)
2172     {
2173       tree def = V_MAY_DEF_RESULT (v_may_defs, i);
2174       if (TREE_CODE (def) == SSA_NAME)
2175         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
2176     }
2177   for (i = 0; i < nv_must_defs; i++)
2178     {
2179       tree def = V_MUST_DEF_RESULT (v_must_defs, i);
2180       if (TREE_CODE (def) == SSA_NAME)
2181         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
2182     }
2183
2184
2185   /** (3) Calculate the initial address the vector-pointer, and set
2186           the vector-pointer to point to it before the loop:  **/
2187
2188   /* Create: (&(base[init_val+offset]) in the loop preheader.  */
2189   new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
2190                                                    offset);
2191   pe = loop_preheader_edge (loop);
2192   new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list);
2193   gcc_assert (!new_bb);
2194   *initial_address = new_temp;
2195
2196   /* Create: p = (vectype *) initial_base  */
2197   vec_stmt = fold_convert (vect_ptr_type, new_temp);
2198   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
2199   new_temp = make_ssa_name (vect_ptr, vec_stmt);
2200   TREE_OPERAND (vec_stmt, 0) = new_temp;
2201   new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt);
2202   gcc_assert (!new_bb);
2203   vect_ptr_init = TREE_OPERAND (vec_stmt, 0);
2204
2205
2206   /** (4) Handle the updating of the vector-pointer inside the loop: **/
2207
2208   if (only_init) /* No update in loop is required.  */
2209     return vect_ptr_init;
2210
2211   idx = vect_create_index_for_vector_ref (loop_vinfo);
2212
2213   /* Create: update = idx * vectype_size  */
2214   tmp = create_tmp_var (integer_type_node, "update");
2215   add_referenced_tmp_var (tmp);
2216   size = TYPE_SIZE (vect_ptr_type); 
2217   type = lang_hooks.types.type_for_size (tree_low_cst (size, 1), 1);
2218   ptr_update = create_tmp_var (type, "update");
2219   add_referenced_tmp_var (ptr_update);
2220   vectype_size = TYPE_SIZE_UNIT (vectype);
2221   vec_stmt = build2 (MULT_EXPR, integer_type_node, idx, vectype_size);
2222   vec_stmt = build2 (MODIFY_EXPR, void_type_node, tmp, vec_stmt);
2223   new_temp = make_ssa_name (tmp, vec_stmt);
2224   TREE_OPERAND (vec_stmt, 0) = new_temp;
2225   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
2226   vec_stmt = fold_convert (type, new_temp);
2227   vec_stmt = build2 (MODIFY_EXPR, void_type_node, ptr_update, vec_stmt);
2228   new_temp = make_ssa_name (ptr_update, vec_stmt);
2229   TREE_OPERAND (vec_stmt, 0) = new_temp;
2230   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
2231
2232   /* Create: data_ref_ptr = vect_ptr_init + update  */
2233   vec_stmt = build2 (PLUS_EXPR, vect_ptr_type, vect_ptr_init, new_temp);
2234   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
2235   new_temp = make_ssa_name (vect_ptr, vec_stmt);
2236   TREE_OPERAND (vec_stmt, 0) = new_temp;
2237   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
2238   data_ref_ptr = TREE_OPERAND (vec_stmt, 0);
2239
2240   return data_ref_ptr;
2241 }
2242
2243
2244 /* Function vect_create_destination_var.
2245
2246    Create a new temporary of type VECTYPE.  */
2247
2248 static tree
2249 vect_create_destination_var (tree scalar_dest, tree vectype)
2250 {
2251   tree vec_dest;
2252   const char *new_name;
2253
2254   gcc_assert (TREE_CODE (scalar_dest) == SSA_NAME);
2255
2256   new_name = get_name (scalar_dest);
2257   if (!new_name)
2258     new_name = "var_";
2259   vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, new_name);
2260   add_referenced_tmp_var (vec_dest);
2261
2262   return vec_dest;
2263 }
2264
2265
2266 /* Function vect_init_vector.
2267
2268    Insert a new stmt (INIT_STMT) that initializes a new vector variable with
2269    the vector elements of VECTOR_VAR. Return the DEF of INIT_STMT. It will be
2270    used in the vectorization of STMT.  */
2271
2272 static tree
2273 vect_init_vector (tree stmt, tree vector_var)
2274 {
2275   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
2276   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
2277   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2278   tree new_var;
2279   tree init_stmt;
2280   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); 
2281   tree vec_oprnd;
2282   edge pe;
2283   tree new_temp;
2284   basic_block new_bb;
2285  
2286   new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_");
2287   add_referenced_tmp_var (new_var); 
2288  
2289   init_stmt = build2 (MODIFY_EXPR, vectype, new_var, vector_var);
2290   new_temp = make_ssa_name (new_var, init_stmt);
2291   TREE_OPERAND (init_stmt, 0) = new_temp;
2292
2293   pe = loop_preheader_edge (loop);
2294   new_bb = bsi_insert_on_edge_immediate (pe, init_stmt);
2295   gcc_assert (!new_bb);
2296
2297   if (vect_debug_details (UNKNOWN_LOC))
2298     {
2299       fprintf (dump_file, "created new init_stmt: ");
2300       print_generic_expr (dump_file, init_stmt, TDF_SLIM);
2301     }
2302
2303   vec_oprnd = TREE_OPERAND (init_stmt, 0);
2304   return vec_oprnd;
2305 }
2306
2307
2308 /* Function vect_get_vec_def_for_operand.
2309
2310    OP is an operand in STMT. This function returns a (vector) def that will be
2311    used in the vectorized stmt for STMT.
2312
2313    In the case that OP is an SSA_NAME which is defined in the loop, then
2314    STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
2315
2316    In case OP is an invariant or constant, a new stmt that creates a vector def
2317    needs to be introduced.  */
2318
2319 static tree
2320 vect_get_vec_def_for_operand (tree op, tree stmt)
2321 {
2322   tree vec_oprnd;
2323   tree vec_stmt;
2324   tree def_stmt;
2325   stmt_vec_info def_stmt_info = NULL;
2326   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
2327   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
2328   int nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
2329   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
2330   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2331   basic_block bb;
2332   tree vec_inv;
2333   tree t = NULL_TREE;
2334   tree def;
2335   int i;
2336
2337   if (vect_debug_details (UNKNOWN_LOC))
2338     {
2339       fprintf (dump_file, "vect_get_vec_def_for_operand: ");
2340       print_generic_expr (dump_file, op, TDF_SLIM);
2341     }
2342
2343   /** ===> Case 1: operand is a constant.  **/
2344
2345   if (TREE_CODE (op) == INTEGER_CST || TREE_CODE (op) == REAL_CST)
2346     {
2347       /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
2348
2349       tree vec_cst;
2350
2351       /* Build a tree with vector elements.  */
2352       if (vect_debug_details (UNKNOWN_LOC))
2353         fprintf (dump_file, "Create vector_cst. nunits = %d", nunits);
2354
2355       for (i = nunits - 1; i >= 0; --i)
2356         {
2357           t = tree_cons (NULL_TREE, op, t);
2358         }
2359       vec_cst = build_vector (vectype, t);
2360       return vect_init_vector (stmt, vec_cst);
2361     }
2362
2363   gcc_assert (TREE_CODE (op) == SSA_NAME);
2364  
2365   /** ===> Case 2: operand is an SSA_NAME - find the stmt that defines it.  **/
2366
2367   def_stmt = SSA_NAME_DEF_STMT (op);
2368   def_stmt_info = vinfo_for_stmt (def_stmt);
2369
2370   if (vect_debug_details (UNKNOWN_LOC))
2371     {
2372       fprintf (dump_file, "vect_get_vec_def_for_operand: def_stmt: ");
2373       print_generic_expr (dump_file, def_stmt, TDF_SLIM);
2374     }
2375
2376
2377   /** ==> Case 2.1: operand is defined inside the loop.  **/
2378
2379   if (def_stmt_info)
2380     {
2381       /* Get the def from the vectorized stmt.  */
2382
2383       vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
2384       gcc_assert (vec_stmt);
2385       vec_oprnd = TREE_OPERAND (vec_stmt, 0);
2386       return vec_oprnd;
2387     }
2388
2389
2390   /** ==> Case 2.2: operand is defined by the loop-header phi-node - 
2391                     it is a reduction/induction.  **/
2392
2393   bb = bb_for_stmt (def_stmt);
2394   if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
2395     {
2396       if (vect_debug_details (UNKNOWN_LOC))
2397         fprintf (dump_file, "reduction/induction - unsupported.");
2398       internal_error ("no support for reduction/induction"); /* FORNOW */
2399     }
2400
2401
2402   /** ==> Case 2.3: operand is defined outside the loop - 
2403                     it is a loop invariant.  */
2404
2405   switch (TREE_CODE (def_stmt))
2406     {
2407     case PHI_NODE:
2408       def = PHI_RESULT (def_stmt);
2409       break;
2410     case MODIFY_EXPR:
2411       def = TREE_OPERAND (def_stmt, 0);
2412       break;
2413     case NOP_EXPR:
2414       def = TREE_OPERAND (def_stmt, 0);
2415       gcc_assert (IS_EMPTY_STMT (def_stmt));
2416       def = op;
2417       break;
2418     default:
2419       if (vect_debug_details (UNKNOWN_LOC))
2420         {
2421           fprintf (dump_file, "unsupported defining stmt: ");
2422           print_generic_expr (dump_file, def_stmt, TDF_SLIM);
2423         }
2424       internal_error ("unsupported defining stmt");
2425     }
2426
2427   /* Build a tree with vector elements. Create 'vec_inv = {inv,inv,..,inv}'  */
2428
2429   if (vect_debug_details (UNKNOWN_LOC))
2430     fprintf (dump_file, "Create vector_inv.");
2431
2432   for (i = nunits - 1; i >= 0; --i)
2433     {
2434       t = tree_cons (NULL_TREE, def, t);
2435     }
2436
2437   vec_inv = build_constructor (vectype, t);
2438   return vect_init_vector (stmt, vec_inv);
2439 }
2440
2441
2442 /* Function vect_finish_stmt_generation.
2443
2444    Insert a new stmt.  */
2445
2446 static void
2447 vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi)
2448 {
2449   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
2450
2451   if (vect_debug_details (UNKNOWN_LOC))
2452     {
2453       fprintf (dump_file, "add new stmt: ");
2454       print_generic_expr (dump_file, vec_stmt, TDF_SLIM);
2455     }
2456
2457 #ifdef ENABLE_CHECKING
2458   /* Make sure bsi points to the stmt that is being vectorized.  */
2459   gcc_assert (stmt == bsi_stmt (*bsi));
2460 #endif
2461
2462 #ifdef USE_MAPPED_LOCATION
2463   SET_EXPR_LOCATION (vec_stmt, EXPR_LOCUS (stmt));
2464 #else
2465   SET_EXPR_LOCUS (vec_stmt, EXPR_LOCUS (stmt));
2466 #endif
2467 }
2468
2469
2470 /* Function vectorizable_assignment.
2471
2472    Check if STMT performs an assignment (copy) that can be vectorized. 
2473    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2474    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2475    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2476
2477 static bool
2478 vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2479 {
2480   tree vec_dest;
2481   tree scalar_dest;
2482   tree op;
2483   tree vec_oprnd;
2484   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2485   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2486   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2487   tree new_temp;
2488
2489   /* Is vectorizable assignment?  */
2490
2491   if (TREE_CODE (stmt) != MODIFY_EXPR)
2492     return false;
2493
2494   scalar_dest = TREE_OPERAND (stmt, 0);
2495   if (TREE_CODE (scalar_dest) != SSA_NAME)
2496     return false;
2497
2498   op = TREE_OPERAND (stmt, 1);
2499   if (!vect_is_simple_use (op, loop_vinfo, NULL))
2500     {
2501       if (vect_debug_details (UNKNOWN_LOC))
2502         fprintf (dump_file, "use not simple.");
2503       return false;
2504     }
2505
2506   if (!vec_stmt) /* transformation not required.  */
2507     {
2508       STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
2509       return true;
2510     }
2511
2512   /** Transform.  **/
2513   if (vect_debug_details (UNKNOWN_LOC))
2514     fprintf (dump_file, "transform assignment.");
2515
2516   /* Handle def.  */
2517   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2518
2519   /* Handle use.  */
2520   op = TREE_OPERAND (stmt, 1);
2521   vec_oprnd = vect_get_vec_def_for_operand (op, stmt);
2522
2523   /* Arguments are ready. create the new vector stmt.  */
2524   *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_oprnd);
2525   new_temp = make_ssa_name (vec_dest, *vec_stmt);
2526   TREE_OPERAND (*vec_stmt, 0) = new_temp;
2527   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2528   
2529   return true;
2530 }
2531
2532
2533 /* Function vectorizable_operation.
2534
2535    Check if STMT performs a binary or unary operation that can be vectorized. 
2536    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2537    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2538    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2539
2540 static bool
2541 vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2542 {
2543   tree vec_dest;
2544   tree scalar_dest;
2545   tree operation;
2546   tree op0, op1 = NULL;
2547   tree vec_oprnd0, vec_oprnd1=NULL;
2548   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2549   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2550   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2551   int i;
2552   enum tree_code code;
2553   enum machine_mode vec_mode;
2554   tree new_temp;
2555   int op_type;
2556   tree op;
2557   optab optab;
2558
2559   /* Is STMT a vectorizable binary/unary operation?   */
2560   if (TREE_CODE (stmt) != MODIFY_EXPR)
2561     return false;
2562
2563   if (TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
2564     return false;
2565
2566   operation = TREE_OPERAND (stmt, 1);
2567   code = TREE_CODE (operation);
2568   optab = optab_for_tree_code (code, vectype);
2569
2570   /* Support only unary or binary operations.  */
2571   op_type = TREE_CODE_LENGTH (code);
2572   if (op_type != unary_op && op_type != binary_op)
2573     {
2574       if (vect_debug_details (UNKNOWN_LOC))
2575         fprintf (dump_file, "num. args = %d (not unary/binary op).", op_type);
2576       return false;
2577     }
2578
2579   for (i = 0; i < op_type; i++)
2580     {
2581       op = TREE_OPERAND (operation, i);
2582       if (!vect_is_simple_use (op, loop_vinfo, NULL))
2583         {
2584           if (vect_debug_details (UNKNOWN_LOC))
2585             fprintf (dump_file, "use not simple.");
2586           return false;
2587         }       
2588     } 
2589
2590   /* Supportable by target?  */
2591   if (!optab)
2592     {
2593       if (vect_debug_details (UNKNOWN_LOC))
2594         fprintf (dump_file, "no optab.");
2595       return false;
2596     }
2597   vec_mode = TYPE_MODE (vectype);
2598   if (optab->handlers[(int) vec_mode].insn_code == CODE_FOR_nothing)
2599     {
2600       if (vect_debug_details (UNKNOWN_LOC))
2601         fprintf (dump_file, "op not supported by target.");
2602       return false;
2603     }
2604
2605   if (!vec_stmt) /* transformation not required.  */
2606     {
2607       STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
2608       return true;
2609     }
2610
2611   /** Transform.  **/
2612
2613   if (vect_debug_details (UNKNOWN_LOC))
2614     fprintf (dump_file, "transform binary/unary operation.");
2615
2616   /* Handle def.  */
2617   scalar_dest = TREE_OPERAND (stmt, 0);
2618   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2619
2620   /* Handle uses.  */
2621   op0 = TREE_OPERAND (operation, 0);
2622   vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
2623
2624   if (op_type == binary_op)
2625     {
2626       op1 = TREE_OPERAND (operation, 1);
2627       vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt); 
2628     }
2629
2630   /* Arguments are ready. create the new vector stmt.  */
2631
2632   if (op_type == binary_op)
2633     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
2634                 build2 (code, vectype, vec_oprnd0, vec_oprnd1));
2635   else
2636     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
2637                 build1 (code, vectype, vec_oprnd0));
2638   new_temp = make_ssa_name (vec_dest, *vec_stmt);
2639   TREE_OPERAND (*vec_stmt, 0) = new_temp;
2640   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2641
2642   return true;
2643 }
2644
2645
2646 /* Function vectorizable_store.
2647
2648    Check if STMT defines a non scalar data-ref (array/pointer/structure) that 
2649    can be vectorized. 
2650    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2651    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2652    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2653
2654 static bool
2655 vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2656 {
2657   tree scalar_dest;
2658   tree data_ref;
2659   tree op;
2660   tree vec_oprnd1;
2661   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2662   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2663   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2664   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2665   enum machine_mode vec_mode;
2666   tree dummy;
2667   enum dr_alignment_support alignment_support_cheme;
2668
2669   /* Is vectorizable store? */
2670
2671   if (TREE_CODE (stmt) != MODIFY_EXPR)
2672     return false;
2673
2674   scalar_dest = TREE_OPERAND (stmt, 0);
2675   if (TREE_CODE (scalar_dest) != ARRAY_REF
2676       && TREE_CODE (scalar_dest) != INDIRECT_REF)
2677     return false;
2678
2679   op = TREE_OPERAND (stmt, 1);
2680   if (!vect_is_simple_use (op, loop_vinfo, NULL))
2681     {
2682       if (vect_debug_details (UNKNOWN_LOC))
2683         fprintf (dump_file, "use not simple.");
2684       return false;
2685     }
2686
2687   vec_mode = TYPE_MODE (vectype);
2688   /* FORNOW. In some cases can vectorize even if data-type not supported
2689      (e.g. - array initialization with 0).  */
2690   if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing)
2691     return false;
2692
2693   if (!STMT_VINFO_DATA_REF (stmt_info))
2694     return false;
2695
2696
2697   if (!vec_stmt) /* transformation not required.  */
2698     {
2699       STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
2700       return true;
2701     }
2702
2703   /** Transform.  **/
2704
2705   if (vect_debug_details (UNKNOWN_LOC))
2706     fprintf (dump_file, "transform store");
2707
2708   alignment_support_cheme = vect_supportable_dr_alignment (dr);
2709   gcc_assert (alignment_support_cheme);
2710   gcc_assert (alignment_support_cheme = dr_aligned);  /* FORNOW */
2711
2712   /* Handle use - get the vectorized def from the defining stmt.  */
2713   vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt);
2714
2715   /* Handle def.  */
2716   /* FORNOW: make sure the data reference is aligned.  */
2717   vect_align_data_ref (stmt);
2718   data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
2719   data_ref = build_fold_indirect_ref (data_ref);
2720
2721   /* Arguments are ready. create the new vector stmt.  */
2722   *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
2723   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2724
2725   return true;
2726 }
2727
2728
2729 /* vectorizable_load.
2730
2731    Check if STMT reads a non scalar data-ref (array/pointer/structure) that 
2732    can be vectorized. 
2733    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2734    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2735    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2736
2737 static bool
2738 vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2739 {
2740   tree scalar_dest;
2741   tree vec_dest = NULL;
2742   tree data_ref = NULL;
2743   tree op;
2744   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2745   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2746   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2747   tree new_temp;
2748   int mode;
2749   tree init_addr;
2750   tree new_stmt;
2751   tree dummy;
2752   basic_block new_bb;
2753   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2754   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2755   edge pe = loop_preheader_edge (loop);
2756   enum dr_alignment_support alignment_support_cheme;
2757
2758   /* Is vectorizable load? */
2759
2760   if (TREE_CODE (stmt) != MODIFY_EXPR)
2761     return false;
2762
2763   scalar_dest = TREE_OPERAND (stmt, 0);
2764   if (TREE_CODE (scalar_dest) != SSA_NAME)
2765     return false;
2766
2767   op = TREE_OPERAND (stmt, 1);
2768   if (TREE_CODE (op) != ARRAY_REF && TREE_CODE (op) != INDIRECT_REF)
2769     return false;
2770
2771   if (!STMT_VINFO_DATA_REF (stmt_info))
2772     return false;
2773
2774   mode = (int) TYPE_MODE (vectype);
2775
2776   /* FORNOW. In some cases can vectorize even if data-type not supported
2777     (e.g. - data copies).  */
2778   if (mov_optab->handlers[mode].insn_code == CODE_FOR_nothing)
2779     {
2780       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
2781         fprintf (dump_file, "Aligned load, but unsupported type.");
2782       return false;
2783     }
2784
2785   if (!vec_stmt) /* transformation not required.  */
2786     {
2787       STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
2788       return true;
2789     }
2790
2791   /** Transform.  **/
2792
2793   if (vect_debug_details (UNKNOWN_LOC))
2794     fprintf (dump_file, "transform load.");
2795
2796   alignment_support_cheme = vect_supportable_dr_alignment (dr);
2797   gcc_assert (alignment_support_cheme);
2798
2799   if (alignment_support_cheme == dr_aligned
2800       || alignment_support_cheme == dr_unaligned_supported)
2801     {
2802       /* Create:
2803          p = initial_addr;
2804          indx = 0;
2805          loop {
2806            vec_dest = *(p);
2807            indx = indx + 1;
2808          }
2809       */
2810
2811       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2812       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
2813       if (aligned_access_p (dr))
2814         data_ref = build_fold_indirect_ref (data_ref);
2815       else
2816         {
2817           int mis = DR_MISALIGNMENT (dr);
2818           tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
2819           tmis = size_binop (MULT_EXPR, tmis, size_int(BITS_PER_UNIT));
2820           data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, data_ref, tmis);
2821         }
2822       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2823       new_temp = make_ssa_name (vec_dest, new_stmt);
2824       TREE_OPERAND (new_stmt, 0) = new_temp;
2825       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2826     }
2827   else if (alignment_support_cheme == dr_unaligned_software_pipeline)
2828     {
2829       /* Create:
2830          p1 = initial_addr;
2831          msq_init = *(floor(p1))
2832          p2 = initial_addr + VS - 1;
2833          magic = have_builtin ? builtin_result : initial_address;
2834          indx = 0;
2835          loop {
2836            p2' = p2 + indx * vectype_size
2837            lsq = *(floor(p2'))
2838            vec_dest = realign_load (msq, lsq, magic)
2839            indx = indx + 1;
2840            msq = lsq;
2841          }
2842       */
2843
2844       tree offset;
2845       tree magic;
2846       tree phi_stmt;
2847       tree msq_init;
2848       tree msq, lsq;
2849       tree dataref_ptr;
2850       tree params;
2851
2852       /* <1> Create msq_init = *(floor(p1)) in the loop preheader  */
2853       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2854       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, 
2855                                            &init_addr, true);
2856       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, data_ref);
2857       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2858       new_temp = make_ssa_name (vec_dest, new_stmt);
2859       TREE_OPERAND (new_stmt, 0) = new_temp;
2860       new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
2861       gcc_assert (!new_bb);
2862       msq_init = TREE_OPERAND (new_stmt, 0);
2863
2864
2865       /* <2> Create lsq = *(floor(p2')) in the loop  */ 
2866       offset = build_int_cst (integer_type_node, 
2867                               GET_MODE_NUNITS (TYPE_MODE (vectype)));
2868       offset = int_const_binop (MINUS_EXPR, offset, integer_one_node, 1);
2869       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2870       dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy, false);
2871       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
2872       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2873       new_temp = make_ssa_name (vec_dest, new_stmt);
2874       TREE_OPERAND (new_stmt, 0) = new_temp;
2875       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2876       lsq = TREE_OPERAND (new_stmt, 0);
2877
2878
2879       /* <3> */
2880       if (targetm.vectorize.builtin_mask_for_load)
2881         {
2882           /* Create permutation mask, if required, in loop preheader.  */
2883           tree builtin_decl;
2884           params = build_tree_list (NULL_TREE, init_addr);
2885           vec_dest = vect_create_destination_var (scalar_dest, vectype);
2886           builtin_decl = targetm.vectorize.builtin_mask_for_load ();
2887           new_stmt = build_function_call_expr (builtin_decl, params);
2888           new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
2889           new_temp = make_ssa_name (vec_dest, new_stmt);
2890           TREE_OPERAND (new_stmt, 0) = new_temp;
2891           new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
2892           gcc_assert (!new_bb);
2893           magic = TREE_OPERAND (new_stmt, 0);
2894
2895           /* Since we have just created a CALL_EXPR, we may need to
2896              rename call-clobbered variables.  */
2897           mark_call_clobbered_vars_to_rename ();
2898         }
2899       else
2900         {
2901           /* Use current address instead of init_addr for reduced reg pressure.
2902            */
2903           magic = dataref_ptr;
2904         }
2905
2906
2907       /* <4> Create msq = phi <msq_init, lsq> in loop  */ 
2908       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2909       msq = make_ssa_name (vec_dest, NULL_TREE);
2910       phi_stmt = create_phi_node (msq, loop->header); /* CHECKME */
2911       SSA_NAME_DEF_STMT (msq) = phi_stmt;
2912       add_phi_arg (phi_stmt, msq_init, loop_preheader_edge (loop));
2913       add_phi_arg (phi_stmt, lsq, loop_latch_edge (loop));
2914
2915
2916       /* <5> Create <vec_dest = realign_load (msq, lsq, magic)> in loop  */
2917       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2918       new_stmt = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq, magic);
2919       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
2920       new_temp = make_ssa_name (vec_dest, new_stmt); 
2921       TREE_OPERAND (new_stmt, 0) = new_temp;
2922       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2923     }
2924   else
2925     gcc_unreachable ();
2926
2927   *vec_stmt = new_stmt;
2928   return true;
2929 }
2930
2931
2932 /* Function vect_supportable_dr_alignment
2933
2934    Return whether the data reference DR is supported with respect to its
2935    alignment.  */
2936
2937 static enum dr_alignment_support
2938 vect_supportable_dr_alignment (struct data_reference *dr)
2939 {
2940   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)));
2941   enum machine_mode mode = (int) TYPE_MODE (vectype);
2942
2943   if (aligned_access_p (dr))
2944     return dr_aligned;
2945
2946   /* Possibly unaligned access.  */
2947   
2948   if (DR_IS_READ (dr))
2949     {
2950       if (vec_realign_load_optab->handlers[mode].insn_code != CODE_FOR_nothing
2951           && (!targetm.vectorize.builtin_mask_for_load
2952               || targetm.vectorize.builtin_mask_for_load ()))
2953         return dr_unaligned_software_pipeline;
2954
2955       if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
2956         /* Can't software pipeline the loads, but can at least do them.  */
2957         return dr_unaligned_supported;
2958     }
2959
2960   /* Unsupported.  */
2961   return dr_unaligned_unsupported;
2962 }
2963
2964
2965 /* Function vect_transform_stmt.
2966
2967    Create a vectorized stmt to replace STMT, and insert it at BSI.  */
2968
2969 static bool
2970 vect_transform_stmt (tree stmt, block_stmt_iterator *bsi)
2971 {
2972   bool is_store = false;
2973   tree vec_stmt = NULL_TREE;
2974   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2975   bool done;
2976
2977   switch (STMT_VINFO_TYPE (stmt_info))
2978     {
2979     case op_vec_info_type:
2980       done = vectorizable_operation (stmt, bsi, &vec_stmt);
2981       gcc_assert (done);
2982       break;
2983
2984     case assignment_vec_info_type:
2985       done = vectorizable_assignment (stmt, bsi, &vec_stmt);
2986       gcc_assert (done);
2987       break;
2988
2989     case load_vec_info_type:
2990       done = vectorizable_load (stmt, bsi, &vec_stmt);
2991       gcc_assert (done);
2992       break;
2993
2994     case store_vec_info_type:
2995       done = vectorizable_store (stmt, bsi, &vec_stmt);
2996       gcc_assert (done);
2997       is_store = true;
2998       break;
2999     default:
3000       if (vect_debug_details (UNKNOWN_LOC))
3001         fprintf (dump_file, "stmt not supported.");
3002       gcc_unreachable ();
3003     }
3004
3005   STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
3006
3007   return is_store;
3008 }
3009
3010
3011 /* This function builds ni_name = number of iterations loop executes
3012    on the loop preheader.  */
3013
3014 static tree
3015 vect_build_loop_niters (loop_vec_info loop_vinfo)
3016 {
3017   tree ni_name, stmt, var;
3018   edge pe;
3019   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3020   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
3021
3022   var = create_tmp_var (TREE_TYPE (ni), "niters");
3023   add_referenced_tmp_var (var);
3024   ni_name = force_gimple_operand (ni, &stmt, false, var);
3025
3026   pe = loop_preheader_edge (loop);
3027   if (stmt)
3028     {
3029       basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
3030       gcc_assert (!new_bb);
3031     }
3032       
3033   return ni_name;
3034 }
3035
3036
3037 /* This function generates the following statements:
3038
3039  ni_name = number of iterations loop executes
3040  ratio = ni_name / vf
3041  ratio_mult_vf_name = ratio * vf
3042
3043  and places them at the loop preheader edge.  */
3044
3045 static void 
3046 vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo, 
3047                                  tree *ni_name_ptr,
3048                                  tree *ratio_mult_vf_name_ptr, 
3049                                  tree *ratio_name_ptr)
3050 {
3051
3052   edge pe;
3053   basic_block new_bb;
3054   tree stmt, ni_name;
3055   tree var;
3056   tree ratio_name;
3057   tree ratio_mult_vf_name;
3058   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3059   tree ni = LOOP_VINFO_NITERS (loop_vinfo);
3060   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3061   tree log_vf = build_int_cst (unsigned_type_node, exact_log2 (vf));
3062
3063   pe = loop_preheader_edge (loop);
3064
3065   /* Generate temporary variable that contains 
3066      number of iterations loop executes.  */
3067
3068   ni_name = vect_build_loop_niters (loop_vinfo);
3069
3070   /* Create: ratio = ni >> log2(vf) */
3071
3072   var = create_tmp_var (TREE_TYPE (ni), "bnd");
3073   add_referenced_tmp_var (var);
3074   ratio_name = make_ssa_name (var, NULL_TREE);
3075   stmt = build2 (MODIFY_EXPR, void_type_node, ratio_name,
3076            build2 (RSHIFT_EXPR, TREE_TYPE (ni_name), ni_name, log_vf));
3077   SSA_NAME_DEF_STMT (ratio_name) = stmt;
3078
3079   pe = loop_preheader_edge (loop);
3080   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
3081   gcc_assert (!new_bb);
3082        
3083   /* Create: ratio_mult_vf = ratio << log2 (vf).  */
3084
3085   var = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf");
3086   add_referenced_tmp_var (var);
3087   ratio_mult_vf_name = make_ssa_name (var, NULL_TREE);
3088   stmt = build2 (MODIFY_EXPR, void_type_node, ratio_mult_vf_name,
3089            build2 (LSHIFT_EXPR, TREE_TYPE (ratio_name), ratio_name, log_vf));
3090   SSA_NAME_DEF_STMT (ratio_mult_vf_name) = stmt;
3091
3092   pe = loop_preheader_edge (loop);
3093   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
3094   gcc_assert (!new_bb);
3095
3096   *ni_name_ptr = ni_name;
3097   *ratio_mult_vf_name_ptr = ratio_mult_vf_name;
3098   *ratio_name_ptr = ratio_name;
3099     
3100   return;  
3101 }
3102
3103
3104 /*   Function vect_update_ivs_after_vectorizer.
3105
3106      "Advance" the induction variables of LOOP to the value they should take
3107      after the execution of LOOP.  This is currently necessary because the
3108      vectorizer does not handle induction variables that are used after the
3109      loop.  Such a situation occurs when the last iterations of LOOP are
3110      peeled, because:
3111      1. We introduced new uses after LOOP for IVs that were not originally used
3112         after LOOP: the IVs of LOOP are now used by an epilog loop.
3113      2. LOOP is going to be vectorized; this means that it will iterate N/VF
3114         times, whereas the loop IVs should be bumped N times.
3115
3116      Input:
3117      - LOOP - a loop that is going to be vectorized. The last few iterations
3118               of LOOP were peeled.
3119      - NITERS - the number of iterations that LOOP executes (before it is
3120                 vectorized). i.e, the number of times the ivs should be bumped.
3121      - UPDATE_E - a successor edge of LOOP->exit that is on the (only) path
3122                   coming out from LOOP on which there are uses of the LOOP ivs
3123                   (this is the path from LOOP->exit to epilog_loop->preheader).
3124
3125                   The new definitions of the ivs are placed in LOOP->exit.
3126                   The phi args associated with the edge UPDATE_E in the bb
3127                   UPDATE_E->dest are updated accordingly.
3128
3129      Assumption 1: Like the rest of the vectorizer, this function assumes
3130      a single loop exit that has a single predecessor.
3131
3132      Assumption 2: The phi nodes in the LOOP header and in update_bb are
3133      organized in the same order.
3134
3135      Assumption 3: The access function of the ivs is simple enough (see
3136      vect_can_advance_ivs_p).  This assumption will be relaxed in the future.
3137
3138      Assumption 4: Exactly one of the successors of LOOP exit-bb is on a path
3139      coming out of LOOP on which the ivs of LOOP are used (this is the path 
3140      that leads to the epilog loop; other paths skip the epilog loop).  This
3141      path starts with the edge UPDATE_E, and its destination (denoted update_bb)
3142      needs to have its phis updated.
3143  */
3144
3145 static void
3146 vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, 
3147                                   edge update_e)
3148 {
3149   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3150   basic_block exit_bb = loop->exit_edges[0]->dest;
3151   tree phi, phi1;
3152   basic_block update_bb = update_e->dest;
3153
3154   /* gcc_assert (vect_can_advance_ivs_p (loop_vinfo)); */
3155
3156   /* Make sure there exists a single-predecessor exit bb:  */
3157   gcc_assert (EDGE_COUNT (exit_bb->preds) == 1);
3158
3159   for (phi = phi_nodes (loop->header), phi1 = phi_nodes (update_bb); 
3160        phi && phi1; 
3161        phi = PHI_CHAIN (phi), phi1 = PHI_CHAIN (phi1))
3162     {
3163       tree access_fn = NULL;
3164       tree evolution_part;
3165       tree init_expr;
3166       tree step_expr;
3167       tree var, stmt, ni, ni_name;
3168       block_stmt_iterator last_bsi;
3169
3170       /* Skip virtual phi's.  */
3171       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
3172         {
3173           if (vect_debug_details (UNKNOWN_LOC))
3174             fprintf (dump_file, "virtual phi. skip.");
3175           continue;
3176         }
3177
3178       access_fn = analyze_scalar_evolution (loop, PHI_RESULT (phi)); 
3179       gcc_assert (access_fn);
3180       evolution_part =
3181          unshare_expr (evolution_part_in_loop_num (access_fn, loop->num));
3182       gcc_assert (evolution_part != NULL_TREE);
3183       
3184       /* FORNOW: We do not support IVs whose evolution function is a polynomial
3185          of degree >= 2 or exponential.  */
3186       gcc_assert (!tree_is_chrec (evolution_part));
3187
3188       step_expr = evolution_part;
3189       init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, 
3190                                                                loop->num));
3191
3192       ni = build2 (PLUS_EXPR, TREE_TYPE (init_expr),
3193                   build2 (MULT_EXPR, TREE_TYPE (niters),
3194                        niters, step_expr), init_expr);
3195
3196       var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
3197       add_referenced_tmp_var (var);
3198
3199       ni_name = force_gimple_operand (ni, &stmt, false, var);
3200       
3201       /* Insert stmt into exit_bb.  */
3202       last_bsi = bsi_last (exit_bb);
3203       if (stmt)
3204         bsi_insert_before (&last_bsi, stmt, BSI_SAME_STMT);   
3205
3206       /* Fix phi expressions in the successor bb.  */
3207       gcc_assert (PHI_ARG_DEF_FROM_EDGE (phi1, update_e) ==
3208                   PHI_ARG_DEF_FROM_EDGE (phi, EDGE_SUCC (loop->latch, 0)));
3209       SET_PHI_ARG_DEF (phi1, update_e->dest_idx, ni_name);
3210     }
3211 }
3212
3213
3214 /* Function vect_do_peeling_for_loop_bound
3215
3216    Peel the last iterations of the loop represented by LOOP_VINFO.
3217    The peeled iterations form a new epilog loop.  Given that the loop now 
3218    iterates NITERS times, the new epilog loop iterates
3219    NITERS % VECTORIZATION_FACTOR times.
3220    
3221    The original loop will later be made to iterate 
3222    NITERS / VECTORIZATION_FACTOR times (this value is placed into RATIO).  */
3223
3224 static void 
3225 vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
3226                                 struct loops *loops)
3227 {
3228
3229   tree ni_name, ratio_mult_vf_name;
3230   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3231   struct loop *new_loop;
3232   edge update_e;
3233 #ifdef ENABLE_CHECKING
3234   int loop_num;
3235 #endif
3236
3237   if (vect_debug_details (UNKNOWN_LOC))
3238     fprintf (dump_file, "\n<<vect_transtorm_for_unknown_loop_bound>>\n");
3239
3240   /* Generate the following variables on the preheader of original loop:
3241          
3242      ni_name = number of iteration the original loop executes
3243      ratio = ni_name / vf
3244      ratio_mult_vf_name = ratio * vf  */
3245   vect_generate_tmps_on_preheader (loop_vinfo, &ni_name,
3246                                    &ratio_mult_vf_name, ratio);
3247
3248   /* Update loop info.  */
3249   loop->pre_header = loop_preheader_edge (loop)->src;
3250   loop->pre_header_edges[0] = loop_preheader_edge (loop);
3251
3252 #ifdef ENABLE_CHECKING
3253   loop_num  = loop->num; 
3254 #endif
3255   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->exit_edges[0],
3256                                             ratio_mult_vf_name, ni_name, false);
3257 #ifdef ENABLE_CHECKING
3258   gcc_assert (new_loop);
3259   gcc_assert (loop_num == loop->num);
3260   slpeel_verify_cfg_after_peeling (loop, new_loop);
3261 #endif
3262
3263   /* A guard that controls whether the new_loop is to be executed or skipped
3264      is placed in LOOP->exit.  LOOP->exit therefore has two successors - one
3265      is the preheader of NEW_LOOP, where the IVs from LOOP are used.  The other
3266      is a bb after NEW_LOOP, where these IVs are not used.  Find the edge that
3267      is on the path where the LOOP IVs are used and need to be updated.  */
3268
3269   if (EDGE_PRED (new_loop->pre_header, 0)->src == loop->exit_edges[0]->dest)
3270     update_e = EDGE_PRED (new_loop->pre_header, 0);
3271   else
3272     update_e = EDGE_PRED (new_loop->pre_header, 1);
3273
3274   /* Update IVs of original loop as if they were advanced 
3275      by ratio_mult_vf_name steps.  */
3276   vect_update_ivs_after_vectorizer (loop_vinfo, ratio_mult_vf_name, update_e); 
3277
3278   /* After peeling we have to reset scalar evolution analyzer.  */
3279   scev_reset ();
3280
3281   return;
3282 }
3283
3284
3285 /* Function vect_gen_niters_for_prolog_loop
3286
3287    Set the number of iterations for the loop represented by LOOP_VINFO
3288    to the minimum between LOOP_NITERS (the original iteration count of the loop)
3289    and the misalignment of DR - the first data reference recorded in
3290    LOOP_VINFO_UNALIGNED_DR (LOOP_VINFO).  As a result, after the execution of 
3291    this loop, the data reference DR will refer to an aligned location.
3292
3293    The following computation is generated:
3294
3295    compute address misalignment in bytes:
3296    addr_mis = addr & (vectype_size - 1)
3297
3298    prolog_niters = min ( LOOP_NITERS , (VF - addr_mis/elem_size)&(VF-1) )
3299    
3300    (elem_size = element type size; an element is the scalar element 
3301         whose type is the inner type of the vectype)  */
3302
3303 static tree 
3304 vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
3305 {
3306   struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
3307   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3308   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3309   tree var, stmt;
3310   tree iters, iters_name;
3311   edge pe;
3312   basic_block new_bb;
3313   tree dr_stmt = DR_STMT (dr);
3314   stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
3315   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
3316   int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT;
3317   tree elem_misalign;
3318   tree byte_misalign;
3319   tree new_stmts = NULL_TREE;
3320   tree start_addr = 
3321         vect_create_addr_base_for_vector_ref (dr_stmt, &new_stmts, NULL_TREE);
3322   tree ptr_type = TREE_TYPE (start_addr);
3323   tree size = TYPE_SIZE (ptr_type);
3324   tree type = lang_hooks.types.type_for_size (tree_low_cst (size, 1), 1);
3325   tree vectype_size_minus_1 = build_int_cst (type, vectype_align - 1);
3326   tree vf_minus_1 = build_int_cst (unsigned_type_node, vf - 1);
3327   tree niters_type = TREE_TYPE (loop_niters);
3328   tree elem_size_log = 
3329         build_int_cst (unsigned_type_node, exact_log2 (vectype_align/vf));
3330   tree vf_tree = build_int_cst (unsigned_type_node, vf);
3331
3332   pe = loop_preheader_edge (loop); 
3333   new_bb = bsi_insert_on_edge_immediate (pe, new_stmts); 
3334   gcc_assert (!new_bb);
3335
3336   /* Create:  byte_misalign = addr & (vectype_size - 1)  */
3337   byte_misalign = build2 (BIT_AND_EXPR, type, start_addr, vectype_size_minus_1);
3338
3339   /* Create:  elem_misalign = byte_misalign / element_size  */
3340   elem_misalign = 
3341         build2 (RSHIFT_EXPR, unsigned_type_node, byte_misalign, elem_size_log);
3342   
3343   /* Create:  (niters_type) (VF - elem_misalign)&(VF - 1)  */
3344   iters = build2 (MINUS_EXPR, unsigned_type_node, vf_tree, elem_misalign);
3345   iters = build2 (BIT_AND_EXPR, unsigned_type_node, iters, vf_minus_1);
3346   iters = fold_convert (niters_type, iters);
3347   
3348   /* Create:  prolog_loop_niters = min (iters, loop_niters) */
3349   /* If the loop bound is known at compile time we already verified that it is
3350      greater than vf; since the misalignment ('iters') is at most vf, there's
3351      no need to generate the MIN_EXPR in this case.  */
3352   if (TREE_CODE (loop_niters) != INTEGER_CST)
3353     iters = build2 (MIN_EXPR, niters_type, iters, loop_niters);
3354
3355   var = create_tmp_var (niters_type, "prolog_loop_niters");
3356   add_referenced_tmp_var (var);
3357   iters_name = force_gimple_operand (iters, &stmt, false, var);
3358
3359   /* Insert stmt on loop preheader edge.  */
3360   pe = loop_preheader_edge (loop);
3361   if (stmt)
3362     {
3363       basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
3364       gcc_assert (!new_bb);
3365     }
3366
3367   return iters_name; 
3368 }
3369
3370
3371 /* Function vect_update_inits_of_dr
3372
3373    NITERS iterations were peeled from LOOP.  DR represents a data reference
3374    in LOOP.  This function updates the information recorded in DR to
3375    account for the fact that the first NITERS iterations had already been 
3376    executed.  Specifically, it updates the OFFSET field of stmt_info.  */
3377
3378 static void
3379 vect_update_inits_of_dr (struct data_reference *dr, tree niters)
3380 {
3381   stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
3382   tree offset = STMT_VINFO_VECT_INIT_OFFSET (stmt_info);
3383       
3384   niters = fold (build2 (MULT_EXPR, TREE_TYPE (niters), niters, 
3385                          STMT_VINFO_VECT_STEP (stmt_info)));
3386   offset = fold (build2 (PLUS_EXPR, TREE_TYPE (offset), offset, niters));
3387   STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
3388 }
3389
3390
3391 /* Function vect_update_inits_of_drs
3392
3393    NITERS iterations were peeled from the loop represented by LOOP_VINFO.  
3394    This function updates the information recorded for the data references in 
3395    the loop to account for the fact that the first NITERS iterations had 
3396    already been executed.  Specifically, it updates the initial_condition of the
3397    access_function of all the data_references in the loop.  */
3398
3399 static void
3400 vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
3401 {
3402   unsigned int i;
3403   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
3404   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
3405
3406   if (dump_file && (dump_flags & TDF_DETAILS))
3407     fprintf (dump_file, "\n<<vect_update_inits_of_dr>>\n");
3408
3409   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
3410     {
3411       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
3412       vect_update_inits_of_dr (dr, niters);
3413     }
3414
3415   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
3416     {
3417       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
3418       vect_update_inits_of_dr (dr, niters);
3419     }
3420 }
3421
3422
3423 /* Function vect_do_peeling_for_alignment
3424
3425    Peel the first 'niters' iterations of the loop represented by LOOP_VINFO.
3426    'niters' is set to the misalignment of one of the data references in the
3427    loop, thereby forcing it to refer to an aligned location at the beginning
3428    of the execution of this loop.  The data reference for which we are
3429    peeling is recorded in LOOP_VINFO_UNALIGNED_DR.  */
3430
3431 static void
3432 vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
3433 {
3434   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3435   tree niters_of_prolog_loop, ni_name;
3436   tree n_iters;
3437   struct loop *new_loop;
3438
3439   if (vect_debug_details (UNKNOWN_LOC))
3440     fprintf (dump_file, "\n<<vect_do_peeling_for_alignment>>\n");
3441
3442   ni_name = vect_build_loop_niters (loop_vinfo);
3443   niters_of_prolog_loop = vect_gen_niters_for_prolog_loop (loop_vinfo, ni_name);
3444   
3445   /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
3446   new_loop = 
3447         slpeel_tree_peel_loop_to_edge (loop, loops, loop_preheader_edge (loop), 
3448                                        niters_of_prolog_loop, ni_name, true); 
3449 #ifdef ENABLE_CHECKING
3450   gcc_assert (new_loop);
3451   slpeel_verify_cfg_after_peeling (new_loop, loop);
3452 #endif
3453
3454   /* Update number of times loop executes.  */
3455   n_iters = LOOP_VINFO_NITERS (loop_vinfo);
3456   LOOP_VINFO_NITERS (loop_vinfo) =
3457     build2 (MINUS_EXPR, TREE_TYPE (n_iters), n_iters, niters_of_prolog_loop);
3458
3459   /* Update the init conditions of the access functions of all data refs.  */
3460   vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
3461
3462   /* After peeling we have to reset scalar evolution analyzer.  */
3463   scev_reset ();
3464
3465   return;
3466 }
3467
3468
3469 /* Function vect_transform_loop.
3470
3471    The analysis phase has determined that the loop is vectorizable.
3472    Vectorize the loop - created vectorized stmts to replace the scalar
3473    stmts in the loop, and update the loop exit condition.  */
3474
3475 static void
3476 vect_transform_loop (loop_vec_info loop_vinfo, 
3477                      struct loops *loops ATTRIBUTE_UNUSED)
3478 {
3479   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3480   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3481   int nbbs = loop->num_nodes;
3482   block_stmt_iterator si;
3483   int i;
3484   tree ratio = NULL;
3485   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3486
3487   if (vect_debug_details (UNKNOWN_LOC))
3488     fprintf (dump_file, "\n<<vec_transform_loop>>\n");
3489
3490   
3491   /* Peel the loop if there are data refs with unknown alignment.
3492      Only one data ref with unknown store is allowed.  */
3493
3494   if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo))
3495     vect_do_peeling_for_alignment (loop_vinfo, loops);
3496   
3497   /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
3498      compile time constant), or it is a constant that doesn't divide by the
3499      vectorization factor, then an epilog loop needs to be created.
3500      We therefore duplicate the loop: the original loop will be vectorized,
3501      and will compute the first (n/VF) iterations. The second copy of the loop
3502      will remain scalar and will compute the remaining (n%VF) iterations.
3503      (VF is the vectorization factor).  */
3504
3505   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3506       || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3507           && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
3508     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
3509   else
3510     ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
3511                 LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
3512
3513   /* 1) Make sure the loop header has exactly two entries
3514      2) Make sure we have a preheader basic block.  */
3515
3516   gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
3517
3518   loop_split_edge_with (loop_preheader_edge (loop), NULL);
3519
3520
3521   /* FORNOW: the vectorizer supports only loops which body consist
3522      of one basic block (header + empty latch). When the vectorizer will 
3523      support more involved loop forms, the order by which the BBs are 
3524      traversed need to be reconsidered.  */
3525
3526   for (i = 0; i < nbbs; i++)
3527     {
3528       basic_block bb = bbs[i];
3529
3530       for (si = bsi_start (bb); !bsi_end_p (si);)
3531         {
3532           tree stmt = bsi_stmt (si);
3533           stmt_vec_info stmt_info;
3534           bool is_store;
3535
3536           if (vect_debug_details (UNKNOWN_LOC))
3537             {
3538               fprintf (dump_file, "------>vectorizing statement: ");
3539               print_generic_expr (dump_file, stmt, TDF_SLIM);
3540             }   
3541           stmt_info = vinfo_for_stmt (stmt);
3542           gcc_assert (stmt_info);
3543           if (!STMT_VINFO_RELEVANT_P (stmt_info))
3544             {
3545               bsi_next (&si);
3546               continue;
3547             }
3548 #ifdef ENABLE_CHECKING
3549           /* FORNOW: Verify that all stmts operate on the same number of
3550                      units and no inner unrolling is necessary.  */
3551           gcc_assert 
3552                 (GET_MODE_NUNITS (TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info)))
3553                  == vectorization_factor);
3554 #endif
3555           /* -------- vectorize statement ------------ */
3556           if (vect_debug_details (UNKNOWN_LOC))
3557             fprintf (dump_file, "transform statement.");
3558
3559           is_store = vect_transform_stmt (stmt, &si);
3560           if (is_store)
3561             {
3562               /* free the attached stmt_vec_info and remove the stmt.  */
3563               stmt_ann_t ann = stmt_ann (stmt);
3564               free (stmt_info);
3565               set_stmt_info (ann, NULL);
3566               bsi_remove (&si);
3567               continue;
3568             }
3569
3570           bsi_next (&si);
3571         }                       /* stmts in BB */
3572     }                           /* BBs in loop */
3573
3574   slpeel_make_loop_iterate_ntimes (loop, ratio);
3575
3576   if (vect_debug_details (LOOP_LOC (loop_vinfo)))
3577     fprintf (dump_file,"Success! loop vectorized.");
3578   if (vect_debug_stats (LOOP_LOC (loop_vinfo)))
3579     fprintf (dump_file, "LOOP VECTORIZED.");
3580 }
3581
3582
3583 /* Function vect_is_simple_use.
3584
3585    Input:
3586    LOOP - the loop that is being vectorized.
3587    OPERAND - operand of a stmt in LOOP.
3588    DEF - the defining stmt in case OPERAND is an SSA_NAME.
3589
3590    Returns whether a stmt with OPERAND can be vectorized.
3591    Supportable operands are constants, loop invariants, and operands that are
3592    defined by the current iteration of the loop. Unsupportable operands are 
3593    those that are defined by a previous iteration of the loop (as is the case
3594    in reduction/induction computations).  */
3595
3596 static bool
3597 vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def)
3598
3599   tree def_stmt;
3600   basic_block bb;
3601   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3602
3603   if (def)
3604     *def = NULL_TREE;
3605
3606   if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
3607     return true;
3608
3609   if (TREE_CODE (operand) != SSA_NAME)
3610     return false;
3611
3612   def_stmt = SSA_NAME_DEF_STMT (operand);
3613   if (def_stmt == NULL_TREE )
3614     {
3615       if (vect_debug_details (UNKNOWN_LOC))
3616         fprintf (dump_file, "no def_stmt.");
3617       return false;
3618     }
3619
3620   /* empty stmt is expected only in case of a function argument.
3621      (Otherwise - we expect a phi_node or a modify_expr).  */
3622   if (IS_EMPTY_STMT (def_stmt))
3623     {
3624       tree arg = TREE_OPERAND (def_stmt, 0);
3625       if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
3626         return true;
3627       if (vect_debug_details (UNKNOWN_LOC))
3628         {
3629           fprintf (dump_file, "Unexpected empty stmt: ");
3630           print_generic_expr (dump_file, def_stmt, TDF_SLIM);
3631         }
3632       return false;  
3633     }
3634
3635   /* phi_node inside the loop indicates an induction/reduction pattern.
3636      This is not supported yet.  */
3637   bb = bb_for_stmt (def_stmt);
3638   if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
3639     {
3640       if (vect_debug_details (UNKNOWN_LOC))
3641         fprintf (dump_file, "reduction/induction - unsupported.");
3642       return false; /* FORNOW: not supported yet.  */
3643     }
3644
3645   /* Expecting a modify_expr or a phi_node.  */
3646   if (TREE_CODE (def_stmt) == MODIFY_EXPR
3647       || TREE_CODE (def_stmt) == PHI_NODE)
3648     {
3649       if (def)
3650         *def = def_stmt;        
3651       return true;
3652     }
3653
3654   return false;
3655 }
3656
3657
3658 /* Function vect_analyze_operations.
3659
3660    Scan the loop stmts and make sure they are all vectorizable.  */
3661
3662 static bool
3663 vect_analyze_operations (loop_vec_info loop_vinfo)
3664 {
3665   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3666   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3667   int nbbs = loop->num_nodes;
3668   block_stmt_iterator si;
3669   unsigned int vectorization_factor = 0;
3670   int i;
3671   bool ok;
3672   tree scalar_type;
3673
3674   if (vect_debug_details (UNKNOWN_LOC))
3675     fprintf (dump_file, "\n<<vect_analyze_operations>>\n");
3676
3677   for (i = 0; i < nbbs; i++)
3678     {
3679       basic_block bb = bbs[i];
3680
3681       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
3682         {
3683           tree stmt = bsi_stmt (si);
3684           unsigned int nunits;
3685           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3686           tree vectype;
3687
3688           if (vect_debug_details (UNKNOWN_LOC))
3689             {
3690               fprintf (dump_file, "==> examining statement: ");
3691               print_generic_expr (dump_file, stmt, TDF_SLIM);
3692             }
3693
3694           gcc_assert (stmt_info);
3695
3696           /* skip stmts which do not need to be vectorized.
3697              this is expected to include:
3698              - the COND_EXPR which is the loop exit condition
3699              - any LABEL_EXPRs in the loop
3700              - computations that are used only for array indexing or loop
3701              control  */
3702
3703           if (!STMT_VINFO_RELEVANT_P (stmt_info))
3704             {
3705               if (vect_debug_details (UNKNOWN_LOC))
3706                 fprintf (dump_file, "irrelevant.");
3707               continue;
3708             }
3709
3710           if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
3711             {
3712               if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3713                   || vect_debug_details (LOOP_LOC (loop_vinfo)))
3714                 {
3715                   fprintf (dump_file, "not vectorized: vector stmt in loop:");
3716                   print_generic_expr (dump_file, stmt, TDF_SLIM);
3717                 }
3718               return false;
3719             }
3720
3721           if (STMT_VINFO_DATA_REF (stmt_info))
3722             scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));    
3723           else if (TREE_CODE (stmt) == MODIFY_EXPR)
3724             scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
3725           else
3726             scalar_type = TREE_TYPE (stmt);
3727
3728           if (vect_debug_details (UNKNOWN_LOC))
3729             {
3730               fprintf (dump_file, "get vectype for scalar type:  ");
3731               print_generic_expr (dump_file, scalar_type, TDF_SLIM);
3732             }
3733
3734           vectype = get_vectype_for_scalar_type (scalar_type);
3735           if (!vectype)
3736             {
3737               if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3738                   || vect_debug_details (LOOP_LOC (loop_vinfo)))
3739                 {
3740                   fprintf (dump_file, "not vectorized: unsupported data-type ");
3741                   print_generic_expr (dump_file, scalar_type, TDF_SLIM);
3742                 }
3743               return false;
3744             }
3745
3746           if (vect_debug_details (UNKNOWN_LOC))
3747             {
3748               fprintf (dump_file, "vectype: ");
3749               print_generic_expr (dump_file, vectype, TDF_SLIM);
3750             }
3751           STMT_VINFO_VECTYPE (stmt_info) = vectype;
3752
3753           ok = (vectorizable_operation (stmt, NULL, NULL)
3754                 || vectorizable_assignment (stmt, NULL, NULL)
3755                 || vectorizable_load (stmt, NULL, NULL)
3756                 || vectorizable_store (stmt, NULL, NULL));
3757
3758           if (!ok)
3759             {
3760               if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3761                   || vect_debug_details (LOOP_LOC (loop_vinfo)))
3762                 {
3763                   fprintf (dump_file, "not vectorized: stmt not supported: ");
3764                   print_generic_expr (dump_file, stmt, TDF_SLIM);
3765                 }
3766               return false;
3767             }
3768
3769           nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
3770           if (vect_debug_details (UNKNOWN_LOC))
3771             fprintf (dump_file, "nunits = %d", nunits);
3772
3773           if (vectorization_factor)
3774             {
3775               /* FORNOW: don't allow mixed units.
3776                  This restriction will be relaxed in the future.  */
3777               if (nunits != vectorization_factor)
3778                 {
3779                   if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3780                       || vect_debug_details (LOOP_LOC (loop_vinfo)))
3781                     fprintf (dump_file, "not vectorized: mixed data-types");
3782                   return false;
3783                 }
3784             }
3785           else
3786             vectorization_factor = nunits;
3787
3788 #ifdef ENABLE_CHECKING
3789           gcc_assert (GET_MODE_SIZE (TYPE_MODE (scalar_type))
3790                         * vectorization_factor == UNITS_PER_SIMD_WORD);
3791 #endif
3792         }
3793     }
3794
3795   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
3796
3797   if (vectorization_factor <= 1)
3798     {
3799       if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3800           || vect_debug_details (LOOP_LOC (loop_vinfo)))
3801         fprintf (dump_file, "not vectorized: unsupported data-type");
3802       return false;
3803     }
3804   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
3805
3806   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3807       && vect_debug_details (UNKNOWN_LOC))
3808     fprintf (dump_file,
3809         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
3810         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
3811
3812   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3813       && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
3814     {
3815       if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3816           || vect_debug_details (LOOP_LOC (loop_vinfo)))
3817         fprintf (dump_file, "not vectorized: iteration count too small.");
3818       return false;
3819     }
3820
3821   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3822       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
3823     {
3824       if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3825           || vect_debug_details (LOOP_LOC (loop_vinfo)))
3826         fprintf (dump_file, "epilog loop required.");
3827       if (!vect_can_advance_ivs_p (loop_vinfo))
3828         {
3829           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3830               || vect_debug_details (LOOP_LOC (loop_vinfo)))
3831             fprintf (dump_file, "not vectorized: can't create epilog loop 1.");
3832           return false;
3833         }
3834       if (!slpeel_can_duplicate_loop_p (loop, loop->exit_edges[0]))
3835         {
3836           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
3837               || vect_debug_details (LOOP_LOC (loop_vinfo)))
3838             fprintf (dump_file, "not vectorized: can't create epilog loop 2.");
3839           return false;
3840         }
3841     }
3842
3843   return true;
3844 }
3845
3846
3847 /* Function exist_non_indexing_operands_for_use_p 
3848
3849    USE is one of the uses attached to STMT. Check if USE is 
3850    used in STMT for anything other than indexing an array.  */
3851
3852 static bool
3853 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
3854 {
3855   tree operand;
3856   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3857  
3858   /* USE corresponds to some operand in STMT. If there is no data
3859      reference in STMT, then any operand that corresponds to USE
3860      is not indexing an array.  */
3861   if (!STMT_VINFO_DATA_REF (stmt_info))
3862     return true;
3863  
3864   /* STMT has a data_ref. FORNOW this means that its of one of
3865      the following forms:
3866      -1- ARRAY_REF = var
3867      -2- var = ARRAY_REF
3868      (This should have been verified in analyze_data_refs).
3869
3870      'var' in the second case corresponds to a def, not a use,
3871      so USE cannot correspond to any operands that are not used 
3872      for array indexing.
3873
3874      Therefore, all we need to check is if STMT falls into the
3875      first case, and whether var corresponds to USE.  */
3876  
3877   if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
3878     return false;
3879
3880   operand = TREE_OPERAND (stmt, 1);
3881
3882   if (TREE_CODE (operand) != SSA_NAME)
3883     return false;
3884
3885   if (operand == use)
3886     return true;
3887
3888   return false;
3889 }
3890
3891
3892 /* Function vect_is_simple_iv_evolution.
3893
3894    FORNOW: A simple evolution of an induction variables in the loop is
3895    considered a polynomial evolution with constant step.  */
3896
3897 static bool
3898 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, 
3899                                 tree * step, bool strict)
3900 {
3901   tree init_expr;
3902   tree step_expr;
3903   
3904   tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
3905
3906   /* When there is no evolution in this loop, the evolution function
3907      is not "simple".  */  
3908   if (evolution_part == NULL_TREE)
3909     return false;
3910   
3911   /* When the evolution is a polynomial of degree >= 2
3912      the evolution function is not "simple".  */
3913   if (tree_is_chrec (evolution_part))
3914     return false;
3915   
3916   step_expr = evolution_part;
3917   init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb));
3918
3919   if (vect_debug_details (UNKNOWN_LOC))
3920     {
3921       fprintf (dump_file, "step: ");
3922       print_generic_expr (dump_file, step_expr, TDF_SLIM);
3923       fprintf (dump_file, ",  init: ");
3924       print_generic_expr (dump_file, init_expr, TDF_SLIM);
3925     }
3926
3927   *init = init_expr;
3928   *step = step_expr;
3929
3930   if (TREE_CODE (step_expr) != INTEGER_CST)
3931     {
3932       if (vect_debug_details (UNKNOWN_LOC))
3933         fprintf (dump_file, "step unknown.");
3934       return false;
3935     }
3936
3937   if (strict)
3938     if (!integer_onep (step_expr))
3939       {
3940         if (vect_debug_details (UNKNOWN_LOC))
3941           print_generic_expr (dump_file, step_expr, TDF_SLIM);
3942         return false;
3943       }
3944
3945   return true;
3946 }
3947
3948
3949 /* Function vect_analyze_scalar_cycles.
3950
3951    Examine the cross iteration def-use cycles of scalar variables, by
3952    analyzing the loop (scalar) PHIs; verify that the cross iteration def-use
3953    cycles that they represent do not impede vectorization.
3954
3955    FORNOW: Reduction as in the following loop, is not supported yet:
3956               loop1:
3957               for (i=0; i<N; i++)
3958                  sum += a[i];
3959            The cross-iteration cycle corresponding to variable 'sum' will be
3960            considered too complicated and will impede vectorization.
3961
3962    FORNOW: Induction as in the following loop, is not supported yet:
3963               loop2:
3964               for (i=0; i<N; i++)
3965                  a[i] = i;
3966
3967            However, the following loop *is* vectorizable:
3968               loop3:
3969               for (i=0; i<N; i++)
3970                  a[i] = b[i];
3971
3972            In both loops there exists a def-use cycle for the variable i:
3973               loop: i_2 = PHI (i_0, i_1)
3974                     a[i_2] = ...;
3975                     i_1 = i_2 + 1;
3976                     GOTO loop;
3977
3978            The evolution of the above cycle is considered simple enough,
3979            however, we also check that the cycle does not need to be
3980            vectorized, i.e - we check that the variable that this cycle
3981            defines is only used for array indexing or in stmts that do not
3982            need to be vectorized. This is not the case in loop2, but it
3983            *is* the case in loop3.  */
3984
3985 static bool
3986 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
3987 {
3988   tree phi;
3989   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3990   basic_block bb = loop->header;
3991   tree dummy;
3992
3993   if (vect_debug_details (UNKNOWN_LOC))
3994     fprintf (dump_file, "\n<<vect_analyze_scalar_cycles>>\n");
3995
3996   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
3997     {
3998       tree access_fn = NULL;
3999
4000       if (vect_debug_details (UNKNOWN_LOC))
4001         {
4002           fprintf (dump_file, "Analyze phi: ");
4003           print_generic_expr (dump_file, phi, TDF_SLIM);
4004         }
4005
4006       /* Skip virtual phi's. The data dependences that are associated with
4007          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
4008
4009       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
4010         {
4011           if (vect_debug_details (UNKNOWN_LOC))
4012             fprintf (dump_file, "virtual phi. skip.");
4013           continue;
4014         }
4015
4016       /* Analyze the evolution function.  */
4017
4018       /* FORNOW: The only scalar cross-iteration cycles that we allow are
4019          those of loop induction variables; This property is verified here.
4020
4021          Furthermore, if that induction variable is used in an operation
4022          that needs to be vectorized (i.e, is not solely used to index
4023          arrays and check the exit condition) - we do not support its
4024          vectorization yet. This property is verified in vect_is_simple_use,
4025          during vect_analyze_operations.  */
4026
4027       access_fn = /* instantiate_parameters
4028                      (loop,*/
4029          analyze_scalar_evolution (loop, PHI_RESULT (phi));
4030
4031       if (!access_fn)
4032         {
4033           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
4034               || vect_debug_details (LOOP_LOC (loop_vinfo)))
4035             fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
4036           return false;
4037         }
4038
4039       if (vect_debug_details (UNKNOWN_LOC))
4040         {
4041            fprintf (dump_file, "Access function of PHI: ");
4042            print_generic_expr (dump_file, access_fn, TDF_SLIM);
4043         }
4044
4045       if (!vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, 
4046                                         &dummy, false))
4047         {
4048           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
4049               || vect_debug_details (LOOP_LOC (loop_vinfo)))
4050             fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
4051           return false;
4052         }
4053     }
4054
4055   return true;
4056 }
4057
4058
4059 /* Function vect_analyze_data_ref_dependence.
4060
4061    Return TRUE if there (might) exist a dependence between a memory-reference
4062    DRA and a memory-reference DRB.  */
4063
4064 static bool
4065 vect_analyze_data_ref_dependence (struct data_reference *dra,
4066                                   struct data_reference *drb, 
4067                                   loop_vec_info loop_vinfo)
4068 {
4069   bool differ_p; 
4070   struct data_dependence_relation *ddr;
4071   
4072   if (!array_base_name_differ_p (dra, drb, &differ_p))
4073     {
4074       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4075           || vect_debug_details (LOOP_LOC (loop_vinfo)))   
4076         {
4077           fprintf (dump_file,
4078                 "not vectorized: can't determine dependence between: ");
4079           print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
4080           fprintf (dump_file, " and ");
4081           print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
4082         }
4083       return true;
4084     }
4085
4086   if (differ_p)
4087     return false;
4088
4089   ddr = initialize_data_dependence_relation (dra, drb);
4090   compute_affine_dependence (ddr);
4091
4092   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
4093     return false;
4094   
4095   if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4096       || vect_debug_details (LOOP_LOC (loop_vinfo)))
4097     {
4098       fprintf (dump_file,
4099         "not vectorized: possible dependence between data-refs ");
4100       print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
4101       fprintf (dump_file, " and ");
4102       print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
4103     }
4104
4105   return true;
4106 }
4107
4108
4109 /* Function vect_analyze_data_ref_dependences.
4110
4111    Examine all the data references in the loop, and make sure there do not
4112    exist any data dependences between them.
4113
4114    TODO: dependences which distance is greater than the vectorization factor
4115          can be ignored.  */
4116
4117 static bool
4118 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
4119 {
4120   unsigned int i, j;
4121   varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4122   varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4123
4124   /* Examine store-store (output) dependences.  */
4125
4126   if (vect_debug_details (UNKNOWN_LOC))
4127     fprintf (dump_file, "\n<<vect_analyze_dependences>>\n");
4128
4129   if (vect_debug_details (UNKNOWN_LOC))
4130     fprintf (dump_file, "compare all store-store pairs.");
4131
4132   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
4133     {
4134       for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
4135         {
4136           struct data_reference *dra =
4137             VARRAY_GENERIC_PTR (loop_write_refs, i);
4138           struct data_reference *drb =
4139             VARRAY_GENERIC_PTR (loop_write_refs, j);
4140           if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
4141             return false;
4142         }
4143     }
4144
4145   /* Examine load-store (true/anti) dependences.  */
4146
4147   if (vect_debug_details (UNKNOWN_LOC))
4148     fprintf (dump_file, "compare all load-store pairs.");
4149
4150   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
4151     {
4152       for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
4153         {
4154           struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
4155           struct data_reference *drb =
4156             VARRAY_GENERIC_PTR (loop_write_refs, j);
4157           if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
4158             return false;
4159         }
4160     }
4161
4162   return true;
4163 }
4164
4165
4166 /* Function vect_compute_data_ref_alignment
4167
4168    Compute the misalignment of the data reference DR.
4169
4170    Output:
4171    1. If during the misalignment computation it is found that the data reference
4172       cannot be vectorized then false is returned.
4173    2. DR_MISALIGNMENT (DR) is defined.
4174
4175    FOR NOW: No analysis is actually performed. Misalignment is calculated
4176    only for trivial cases. TODO.  */
4177
4178 static bool
4179 vect_compute_data_ref_alignment (struct data_reference *dr)
4180 {
4181   tree stmt = DR_STMT (dr);
4182   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
4183   tree ref = DR_REF (dr);
4184   tree vectype;
4185   tree base, alignment;
4186   bool base_aligned_p;
4187   tree misalign;
4188    
4189   if (vect_debug_details (UNKNOWN_LOC))
4190     fprintf (dump_file, "vect_compute_data_ref_alignment:");
4191
4192   /* Initialize misalignment to unknown.  */
4193   DR_MISALIGNMENT (dr) = -1;
4194
4195   misalign = STMT_VINFO_VECT_MISALIGNMENT (stmt_info);
4196   base_aligned_p = STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info);
4197   base = STMT_VINFO_VECT_DR_BASE (stmt_info);
4198   vectype = STMT_VINFO_VECTYPE (stmt_info);
4199
4200   if (!misalign)
4201     {
4202       if (vect_debug_details (UNKNOWN_LOC)) 
4203         {
4204           fprintf (dump_file, "Unknown alignment for access: ");
4205           print_generic_expr (dump_file, base, TDF_SLIM);
4206         }
4207       return true;
4208     }
4209
4210   if (!base_aligned_p) 
4211     {
4212       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
4213         {
4214           if (vect_debug_details (UNKNOWN_LOC))
4215             {
4216               fprintf (dump_file, "can't force alignment of ref: ");
4217               print_generic_expr (dump_file, ref, TDF_SLIM);
4218             }
4219           return true;
4220         }
4221       
4222       /* Force the alignment of the decl.
4223          NOTE: This is the only change to the code we make during
4224          the analysis phase, before deciding to vectorize the loop.  */
4225       if (vect_debug_details (UNKNOWN_LOC))
4226         fprintf (dump_file, "force alignment");
4227       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
4228       DECL_USER_ALIGN (base) = 1;
4229     }
4230
4231   /* At this point we assume that the base is aligned.  */
4232   gcc_assert (base_aligned_p 
4233               || (TREE_CODE (base) == VAR_DECL 
4234                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
4235
4236   /* Alignment required, in bytes:  */
4237   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
4238
4239   /* Modulo alignment.  */
4240   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
4241   if (tree_int_cst_sgn (misalign) < 0)
4242     {
4243       /* Negative misalignment value.  */
4244       if (vect_debug_details (UNKNOWN_LOC))
4245         fprintf (dump_file, "unexpected misalign value");
4246       return false;
4247     }
4248
4249   DR_MISALIGNMENT (dr) = tree_low_cst (misalign, 1);
4250
4251   if (vect_debug_details (UNKNOWN_LOC))
4252     fprintf (dump_file, "misalign = %d", DR_MISALIGNMENT (dr));
4253
4254   return true;
4255 }
4256
4257
4258 /* Function vect_compute_data_refs_alignment
4259
4260    Compute the misalignment of data references in the loop.
4261    This pass may take place at function granularity instead of at loop
4262    granularity.
4263
4264    FOR NOW: No analysis is actually performed. Misalignment is calculated
4265    only for trivial cases. TODO.  */
4266
4267 static bool
4268 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
4269 {
4270   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4271   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4272   unsigned int i;
4273
4274   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4275     {
4276       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4277       if (!vect_compute_data_ref_alignment (dr))
4278         return false;
4279     }
4280
4281   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4282     {
4283       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4284       if (!vect_compute_data_ref_alignment (dr))
4285         return false;
4286     }
4287
4288   return true;
4289 }
4290
4291
4292 /* Function vect_enhance_data_refs_alignment
4293
4294    This pass will use loop versioning and loop peeling in order to enhance
4295    the alignment of data references in the loop.
4296
4297    FOR NOW: we assume that whatever versioning/peeling takes place, only the
4298    original loop is to be vectorized; Any other loops that are created by
4299    the transformations performed in this pass - are not supposed to be
4300    vectorized. This restriction will be relaxed.  */
4301
4302 static void
4303 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
4304 {
4305   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4306   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4307   unsigned int i;
4308
4309   /*
4310      This pass will require a cost model to guide it whether to apply peeling 
4311      or versioning or a combination of the two. For example, the scheme that
4312      intel uses when given a loop with several memory accesses, is as follows:
4313      choose one memory access ('p') which alignment you want to force by doing 
4314      peeling. Then, either (1) generate a loop in which 'p' is aligned and all 
4315      other accesses are not necessarily aligned, or (2) use loop versioning to 
4316      generate one loop in which all accesses are aligned, and another loop in 
4317      which only 'p' is necessarily aligned. 
4318
4319      ("Automatic Intra-Register Vectorization for the Intel Architecture",
4320       Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
4321       Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)     
4322
4323      Devising a cost model is the most critical aspect of this work. It will 
4324      guide us on which access to peel for, whether to use loop versioning, how 
4325      many versions to create, etc. The cost model will probably consist of 
4326      generic considerations as well as target specific considerations (on 
4327      powerpc for example, misaligned stores are more painful than misaligned 
4328      loads). 
4329
4330      Here is the general steps involved in alignment enhancements:
4331     
4332      -- original loop, before alignment analysis:
4333         for (i=0; i<N; i++){
4334           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
4335           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
4336         }
4337
4338      -- After vect_compute_data_refs_alignment:
4339         for (i=0; i<N; i++){
4340           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4341           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
4342         }
4343
4344      -- Possibility 1: we do loop versioning:
4345      if (p is aligned) {
4346         for (i=0; i<N; i++){    # loop 1A
4347           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4348           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
4349         }
4350      } 
4351      else {
4352         for (i=0; i<N; i++){    # loop 1B
4353           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4354           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
4355         }
4356      }
4357    
4358      -- Possibility 2: we do loop peeling:
4359      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
4360         x = q[i];
4361         p[i] = y;
4362      }
4363      for (i = 3; i < N; i++){   # loop 2A
4364         x = q[i];                       # DR_MISALIGNMENT(q) = 0
4365         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
4366      }
4367
4368      -- Possibility 3: combination of loop peeling and versioning:
4369      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
4370         x = q[i];
4371         p[i] = y;
4372      }
4373      if (p is aligned) {
4374         for (i = 3; i<N; i++){  # loop 3A
4375           x = q[i];                     # DR_MISALIGNMENT(q) = 0
4376           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
4377         }
4378      } 
4379      else {
4380         for (i = 3; i<N; i++){  # loop 3B
4381           x = q[i];                     # DR_MISALIGNMENT(q) = 0
4382           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
4383         }
4384      }
4385
4386      These loops are later passed to loop_transform to be vectorized. The 
4387      vectorizer will use the alignment information to guide the transformation 
4388      (whether to generate regular loads/stores, or with special handling for 
4389      misalignment). 
4390    */
4391
4392   /* (1) Peeling to force alignment.  */
4393
4394   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
4395      Considerations:
4396      + How many accesses will become aligned due to the peeling
4397      - How many accesses will become unaligned due to the peeling,
4398        and the cost of misaligned accesses.
4399      - The cost of peeling (the extra runtime checks, the increase 
4400        in code size).
4401
4402      The scheme we use FORNOW: peel to force the alignment of the first
4403      misaligned store in the loop.
4404      Rationale: misaligned stores are not yet supported.
4405
4406      TODO: Use a better cost model.  */
4407
4408   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4409     {
4410       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4411       if (!aligned_access_p (dr))
4412         {
4413           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr;
4414           LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo) = true;
4415           break;
4416         }
4417     }
4418
4419   if (!LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4420     {
4421       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
4422         fprintf (dump_file, "Peeling for alignment will not be applied.");
4423       return;
4424     }
4425   else
4426     if (vect_debug_details (LOOP_LOC (loop_vinfo)))
4427       fprintf (dump_file, "Peeling for alignment will be applied.");
4428
4429
4430   /* (1.2) Update the alignment info according to the peeling factor.
4431            If the misalignment of the DR we peel for is M, then the
4432            peeling factor is VF - M, and the misalignment of each access DR_i
4433            in the loop is DR_MISALIGNMENT (DR_i) + VF - M.
4434            If the misalignment of the DR we peel for is unknown, then the 
4435            misalignment of each access DR_i in the loop is also unknown.
4436
4437            FORNOW: set the misalignment of the accesses to unknown even
4438                    if the peeling factor is known at compile time.
4439
4440            TODO: - if the peeling factor is known at compile time, use that
4441                    when updating the misalignment info of the loop DRs.
4442                  - consider accesses that are known to have the same 
4443                    alignment, even if that alignment is unknown.  */
4444    
4445   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4446     {
4447       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4448       if (dr == LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4449         {
4450           DR_MISALIGNMENT (dr) = 0;
4451           if (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4452               || vect_debug_stats (LOOP_LOC (loop_vinfo)))
4453             fprintf (dump_file, "Alignment of access forced using peeling.");
4454         }
4455       else
4456         DR_MISALIGNMENT (dr) = -1;
4457     }
4458   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4459     {
4460       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4461       if (dr == LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4462         {
4463           DR_MISALIGNMENT (dr) = 0;
4464           if (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4465               || vect_debug_stats (LOOP_LOC (loop_vinfo)))
4466             fprintf (dump_file, "Alignment of access forced using peeling.");
4467         }
4468       else
4469         DR_MISALIGNMENT (dr) = -1;
4470     }
4471 }
4472
4473
4474 /* Function vect_analyze_data_refs_alignment
4475
4476    Analyze the alignment of the data-references in the loop.
4477    FOR NOW: Until support for misliagned accesses is in place, only if all
4478    accesses are aligned can the loop be vectorized. This restriction will be 
4479    relaxed.  */ 
4480
4481 static bool
4482 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
4483 {
4484   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4485   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4486   enum dr_alignment_support supportable_dr_alignment;
4487   unsigned int i;
4488
4489   if (vect_debug_details (UNKNOWN_LOC))
4490     fprintf (dump_file, "\n<<vect_analyze_data_refs_alignment>>\n");
4491
4492
4493   /* This pass may take place at function granularity instead of at loop
4494      granularity.  */
4495
4496   if (!vect_compute_data_refs_alignment (loop_vinfo))
4497     {
4498       if (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4499           || vect_debug_stats (LOOP_LOC (loop_vinfo)))
4500         fprintf (dump_file, 
4501                  "not vectorized: can't calculate alignment for data ref.");
4502       return false;
4503     }
4504
4505
4506   /* This pass will decide on using loop versioning and/or loop peeling in 
4507      order to enhance the alignment of data references in the loop.  */
4508
4509   vect_enhance_data_refs_alignment (loop_vinfo);
4510
4511
4512   /* Finally, check that all the data references in the loop can be
4513      handled with respect to their alignment.  */
4514
4515   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4516     {
4517       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4518       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
4519       if (!supportable_dr_alignment)
4520         {
4521           if (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4522               || vect_debug_stats (LOOP_LOC (loop_vinfo)))
4523             fprintf (dump_file, "not vectorized: unsupported unaligned load.");
4524           return false;
4525         }
4526       if (supportable_dr_alignment != dr_aligned 
4527           && (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4528               || vect_debug_stats (LOOP_LOC (loop_vinfo))))
4529         fprintf (dump_file, "Vectorizing an unaligned access.");
4530     }
4531   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4532     {
4533       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4534       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
4535       if (!supportable_dr_alignment)
4536         {
4537           if (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4538               || vect_debug_stats (LOOP_LOC (loop_vinfo)))
4539             fprintf (dump_file, "not vectorized: unsupported unaligned store.");
4540           return false;
4541         }
4542       if (supportable_dr_alignment != dr_aligned 
4543           && (vect_debug_details (LOOP_LOC (loop_vinfo)) 
4544               || vect_debug_stats (LOOP_LOC (loop_vinfo))))
4545         fprintf (dump_file, "Vectorizing an unaligned access.");
4546     }
4547
4548   return true;
4549 }
4550
4551
4552 /* Function vect_analyze_data_ref_access.
4553
4554    Analyze the access pattern of the data-reference DR. For now, a data access
4555    has to consecutive to be considered vectorizable.  */
4556
4557 static bool
4558 vect_analyze_data_ref_access (struct data_reference *dr)
4559 {
4560   tree stmt = DR_STMT (dr);
4561   stmt_vec_info stmt_info = vinfo_for_stmt (stmt); 
4562   tree step = STMT_VINFO_VECT_STEP (stmt_info);
4563   tree scalar_type = TREE_TYPE (DR_REF (dr));
4564
4565   if (!step || tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
4566     {
4567       if (vect_debug_details (UNKNOWN_LOC))
4568         fprintf (dump_file, "not consecutive access");
4569       return false;
4570     }
4571   return true;
4572 }
4573
4574
4575 /* Function vect_analyze_data_ref_accesses.
4576
4577    Analyze the access pattern of all the data references in the loop.
4578
4579    FORNOW: the only access pattern that is considered vectorizable is a
4580            simple step 1 (consecutive) access.
4581
4582    FORNOW: handle only arrays and pointer accesses.  */
4583
4584 static bool
4585 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
4586 {
4587   unsigned int i;
4588   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4589   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4590
4591   if (vect_debug_details (UNKNOWN_LOC))
4592     fprintf (dump_file, "\n<<vect_analyze_data_ref_accesses>>\n");
4593
4594   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4595     {
4596       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4597       bool ok = vect_analyze_data_ref_access (dr);
4598       if (!ok)
4599         {
4600           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
4601               || vect_debug_details (LOOP_LOC (loop_vinfo)))
4602             fprintf (dump_file, "not vectorized: complicated access pattern.");
4603           return false;
4604         }
4605     }
4606
4607   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4608     {
4609       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4610       bool ok = vect_analyze_data_ref_access (dr);
4611       if (!ok)
4612         {
4613           if (vect_debug_stats (LOOP_LOC (loop_vinfo))
4614               || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4615             fprintf (dump_file, "not vectorized: complicated access pattern.");
4616           return false;
4617         }
4618     }
4619
4620   return true;
4621 }
4622
4623
4624 /* Function vect_analyze_pointer_ref_access.
4625
4626    Input:
4627    STMT - a stmt that contains a data-ref
4628    MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
4629
4630    If the data-ref access is vectorizable, return a data_reference structure
4631    that represents it (DR). Otherwise - return NULL.  */
4632
4633 static struct data_reference *
4634 vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read)
4635 {
4636   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4637   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4638   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4639   tree access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
4640   tree init, step;      
4641   tree reftype, innertype;
4642   tree indx_access_fn; 
4643   int loopnum = loop->num;
4644   struct data_reference *dr;
4645
4646   if (!access_fn)
4647     {
4648       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4649           || vect_debug_details (LOOP_LOC (loop_vinfo)))
4650         fprintf (dump_file, "not vectorized: complicated pointer access.");     
4651       return NULL;
4652     }
4653
4654   if (vect_debug_details (UNKNOWN_LOC))
4655     {
4656       fprintf (dump_file, "Access function of ptr: ");
4657       print_generic_expr (dump_file, access_fn, TDF_SLIM);
4658     }
4659
4660   if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step, false))
4661     {
4662       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4663           || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4664         fprintf (dump_file, "not vectorized: pointer access is not simple.");   
4665       return NULL;
4666     }
4667                 
4668   STRIP_NOPS (init);
4669
4670   if (!expr_invariant_in_loop_p (loop, init))
4671     {
4672       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4673           || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4674         fprintf (dump_file, 
4675                  "not vectorized: initial condition is not loop invariant.");   
4676       return NULL;
4677     }
4678
4679   if (TREE_CODE (step) != INTEGER_CST)
4680     {
4681       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4682           || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4683         fprintf (dump_file, 
4684                 "not vectorized: non constant step for pointer access.");       
4685       return NULL;
4686     }
4687
4688   reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
4689   if (TREE_CODE (reftype) != POINTER_TYPE) 
4690     {
4691       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4692           || vect_debug_details (LOOP_LOC (loop_vinfo)))
4693         fprintf (dump_file, "not vectorized: unexpected pointer access form."); 
4694       return NULL;
4695     }
4696
4697   reftype = TREE_TYPE (init);
4698   if (TREE_CODE (reftype) != POINTER_TYPE) 
4699     {
4700       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4701           || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4702         fprintf (dump_file, "not vectorized: unexpected pointer access form.");
4703       return NULL;
4704     }
4705
4706   innertype = TREE_TYPE (reftype);
4707   if (tree_int_cst_compare (TYPE_SIZE_UNIT (innertype), step))
4708     {
4709       /* FORNOW: support only consecutive access */
4710       if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
4711           || vect_debug_details (LOOP_LOC (loop_vinfo))) 
4712         fprintf (dump_file, "not vectorized: non consecutive access."); 
4713       return NULL;
4714     }
4715
4716   STMT_VINFO_VECT_STEP (stmt_info) = fold_convert (ssizetype, step);
4717   if (TREE_CODE (init) == PLUS_EXPR 
4718       || TREE_CODE (init) == MINUS_EXPR)
4719     STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = 
4720       size_binop (TREE_CODE (init), ssize_int (0),  
4721                   fold_convert (ssizetype, TREE_OPERAND (init, 1)));
4722   else
4723     STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = ssize_int (0);
4724
4725   indx_access_fn = 
4726         build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
4727   if (vect_debug_details (LOOP_LOC (loop_vinfo))) 
4728     {
4729       fprintf (dump_file, "Access function of ptr indx: ");
4730       print_generic_expr (dump_file, indx_access_fn, TDF_SLIM);
4731     }
4732   dr = init_data_ref (stmt, memref, init, indx_access_fn, is_read);
4733   return dr;
4734 }
4735
4736
4737 /* Function vect_get_memtag_and_dr.  
4738
4739    The function returns the relevant variable for memory tag (for aliasing 
4740    purposes). Also data reference structure DR is created.  
4741
4742    This function handles three kinds of MEMREF:
4743
4744    It is called from vect_analyze_data_refs with a MEMREF that is either an 
4745    ARRAY_REF or an INDIRECT_REF (this is category 1 - "recursion begins"). 
4746    It builds a DR for them using vect_get_base_and_offset, and calls itself 
4747    recursively to retrieve the relevant memtag for the MEMREF, "peeling" the 
4748    MEMREF along the way. During the recursive calls, the function may be called 
4749    with a MEMREF for which the recursion has to continue - PLUS_EXPR, 
4750    MINUS_EXPR, INDIRECT_REF (category 2 - "recursion continues"), 
4751    and/or with a MEMREF for which a memtag can be trivially obtained - VAR_DECL 
4752    and SSA_NAME (this is category 3 - "recursion stop condition"). 
4753
4754    When the MEMREF falls into category 1 there is still no data reference struct 
4755    (DR) available. It is created by this function, and then, along the 
4756    recursion, MEMREF will fall into category 2 or 3, in which case a DR will 
4757    have already been created, but the analysis continues to retrieve the MEMTAG.
4758
4759    Input:
4760    MEMREF - data reference in STMT
4761    IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
4762    
4763    Output:
4764    DR - data_reference struct for MEMREF
4765    return value - the relevant variable for memory tag (for aliasing purposes).
4766
4767 */ 
4768
4769 static tree
4770 vect_get_memtag_and_dr (tree memref, tree stmt, bool is_read, 
4771                         loop_vec_info loop_vinfo, 
4772                         tree vectype, struct data_reference **dr)
4773 {
4774   tree symbl, oprnd0, oprnd1;
4775   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4776   tree offset, misalign, step;
4777   tree ref_to_be_analyzed, tag, dr_base;
4778   struct data_reference *new_dr;
4779   bool base_aligned_p;
4780
4781   if (*dr)
4782     {
4783       /* Category 3: recursion stop condition.  */
4784       /* (1) A DR already exists. We only need to get the relevant memtag for
4785          MEMREF, the rest of the data was already initialized.  */
4786
4787       switch (TREE_CODE (memref))
4788         {
4789           /* (1.1) Stop condition: find the relevant memtag and return.  */
4790         case SSA_NAME:
4791           symbl = SSA_NAME_VAR (memref);
4792           tag = get_var_ann (symbl)->type_mem_tag;
4793           if (!tag)
4794             {
4795               tree ptr = TREE_OPERAND (DR_REF ((*dr)), 0);
4796               if (TREE_CODE (ptr) == SSA_NAME)
4797                 tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
4798             }
4799           if (!tag)
4800             {
4801               if (vect_debug_details (UNKNOWN_LOC))
4802                 fprintf (dump_file, "not vectorized: no memtag for ref.");
4803               return NULL_TREE;
4804             }
4805           return tag;
4806
4807         case VAR_DECL:
4808         case PARM_DECL:
4809           return memref;
4810
4811           /* Category 2: recursion continues.  */
4812           /* (1.2) A recursive call to find the relevant memtag is required.  */
4813         case INDIRECT_REF:
4814           symbl = TREE_OPERAND (memref, 0); 
4815           break; /* For recursive call.  */
4816
4817         case COMPONENT_REF:
4818           /* Could have recorded more accurate information - 
4819              i.e, the actual FIELD_DECL that is being referenced -
4820              but later passes expect VAR_DECL as the nmt.  */
4821           /* Fall through.  */
4822         
4823         case ADDR_EXPR:
4824           symbl = STMT_VINFO_VECT_DR_BASE (stmt_info);
4825           break; /* For recursive call.  */
4826
4827         case PLUS_EXPR:
4828         case MINUS_EXPR:
4829           /* Although DR exists, we have to call the function recursively to 
4830              build MEMTAG for such expression. This is handled below.  */
4831           oprnd0 = TREE_OPERAND (memref, 0);
4832           oprnd1 = TREE_OPERAND (memref, 1);
4833       
4834           STRIP_NOPS (oprnd1); 
4835            /* Supported plus/minus expressions are of the form 
4836              {address_base + offset}, such that address_base is of type 
4837              POINTER/ARRAY, and offset is either an INTEGER_CST of type POINTER, 
4838              or it's not of type POINTER/ARRAY. 
4839              TODO: swap operands if {offset + address_base}.  */
4840           if ((TREE_CODE (TREE_TYPE (oprnd1)) == POINTER_TYPE 
4841                && TREE_CODE (oprnd1) != INTEGER_CST)
4842               || TREE_CODE (TREE_TYPE (oprnd1)) == ARRAY_TYPE)
4843             return NULL_TREE;
4844       
4845           symbl = oprnd0;        
4846           break; /* For recursive call.  */
4847
4848         default:
4849           return NULL_TREE;
4850         }
4851     }  
4852   else
4853     {
4854       /* Category 1: recursion begins.  */
4855       /* (2) A DR does not exist yet and must be built, followed by a
4856          recursive call to get the relevant memtag for MEMREF.  */
4857
4858       switch (TREE_CODE (memref))
4859         {      
4860         case INDIRECT_REF:
4861           new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read);
4862           if (!new_dr)
4863             return NULL_TREE; 
4864           *dr = new_dr;
4865           symbl = DR_BASE_NAME (new_dr);
4866           ref_to_be_analyzed = DR_BASE_NAME (new_dr);
4867           break;
4868       
4869         case ARRAY_REF:
4870           new_dr = analyze_array (stmt, memref, is_read);
4871           *dr = new_dr;
4872           symbl = DR_BASE_NAME (new_dr);
4873           ref_to_be_analyzed = memref;
4874           break;
4875
4876         default:
4877           /* TODO: Support data-refs of form a[i].p for unions and single
4878              field structures.  */
4879           return NULL_TREE;
4880         }  
4881
4882       offset = ssize_int (0);
4883       misalign = ssize_int (0);
4884       step = ssize_int (0);
4885
4886       /* Analyze data-ref, find its base, initial offset from the base, step,
4887          and alignment.  */
4888       dr_base = vect_get_base_and_offset (new_dr, ref_to_be_analyzed, 
4889                                           vectype, loop_vinfo, &offset, 
4890                                           &misalign, &step, &base_aligned_p);
4891       if (!dr_base)
4892         return NULL_TREE;
4893     
4894       /* Initialize information according to above analysis.  */
4895       /* Since offset and step of a pointer can be also set in
4896          vect_analyze_pointer_ref_access, we combine the values here. */
4897       if (STMT_VINFO_VECT_INIT_OFFSET (stmt_info))
4898         STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = 
4899           size_binop (PLUS_EXPR, offset, 
4900                       STMT_VINFO_VECT_INIT_OFFSET (stmt_info));           
4901       else
4902         STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
4903
4904       if (step && STMT_VINFO_VECT_STEP (stmt_info))
4905         STMT_VINFO_VECT_STEP (stmt_info) = 
4906           size_binop (PLUS_EXPR, step, STMT_VINFO_VECT_STEP (stmt_info));
4907       else
4908         STMT_VINFO_VECT_STEP (stmt_info) = step;
4909
4910       STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info) = base_aligned_p;
4911       STMT_VINFO_VECT_MISALIGNMENT (stmt_info) = misalign;
4912       STMT_VINFO_VECT_DR_BASE (stmt_info) = dr_base;         
4913     }
4914
4915   if (!symbl)
4916     return NULL_TREE;
4917   /* Recursive call to retrieve the relevant memtag.  */
4918   tag = vect_get_memtag_and_dr (symbl, stmt, is_read, loop_vinfo, vectype, dr);
4919   return tag;
4920 }
4921
4922
4923 /* Function vect_analyze_data_refs.
4924
4925    Find all the data references in the loop.
4926
4927    The general structure of the analysis of data refs in the vectorizer is as 
4928    follows:
4929    1- vect_analyze_data_refs(loop): 
4930       Find and analyze all data-refs in the loop:
4931           foreach ref
4932              ref_stmt.memtag =  vect_get_memtag_and_dr (ref)
4933    1.1- vect_get_memtag_and_dr(ref): 
4934       Analyze ref, and build a DR (data_referece struct) for it;
4935       call vect_get_base_and_offset to compute base, initial_offset, 
4936       step and alignment. Set ref_stmt.base, ref_stmt.initial_offset,
4937       ref_stmt.alignment, and ref_stmt.step accordingly. 
4938    1.1.1- vect_get_base_and_offset():
4939       Calculate base, initial_offset, step and alignment.      
4940       For ARRAY_REFs and COMPONENT_REFs use call get_inner_reference.
4941    2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
4942    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
4943    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
4944
4945    FORNOW: Handle aligned INDIRECT_REFs and ARRAY_REFs 
4946            which base is really an array (not a pointer) and which alignment 
4947            can be forced. This restriction will be relaxed.  */
4948
4949 static bool
4950 vect_analyze_data_refs (loop_vec_info loop_vinfo)
4951 {
4952   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4953   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
4954   int nbbs = loop->num_nodes;
4955   block_stmt_iterator si;
4956   int j;
4957   struct data_reference *dr;
4958
4959   if (vect_debug_details (UNKNOWN_LOC))
4960     fprintf (dump_file, "\n<<vect_analyze_data_refs>>\n");
4961
4962   for (j = 0; j < nbbs; j++)
4963     {
4964       basic_block bb = bbs[j];
4965       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
4966         {
4967           bool is_read = false;
4968           tree stmt = bsi_stmt (si);
4969           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4970           v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
4971           v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
4972           vuse_optype vuses = STMT_VUSE_OPS (stmt);
4973           varray_type *datarefs = NULL;
4974           int nvuses, nv_may_defs, nv_must_defs;
4975           tree memref = NULL;
4976           tree symbl;
4977           tree scalar_type, vectype;
4978
4979           /* Assumption: there exists a data-ref in stmt, if and only if 
4980              it has vuses/vdefs.  */
4981
4982           if (!vuses && !v_may_defs && !v_must_defs)
4983             continue;
4984
4985           nvuses = NUM_VUSES (vuses);
4986           nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
4987           nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
4988
4989           if (nvuses && (nv_may_defs || nv_must_defs))
4990             {
4991               if (vect_debug_details (UNKNOWN_LOC))
4992                 {
4993                   fprintf (dump_file, "unexpected vdefs and vuses in stmt: ");
4994                   print_generic_expr (dump_file, stmt, TDF_SLIM);
4995                 }
4996               return false;
4997             }
4998
4999           if (TREE_CODE (stmt) != MODIFY_EXPR)
5000             {
5001               if (vect_debug_details (UNKNOWN_LOC))
5002                 {
5003                   fprintf (dump_file, "unexpected vops in stmt: ");
5004                   print_generic_expr (dump_file, stmt, TDF_SLIM);
5005                 }
5006               return false;
5007             }
5008
5009           if (vuses)
5010             {
5011               memref = TREE_OPERAND (stmt, 1);
5012               datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
5013               is_read = true;
5014             } 
5015           else /* vdefs */
5016             {
5017               memref = TREE_OPERAND (stmt, 0);
5018               datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
5019               is_read = false;
5020             }
5021           
5022           scalar_type = TREE_TYPE (memref);
5023           vectype = get_vectype_for_scalar_type (scalar_type);
5024           if (!vectype)
5025             {
5026               if (vect_debug_details (UNKNOWN_LOC))
5027                 {
5028                   fprintf (dump_file, "no vectype for stmt: ");
5029                   print_generic_expr (dump_file, stmt, TDF_SLIM);
5030                   fprintf (dump_file, " scalar_type: ");
5031                   print_generic_expr (dump_file, scalar_type, TDF_DETAILS);
5032                 }
5033               /* It is not possible to vectorize this data reference.  */
5034               return false;
5035             }
5036           /* Analyze MEMREF. If it is of a supported form, build data_reference
5037              struct for it (DR) and find memtag for aliasing purposes.  */
5038           dr = NULL;
5039           symbl = vect_get_memtag_and_dr (memref, stmt, is_read, loop_vinfo, 
5040                                           vectype, &dr);
5041           if (!symbl)
5042             {
5043               if (vect_debug_stats (LOOP_LOC (loop_vinfo)) 
5044                   || vect_debug_details (LOOP_LOC (loop_vinfo)))
5045                 {
5046                   fprintf (dump_file, "not vectorized: unhandled data ref: "); 
5047                   print_generic_expr (dump_file, stmt, TDF_SLIM);
5048                 }
5049               return false;
5050             }
5051           STMT_VINFO_MEMTAG (stmt_info) = symbl;
5052           STMT_VINFO_VECTYPE (stmt_info) = vectype;
5053           VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
5054           STMT_VINFO_DATA_REF (stmt_info) = dr;
5055         }
5056     }
5057
5058   return true;
5059 }
5060
5061
5062 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
5063
5064 /* Function vect_mark_relevant.
5065
5066    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
5067
5068 static void
5069 vect_mark_relevant (varray_type *worklist, tree stmt)
5070 {
5071   stmt_vec_info stmt_info;
5072
5073   if (vect_debug_details (UNKNOWN_LOC))
5074     fprintf (dump_file, "mark relevant.");
5075
5076   if (TREE_CODE (stmt) == PHI_NODE)
5077     {
5078       VARRAY_PUSH_TREE (*worklist, stmt);
5079       return;
5080     }
5081
5082   stmt_info = vinfo_for_stmt (stmt);
5083
5084   if (!stmt_info)
5085     {
5086       if (vect_debug_details (UNKNOWN_LOC))
5087         {
5088           fprintf (dump_file, "mark relevant: no stmt info!!.");
5089           print_generic_expr (dump_file, stmt, TDF_SLIM);
5090         }
5091       return;
5092     }
5093
5094   if (STMT_VINFO_RELEVANT_P (stmt_info))
5095     {
5096       if (vect_debug_details (UNKNOWN_LOC))
5097         fprintf (dump_file, "already marked relevant.");
5098       return;
5099     }
5100
5101   STMT_VINFO_RELEVANT_P (stmt_info) = 1;
5102   VARRAY_PUSH_TREE (*worklist, stmt);
5103 }
5104
5105
5106 /* Function vect_stmt_relevant_p.
5107
5108    Return true if STMT in loop that is represented by LOOP_VINFO is
5109    "relevant for vectorization".
5110
5111    A stmt is considered "relevant for vectorization" if:
5112    - it has uses outside the loop.
5113    - it has vdefs (it alters memory).
5114    - control stmts in the loop (except for the exit condition).
5115
5116    CHECKME: what other side effects would the vectorizer allow?  */
5117
5118 static bool
5119 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
5120 {
5121   v_may_def_optype v_may_defs;
5122   v_must_def_optype v_must_defs;
5123   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5124   int i;
5125   dataflow_t df;
5126   int num_uses;
5127
5128   /* cond stmt other than loop exit cond.  */
5129   if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
5130     return true;
5131
5132   /* changing memory.  */
5133   v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
5134   v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
5135   if (v_may_defs || v_must_defs)
5136     {
5137       if (vect_debug_details (UNKNOWN_LOC))
5138         fprintf (dump_file, "vec_stmt_relevant_p: stmt has vdefs.");
5139       return true;
5140     }
5141
5142   /* uses outside the loop.  */
5143   df = get_immediate_uses (stmt);
5144   num_uses = num_immediate_uses (df);
5145   for (i = 0; i < num_uses; i++)
5146     {
5147       tree use = immediate_use (df, i);
5148       basic_block bb = bb_for_stmt (use);
5149       if (!flow_bb_inside_loop_p (loop, bb))
5150         {
5151           if (vect_debug_details (UNKNOWN_LOC))
5152             fprintf (dump_file, "vec_stmt_relevant_p: used out of loop.");
5153           return true;
5154         }
5155     }
5156
5157   return false;
5158 }
5159
5160
5161 /* Function vect_mark_stmts_to_be_vectorized.
5162
5163    Not all stmts in the loop need to be vectorized. For example:
5164
5165      for i...
5166        for j...
5167    1.    T0 = i + j
5168    2.    T1 = a[T0]
5169
5170    3.    j = j + 1
5171
5172    Stmt 1 and 3 do not need to be vectorized, because loop control and
5173    addressing of vectorized data-refs are handled differently.
5174
5175    This pass detects such stmts.  */
5176
5177 static bool
5178 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
5179 {
5180   varray_type worklist;
5181   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5182   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
5183   unsigned int nbbs = loop->num_nodes;
5184   block_stmt_iterator si;
5185   tree stmt;
5186   stmt_ann_t ann;
5187   unsigned int i;
5188   int j;
5189   use_optype use_ops;
5190   stmt_vec_info stmt_info;
5191   basic_block bb;
5192   tree phi;
5193
5194   if (vect_debug_details (UNKNOWN_LOC))
5195     fprintf (dump_file, "\n<<vect_mark_stmts_to_be_vectorized>>\n");
5196
5197   bb = loop->header;
5198   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
5199     {
5200       if (vect_debug_details (UNKNOWN_LOC))
5201         {
5202           fprintf (dump_file, "init: phi relevant? ");
5203           print_generic_expr (dump_file, phi, TDF_SLIM);
5204         }
5205
5206       if (vect_stmt_relevant_p (phi, loop_vinfo))
5207         {
5208           if (vect_debug_details (UNKNOWN_LOC))
5209             fprintf (dump_file, "unsupported reduction/induction.");
5210           return false;
5211         }
5212     }
5213
5214   VARRAY_TREE_INIT (worklist, 64, "work list");
5215
5216   /* 1. Init worklist.  */
5217
5218   for (i = 0; i < nbbs; i++)
5219     {
5220       bb = bbs[i];
5221       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
5222         {
5223           stmt = bsi_stmt (si);
5224
5225           if (vect_debug_details (UNKNOWN_LOC))
5226             {
5227               fprintf (dump_file, "init: stmt relevant? ");
5228               print_generic_expr (dump_file, stmt, TDF_SLIM);
5229             } 
5230
5231           stmt_info = vinfo_for_stmt (stmt);
5232           STMT_VINFO_RELEVANT_P (stmt_info) = 0;
5233
5234           if (vect_stmt_relevant_p (stmt, loop_vinfo))
5235             vect_mark_relevant (&worklist, stmt);
5236         }
5237     }
5238
5239
5240   /* 2. Process_worklist */
5241
5242   while (VARRAY_ACTIVE_SIZE (worklist) > 0)
5243     {
5244       stmt = VARRAY_TOP_TREE (worklist);
5245       VARRAY_POP (worklist);
5246
5247       if (vect_debug_details (UNKNOWN_LOC))
5248         {
5249           fprintf (dump_file, "worklist: examine stmt: ");
5250           print_generic_expr (dump_file, stmt, TDF_SLIM);
5251         }
5252
5253       /* Examine the USES in this statement. Mark all the statements which
5254          feed this statement's uses as "relevant", unless the USE is used as
5255          an array index.  */
5256
5257       if (TREE_CODE (stmt) == PHI_NODE)
5258         {
5259           /* follow the def-use chain inside the loop.  */
5260           for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
5261             {
5262               tree arg = PHI_ARG_DEF (stmt, j);
5263               tree def_stmt = NULL_TREE;
5264               basic_block bb;
5265               if (!vect_is_simple_use (arg, loop_vinfo, &def_stmt))
5266                 {
5267                   if (vect_debug_details (UNKNOWN_LOC)) 
5268                     fprintf (dump_file, "worklist: unsupported use.");
5269                   varray_clear (worklist);
5270                   return false;
5271                 }
5272               if (!def_stmt)
5273                 continue;
5274
5275               if (vect_debug_details (UNKNOWN_LOC))
5276                 {
5277                   fprintf (dump_file, "worklist: def_stmt: ");
5278                   print_generic_expr (dump_file, def_stmt, TDF_SLIM);
5279                 }
5280
5281               bb = bb_for_stmt (def_stmt);
5282               if (flow_bb_inside_loop_p (loop, bb))
5283                 vect_mark_relevant (&worklist, def_stmt);
5284             }
5285         } 
5286
5287       ann = stmt_ann (stmt);
5288       use_ops = USE_OPS (ann);
5289
5290       for (i = 0; i < NUM_USES (use_ops); i++)
5291         {
5292           tree use = USE_OP (use_ops, i);
5293
5294           /* We are only interested in uses that need to be vectorized. Uses 
5295              that are used for address computation are not considered relevant.
5296            */
5297           if (exist_non_indexing_operands_for_use_p (use, stmt))
5298             {
5299               tree def_stmt = NULL_TREE;
5300               basic_block bb;
5301               if (!vect_is_simple_use (use, loop_vinfo, &def_stmt))
5302                 {
5303                   if (vect_debug_details (UNKNOWN_LOC))        
5304                     fprintf (dump_file, "worklist: unsupported use.");
5305                   varray_clear (worklist);
5306                   return false;
5307                 }
5308
5309               if (!def_stmt)
5310                 continue;
5311
5312               if (vect_debug_details (UNKNOWN_LOC))
5313                 {
5314                   fprintf (dump_file, "worklist: examine use %d: ", i);
5315                   print_generic_expr (dump_file, use, TDF_SLIM);
5316                 }
5317
5318               bb = bb_for_stmt (def_stmt);
5319               if (flow_bb_inside_loop_p (loop, bb))
5320                 vect_mark_relevant (&worklist, def_stmt);
5321             }
5322         }
5323     }                           /* while worklist */
5324
5325   varray_clear (worklist);
5326   return true;
5327 }
5328
5329
5330 /* Function vect_can_advance_ivs_p
5331
5332    In case the number of iterations that LOOP iterates in unknown at compile 
5333    time, an epilog loop will be generated, and the loop induction variables 
5334    (IVs) will be "advanced" to the value they are supposed to take just before 
5335    the epilog loop.  Here we check that the access function of the loop IVs
5336    and the expression that represents the loop bound are simple enough.
5337    These restrictions will be relaxed in the future.  */
5338
5339 static bool 
5340 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
5341 {
5342   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5343   basic_block bb = loop->header;
5344   tree phi;
5345
5346   /* Analyze phi functions of the loop header.  */
5347
5348   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
5349     {
5350       tree access_fn = NULL;
5351       tree evolution_part;
5352
5353       if (vect_debug_details (UNKNOWN_LOC))
5354         {
5355           fprintf (dump_file, "Analyze phi: ");
5356           print_generic_expr (dump_file, phi, TDF_SLIM);
5357         }
5358
5359       /* Skip virtual phi's. The data dependences that are associated with
5360          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
5361
5362       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
5363         {
5364           if (vect_debug_details (UNKNOWN_LOC))
5365             fprintf (dump_file, "virtual phi. skip.");
5366           continue;
5367         }
5368
5369       /* Analyze the evolution function.  */
5370
5371       access_fn = instantiate_parameters
5372         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
5373
5374       if (!access_fn)
5375         {
5376           if (vect_debug_details (UNKNOWN_LOC))
5377             fprintf (dump_file, "No Access function.");
5378           return false;
5379         }
5380
5381       if (vect_debug_details (UNKNOWN_LOC))
5382         {
5383           fprintf (dump_file, "Access function of PHI: ");
5384           print_generic_expr (dump_file, access_fn, TDF_SLIM);
5385         }
5386
5387       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
5388       
5389       if (evolution_part == NULL_TREE)
5390         return false;
5391   
5392       /* FORNOW: We do not transform initial conditions of IVs 
5393          which evolution functions are a polynomial of degree >= 2.  */
5394
5395       if (tree_is_chrec (evolution_part))
5396         return false;  
5397     }
5398
5399   return true;
5400 }
5401
5402
5403 /* Function vect_get_loop_niters.
5404
5405    Determine how many iterations the loop is executed.
5406    If an expression that represents the number of iterations
5407    can be constructed, place it in NUMBER_OF_ITERATIONS.
5408    Return the loop exit condition.  */
5409
5410 static tree
5411 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
5412 {
5413   tree niters;
5414
5415   if (vect_debug_details (UNKNOWN_LOC))
5416     fprintf (dump_file, "\n<<get_loop_niters>>\n");
5417
5418   niters = number_of_iterations_in_loop (loop);
5419
5420   if (niters != NULL_TREE
5421       && niters != chrec_dont_know)
5422     {
5423       *number_of_iterations = niters;
5424
5425       if (vect_debug_details (UNKNOWN_LOC))
5426         {
5427           fprintf (dump_file, "==> get_loop_niters:" );
5428           print_generic_expr (dump_file, *number_of_iterations, TDF_SLIM);
5429         }
5430     }
5431
5432   return get_loop_exit_condition (loop);
5433 }
5434
5435
5436 /* Function vect_analyze_loop_form.
5437
5438    Verify the following restrictions (some may be relaxed in the future):
5439    - it's an inner-most loop
5440    - number of BBs = 2 (which are the loop header and the latch)
5441    - the loop has a pre-header
5442    - the loop has a single entry and exit
5443    - the loop exit condition is simple enough, and the number of iterations
5444      can be analyzed (a countable loop).  */
5445
5446 static loop_vec_info
5447 vect_analyze_loop_form (struct loop *loop)
5448 {
5449   loop_vec_info loop_vinfo;
5450   tree loop_cond;
5451   tree number_of_iterations = NULL;
5452   bool rescan = false;
5453   LOC loop_loc;
5454
5455   loop_loc = find_loop_location (loop);
5456
5457   if (vect_debug_details (loop_loc))
5458     fprintf (dump_file, "\n<<vect_analyze_loop_form>>\n");
5459
5460   if (loop->inner
5461       || !loop->single_exit
5462       || loop->num_nodes != 2
5463       || EDGE_COUNT (loop->header->preds) != 2
5464       || loop->num_entries != 1)
5465     {
5466       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc)) 
5467         {
5468           fprintf (dump_file, "not vectorized: bad loop form. ");
5469           if (loop->inner)
5470             fprintf (dump_file, "nested loop.");
5471           else if (!loop->single_exit)
5472             fprintf (dump_file, "multiple exits.");
5473           else if (loop->num_nodes != 2)
5474             fprintf (dump_file, "too many BBs in loop.");
5475           else if (EDGE_COUNT (loop->header->preds) != 2)
5476             fprintf (dump_file, "too many incoming edges.");
5477           else if (loop->num_entries != 1)
5478             fprintf (dump_file, "too many entries.");
5479         }
5480
5481       return NULL;
5482     }
5483
5484   /* We assume that the loop exit condition is at the end of the loop. i.e,
5485      that the loop is represented as a do-while (with a proper if-guard
5486      before the loop if needed), where the loop header contains all the
5487      executable statements, and the latch is empty.  */
5488   if (!empty_block_p (loop->latch))
5489     {
5490       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc))
5491         fprintf (dump_file, "not vectorized: unexpectd loop form.");
5492       return NULL;
5493     }
5494
5495   /* Make sure we have a preheader basic block.  */
5496   if (!loop->pre_header)
5497     {
5498       rescan = true;
5499       loop_split_edge_with (loop_preheader_edge (loop), NULL);
5500     }
5501     
5502   /* Make sure there exists a single-predecessor exit bb:  */
5503   if (EDGE_COUNT (loop->exit_edges[0]->dest->preds) != 1)
5504     {
5505       rescan = true;
5506       loop_split_edge_with (loop->exit_edges[0], NULL);
5507     }
5508     
5509   if (rescan)
5510     {
5511       flow_loop_scan (loop, LOOP_ALL);
5512       /* Flow loop scan does not update loop->single_exit field.  */
5513       loop->single_exit = loop->exit_edges[0];
5514     }
5515
5516   if (empty_block_p (loop->header))
5517     {
5518       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc))
5519         fprintf (dump_file, "not vectorized: empty loop.");
5520       return NULL;
5521     }
5522
5523   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
5524   if (!loop_cond)
5525     {
5526       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc))
5527         fprintf (dump_file, "not vectorized: complicated exit condition.");
5528       return NULL;
5529     }
5530   
5531   if (!number_of_iterations) 
5532     {
5533       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc))
5534         fprintf (dump_file, 
5535                  "not vectorized: number of iterations cannot be computed.");
5536       return NULL;
5537     }
5538
5539   if (chrec_contains_undetermined (number_of_iterations))
5540     {
5541       if (vect_debug_details (loop_loc))
5542         fprintf (dump_file, "Infinite number of iterations.");
5543       return false;
5544     }
5545
5546   loop_vinfo = new_loop_vec_info (loop);
5547   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
5548
5549   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
5550     {
5551       if (vect_debug_details (loop_loc))
5552         {
5553           fprintf (dump_file, "loop bound unknown.\n");
5554           fprintf (dump_file, "Symbolic number of iterations is ");
5555           print_generic_expr (dump_file, number_of_iterations, TDF_DETAILS);
5556         }
5557     }
5558   else
5559   if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
5560     {
5561       if (vect_debug_stats (loop_loc) || vect_debug_details (loop_loc))
5562         fprintf (dump_file, "not vectorized: number of iterations = 0.");
5563       return NULL;
5564     }
5565
5566   LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
5567   LOOP_VINFO_LOC (loop_vinfo) = loop_loc;
5568
5569   return loop_vinfo;
5570 }
5571
5572
5573 /* Function vect_analyze_loop.
5574
5575    Apply a set of analyses on LOOP, and create a loop_vec_info struct
5576    for it. The different analyses will record information in the
5577    loop_vec_info struct.  */
5578
5579 static loop_vec_info
5580 vect_analyze_loop (struct loop *loop)
5581 {
5582   bool ok;
5583   loop_vec_info loop_vinfo;
5584
5585   if (vect_debug_details (UNKNOWN_LOC))
5586     fprintf (dump_file, "\n<<<<<<< analyze_loop_nest >>>>>>>\n");
5587
5588   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
5589
5590   loop_vinfo = vect_analyze_loop_form (loop);
5591   if (!loop_vinfo)
5592     {
5593       if (vect_debug_details (UNKNOWN_LOC))
5594         fprintf (dump_file, "bad loop form.");
5595       return NULL;
5596     }
5597
5598   /* Find all data references in the loop (which correspond to vdefs/vuses)
5599      and analyze their evolution in the loop.
5600
5601      FORNOW: Handle only simple, array references, which
5602      alignment can be forced, and aligned pointer-references.  */
5603
5604   ok = vect_analyze_data_refs (loop_vinfo);
5605   if (!ok)
5606     {
5607       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5608         fprintf (dump_file, "bad data references.");
5609       destroy_loop_vec_info (loop_vinfo);
5610       return NULL;
5611     }
5612
5613   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
5614
5615   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
5616   if (!ok)
5617     {
5618       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5619         fprintf (dump_file, "unexpected pattern.");
5620       if (vect_debug_stats (LOOP_LOC (loop_vinfo)))
5621         fprintf (dump_file, "not vectorized: unexpected pattern.");
5622       destroy_loop_vec_info (loop_vinfo);
5623       return NULL;
5624     }
5625
5626   /* Check that all cross-iteration scalar data-flow cycles are OK.
5627      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
5628
5629   ok = vect_analyze_scalar_cycles (loop_vinfo);
5630   if (!ok)
5631     {
5632       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5633         fprintf (dump_file, "bad scalar cycle.");
5634       destroy_loop_vec_info (loop_vinfo);
5635       return NULL;
5636     }
5637
5638   /* Analyze data dependences between the data-refs in the loop. 
5639      FORNOW: fail at the first data dependence that we encounter.  */
5640
5641   ok = vect_analyze_data_ref_dependences (loop_vinfo);
5642   if (!ok)
5643     {
5644       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5645         fprintf (dump_file, "bad data dependence.");
5646       destroy_loop_vec_info (loop_vinfo);
5647       return NULL;
5648     }
5649
5650   /* Analyze the access patterns of the data-refs in the loop (consecutive,
5651      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
5652
5653   ok = vect_analyze_data_ref_accesses (loop_vinfo);
5654   if (!ok)
5655     {
5656       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5657         fprintf (dump_file, "bad data access.");
5658       destroy_loop_vec_info (loop_vinfo);
5659       return NULL;
5660     }
5661
5662   /* Analyze the alignment of the data-refs in the loop.
5663      FORNOW: Only aligned accesses are handled.  */
5664
5665   ok = vect_analyze_data_refs_alignment (loop_vinfo);
5666   if (!ok)
5667     {
5668       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5669         fprintf (dump_file, "bad data alignment.");
5670       destroy_loop_vec_info (loop_vinfo);
5671       return NULL;
5672     }
5673
5674   /* Scan all the operations in the loop and make sure they are
5675      vectorizable.  */
5676
5677   ok = vect_analyze_operations (loop_vinfo);
5678   if (!ok)
5679     {
5680       if (vect_debug_details (LOOP_LOC (loop_vinfo)))
5681         fprintf (dump_file, "bad operation or unsupported loop bound.");
5682       destroy_loop_vec_info (loop_vinfo);
5683       return NULL;
5684     }
5685
5686   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
5687
5688   return loop_vinfo;
5689 }
5690
5691
5692 /* Function need_imm_uses_for.
5693
5694    Return whether we ought to include information for 'var'
5695    when calculating immediate uses.  For this pass we only want use
5696    information for non-virtual variables.  */
5697
5698 static bool
5699 need_imm_uses_for (tree var)
5700 {
5701   return is_gimple_reg (var);
5702 }
5703
5704
5705 /* Function vectorize_loops.
5706    
5707    Entry Point to loop vectorization phase.  */
5708
5709 void
5710 vectorize_loops (struct loops *loops)
5711 {
5712   unsigned int i, loops_num;
5713   unsigned int num_vectorized_loops = 0;
5714
5715   /* Does the target support SIMD?  */
5716   /* FORNOW: until more sophisticated machine modelling is in place.  */
5717   if (!UNITS_PER_SIMD_WORD)
5718     {
5719       if (vect_debug_details (UNKNOWN_LOC))
5720         fprintf (dump_file, "vectorizer: target vector size is not defined.");
5721       return;
5722     }
5723
5724 #ifdef ENABLE_CHECKING
5725   verify_loop_closed_ssa ();
5726 #endif
5727
5728   compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
5729
5730   /*  ----------- Analyze loops. -----------  */
5731
5732   /* If some loop was duplicated, it gets bigger number 
5733      than all previously defined loops. This fact allows us to run 
5734      only over initial loops skipping newly generated ones.  */
5735   loops_num = loops->num;
5736   for (i = 1; i < loops_num; i++)
5737     {
5738       loop_vec_info loop_vinfo;
5739       struct loop *loop = loops->parray[i];
5740
5741       if (!loop)
5742         continue;
5743
5744       loop_vinfo = vect_analyze_loop (loop);
5745       loop->aux = loop_vinfo;
5746
5747       if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
5748         continue;
5749
5750       vect_transform_loop (loop_vinfo, loops); 
5751       num_vectorized_loops++;
5752     }
5753
5754   if (vect_debug_stats (UNKNOWN_LOC) || vect_debug_details (UNKNOWN_LOC))
5755     fprintf (dump_file, "\nvectorized %u loops in function.\n",
5756              num_vectorized_loops);
5757
5758   /*  ----------- Finalize. -----------  */
5759
5760   free_df ();
5761   for (i = 1; i < loops_num; i++)
5762     {
5763       struct loop *loop = loops->parray[i];
5764       loop_vec_info loop_vinfo;
5765
5766       if (!loop)
5767         continue;
5768       loop_vinfo = loop->aux;
5769       destroy_loop_vec_info (loop_vinfo);
5770       loop->aux = NULL;
5771     }
5772
5773   rewrite_into_ssa (false);
5774   rewrite_into_loop_closed_ssa (); /* FORNOW */
5775   bitmap_clear (vars_to_rename);
5776 }