2012-03-22 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Mar 2012 11:36:46 +0000 (11:36 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Mar 2012 11:36:46 +0000 (11:36 +0000)
PR tree-optimization/52638
* tree-vect-stmts.c (vect_init_vector_1): New function, split
out from ...
(vect_init_vector): ... here.  Handle scalar vector inits.
(vect_get_vec_def_for_operand): Adjust.
(vectorizable_load): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185687 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-vect-stmts.c

index 73bc0bc..af9f870 100644 (file)
@@ -1,3 +1,12 @@
+2012-03-22  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52638
+       * tree-vect-stmts.c (vect_init_vector_1): New function, split
+       out from ...
+       (vect_init_vector): ... here.  Handle scalar vector inits.
+       (vect_get_vec_def_for_operand): Adjust.
+       (vectorizable_load): Likewise.
+
 2012-03-22  Uros Bizjak  <ubizjak@gmail.com>
 
        * config.gcc (alpha*-*-linux*): Add elfos.h to tm_file.
index c941e15..3a4d91a 100644 (file)
@@ -1136,48 +1136,31 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
     }
 }
 
+/* Insert the new stmt NEW_STMT at *GSI or at the appropriate place in
+   the loop preheader for the vectorized stmt STMT.  */
 
-/* Function vect_init_vector.
-
-   Insert a new stmt (INIT_STMT) that initializes a new vector variable with
-   the vector elements of VECTOR_VAR.  Place the initialization at BSI if it
-   is not NULL.  Otherwise, place the initialization at the loop preheader.
-   Return the DEF of INIT_STMT.
-   It will be used in the vectorization of STMT.  */
-
-tree
-vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
-                 gimple_stmt_iterator *gsi)
+static void
+vect_init_vector_1 (gimple stmt, gimple new_stmt, gimple_stmt_iterator *gsi)
 {
-  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
-  tree new_var;
-  gimple init_stmt;
-  tree vec_oprnd;
-  edge pe;
-  tree new_temp;
-  basic_block new_bb;
-
-  new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
-  add_referenced_var (new_var);
-  init_stmt = gimple_build_assign  (new_var, vector_var);
-  new_temp = make_ssa_name (new_var, init_stmt);
-  gimple_assign_set_lhs (init_stmt, new_temp);
 
   if (gsi)
-    vect_finish_stmt_generation (stmt, init_stmt, gsi);
+    vect_finish_stmt_generation (stmt, new_stmt, gsi);
   else
     {
+      stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
       loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
 
       if (loop_vinfo)
         {
           struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+         basic_block new_bb;
+         edge pe;
 
           if (nested_in_vect_loop_p (loop, stmt))
             loop = loop->inner;
 
          pe = loop_preheader_edge (loop);
-          new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
+          new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
           gcc_assert (!new_bb);
        }
       else
@@ -1189,16 +1172,64 @@ vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
           gcc_assert (bb_vinfo);
           bb = BB_VINFO_BB (bb_vinfo);
           gsi_bb_start = gsi_after_labels (bb);
-          gsi_insert_before (&gsi_bb_start, init_stmt, GSI_SAME_STMT);
+          gsi_insert_before (&gsi_bb_start, new_stmt, GSI_SAME_STMT);
        }
     }
 
   if (vect_print_dump_info (REPORT_DETAILS))
     {
       fprintf (vect_dump, "created new init_stmt: ");
-      print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
+      print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
+    }
+}
+
+/* Function vect_init_vector.
+
+   Insert a new stmt (INIT_STMT) that initializes a new vector variable with
+   the vector elements of VECTOR_VAR.  Place the initialization at BSI if it
+   is not NULL.  Otherwise, place the initialization at the loop preheader.
+   Return the DEF of INIT_STMT.
+   It will be used in the vectorization of STMT.  */
+
+tree
+vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
+                 gimple_stmt_iterator *gsi)
+{
+  tree new_var;
+  gimple init_stmt;
+  tree vec_oprnd;
+  tree new_temp;
+
+  if (TREE_CODE (TREE_TYPE (vector_var)) != VECTOR_TYPE)
+    {
+      if (!types_compatible_p (TREE_TYPE (vector_type),
+                              TREE_TYPE (vector_var)))
+       {
+         if (CONSTANT_CLASS_P (vector_var))
+           vector_var = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type),
+                                    vector_var);
+         else
+           {
+             new_var = create_tmp_reg (TREE_TYPE (vector_type), NULL);
+             add_referenced_var (new_var);
+             init_stmt = gimple_build_assign_with_ops (NOP_EXPR,
+                                                       new_var, vector_var,
+                                                       NULL_TREE);
+             new_temp = make_ssa_name (new_var, init_stmt);
+             gimple_assign_set_lhs (init_stmt, new_temp);
+             vect_init_vector_1 (stmt, init_stmt, gsi);
+             vector_var = new_temp;
+           }
+       }
+      vector_var = build_vector_from_val (vector_type, vector_var);
     }
 
+  new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
+  add_referenced_var (new_var);
+  init_stmt = gimple_build_assign  (new_var, vector_var);
+  new_temp = make_ssa_name (new_var, init_stmt);
+  gimple_assign_set_lhs (init_stmt, new_temp);
+  vect_init_vector_1 (stmt, init_stmt, gsi);
   vec_oprnd = gimple_assign_lhs (init_stmt);
   return vec_oprnd;
 }
@@ -1225,8 +1256,6 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
   unsigned int nunits;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  tree vec_inv;
-  tree vec_cst;
   tree def;
   enum vect_def_type dt;
   bool is_simple_use;
@@ -1271,14 +1300,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
         if (vect_print_dump_info (REPORT_DETAILS))
           fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
 
-       if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
-         {
-           op = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type), op);
-           gcc_assert (op && CONSTANT_CLASS_P (op));
-         }
-
-        vec_cst = build_vector_from_val (vector_type, op);
-        return vect_init_vector (stmt, vec_cst, vector_type, NULL);
+        return vect_init_vector (stmt, op, vector_type, NULL);
       }
 
     /* Case 2: operand is defined outside the loop - loop invariant.  */
@@ -1294,8 +1316,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
         if (vect_print_dump_info (REPORT_DETAILS))
           fprintf (vect_dump, "Create vector_inv.");
 
-       vec_inv = build_vector_from_val (vector_type, def);
-        return vect_init_vector (stmt, vec_inv, vector_type, NULL);
+        return vect_init_vector (stmt, def, vector_type, NULL);
       }
 
     /* Case 3: operand is defined inside the loop.  */
@@ -4875,21 +4896,10 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
              /* 4. Handle invariant-load.  */
              if (inv_p && !bb_vinfo)
                {
-                 tree tem, vec_inv;
                  gimple_stmt_iterator gsi2 = *gsi;
                  gcc_assert (!strided_load);
                  gsi_next (&gsi2);
-                 tem = scalar_dest;
-                 if (!useless_type_conversion_p (TREE_TYPE (vectype),
-                                                 TREE_TYPE (tem)))
-                   {
-                     tem = fold_convert (TREE_TYPE (vectype), tem);
-                     tem = force_gimple_operand_gsi (&gsi2, tem, true,
-                                                     NULL_TREE, true,
-                                                     GSI_SAME_STMT);
-                   }
-                 vec_inv = build_vector_from_val (vectype, tem);
-                 new_temp = vect_init_vector (stmt, vec_inv,
+                 new_temp = vect_init_vector (stmt, scalar_dest,
                                               vectype, &gsi2);
                  new_stmt = SSA_NAME_DEF_STMT (new_temp);
                }