This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR52638


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  <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.

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);
  		}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]