OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-loop.c
index 051d340..978442d 100644 (file)
@@ -565,11 +565,15 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
       /* Analyze the evolution function.  */
       access_fn = analyze_scalar_evolution (loop, def);
       if (access_fn)
-       STRIP_NOPS (access_fn);
-      if (access_fn && vect_print_dump_info (REPORT_DETAILS))
        {
-         fprintf (vect_dump, "Access function of PHI: ");
-         print_generic_expr (vect_dump, access_fn, TDF_SLIM);
+         STRIP_NOPS (access_fn);
+         if (vect_print_dump_info (REPORT_DETAILS))
+           {
+             fprintf (vect_dump, "Access function of PHI: ");
+             print_generic_expr (vect_dump, access_fn, TDF_SLIM);
+           }
+         STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo)
+           = evolution_part_in_loop_num (access_fn, loop->num);
        }
 
       if (!access_fn
@@ -579,6 +583,8 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
          continue;
        }
 
+      gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) != NULL_TREE);
+
       if (vect_print_dump_info (REPORT_DETAILS))
        fprintf (vect_dump, "Detected induction.");
       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
@@ -1320,7 +1326,9 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
                     return false;
 
                   op_def_stmt = SSA_NAME_DEF_STMT (phi_op);
-                  if (!op_def_stmt || !vinfo_for_stmt (op_def_stmt))
+                 if (!op_def_stmt
+                     || !flow_bb_inside_loop_p (loop, gimple_bb (op_def_stmt))
+                     || !vinfo_for_stmt (op_def_stmt))
                     return false;
 
                   if (STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
@@ -2417,7 +2425,8 @@ vect_get_single_scalar_iteraion_cost (loop_vec_info loop_vinfo)
           if (stmt_info
               && !STMT_VINFO_RELEVANT_P (stmt_info)
               && (!STMT_VINFO_LIVE_P (stmt_info)
-                  || STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def))
+                  || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
+             && !STMT_VINFO_IN_PATTERN_P (stmt_info))
             continue;
 
           if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
@@ -2564,15 +2573,46 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
        {
          gimple stmt = gsi_stmt (si);
          stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+
+         if (STMT_VINFO_IN_PATTERN_P (stmt_info))
+           {
+             stmt = STMT_VINFO_RELATED_STMT (stmt_info);
+             stmt_info = vinfo_for_stmt (stmt);
+           }
+
          /* Skip stmts that are not vectorized inside the loop.  */
          if (!STMT_VINFO_RELEVANT_P (stmt_info)
              && (!STMT_VINFO_LIVE_P (stmt_info)
-                 || STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def))
+                 || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))))
            continue;
+
          vec_inside_cost += STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) * factor;
          /* FIXME: for stmts in the inner-loop in outer-loop vectorization,
             some of the "outside" costs are generated inside the outer-loop.  */
          vec_outside_cost += STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info);
+          if (is_pattern_stmt_p (stmt_info)
+             && STMT_VINFO_PATTERN_DEF_SEQ (stmt_info))
+            {
+             gimple_stmt_iterator gsi;
+             
+             for (gsi = gsi_start (STMT_VINFO_PATTERN_DEF_SEQ (stmt_info));
+                  !gsi_end_p (gsi); gsi_next (&gsi))
+                {
+                  gimple pattern_def_stmt = gsi_stmt (gsi);
+                  stmt_vec_info pattern_def_stmt_info
+                   = vinfo_for_stmt (pattern_def_stmt);
+                  if (STMT_VINFO_RELEVANT_P (pattern_def_stmt_info)
+                      || STMT_VINFO_LIVE_P (pattern_def_stmt_info))
+                   {
+                      vec_inside_cost
+                       += STMT_VINFO_INSIDE_OF_LOOP_COST
+                          (pattern_def_stmt_info) * factor;
+                      vec_outside_cost
+                       += STMT_VINFO_OUTSIDE_OF_LOOP_COST
+                          (pattern_def_stmt_info);
+                    }
+               }
+           }
        }
     }
 
@@ -5010,12 +5050,46 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
   tree vec_def;
 
   gcc_assert (ncopies >= 1);
-  /* FORNOW. This restriction should be relaxed.  */
-  if (nested_in_vect_loop_p (loop, phi) && ncopies > 1)
+  /* FORNOW. These restrictions should be relaxed.  */
+  if (nested_in_vect_loop_p (loop, phi))
     {
-      if (vect_print_dump_info (REPORT_DETAILS))
-        fprintf (vect_dump, "multiple types in nested loop.");
-      return false;
+      imm_use_iterator imm_iter;
+      use_operand_p use_p;
+      gimple exit_phi;
+      edge latch_e;
+      tree loop_arg;
+
+      if (ncopies > 1)
+       {
+         if (vect_print_dump_info (REPORT_DETAILS))
+           fprintf (vect_dump, "multiple types in nested loop.");
+         return false;
+       }
+
+      exit_phi = NULL;
+      latch_e = loop_latch_edge (loop->inner);
+      loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
+      FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg)
+       {
+         if (!flow_bb_inside_loop_p (loop->inner,
+                                     gimple_bb (USE_STMT (use_p))))
+           {
+             exit_phi = USE_STMT (use_p);
+             break;
+           }
+       }
+      if (exit_phi)
+       {
+         stmt_vec_info exit_phi_vinfo  = vinfo_for_stmt (exit_phi);
+         if (!(STMT_VINFO_RELEVANT_P (exit_phi_vinfo)
+               && !STMT_VINFO_LIVE_P (exit_phi_vinfo)))
+           {
+             if (vect_print_dump_info (REPORT_DETAILS))
+               fprintf (vect_dump, "inner-loop induction only used outside "
+                        "of the outer vectorized loop.");
+             return false;
+           }
+       }
     }
 
   if (!STMT_VINFO_RELEVANT_P (stmt_info))