OSDN Git Service

* trans-intrinsic.c (gfc_conv_intrinsic_sign): New branchless
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-analyze.c
index 8955515..114f823 100644 (file)
@@ -109,51 +109,67 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
 
       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
         {
-          tree stmt = bsi_stmt (si);
-          unsigned int nunits;
-          stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
-          tree vectype;
+         tree stmt = bsi_stmt (si);
+         unsigned int nunits;
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         tree vectype;
 
-          if (vect_print_dump_info (REPORT_DETAILS))
-            {
-              fprintf (vect_dump, "==> examining statement: ");
-              print_generic_expr (vect_dump, stmt, TDF_SLIM);
-            }
+         if (vect_print_dump_info (REPORT_DETAILS))
+           {
+             fprintf (vect_dump, "==> examining statement: ");
+             print_generic_expr (vect_dump, stmt, TDF_SLIM);
+           }
 
-          gcc_assert (stmt_info);
-          /* skip stmts which do not need to be vectorized.  */
-          if (!STMT_VINFO_RELEVANT_P (stmt_info)
+         if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+           continue;
+
+         gcc_assert (stmt_info);
+
+         /* skip stmts which do not need to be vectorized.  */
+         if (!STMT_VINFO_RELEVANT_P (stmt_info)
              && !STMT_VINFO_LIVE_P (stmt_info))
-            {
-              if (vect_print_dump_info (REPORT_DETAILS))
-                fprintf (vect_dump, "skip.");
-              continue;
-            }
+           {
+             if (vect_print_dump_info (REPORT_DETAILS))
+               fprintf (vect_dump, "skip.");
+             continue;
+           }
 
-          if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
-            {
-              if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-                {
-                  fprintf (vect_dump, "not vectorized: vector stmt in loop:");
-                  print_generic_expr (vect_dump, stmt, TDF_SLIM);
-                }
-              return false;
-            }
+         if (!GIMPLE_STMT_P (stmt)
+             && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
+           {
+             if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+               {
+                 fprintf (vect_dump, "not vectorized: vector stmt in loop:");
+                 print_generic_expr (vect_dump, stmt, TDF_SLIM);
+               }
+             return false;
+           }
 
          if (STMT_VINFO_VECTYPE (stmt_info))
            {
+             /* The only case when a vectype had been already set is for stmts 
+                that contain a dataref, or for "pattern-stmts" (stmts generated
+                by the vectorizer to represent/replace a certain idiom).  */
+             gcc_assert (STMT_VINFO_DATA_REF (stmt_info) 
+                         || is_pattern_stmt_p (stmt_info));
              vectype = STMT_VINFO_VECTYPE (stmt_info);
-             scalar_type = TREE_TYPE (vectype);
            }
          else
            {
-             if (STMT_VINFO_DATA_REF (stmt_info))
-               scalar_type = 
-                       TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
-             else if (TREE_CODE (stmt) == MODIFY_EXPR)
-               scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
-             else
-               scalar_type = TREE_TYPE (stmt);
+             gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
+                         && !is_pattern_stmt_p (stmt_info));
+
+             /* We set the vectype according to the type of the result (lhs).
+                For stmts whose result-type is different than the type of the
+                arguments (e.g. demotion, promotion), vectype will be reset 
+                appropriately (later).  Note that we have to visit the smallest 
+                datatype in this function, because that determines the VF.  
+                If the samallest datatype in the loop is present only as the 
+                rhs of a promotion operation - we'd miss it here.
+                However, in such a case, that a variable of this datatype
+                does not appear in the lhs anywhere in the loop, it shouldn't
+                affect the vectorization factor.   */
+             scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
 
              if (vect_print_dump_info (REPORT_DETAILS))
                {
@@ -175,17 +191,17 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
              STMT_VINFO_VECTYPE (stmt_info) = vectype;
             }
 
-          if (vect_print_dump_info (REPORT_DETAILS))
-            {
-              fprintf (vect_dump, "vectype: ");
-              print_generic_expr (vect_dump, vectype, TDF_SLIM);
-            }
+         if (vect_print_dump_info (REPORT_DETAILS))
+           {
+             fprintf (vect_dump, "vectype: ");
+             print_generic_expr (vect_dump, vectype, TDF_SLIM);
+           }
 
-          nunits = TYPE_VECTOR_SUBPARTS (vectype);
-          if (vect_print_dump_info (REPORT_DETAILS))
-            fprintf (vect_dump, "nunits = %d", nunits);
+         nunits = TYPE_VECTOR_SUBPARTS (vectype);
+         if (vect_print_dump_info (REPORT_DETAILS))
+           fprintf (vect_dump, "nunits = %d", nunits);
 
-          if (!vectorization_factor
+         if (!vectorization_factor
              || (nunits > vectorization_factor))
            vectorization_factor = nunits;
 
@@ -293,7 +309,8 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
 
           if (STMT_VINFO_RELEVANT_P (stmt_info))
             {
-              gcc_assert (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
+              gcc_assert (GIMPLE_STMT_P (stmt)
+                         || !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
               gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
 
              ok = (vectorizable_type_promotion (stmt, NULL, NULL)
@@ -366,7 +383,10 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
 
   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
-      && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
+      && ((LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
+         || (LOOP_VINFO_INT_NITERS (loop_vinfo) <=
+               ((unsigned) (PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)) 
+                                          * vectorization_factor))))
     {
       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
        fprintf (vect_dump, "not vectorized: iteration count too small.");
@@ -429,10 +449,10 @@ exist_non_indexing_operands_for_use_p (tree use, tree stmt)
      Therefore, all we need to check is if STMT falls into the
      first case, and whether var corresponds to USE.  */
  
-  if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
+  if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
     return false;
 
-  operand = TREE_OPERAND (stmt, 1);
+  operand = GIMPLE_STMT_OPERAND (stmt, 1);
 
   if (TREE_CODE (operand) != SSA_NAME)
     return false;
@@ -1802,7 +1822,8 @@ vect_analyze_data_ref_access (struct data_reference *dr)
       /* COUNT is the number of accesses found, we multiply it by the size of 
         the type to get COUNT_IN_BYTES.  */
       count_in_bytes = type_size * count;
-      /* Check the size of the interleaving is not greater than STEP.  */
+
+      /* Check that the size of the interleaving is not greater than STEP.  */
       if (dr_step < count_in_bytes) 
        {
          if (vect_print_dump_info (REPORT_DETAILS))
@@ -1813,6 +1834,15 @@ vect_analyze_data_ref_access (struct data_reference *dr)
          return false;
        }
 
+      /* Check that the size of the interleaving is equal to STEP for stores, 
+         i.e., that there are no gaps.  */ 
+      if (!DR_IS_READ (dr) && dr_step != count_in_bytes) 
+       {
+         if (vect_print_dump_info (REPORT_DETAILS))
+           fprintf (vect_dump, "interleaved store with gaps");
+         return false;
+       }
+
       /* Check that STEP is a multiple of type size.  */
       if ((dr_step % type_size) != 0)
        {
@@ -2391,7 +2421,7 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "=== get_loop_niters ===");
 
-  niters = number_of_iterations_in_loop (loop);
+  niters = number_of_exit_cond_executions (loop);
 
   if (niters != NULL_TREE
       && niters != chrec_dont_know)