This fixes PR52638, I made vect_init_vector handle scalar inits
to not duplicate this code all over the place.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-22  Richard Guenther  <rguent...@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.

Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c       (revision 185675)
--- gcc/tree-vect-stmts.c       (working copy)
*************** vect_get_load_cost (struct data_referenc
*** 1136,1183 ****
      }
  }
  
  
! /* 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)
  {
-   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);
    else
      {
        loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
  
        if (loop_vinfo)
          {
            struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
  
            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);
            gcc_assert (!new_bb);
        }
        else
--- 1136,1166 ----
      }
  }
  
+ /* Insert the new stmt NEW_STMT at *GSI or at the appropriate place in
+    the loop preheader for the vectorized stmt STMT.  */
  
! static void
! vect_init_vector_1 (gimple stmt, gimple new_stmt, gimple_stmt_iterator *gsi)
  {
  
    if (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, new_stmt);
            gcc_assert (!new_bb);
        }
        else
*************** vect_init_vector (gimple stmt, tree vect
*** 1189,1204 ****
            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);
         }
      }
  
    if (vect_print_dump_info (REPORT_DETAILS))
      {
        fprintf (vect_dump, "created new init_stmt: ");
!       print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
      }
  
    vec_oprnd = gimple_assign_lhs (init_stmt);
    return vec_oprnd;
  }
--- 1172,1235 ----
            gcc_assert (bb_vinfo);
            bb = BB_VINFO_BB (bb_vinfo);
            gsi_bb_start = gsi_after_labels (bb);
!           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, 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;
  }
*************** vect_get_vec_def_for_operand (tree op, g
*** 1225,1232 ****
    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;
--- 1256,1261 ----
*************** vect_get_vec_def_for_operand (tree op, g
*** 1271,1284 ****
          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);
        }
  
      /* Case 2: operand is defined outside the loop - loop invariant.  */
--- 1300,1306 ----
          if (vect_print_dump_info (REPORT_DETAILS))
            fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
  
!         return vect_init_vector (stmt, op, vector_type, NULL);
        }
  
      /* Case 2: operand is defined outside the loop - loop invariant.  */
*************** vect_get_vec_def_for_operand (tree op, g
*** 1294,1301 ****
          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);
        }
  
      /* Case 3: operand is defined inside the loop.  */
--- 1316,1322 ----
          if (vect_print_dump_info (REPORT_DETAILS))
            fprintf (vect_dump, "Create vector_inv.");
  
!         return vect_init_vector (stmt, def, vector_type, NULL);
        }
  
      /* Case 3: operand is defined inside the loop.  */
*************** vectorizable_load (gimple stmt, gimple_s
*** 4875,4895 ****
              /* 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,
                                               vectype, &gsi2);
                  new_stmt = SSA_NAME_DEF_STMT (new_temp);
                }
--- 4896,4905 ----
              /* 4. Handle invariant-load.  */
              if (inv_p && !bb_vinfo)
                {
                  gimple_stmt_iterator gsi2 = *gsi;
                  gcc_assert (!strided_load);
                  gsi_next (&gsi2);
!                 new_temp = vect_init_vector (stmt, scalar_dest,
                                               vectype, &gsi2);
                  new_stmt = SSA_NAME_DEF_STMT (new_temp);
                }

Reply via email to