public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] More vectorizer TLC
@ 2015-10-13  8:38 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-13  8:38 UTC (permalink / raw)
  To: gcc-patches


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

Richard.

2015-10-13  Richard Biener  <rguenther@suse.de>

	* tree-vect-data-refs.c (vect_analyze_data_ref_dependences): Allocate
	the data dependence vector.
	(vect_peeling_hash_insert): Get the peeling hash table as argument.
	(vect_peeling_hash_get_lowest_cost): Likewise.
	(vect_enhance_data_refs_alignment): Adjust.
	(struct _vect_peel_info, struct _vect_peel_extended_info,
	struct peel_info_hasher): Move from ...
	* tree-vectorizer.h: ... here.
	(LOOP_VINFO_COST_MODEL_MIN_ITERS): Remove.
	(LOOP_VINFO_PEELING_HTAB): Likewise.
	(struct _loop_vec_info): Remove min_profitable_iters and
	peeling_htab members.
	* tree-vect-loop.c (new_loop_vec_info): Do not allocate vectors
	here.
	(destroy_loop_vec_info): Adjust.
	(vect_analyze_loop_2): Do not set LOOP_VINFO_COST_MODEL_MIN_ITERS.
	(vect_estimate_min_profitable_iters): Use LOOP_VINFO_COMP_ALIAS_DDRS
	to estimate alias versioning cost.
	* tree-vect-slp.c (vect_analyze_slp_cost): Dump header.


Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c	(revision 228709)
--- gcc/tree-vect-data-refs.c	(working copy)
*************** vect_analyze_data_ref_dependences (loop_
*** 468,473 ****
--- 468,476 ----
      dump_printf_loc (MSG_NOTE, vect_location,
                       "=== vect_analyze_data_ref_dependences ===\n");
  
+   LOOP_VINFO_DDRS (loop_vinfo)
+     .create (LOOP_VINFO_DATAREFS (loop_vinfo).length ()
+ 	     * LOOP_VINFO_DATAREFS (loop_vinfo).length ());
    LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = true;
    if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo),
  				&LOOP_VINFO_DDRS (loop_vinfo),
*************** vect_get_data_access_cost (struct data_r
*** 1039,1048 ****
  }
  
  
  /* Insert DR into peeling hash table with NPEEL as key.  */
  
  static void
! vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
                            int npeel)
  {
    struct _vect_peel_info elem, *slot;
--- 1042,1089 ----
  }
  
  
+ typedef struct _vect_peel_info
+ {
+   int npeel;
+   struct data_reference *dr;
+   unsigned int count;
+ } *vect_peel_info;
+ 
+ typedef struct _vect_peel_extended_info
+ {
+   struct _vect_peel_info peel_info;
+   unsigned int inside_cost;
+   unsigned int outside_cost;
+   stmt_vector_for_cost body_cost_vec;
+ } *vect_peel_extended_info;
+ 
+ 
+ /* Peeling hashtable helpers.  */
+ 
+ struct peel_info_hasher : free_ptr_hash <_vect_peel_info>
+ {
+   static inline hashval_t hash (const _vect_peel_info *);
+   static inline bool equal (const _vect_peel_info *, const _vect_peel_info *);
+ };
+ 
+ inline hashval_t
+ peel_info_hasher::hash (const _vect_peel_info *peel_info)
+ {
+   return (hashval_t) peel_info->npeel;
+ }
+ 
+ inline bool
+ peel_info_hasher::equal (const _vect_peel_info *a, const _vect_peel_info *b)
+ {
+   return (a->npeel == b->npeel);
+ }
+ 
+ 
  /* Insert DR into peeling hash table with NPEEL as key.  */
  
  static void
! vect_peeling_hash_insert (hash_table<peel_info_hasher> *peeling_htab,
! 			  loop_vec_info loop_vinfo, struct data_reference *dr,
                            int npeel)
  {
    struct _vect_peel_info elem, *slot;
*************** vect_peeling_hash_insert (loop_vec_info
*** 1050,1056 ****
    bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
  
    elem.npeel = npeel;
!   slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find (&elem);
    if (slot)
      slot->count++;
    else
--- 1091,1097 ----
    bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
  
    elem.npeel = npeel;
!   slot = peeling_htab->find (&elem);
    if (slot)
      slot->count++;
    else
*************** vect_peeling_hash_insert (loop_vec_info
*** 1059,1066 ****
        slot->npeel = npeel;
        slot->dr = dr;
        slot->count = 1;
!       new_slot
!        	= LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find_slot (slot, INSERT);
        *new_slot = slot;
      }
  
--- 1100,1106 ----
        slot->npeel = npeel;
        slot->dr = dr;
        slot->count = 1;
!       new_slot = peeling_htab->find_slot (slot, INSERT);
        *new_slot = slot;
      }
  
*************** vect_peeling_hash_get_lowest_cost (_vect
*** 1164,1170 ****
     option that aligns as many accesses as possible.  */
  
  static struct data_reference *
! vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
                                         unsigned int *npeel,
  				       stmt_vector_for_cost *body_cost_vec)
  {
--- 1204,1211 ----
     option that aligns as many accesses as possible.  */
  
  static struct data_reference *
! vect_peeling_hash_choose_best_peeling (hash_table<peel_info_hasher> *peeling_htab,
! 				       loop_vec_info loop_vinfo,
                                         unsigned int *npeel,
  				       stmt_vector_for_cost *body_cost_vec)
  {
*************** vect_peeling_hash_choose_best_peeling (l
*** 1177,1192 ****
       {
         res.inside_cost = INT_MAX;
         res.outside_cost = INT_MAX;
!        LOOP_VINFO_PEELING_HTAB (loop_vinfo)
!            ->traverse <_vect_peel_extended_info *,
!                        vect_peeling_hash_get_lowest_cost> (&res);
       }
     else
       {
         res.peel_info.count = 0;
!        LOOP_VINFO_PEELING_HTAB (loop_vinfo)
!            ->traverse <_vect_peel_extended_info *,
!                        vect_peeling_hash_get_most_frequent> (&res);
       }
  
     *npeel = res.peel_info.npeel;
--- 1218,1231 ----
       {
         res.inside_cost = INT_MAX;
         res.outside_cost = INT_MAX;
!        peeling_htab->traverse <_vect_peel_extended_info *,
! 	   		       vect_peeling_hash_get_lowest_cost> (&res);
       }
     else
       {
         res.peel_info.count = 0;
!        peeling_htab->traverse <_vect_peel_extended_info *,
! 	   		       vect_peeling_hash_get_most_frequent> (&res);
       }
  
     *npeel = res.peel_info.npeel;
*************** vect_enhance_data_refs_alignment (loop_v
*** 1307,1312 ****
--- 1346,1352 ----
    tree vectype;
    unsigned int nelements, mis, same_align_drs_max = 0;
    stmt_vector_for_cost body_cost_vec = stmt_vector_for_cost ();
+   hash_table<peel_info_hasher> peeling_htab (1);
  
    if (dump_enabled_p ())
      dump_printf_loc (MSG_NOTE, vect_location,
*************** vect_enhance_data_refs_alignment (loop_v
*** 1379,1388 ****
  						    size_zero_node) < 0;
  
                /* Save info about DR in the hash table.  */
-               if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo))
-                 LOOP_VINFO_PEELING_HTAB (loop_vinfo)
- 		  = new hash_table<peel_info_hasher> (1);
- 
                vectype = STMT_VINFO_VECTYPE (stmt_info);
                nelements = TYPE_VECTOR_SUBPARTS (vectype);
                mis = DR_MISALIGNMENT (dr) / GET_MODE_SIZE (TYPE_MODE (
--- 1419,1424 ----
*************** vect_enhance_data_refs_alignment (loop_v
*** 1424,1430 ****
  
                for (j = 0; j < possible_npeel_number; j++)
                  {
!                   vect_peeling_hash_insert (loop_vinfo, dr, npeel_tmp);
                    npeel_tmp += nelements;
                  }
  
--- 1460,1467 ----
  
                for (j = 0; j < possible_npeel_number; j++)
                  {
!                   vect_peeling_hash_insert (&peeling_htab, loop_vinfo,
! 					    dr, npeel_tmp);
                    npeel_tmp += nelements;
                  }
  
*************** vect_enhance_data_refs_alignment (loop_v
*** 1590,1596 ****
        gcc_assert (!all_misalignments_unknown);
  
        /* Choose the best peeling from the hash table.  */
!       dr0 = vect_peeling_hash_choose_best_peeling (loop_vinfo, &npeel,
  						   &body_cost_vec);
        if (!dr0 || !npeel)
          do_peeling = false;
--- 1627,1634 ----
        gcc_assert (!all_misalignments_unknown);
  
        /* Choose the best peeling from the hash table.  */
!       dr0 = vect_peeling_hash_choose_best_peeling (&peeling_htab,
! 						   loop_vinfo, &npeel,
  						   &body_cost_vec);
        if (!dr0 || !npeel)
          do_peeling = false;
Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c	(revision 228709)
--- gcc/tree-vect-loop.c	(working copy)
*************** new_loop_vec_info (struct loop *loop)
*** 937,959 ****
    LOOP_VINFO_NITERSM1 (res) = NULL;
    LOOP_VINFO_NITERS (res) = NULL;
    LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
-   LOOP_VINFO_COST_MODEL_MIN_ITERS (res) = 0;
    LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0;
    LOOP_VINFO_VECTORIZABLE_P (res) = 0;
    LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0;
    LOOP_VINFO_VECT_FACTOR (res) = 0;
!   LOOP_VINFO_LOOP_NEST (res).create (3);
!   LOOP_VINFO_DATAREFS (res).create (10);
!   LOOP_VINFO_DDRS (res).create (10 * 10);
    LOOP_VINFO_UNALIGNED_DR (res) = NULL;
!   LOOP_VINFO_MAY_MISALIGN_STMTS (res).create (
! 	     PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
!   LOOP_VINFO_MAY_ALIAS_DDRS (res).create (
! 	     PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
!   LOOP_VINFO_GROUPED_STORES (res).create (10);
!   LOOP_VINFO_REDUCTIONS (res).create (10);
!   LOOP_VINFO_REDUCTION_CHAINS (res).create (10);
!   LOOP_VINFO_SLP_INSTANCES (res).create (10);
    LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
    LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
    LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
--- 937,956 ----
    LOOP_VINFO_NITERSM1 (res) = NULL;
    LOOP_VINFO_NITERS (res) = NULL;
    LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
    LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0;
    LOOP_VINFO_VECTORIZABLE_P (res) = 0;
    LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0;
    LOOP_VINFO_VECT_FACTOR (res) = 0;
!   LOOP_VINFO_LOOP_NEST (res) = vNULL;
!   LOOP_VINFO_DATAREFS (res) = vNULL;
!   LOOP_VINFO_DDRS (res) = vNULL;
    LOOP_VINFO_UNALIGNED_DR (res) = NULL;
!   LOOP_VINFO_MAY_MISALIGN_STMTS (res) = vNULL;
!   LOOP_VINFO_MAY_ALIAS_DDRS (res) = vNULL;
!   LOOP_VINFO_GROUPED_STORES (res) = vNULL;
!   LOOP_VINFO_REDUCTIONS (res) = vNULL;
!   LOOP_VINFO_REDUCTION_CHAINS (res) = vNULL;
!   LOOP_VINFO_SLP_INSTANCES (res) = vNULL;
    LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
    LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
    LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
*************** destroy_loop_vec_info (loop_vec_info loo
*** 1036,1044 ****
    LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
    LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
  
-   delete LOOP_VINFO_PEELING_HTAB (loop_vinfo);
-   LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL;
- 
    destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
    loop_vinfo->scalar_cost_vec.release ();
  
--- 1033,1038 ----
*************** vect_analyze_loop_2 (loop_vec_info loop_
*** 1786,1792 ****
    int min_profitable_estimate, min_profitable_iters;
    vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters,
  				      &min_profitable_estimate);
-   LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
  
    if (min_profitable_iters < 0)
      {
--- 1780,1785 ----
*************** vect_estimate_min_profitable_iters (loop
*** 2810,2816 ****
    if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
      {
        /*  FIXME: Make cost depend on complexity of individual check.  */
!       unsigned len = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).length ();
        (void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
  			    vect_prologue);
        dump_printf (MSG_NOTE,
--- 2803,2809 ----
    if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
      {
        /*  FIXME: Make cost depend on complexity of individual check.  */
!       unsigned len = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).length ();
        (void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
  			    vect_prologue);
        dump_printf (MSG_NOTE,
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c	(revision 228709)
--- gcc/tree-vect-slp.c	(working copy)
*************** vect_analyze_slp_cost (slp_instance inst
*** 1569,1574 ****
--- 1569,1578 ----
    stmt_info_for_cost *si;
    unsigned i;
  
+   if (dump_enabled_p ())
+     dump_printf_loc (MSG_NOTE, vect_location,
+ 		     "=== vect_analyze_slp_cost ===\n");
+ 
    /* Calculate the number of vector stmts to create based on the unrolling
       factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is
       GROUP_SIZE / NUNITS otherwise.  */
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h	(revision 228709)
--- gcc/tree-vectorizer.h	(working copy)
*************** struct dr_with_seg_len_pair_t
*** 194,234 ****
  };
  
  
- typedef struct _vect_peel_info
- {
-   int npeel;
-   struct data_reference *dr;
-   unsigned int count;
- } *vect_peel_info;
- 
- typedef struct _vect_peel_extended_info
- {
-   struct _vect_peel_info peel_info;
-   unsigned int inside_cost;
-   unsigned int outside_cost;
-   stmt_vector_for_cost body_cost_vec;
- } *vect_peel_extended_info;
- 
- 
- /* Peeling hashtable helpers.  */
- 
- struct peel_info_hasher : free_ptr_hash <_vect_peel_info>
- {
-   static inline hashval_t hash (const _vect_peel_info *);
-   static inline bool equal (const _vect_peel_info *, const _vect_peel_info *);
- };
- 
- inline hashval_t
- peel_info_hasher::hash (const _vect_peel_info *peel_info)
- {
-   return (hashval_t) peel_info->npeel;
- }
- 
- inline bool
- peel_info_hasher::equal (const _vect_peel_info *a, const _vect_peel_info *b)
- {
-   return (a->npeel == b->npeel);
- }
  
  /* Vectorizer state common between loop and basic-block vectorization.  */
  struct vec_info {
--- 194,199 ----
*************** typedef struct _loop_vec_info : public v
*** 289,301 ****
    /* Number of iterations of the original loop.  */
    tree num_iters_unchanged;
  
-   /* Minimum number of iterations below which vectorization is expected to
-      not be profitable (as estimated by the cost model).
-      -1 indicates that vectorization will not be profitable.
-      FORNOW: This field is an int. Will be a tree in the future, to represent
- 	     values unknown at compile time.  */
-   int min_profitable_iters;
- 
    /* Threshold of number of iterations below which vectorzation will not be
       performed. It is calculated from MIN_PROFITABLE_ITERS and
       PARAM_MIN_VECT_LOOP_BOUND.  */
--- 254,259 ----
*************** typedef struct _loop_vec_info : public v
*** 349,357 ****
       stmt in the chain.  */
    vec<gimple *> reduction_chains;
  
-   /* Hash table used to choose the best peeling option.  */
-   hash_table<peel_info_hasher> *peeling_htab;
- 
    /* Cost vector for a single scalar iteration.  */
    vec<stmt_info_for_cost> scalar_cost_vec;
  
--- 307,312 ----
*************** typedef struct _loop_vec_info : public v
*** 407,413 ****
     prologue peeling retain total unchanged scalar loop iterations for
     cost model.  */
  #define LOOP_VINFO_NITERS_UNCHANGED(L)     (L)->num_iters_unchanged
- #define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
  #define LOOP_VINFO_COST_MODEL_THRESHOLD(L) (L)->th
  #define LOOP_VINFO_VECTORIZABLE_P(L)       (L)->vectorizable
  #define LOOP_VINFO_VECT_FACTOR(L)          (L)->vectorization_factor
--- 362,367 ----
*************** typedef struct _loop_vec_info : public v
*** 426,432 ****
  #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
  #define LOOP_VINFO_REDUCTIONS(L)           (L)->reductions
  #define LOOP_VINFO_REDUCTION_CHAINS(L)     (L)->reduction_chains
- #define LOOP_VINFO_PEELING_HTAB(L)         (L)->peeling_htab
  #define LOOP_VINFO_TARGET_COST_DATA(L)     (L)->target_cost_data
  #define LOOP_VINFO_PEELING_FOR_GAPS(L)     (L)->peeling_for_gaps
  #define LOOP_VINFO_OPERANDS_SWAPPED(L)     (L)->operands_swapped
--- 380,385 ----

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] More vectorizer TLC
  2015-10-15 11:37 Richard Biener
@ 2015-10-15 12:15 ` Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-15 12:15 UTC (permalink / raw)
  To: gcc-patches

On Thu, 15 Oct 2015, Richard Biener wrote:

> 
> Get rid of some of the ancient way of building stmts and SSA names.
> 
> Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.

Committed an old patch, fixed now.

2015-10-15  Richard Biener  <rguenther@suse.de>

        * tree-vect-stmts.c (vect_init_vector): Remove unused vars.

Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c       (revision 228841)
+++ gcc/tree-vect-stmts.c       (working copy)
@@ -1296,9 +1296,7 @@ vect_init_vector_1 (gimple *stmt, gimple
 tree
 vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator 
*gsi)
 {
-  tree new_var;
   gimple *init_stmt;
-  tree vec_oprnd;
   tree new_temp;
 
   if (TREE_CODE (type) == VECTOR_TYPE

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2015-10-15 11:37 Richard Biener
  2015-10-15 12:15 ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2015-10-15 11:37 UTC (permalink / raw)
  To: gcc-patches


Get rid of some of the ancient way of building stmts and SSA names.

Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-10-15  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (vect_get_new_ssa_name): Declare.
	* tree-vect-data-refs.c (vect_get_new_ssa_name): New helper.
	* tree-vect-loop.c (get_initial_def_for_induction): Drop
	use of force_gimple_operand in favor of gimple_build.
	Use vect_get_new_ssa_name.
	* tree-vect-stmts.c (vect_init_vector): Use vect_get_new_ssa_name.
	(vectorizable_mask_load_store): Likewise.
	(vectorizable_call): Likewise.
	(vectorizable_store): Likewise.
	(vectorizable_load): Likewise.
	(vect_get_vec_def_for_stmt_copy): Remove redundant stmt.

Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	(revision 228811)
+++ gcc/tree-vect-data-refs.c	(working copy)
@@ -3896,6 +3937,41 @@ vect_get_new_vect_var (tree type, enum v
 
   return new_vect_var;
 }
+
+/* Like vect_get_new_vect_var but return an SSA name.  */
+
+tree
+vect_get_new_ssa_name (tree type, enum vect_var_kind var_kind, const char *name)
+{
+  const char *prefix;
+  tree new_vect_var;
+
+  switch (var_kind)
+  {
+  case vect_simple_var:
+    prefix = "vect";
+    break;
+  case vect_scalar_var:
+    prefix = "stmp";
+    break;
+  case vect_pointer_var:
+    prefix = "vectp";
+    break;
+  default:
+    gcc_unreachable ();
+  }
+
+  if (name)
+    {
+      char* tmp = concat (prefix, "_", name, NULL);
+      new_vect_var = make_temp_ssa_name (type, NULL, tmp);
+      free (tmp);
+    }
+  else
+    new_vect_var = make_temp_ssa_name (type, NULL, prefix);
+
+  return new_vect_var;
+}
 
 /* Duplicate ptr info and set alignment/misaligment on NAME from DR.  */
 
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 228811)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
 #include "target.h"
+#include "gimple-fold.h"
 
 /* Loop Vectorization Pass.
 
@@ -3341,9 +3388,8 @@ get_initial_def_for_induction (gimple *i
   struct loop *iv_loop;
   basic_block new_bb;
   tree new_vec, vec_init, vec_step, t;
-  tree new_var;
   tree new_name;
-  gimple *init_stmt, *new_stmt;
+  gimple *new_stmt;
   gphi *induction_phi;
   tree induc_def, vec_def, vec_dest;
   tree init_expr, step_expr;
@@ -3353,7 +3399,7 @@ get_initial_def_for_induction (gimple *i
   tree expr;
   stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
   bool nested_in_vect_loop = false;
-  gimple_seq stmts = NULL;
+  gimple_seq stmts;
   imm_use_iterator imm_iter;
   use_operand_p use_p;
   gimple *exit_phi;
@@ -3394,9 +3440,8 @@ get_initial_def_for_induction (gimple *i
   gcc_assert (ncopies >= 1);
 
   /* Convert the step to the desired type.  */
-  step_expr = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
-						  step_expr),
-				    &stmts, true, NULL_TREE);
+  stmts = NULL;
+  step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr);
   if (stmts)
     {
       new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
@@ -3417,14 +3462,13 @@ get_initial_def_for_induction (gimple *i
       if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init)))
 	{
 	  new_stmt
-	    = gimple_build_assign (vect_get_new_vect_var (vectype,
+	    = gimple_build_assign (vect_get_new_ssa_name (vectype,
 							  vect_simple_var,
 							  "vec_iv_"),
 				   VIEW_CONVERT_EXPR,
 				   build1 (VIEW_CONVERT_EXPR, vectype,
 					   vec_init));
-	  vec_init = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
-	  gimple_assign_set_lhs (new_stmt, vec_init);
+	  vec_init = gimple_assign_lhs (new_stmt);
 	  new_bb = gsi_insert_on_edge_immediate (loop_preheader_edge (iv_loop),
 						 new_stmt);
 	  gcc_assert (!new_bb);
@@ -3438,16 +3482,8 @@ get_initial_def_for_induction (gimple *i
 
       /* iv_loop is the loop to be vectorized. Create:
 	 vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr)  */
-      new_var = vect_get_new_vect_var (TREE_TYPE (vectype),
-				       vect_scalar_var, "var_");
-      new_name = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
-						     init_expr),
-				       &stmts, false, new_var);
-      if (stmts)
-	{
-	  new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
-	  gcc_assert (!new_bb);
-	}
+      stmts = NULL;
+      new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);
 
       vec_alloc (v, nunits);
       bool constant_p = is_gimple_min_invariant (new_name);
@@ -3455,26 +3491,18 @@ get_initial_def_for_induction (gimple *i
       for (i = 1; i < nunits; i++)
 	{
 	  /* Create: new_name_i = new_name + step_expr  */
-	  new_name = fold_build2 (PLUS_EXPR, TREE_TYPE (new_name),
-				  new_name, step_expr);
+	  new_name = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (new_name),
+				   new_name, step_expr);
 	  if (!is_gimple_min_invariant (new_name))
-	    {
-	      init_stmt = gimple_build_assign (new_var, new_name);
-	      new_name = make_ssa_name (new_var, init_stmt);
-	      gimple_assign_set_lhs (init_stmt, new_name);
-	      new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
-	      gcc_assert (!new_bb);
-	      if (dump_enabled_p ())
-		{
-		  dump_printf_loc (MSG_NOTE, vect_location,
-				   "created new init_stmt: ");
-		  dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0);
-                  dump_printf (MSG_NOTE, "\n");
-		}
-	      constant_p = false;
-	    }
+	    constant_p = false;
 	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
 	}
+      if (stmts)
+	{
+	  new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
+	  gcc_assert (!new_bb);
+	}
+
       /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1]  */
       if (constant_p)
 	new_vec = build_vector_from_ctor (vectype, v);
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	(revision 228811)
+++ gcc/tree-vect-stmts.c	(working copy)
@@ -1319,13 +1319,10 @@ vect_init_vector (gimple *stmt, tree val
       val = build_vector_from_val (type, val);
     }
 
-  new_var = vect_get_new_vect_var (type, vect_simple_var, "cst_");
-  init_stmt = gimple_build_assign  (new_var, val);
-  new_temp = make_ssa_name (new_var, init_stmt);
-  gimple_assign_set_lhs (init_stmt, new_temp);
+  new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_");
+  init_stmt = gimple_build_assign  (new_temp, val);
   vect_init_vector_1 (stmt, init_stmt, gsi);
-  vec_oprnd = gimple_assign_lhs (init_stmt);
-  return vec_oprnd;
+  return new_temp;
 }
 
 
@@ -1509,7 +1506,6 @@ vect_get_vec_def_for_stmt_copy (enum vec
   gcc_assert (def_stmt_info);
   vec_stmt_for_operand = STMT_VINFO_RELATED_STMT (def_stmt_info);
   gcc_assert (vec_stmt_for_operand);
-  vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
   if (gimple_code (vec_stmt_for_operand) == GIMPLE_PHI)
     vec_oprnd = PHI_RESULT (vec_stmt_for_operand);
   else
@@ -1888,8 +1884,7 @@ vectorizable_mask_load_store (gimple *st
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
 			  == TYPE_VECTOR_SUBPARTS (idxtype));
-	      var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
-	      var = make_ssa_name (var);
+	      var = vect_get_new_ssa_name (idxtype, vect_simple_var);
 	      op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
 	      new_stmt
 		= gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
@@ -1915,9 +1910,7 @@ vectorizable_mask_load_store (gimple *st
 		{
 		  gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
 			      == TYPE_VECTOR_SUBPARTS (masktype));
-		  var = vect_get_new_vect_var (masktype, vect_simple_var,
-					       NULL);
-		  var = make_ssa_name (var);
+		  var = vect_get_new_ssa_name (masktype, vect_simple_var);
 		  mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
 		  new_stmt
 		    = gimple_build_assign (var, VIEW_CONVERT_EXPR, mask_op);
@@ -1934,8 +1927,7 @@ vectorizable_mask_load_store (gimple *st
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
 			  == TYPE_VECTOR_SUBPARTS (rettype));
-	      var = vect_get_new_vect_var (rettype, vect_simple_var, NULL);
-	      op = make_ssa_name (var, new_stmt);
+	      op = vect_get_new_ssa_name (rettype, vect_simple_var);
 	      gimple_call_set_lhs (new_stmt, op);
 	      vect_finish_stmt_generation (stmt, new_stmt, gsi);
 	      var = make_ssa_name (vec_dest);
@@ -2379,14 +2371,11 @@ vectorizable_call (gimple *gs, gimple_st
 		v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k);
 	      tree cst = build_vector (vectype_out, v);
 	      tree new_var
-		= vect_get_new_vect_var (vectype_out, vect_simple_var, "cst_");
+		= vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_");
 	      gimple *init_stmt = gimple_build_assign (new_var, cst);
-	      new_temp = make_ssa_name (new_var, init_stmt);
-	      gimple_assign_set_lhs (init_stmt, new_temp);
 	      vect_init_vector_1 (stmt, init_stmt, NULL);
 	      new_temp = make_ssa_name (vec_dest);
-	      new_stmt = gimple_build_assign (new_temp,
-					      gimple_assign_lhs (init_stmt));
+	      new_stmt = gimple_build_assign (new_temp, new_var);
 	    }
 	  else
 	    {
@@ -5350,8 +5400,7 @@ vectorizable_store (gimple *stmt, gimple
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (src))
 			  == TYPE_VECTOR_SUBPARTS (srctype));
-	      var = vect_get_new_vect_var (srctype, vect_simple_var, NULL);
-	      var = make_ssa_name (var);
+	      var = vect_get_new_ssa_name (srctype, vect_simple_var);
 	      src = build1 (VIEW_CONVERT_EXPR, srctype, src);
 	      new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, src);
 	      vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -5362,8 +5411,7 @@ vectorizable_store (gimple *stmt, gimple
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
 			  == TYPE_VECTOR_SUBPARTS (idxtype));
-	      var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
-	      var = make_ssa_name (var);
+	      var = vect_get_new_ssa_name (idxtype, vect_simple_var);
 	      op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
 	      new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
 	      vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -6408,8 +6456,7 @@ vectorizable_load (gimple *stmt, gimple_
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
 			  == TYPE_VECTOR_SUBPARTS (idxtype));
-	      var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
-	      var = make_ssa_name (var);
+	      var = vect_get_new_ssa_name (idxtype, vect_simple_var);
 	      op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
 	      new_stmt
 		= gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
@@ -6424,8 +6471,7 @@ vectorizable_load (gimple *stmt, gimple_
 	    {
 	      gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
 			  == TYPE_VECTOR_SUBPARTS (rettype));
-	      var = vect_get_new_vect_var (rettype, vect_simple_var, NULL);
-	      op = make_ssa_name (var, new_stmt);
+	      op = vect_get_new_ssa_name (rettype, vect_simple_var);
 	      gimple_call_set_lhs (new_stmt, op);
 	      vect_finish_stmt_generation (stmt, new_stmt, gsi);
 	      var = make_ssa_name (vec_dest);
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	(revision 228811)
+++ gcc/tree-vectorizer.h	(working copy)
@@ -1020,6 +1020,8 @@ extern void vect_transform_grouped_load
                                          gimple_stmt_iterator *);
 extern void vect_record_grouped_load_vectors (gimple *, vec<tree> );
 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
+extern tree vect_get_new_ssa_name (tree, enum vect_var_kind,
+				   const char * = NULL);
 extern tree vect_create_addr_base_for_vector_ref (gimple *, gimple_seq *,
 						  tree, struct loop *,
 						  tree = NULL_TREE);

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2015-10-14 13:56 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-14 13:56 UTC (permalink / raw)
  To: gcc-patches


This removes superfluous parameters from some analysis helpers.

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

Richard.

2015-10-14  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (vect_is_simple_use): Remove unused parameters.
	(vect_is_simple_use_1): Likewise.  Make overload of vect_is_simple_use.
	(vect_get_vec_def_for_operand): Remove unused parameter.
	* tree-vect-loop.c (get_initial_def_for_induction): Adjust.
	(vect_create_epilog_for_reduction): Likewise.
	(vectorizable_reduction): Likewise.
	(vectorizable_live_operation): Likewise.
	* tree-vect-patterns.c (type_conversion_p): Likewise.
	(vect_recog_vector_vector_shift_pattern): Likewise.
	(check_bool_pattern): Likewise.
	* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.
	(vect_analyze_slp_cost_1): Likewise.
	* tree-vect-stmts.c (process_use): Likewise.
	(vect_get_vec_def_for_operand): Do not handle reductions.
	(vect_get_vec_defs): Adjust.
	(vectorizable_mask_load_store): Likewise.
	(vectorizable_call): Likewise.
	(vectorizable_simd_clone_call): Likewise.
	(vect_get_loop_based_defs): Likewise.
	(vectorizable_conversion): Likewise.
	(vectorizable_assignment): Likewise.
	(vectorizable_shift): Likewise.
	(vectorizable_operation): Likewise.
	(vectorizable_store): Likewise.
	(vectorizable_load): Likewise.
	(vect_is_simple_cond): Likewise.
	(vectorizable_condition): Likewise.
	(vect_is_simple_use): Remove unused parameters.
	(vect_is_simple_use_1): Adjust and rename.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 228806)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -3412,7 +3412,7 @@ get_initial_def_for_induction (gimple *i
       /* iv_loop is nested in the loop to be vectorized.  init_expr had already
 	 been created during vectorization of previous stmts.  We obtain it
 	 from the STMT_VINFO_VEC_STMT of the defining stmt.  */
-      vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi, NULL);
+      vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi);
       /* If the initial value is not of proper type, convert it.  */
       if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init)))
 	{
@@ -3798,8 +3798,7 @@ get_initial_def_for_reduction (gimple *s
         if (adjustment_def)
           {
             if (nested_in_vect_loop)
-              *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt,
-                                                              NULL);
+              *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt);
             else
               *adjustment_def = init_val;
           }
@@ -3853,7 +3852,7 @@ get_initial_def_for_reduction (gimple *s
         if (adjustment_def)
           {
             *adjustment_def = NULL_TREE;
-            init_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
+            init_def = vect_get_vec_def_for_operand (init_val, stmt);
             break;
           }
 
@@ -4012,12 +4011,13 @@ vect_create_epilog_for_reduction (vec<tr
                        NULL, slp_node, reduc_index);
   else
     {
+      /* Get at the scalar def before the loop, that defines the initial value
+	 of the reduction variable.  */
+      gimple *def_stmt = SSA_NAME_DEF_STMT (reduction_op);
+      tree op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
       vec_initial_defs.create (1);
-     /* For the case of reduction, vect_get_vec_def_for_operand returns
-        the scalar def before the loop, that defines the initial value
-        of the reduction variable.  */
-      vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt,
-                                                      &adjustment_def);
+      vec_initial_def = get_initial_def_for_reduction (stmt, op,
+						       &adjustment_def);
       vec_initial_defs.quick_push (vec_initial_def);
     }
 
@@ -4800,7 +4800,6 @@ vectorizable_reduction (gimple *stmt, gi
   int op_type;
   optab optab, reduc_optab;
   tree new_temp = NULL_TREE;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt;
   gphi *new_phi = NULL;
@@ -4956,8 +4955,8 @@ vectorizable_reduction (gimple *stmt, gi
       if (i == 0 && code == COND_EXPR)
         continue;
 
-      is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo,
-					    &def_stmt, &def, &dt, &tem);
+      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
+					  &def_stmt, &dt, &tem);
       if (!vectype_in)
 	vectype_in = tem;
       gcc_assert (is_simple_use);
@@ -4977,8 +4976,7 @@ vectorizable_reduction (gimple *stmt, gi
         }
     }
 
-  is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo,
-					&def_stmt, &def, &dt, &tem);
+  is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt, &dt, &tem);
   if (!vectype_in)
     vectype_in = tem;
   gcc_assert (is_simple_use);
@@ -5340,12 +5338,11 @@ vectorizable_reduction (gimple *stmt, gi
           else
             {
               loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],
-                                                            stmt, NULL);
+                                                            stmt);
               vec_oprnds0.quick_push (loop_vec_def0);
               if (op_type == ternary_op)
                {
-                 loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt,
-                                                               NULL);
+                 loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt);
                  vec_oprnds1.quick_push (loop_vec_def1);
                }
             }
@@ -5356,17 +5353,15 @@ vectorizable_reduction (gimple *stmt, gi
             {
               enum vect_def_type dt;
 	      gimple *dummy_stmt;
-              tree dummy;
 
-              vect_is_simple_use (ops[!reduc_index], stmt, loop_vinfo,
-                                  &dummy_stmt, &dummy, &dt);
+              vect_is_simple_use (ops[!reduc_index], loop_vinfo,
+                                  &dummy_stmt, &dt);
               loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt,
                                                               loop_vec_def0);
               vec_oprnds0[0] = loop_vec_def0;
               if (op_type == ternary_op)
                 {
-                  vect_is_simple_use (op1, stmt, loop_vinfo, &dummy_stmt,
-                                      &dummy, &dt);
+                  vect_is_simple_use (op1, loop_vinfo, &dummy_stmt, &dt);
                   loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt,
                                                                 loop_vec_def1);
                   vec_oprnds1[0] = loop_vec_def1;
@@ -5595,7 +5590,6 @@ vectorizable_live_operation (gimple *stm
   int i;
   int op_type;
   tree op;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt;
   enum tree_code code;
@@ -5667,7 +5661,7 @@ vectorizable_live_operation (gimple *stm
       else
 	op = gimple_op (stmt, i + 1);
       if (op
-          && !vect_is_simple_use (op, stmt, loop_vinfo, &def_stmt, &def, &dt))
+          && !vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt))
         {
           if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	(revision 228806)
+++ gcc/tree-vect-patterns.c	(working copy)
@@ -169,17 +169,14 @@ static bool
 type_conversion_p (tree name, gimple *use_stmt, bool check_sign,
 		   tree *orig_type, gimple **def_stmt, bool *promotion)
 {
-  tree dummy;
   gimple *dummy_gimple;
   stmt_vec_info stmt_vinfo;
   tree type = TREE_TYPE (name);
   tree oprnd0;
   enum vect_def_type dt;
-  tree def;
 
   stmt_vinfo = vinfo_for_stmt (use_stmt);
-  if (!vect_is_simple_use (name, use_stmt, stmt_vinfo->vinfo, def_stmt,
-			   &def, &dt))
+  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, def_stmt, &dt))
     return false;
 
   if (dt != vect_internal_def
@@ -207,8 +204,7 @@ type_conversion_p (tree name, gimple *us
   else
     *promotion = false;
 
-  if (!vect_is_simple_use (oprnd0, *def_stmt, stmt_vinfo->vinfo,
-			   &dummy_gimple, &dummy, &dt))
+  if (!vect_is_simple_use (oprnd0, stmt_vinfo->vinfo, &dummy_gimple, &dt))
     return false;
 
   return true;
@@ -1830,7 +1826,7 @@ vect_recog_rotate_pattern (vec<gimple *>
       || !TYPE_UNSIGNED (type))
     return NULL;
 
-  if (!vect_is_simple_use (oprnd1, last_stmt, vinfo, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
     return NULL;
 
   if (dt != vect_internal_def
@@ -2058,7 +2054,6 @@ vect_recog_vector_vector_shift_pattern (
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
   vec_info *vinfo = stmt_vinfo->vinfo;
   enum vect_def_type dt;
-  tree def;
 
   if (!is_gimple_assign (last_stmt))
     return NULL;
@@ -2090,8 +2085,7 @@ vect_recog_vector_vector_shift_pattern (
 	 != TYPE_PRECISION (TREE_TYPE (oprnd0)))
     return NULL;
 
-  if (!vect_is_simple_use (oprnd1, last_stmt, vinfo, &def_stmt,
-			   &def, &dt))
+  if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
     return NULL;
 
   if (dt != vect_internal_def)
@@ -2102,7 +2096,7 @@ vect_recog_vector_vector_shift_pattern (
   if (*type_in == NULL_TREE)
     return NULL;
 
-  def = NULL_TREE;
+  tree def = NULL_TREE;
   if (gimple_assign_cast_p (def_stmt))
     {
       tree rhs1 = gimple_assign_rhs1 (def_stmt);
@@ -2892,11 +2886,10 @@ check_bool_pattern (tree var, vec_info *
 {
   gimple *def_stmt;
   enum vect_def_type dt;
-  tree def, rhs1;
+  tree rhs1;
   enum tree_code rhs_code;
 
-  if (!vect_is_simple_use (var, NULL, vinfo, &def_stmt, &def,
-			   &dt))
+  if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
     return false;
 
   if (dt != vect_internal_def)
@@ -2905,7 +2898,7 @@ check_bool_pattern (tree var, vec_info *
   if (!is_gimple_assign (def_stmt))
     return false;
 
-  if (!has_single_use (def))
+  if (!has_single_use (var))
     return false;
 
   rhs1 = gimple_assign_rhs1 (def_stmt);
Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c	(revision 228806)
+++ gcc/tree-vect-slp.c	(working copy)
@@ -234,7 +234,6 @@ vect_get_and_check_slp_defs (vec_info *v
 {
   tree oprnd;
   unsigned int i, number_of_oprnds;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt = vect_uninitialized_def;
   struct loop *loop = NULL;
@@ -287,8 +286,7 @@ again:
 
       oprnd_info = (*oprnds_info)[i];
 
-      if (!vect_is_simple_use (oprnd, NULL, vinfo, &def_stmt,
-			       &def, &dt))
+      if (!vect_is_simple_use (oprnd, vinfo, &def_stmt, &dt))
 	{
 	  if (dump_enabled_p ())
 	    {
@@ -355,19 +353,15 @@ again:
 
           switch (gimple_code (def_stmt))
             {
-              case GIMPLE_PHI:
-                def = gimple_phi_result (def_stmt);
-                break;
-
-              case GIMPLE_ASSIGN:
-                def = gimple_assign_lhs (def_stmt);
-                break;
-
-              default:
-                if (dump_enabled_p ())
-                  dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-				   "unsupported defining stmt:\n");
-                return -1;
+            case GIMPLE_PHI:
+            case GIMPLE_ASSIGN:
+	      break;
+
+	    default:
+	      if (dump_enabled_p ())
+		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+				 "unsupported defining stmt:\n");
+	      return -1;
             }
         }
 
@@ -432,7 +426,7 @@ again:
 	    {
 	      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			       "Build SLP failed: illegal type of def ");
-	      dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, def);
+	      dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd);
               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
 	    }
 
@@ -1555,12 +1549,12 @@ vect_analyze_slp_cost_1 (slp_instance in
   lhs = gimple_get_lhs (stmt);
   for (i = 0; i < gimple_num_ops (stmt); ++i)
     {
-      tree def, op = gimple_op (stmt, i);
+      tree op = gimple_op (stmt, i);
       gimple *def_stmt;
       enum vect_def_type dt;
       if (!op || op == lhs)
 	continue;
-      if (vect_is_simple_use (op, NULL, stmt_info->vinfo, &def_stmt, &def, &dt))
+      if (vect_is_simple_use (op, stmt_info->vinfo, &def_stmt, &dt))
 	{
 	  /* Without looking at the actual initializer a vector of
 	     constants can be implemented as load from the constant pool.
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	(revision 228806)
+++ gcc/tree-vect-stmts.c	(working copy)
@@ -450,7 +450,6 @@ process_use (gimple *stmt, tree use, loo
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
   stmt_vec_info dstmt_vinfo;
   basic_block bb, def_bb;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt;
 
@@ -459,7 +458,7 @@ process_use (gimple *stmt, tree use, loo
   if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
      return true;
 
-  if (!vect_is_simple_use (use, stmt, loop_vinfo, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &dt))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -1342,16 +1341,14 @@ vect_init_vector (gimple *stmt, tree val
    needs to be introduced.  */
 
 tree
-vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def)
+vect_get_vec_def_for_operand (tree op, gimple *stmt)
 {
   tree vec_oprnd;
   gimple *vec_stmt;
   gimple *def_stmt;
   stmt_vec_info def_stmt_info = NULL;
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
-  unsigned int nunits;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  tree def;
   enum vect_def_type dt;
   bool is_simple_use;
   tree vector_type;
@@ -1364,19 +1361,11 @@ vect_get_vec_def_for_operand (tree op, g
       dump_printf (MSG_NOTE, "\n");
     }
 
-  is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo,
-				      &def_stmt, &def, &dt);
+  is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt);
   gcc_assert (is_simple_use);
   if (dump_enabled_p ())
     {
       int loc_printed = 0;
-      if (def)
-        {
-          dump_printf_loc (MSG_NOTE, vect_location, "def =  ");
-          loc_printed = 1;
-          dump_generic_expr (MSG_NOTE, TDF_SLIM, def);
-          dump_printf (MSG_NOTE, "\n");
-        }
       if (def_stmt)
         {
           if (loc_printed)
@@ -1389,46 +1378,18 @@ vect_get_vec_def_for_operand (tree op, g
 
   switch (dt)
     {
-    /* Case 1: operand is a constant.  */
+    /* operand is a constant or a loop invariant.  */
     case vect_constant_def:
+    case vect_external_def:
       {
 	vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
 	gcc_assert (vector_type);
-	nunits = TYPE_VECTOR_SUBPARTS (vector_type);
-
-	if (scalar_def)
-	  *scalar_def = op;
-
-        /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
-        if (dump_enabled_p ())
-          dump_printf_loc (MSG_NOTE, vect_location,
-                           "Create vector_cst. nunits = %d\n", nunits);
-
         return vect_init_vector (stmt, op, vector_type, NULL);
       }
 
-    /* Case 2: operand is defined outside the loop - loop invariant.  */
-    case vect_external_def:
-      {
-	vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
-	gcc_assert (vector_type);
-
-	if (scalar_def)
-	  *scalar_def = def;
-
-        /* Create 'vec_inv = {inv,inv,..,inv}'  */
-        if (dump_enabled_p ())
-          dump_printf_loc (MSG_NOTE, vect_location, "Create vector_inv.\n");
-
-        return vect_init_vector (stmt, def, vector_type, NULL);
-      }
-
-    /* Case 3: operand is defined inside the loop.  */
+    /* operand is defined inside the loop.  */
     case vect_internal_def:
       {
-	if (scalar_def)
-	  *scalar_def = NULL/* FIXME tuples: def_stmt*/;
-
         /* Get the def from the vectorized stmt.  */
         def_stmt_info = vinfo_for_stmt (def_stmt);
 
@@ -1449,22 +1410,14 @@ vect_get_vec_def_for_operand (tree op, g
         return vec_oprnd;
       }
 
-    /* Case 4: operand is defined by a loop header phi - reduction  */
+    /* operand is defined by a loop header phi - reduction  */
     case vect_reduction_def:
     case vect_double_reduction_def:
     case vect_nested_cycle:
-      {
-	struct loop *loop;
-
-	gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
-	loop = (gimple_bb (def_stmt))->loop_father;
-
-        /* Get the def before the loop  */
-        op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
-        return get_initial_def_for_reduction (stmt, op, scalar_def);
-     }
+      /* Code should use get_initial_def_for_reduction.  */
+      gcc_unreachable ();
 
-    /* Case 5: operand is defined by loop-header phi - induction.  */
+    /* operand is defined by loop-header phi - induction.  */
     case vect_induction_def:
       {
 	gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
@@ -1618,13 +1571,13 @@ vect_get_vec_defs (tree op0, tree op1, g
       tree vec_oprnd;
 
       vec_oprnds0->create (1);
-      vec_oprnd = vect_get_vec_def_for_operand (op0, stmt, NULL);
+      vec_oprnd = vect_get_vec_def_for_operand (op0, stmt);
       vec_oprnds0->quick_push (vec_oprnd);
 
       if (op1)
 	{
 	  vec_oprnds1->create (1);
-	  vec_oprnd = vect_get_vec_def_for_operand (op1, stmt, NULL);
+	  vec_oprnd = vect_get_vec_def_for_operand (op1, stmt);
 	  vec_oprnds1->quick_push (vec_oprnd);
 	}
     }
@@ -1753,7 +1706,6 @@ vectorizable_mask_load_store (gimple *st
   bool is_store;
   tree mask;
   gimple *def_stmt;
-  tree def;
   enum vect_def_type dt;
 
   if (slp_node != NULL)
@@ -1797,13 +1749,11 @@ vectorizable_mask_load_store (gimple *st
   if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
     {
       gimple *def_stmt;
-      tree def;
       gather_decl = vect_check_gather_scatter (stmt, loop_vinfo, &gather_base,
 				       &gather_off, &gather_scale);
       gcc_assert (gather_decl);
-      if (!vect_is_simple_use_1 (gather_off, NULL, loop_vinfo,
-				 &def_stmt, &def, &gather_dt,
-				 &gather_off_vectype))
+      if (!vect_is_simple_use (gather_off, loop_vinfo, &def_stmt, &gather_dt,
+			       &gather_off_vectype))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -1833,15 +1783,13 @@ vectorizable_mask_load_store (gimple *st
   if (TREE_CODE (mask) != SSA_NAME)
     return false;
 
-  if (!vect_is_simple_use (mask, stmt, loop_vinfo,
-			   &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt))
     return false;
 
   if (is_store)
     {
       tree rhs = gimple_call_arg (stmt, 3);
-      if (!vect_is_simple_use (rhs, stmt, loop_vinfo,
-			       &def_stmt, &def, &dt))
+      if (!vect_is_simple_use (rhs, loop_vinfo, &def_stmt, &dt))
 	return false;
     }
 
@@ -1931,7 +1879,7 @@ vectorizable_mask_load_store (gimple *st
 				       perm_mask, stmt, gsi);
 	  else if (j == 0)
 	    op = vec_oprnd0
-	      = vect_get_vec_def_for_operand (gather_off, stmt, NULL);
+	      = vect_get_vec_def_for_operand (gather_off, stmt);
 	  else
 	    op = vec_oprnd0
 	      = vect_get_vec_def_for_stmt_copy (gather_dt, vec_oprnd0);
@@ -1955,11 +1903,10 @@ vectorizable_mask_load_store (gimple *st
 	  else
 	    {
 	      if (j == 0)
-		vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+		vec_mask = vect_get_vec_def_for_operand (mask, stmt);
 	      else
 		{
-		  vect_is_simple_use (vec_mask, NULL, loop_vinfo,
-				      &def_stmt, &def, &dt);
+		  vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
 		  vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
 		}
 
@@ -2043,8 +1990,8 @@ vectorizable_mask_load_store (gimple *st
 	  if (i == 0)
 	    {
 	      tree rhs = gimple_call_arg (stmt, 3);
-	      vec_rhs = vect_get_vec_def_for_operand (rhs, stmt, NULL);
-	      vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+	      vec_rhs = vect_get_vec_def_for_operand (rhs, stmt);
+	      vec_mask = vect_get_vec_def_for_operand (mask, stmt);
 	      /* We should have catched mismatched types earlier.  */
 	      gcc_assert (useless_type_conversion_p (vectype,
 						     TREE_TYPE (vec_rhs)));
@@ -2055,11 +2002,9 @@ vectorizable_mask_load_store (gimple *st
 	    }
 	  else
 	    {
-	      vect_is_simple_use (vec_rhs, NULL, loop_vinfo, &def_stmt,
-				  &def, &dt);
+	      vect_is_simple_use (vec_rhs, loop_vinfo, &def_stmt, &dt);
 	      vec_rhs = vect_get_vec_def_for_stmt_copy (dt, vec_rhs);
-	      vect_is_simple_use (vec_mask, NULL, loop_vinfo, &def_stmt,
-				  &def, &dt);
+	      vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
 	      vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
 	      dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
 					     TYPE_SIZE_UNIT (vectype));
@@ -2100,7 +2045,7 @@ vectorizable_mask_load_store (gimple *st
 
 	  if (i == 0)
 	    {
-	      vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+	      vec_mask = vect_get_vec_def_for_operand (mask, stmt);
 	      dataref_ptr = vect_create_data_ref_ptr (stmt, vectype, NULL,
 						      NULL_TREE, &dummy, gsi,
 						      &ptr_incr, false, &inv_p);
@@ -2108,8 +2053,7 @@ vectorizable_mask_load_store (gimple *st
 	    }
 	  else
 	    {
-	      vect_is_simple_use (vec_mask, NULL, loop_vinfo, &def_stmt,
-				  &def, &dt);
+	      vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
 	      vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
 	      dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
 					     TYPE_SIZE_UNIT (vectype));
@@ -2180,7 +2124,7 @@ vectorizable_call (gimple *gs, gimple_st
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
   vec_info *vinfo = stmt_info->vinfo;
-  tree fndecl, new_temp, def, rhs_type;
+  tree fndecl, new_temp, rhs_type;
   gimple *def_stmt;
   enum vect_def_type dt[3]
     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
@@ -2253,8 +2197,7 @@ vectorizable_call (gimple *gs, gimple_st
       if (!rhs_type)
 	rhs_type = TREE_TYPE (op);
 
-      if (!vect_is_simple_use_1 (op, stmt, vinfo,
-				 &def_stmt, &def, &dt[i], &opvectype))
+      if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[i], &opvectype))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2416,7 +2359,7 @@ vectorizable_call (gimple *gs, gimple_st
 	      op = gimple_call_arg (stmt, i);
 	      if (j == 0)
 		vec_oprnd0
-		  = vect_get_vec_def_for_operand (op, stmt, NULL);
+		  = vect_get_vec_def_for_operand (op, stmt);
 	      else
 		{
 		  vec_oprnd0 = gimple_call_arg (new_stmt, i);
@@ -2514,7 +2457,7 @@ vectorizable_call (gimple *gs, gimple_st
 	      if (j == 0)
 		{
 		  vec_oprnd0
-		    = vect_get_vec_def_for_operand (op, stmt, NULL);
+		    = vect_get_vec_def_for_operand (op, stmt);
 		  vec_oprnd1
 		    = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
 		}
@@ -2705,7 +2648,7 @@ vectorizable_simd_clone_call (gimple *st
   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
   vec_info *vinfo = stmt_info->vinfo;
   struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
-  tree fndecl, new_temp, def;
+  tree fndecl, new_temp;
   gimple *def_stmt;
   gimple *new_stmt = NULL;
   int ncopies, j;
@@ -2768,9 +2711,8 @@ vectorizable_simd_clone_call (gimple *st
       thisarginfo.simd_lane_linear = false;
 
       op = gimple_call_arg (stmt, i);
-      if (!vect_is_simple_use_1 (op, stmt, vinfo,
-				 &def_stmt, &def, &thisarginfo.dt,
-				 &thisarginfo.vectype)
+      if (!vect_is_simple_use (op, vinfo, &def_stmt, &thisarginfo.dt,
+			       &thisarginfo.vectype)
 	  || thisarginfo.dt == vect_uninitialized_def)
 	{
 	  if (dump_enabled_p ())
@@ -3047,7 +2989,7 @@ vectorizable_simd_clone_call (gimple *st
 		      gcc_assert ((k & (k - 1)) == 0);
 		      if (m == 0)
 			vec_oprnd0
-			  = vect_get_vec_def_for_operand (op, stmt, NULL);
+			  = vect_get_vec_def_for_operand (op, stmt);
 		      else
 			{
 			  vec_oprnd0 = arginfo[i].op;
@@ -3081,7 +3023,7 @@ vectorizable_simd_clone_call (gimple *st
 			{
 			  if (m == 0 && l == 0)
 			    vec_oprnd0
-			      = vect_get_vec_def_for_operand (op, stmt, NULL);
+			      = vect_get_vec_def_for_operand (op, stmt);
 			  else
 			    vec_oprnd0
 			      = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
@@ -3395,7 +3337,7 @@ vect_get_loop_based_defs (tree *oprnd, g
   /* All the vector operands except the very first one (that is scalar oprnd)
      are stmt copies.  */
   if (TREE_CODE (TREE_TYPE (*oprnd)) != VECTOR_TYPE)
-    vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt, NULL);
+    vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt);
   else
     vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, *oprnd);
 
@@ -3555,7 +3497,6 @@ vectorizable_conversion (gimple *stmt, g
   enum tree_code codecvt1 = ERROR_MARK, codecvt2 = ERROR_MARK;
   tree decl1 = NULL_TREE, decl2 = NULL_TREE;
   tree new_temp;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
   gimple *new_stmt = NULL;
@@ -3633,8 +3574,7 @@ vectorizable_conversion (gimple *stmt, g
     }
 
   /* Check the operands of the operation.  */
-  if (!vect_is_simple_use_1 (op0, stmt, vinfo,
-			     &def_stmt, &def, &dt[0], &vectype_in))
+  if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype_in))
     {
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -3650,11 +3590,9 @@ vectorizable_conversion (gimple *stmt, g
       /* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
 	 OP1.  */
       if (CONSTANT_CLASS_P (op0))
-	ok = vect_is_simple_use_1 (op1, stmt, vinfo,
-				   &def_stmt, &def, &dt[1], &vectype_in);
+	ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &vectype_in);
       else
-	ok = vect_is_simple_use (op1, stmt, vinfo, &def_stmt,
-				 &def, &dt[1]);
+	ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]);
 
       if (!ok)
 	{
@@ -3971,15 +3909,14 @@ vectorizable_conversion (gimple *stmt, g
 		}
 	      else
 		{
-		  vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL);
+		  vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
 		  vec_oprnds0.quick_push (vec_oprnd0);
 		  if (op_type == binary_op)
 		    {
 		      if (code == WIDEN_LSHIFT_EXPR)
 			vec_oprnd1 = op1;
 		      else
-			vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt,
-								   NULL);
+			vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt);
 		      vec_oprnds1.quick_push (vec_oprnd1);
 		    }
 		}
@@ -4133,7 +4070,6 @@ vectorizable_assignment (gimple *stmt, g
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   tree new_temp;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
   int ncopies;
@@ -4185,8 +4121,7 @@ vectorizable_assignment (gimple *stmt, g
 
   gcc_assert (ncopies >= 1);
 
-  if (!vect_is_simple_use_1 (op, stmt, vinfo,
-			     &def_stmt, &def, &dt[0], &vectype_in))
+  if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[0], &vectype_in))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4340,7 +4275,6 @@ vectorizable_shift (gimple *stmt, gimple
   optab optab;
   int icode;
   machine_mode optab_op2_mode;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
   gimple *new_stmt = NULL;
@@ -4391,8 +4325,7 @@ vectorizable_shift (gimple *stmt, gimple
     }
 
   op0 = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use_1 (op0, stmt, vinfo,
-                             &def_stmt, &def, &dt[0], &vectype))
+  if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4419,8 +4352,7 @@ vectorizable_shift (gimple *stmt, gimple
     return false;
 
   op1 = gimple_assign_rhs2 (stmt);
-  if (!vect_is_simple_use_1 (op1, stmt, vinfo, &def_stmt,
-			     &def, &dt[1], &op1_vectype))
+  if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &op1_vectype))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4705,7 +4637,6 @@ vectorizable_operation (gimple *stmt, gi
   int op_type;
   optab optab;
   bool target_support_p;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt[3]
     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
@@ -4774,8 +4705,7 @@ vectorizable_operation (gimple *stmt, gi
     }
 
   op0 = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use_1 (op0, stmt, vinfo,
-			     &def_stmt, &def, &dt[0], &vectype))
+  if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4810,8 +4740,7 @@ vectorizable_operation (gimple *stmt, gi
   if (op_type == binary_op || op_type == ternary_op)
     {
       op1 = gimple_assign_rhs2 (stmt);
-      if (!vect_is_simple_use (op1, stmt, vinfo, &def_stmt,
-			       &def, &dt[1]))
+      if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4822,8 +4751,7 @@ vectorizable_operation (gimple *stmt, gi
   if (op_type == ternary_op)
     {
       op2 = gimple_assign_rhs3 (stmt);
-      if (!vect_is_simple_use (op2, stmt, vinfo, &def_stmt,
-			       &def, &dt[2]))
+      if (!vect_is_simple_use (op2, vinfo, &def_stmt, &dt[2]))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4984,8 +4912,7 @@ vectorizable_operation (gimple *stmt, gi
 	    {
 	      vec_oprnds2.create (1);
 	      vec_oprnds2.quick_push (vect_get_vec_def_for_operand (op2,
-		                                                    stmt,
-								    NULL));
+		                                                    stmt));
 	    }
 	}
       else
@@ -5102,7 +5029,6 @@ vectorizable_store (gimple *stmt, gimple
   machine_mode vec_mode;
   tree dummy;
   enum dr_alignment_support alignment_support_scheme;
-  tree def;
   gimple *def_stmt;
   enum vect_def_type dt;
   stmt_vec_info prev_stmt_info = NULL;
@@ -5186,8 +5112,7 @@ vectorizable_store (gimple *stmt, gimple
     }
 
   op = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use (op, stmt, vinfo, &def_stmt,
-			   &def, &dt))
+  if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5277,8 +5202,7 @@ vectorizable_store (gimple *stmt, gimple
             {
 	      gcc_assert (gimple_assign_single_p (next_stmt));
 	      op = gimple_assign_rhs1 (next_stmt);
-              if (!vect_is_simple_use (op, next_stmt, vinfo,
-				       &def_stmt, &def, &dt))
+              if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt))
                 {
                   if (dump_enabled_p ())
                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5293,13 +5217,11 @@ vectorizable_store (gimple *stmt, gimple
   if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
     {
       gimple *def_stmt;
-      tree def;
       scatter_decl = vect_check_gather_scatter (stmt, loop_vinfo, &scatter_base,
 						&scatter_off, &scatter_scale);
       gcc_assert (scatter_decl);
-      if (!vect_is_simple_use_1 (scatter_off, NULL, vinfo,
-				 &def_stmt, &def, &scatter_idx_dt,
-				 &scatter_off_vectype))
+      if (!vect_is_simple_use (scatter_off, vinfo, &def_stmt, &scatter_idx_dt,
+			       &scatter_off_vectype))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5393,9 +5315,9 @@ vectorizable_store (gimple *stmt, gimple
 	  if (j == 0)
 	    {
 	      src = vec_oprnd1
-		= vect_get_vec_def_for_operand (gimple_assign_rhs1 (stmt), stmt, NULL);
+		= vect_get_vec_def_for_operand (gimple_assign_rhs1 (stmt), stmt);
 	      op = vec_oprnd0
-		= vect_get_vec_def_for_operand (scatter_off, stmt, NULL);
+		= vect_get_vec_def_for_operand (scatter_off, stmt);
 	    }
 	  else if (modifier != NONE && (j & 1))
 	    {
@@ -5613,8 +5535,7 @@ vectorizable_store (gimple *stmt, gimple
 		    {
 		      gcc_assert (gimple_assign_single_p (next_stmt));
 		      op = gimple_assign_rhs1 (next_stmt);
-		      vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
-								NULL);
+		      vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
 		    }
 		}
 	      else
@@ -5623,8 +5544,7 @@ vectorizable_store (gimple *stmt, gimple
 		    vec_oprnd = vec_oprnds[j];
 		  else
 		    {
-		      vect_is_simple_use (vec_oprnd, NULL, vinfo,
-					  &def_stmt, &def, &dt);
+		      vect_is_simple_use (vec_oprnd, vinfo, &def_stmt, &dt);
 		      vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
 		    }
 		}
@@ -5767,8 +5687,7 @@ vectorizable_store (gimple *stmt, gimple
 			      && gimple_assign_single_p (next_stmt));
 		  op = gimple_assign_rhs1 (next_stmt);
 
-		  vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
-							    NULL);
+		  vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
 		  dr_chain.quick_push (vec_oprnd);
 		  oprnds.quick_push (vec_oprnd);
 		  next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
@@ -5813,8 +5732,7 @@ vectorizable_store (gimple *stmt, gimple
 	  for (i = 0; i < group_size; i++)
 	    {
 	      op = oprnds[i];
-	      vect_is_simple_use (op, NULL, vinfo, &def_stmt,
-				  &def, &dt);
+	      vect_is_simple_use (op, vinfo, &def_stmt, &dt);
 	      vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
 	      dr_chain[i] = vec_oprnd;
 	      oprnds[i] = vec_oprnd;
@@ -6288,13 +6206,11 @@ vectorizable_load (gimple *stmt, gimple_
   if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
     {
       gimple *def_stmt;
-      tree def;
       gather_decl = vect_check_gather_scatter (stmt, loop_vinfo, &gather_base,
 					       &gather_off, &gather_scale);
       gcc_assert (gather_decl);
-      if (!vect_is_simple_use_1 (gather_off, NULL, vinfo,
-				 &def_stmt, &def, &gather_dt,
-				 &gather_off_vectype))
+      if (!vect_is_simple_use (gather_off, vinfo, &def_stmt, &gather_dt,
+			       &gather_off_vectype))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -6483,7 +6399,7 @@ vectorizable_load (gimple *stmt, gimple_
 				       perm_mask, stmt, gsi);
 	  else if (j == 0)
 	    op = vec_oprnd0
-	      = vect_get_vec_def_for_operand (gather_off, stmt, NULL);
+	      = vect_get_vec_def_for_operand (gather_off, stmt);
 	  else
 	    op = vec_oprnd0
 	      = vect_get_vec_def_for_stmt_copy (gather_dt, vec_oprnd0);
@@ -7224,11 +7140,9 @@ vectorizable_load (gimple *stmt, gimple_
    condition operands are supportable using vec_is_simple_use.  */
 
 static bool
-vect_is_simple_cond (tree cond, gimple *stmt, vec_info *vinfo,
-		     tree *comp_vectype)
+vect_is_simple_cond (tree cond, vec_info *vinfo, tree *comp_vectype)
 {
   tree lhs, rhs;
-  tree def;
   enum vect_def_type dt;
   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
 
@@ -7241,8 +7155,7 @@ vect_is_simple_cond (tree cond, gimple *
   if (TREE_CODE (lhs) == SSA_NAME)
     {
       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
-      if (!vect_is_simple_use_1 (lhs, stmt, vinfo,
-				 &lhs_def_stmt, &def, &dt, &vectype1))
+      if (!vect_is_simple_use (lhs, vinfo, &lhs_def_stmt, &dt, &vectype1))
 	return false;
     }
   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
@@ -7252,8 +7165,7 @@ vect_is_simple_cond (tree cond, gimple *
   if (TREE_CODE (rhs) == SSA_NAME)
     {
       gimple *rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
-      if (!vect_is_simple_use_1 (rhs, stmt, vinfo,
-				 &rhs_def_stmt, &def, &dt, &vectype2))
+      if (!vect_is_simple_use (rhs, vinfo, &rhs_def_stmt, &dt, &vectype2))
 	return false;
     }
   else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
@@ -7292,7 +7204,6 @@ vectorizable_condition (gimple *stmt, gi
   tree vec_compare, vec_cond_expr;
   tree new_temp;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
-  tree def;
   enum vect_def_type dt, dts[4];
   int ncopies;
   enum tree_code code;
@@ -7350,32 +7261,14 @@ vectorizable_condition (gimple *stmt, gi
   then_clause = gimple_assign_rhs2 (stmt);
   else_clause = gimple_assign_rhs3 (stmt);
 
-  if (!vect_is_simple_cond (cond_expr, stmt, stmt_info->vinfo, &comp_vectype)
+  if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo, &comp_vectype)
       || !comp_vectype)
     return false;
 
-  if (TREE_CODE (then_clause) == SSA_NAME)
-    {
-      gimple *then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
-      if (!vect_is_simple_use (then_clause, stmt, stmt_info->vinfo,
-			       &then_def_stmt, &def, &dt))
-	return false;
-    }
-  else if (TREE_CODE (then_clause) != INTEGER_CST
-	   && TREE_CODE (then_clause) != REAL_CST
-	   && TREE_CODE (then_clause) != FIXED_CST)
+  gimple *def_stmt;
+  if (!vect_is_simple_use (then_clause, stmt_info->vinfo, &def_stmt, &dt))
     return false;
-
-  if (TREE_CODE (else_clause) == SSA_NAME)
-    {
-      gimple *else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
-      if (!vect_is_simple_use (else_clause, stmt, stmt_info->vinfo,
-			       &else_def_stmt, &def, &dt))
-	return false;
-    }
-  else if (TREE_CODE (else_clause) != INTEGER_CST
-	   && TREE_CODE (else_clause) != REAL_CST
-	   && TREE_CODE (else_clause) != FIXED_CST)
+  if (!vect_is_simple_use (else_clause, stmt_info->vinfo, &def_stmt, &dt))
     return false;
 
   unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
@@ -7433,33 +7326,31 @@ vectorizable_condition (gimple *stmt, gi
             {
 	      gimple *gtemp;
 	      vec_cond_lhs =
-	      vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
-					    stmt, NULL);
-	      vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
-				  loop_vinfo, &gtemp, &def, &dts[0]);
+	      vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt);
+	      vect_is_simple_use (TREE_OPERAND (cond_expr, 0),
+				  loop_vinfo, &gtemp, &dts[0]);
 
 	      vec_cond_rhs =
 		vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
-						stmt, NULL);
-	      vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
-				  loop_vinfo, &gtemp, &def, &dts[1]);
+					      stmt);
+	      vect_is_simple_use (TREE_OPERAND (cond_expr, 1),
+				  loop_vinfo, &gtemp, &dts[1]);
 	      if (reduc_index == 1)
 		vec_then_clause = reduc_def;
 	      else
 		{
 		  vec_then_clause = vect_get_vec_def_for_operand (then_clause,
-		 		  			      stmt, NULL);
-	          vect_is_simple_use (then_clause, stmt, loop_vinfo,
-				      &gtemp, &def, &dts[2]);
+								  stmt);
+	          vect_is_simple_use (then_clause, loop_vinfo,
+				      &gtemp, &dts[2]);
 		}
 	      if (reduc_index == 2)
 		vec_else_clause = reduc_def;
 	      else
 		{
 		  vec_else_clause = vect_get_vec_def_for_operand (else_clause,
-							      stmt, NULL);
-		  vect_is_simple_use (else_clause, stmt, loop_vinfo,
-				      &gtemp, &def, &dts[3]);
+								  stmt);
+		  vect_is_simple_use (else_clause, loop_vinfo, &gtemp, &dts[3]);
 		}
 	    }
 	}
@@ -8200,10 +8091,11 @@ get_same_sized_vectype (tree scalar_type
 /* Function vect_is_simple_use.
 
    Input:
-   LOOP_VINFO - the vect info of the loop that is being vectorized.
-   BB_VINFO - the vect info of the basic block that is being vectorized.
-   OPERAND - operand of STMT in the loop or bb.
-   DEF - the defining stmt in case OPERAND is an SSA_NAME.
+   VINFO - the vect info of the loop or basic block that is being vectorized.
+   OPERAND - operand in the loop or bb.
+   Output:
+   DEF_STMT - the defining stmt in case OPERAND is an SSA_NAME.
+   DT - the type of definition
 
    Returns whether a stmt with OPERAND can be vectorized.
    For loops, supportable operands are constants, loop invariants, and operands
@@ -8214,11 +8106,10 @@ get_same_sized_vectype (tree scalar_type
    For now, operands defined outside the basic block are not supported.  */
 
 bool
-vect_is_simple_use (tree operand, gimple *stmt, vec_info *vinfo,
-                    gimple **def_stmt, tree *def, enum vect_def_type *dt)
+vect_is_simple_use (tree operand, vec_info *vinfo,
+                    gimple **def_stmt, enum vect_def_type *dt)
 {
   *def_stmt = NULL;
-  *def = NULL_TREE;
   *dt = vect_unknown_def_type;
 
   if (dump_enabled_p ())
@@ -8237,7 +8128,6 @@ vect_is_simple_use (tree operand, gimple
 
   if (is_gimple_min_invariant (operand))
     {
-      *def = operand;
       *dt = vect_external_def;
       return true;
     }
@@ -8252,7 +8142,6 @@ vect_is_simple_use (tree operand, gimple
 
   if (SSA_NAME_IS_DEFAULT_DEF (operand))
     {
-      *def = operand;
       *dt = vect_external_def;
       return true;
     }
@@ -8315,10 +8204,7 @@ vect_is_simple_use (tree operand, gimple
 	}
     }
 
-  if (*dt == vect_unknown_def_type
-      || (stmt
-	  && *dt == vect_double_reduction_def
-	  && gimple_code (stmt) != GIMPLE_PHI))
+  if (*dt == vect_unknown_def_type)
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -8329,18 +8215,9 @@ vect_is_simple_use (tree operand, gimple
   switch (gimple_code (*def_stmt))
     {
     case GIMPLE_PHI:
-      *def = gimple_phi_result (*def_stmt);
-      break;
-
     case GIMPLE_ASSIGN:
-      *def = gimple_assign_lhs (*def_stmt);
-      break;
-
     case GIMPLE_CALL:
-      *def = gimple_call_lhs (*def_stmt);
-      if (*def != NULL)
-	break;
-      /* FALLTHRU */
+      break;
     default:
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -8351,9 +8228,9 @@ vect_is_simple_use (tree operand, gimple
   return true;
 }
 
-/* Function vect_is_simple_use_1.
+/* Function vect_is_simple_use.
 
-   Same as vect_is_simple_use_1 but also determines the vector operand
+   Same as vect_is_simple_use but also determines the vector operand
    type of OPERAND and stores it to *VECTYPE.  If the definition of
    OPERAND is vect_uninitialized_def, vect_constant_def or
    vect_external_def *VECTYPE will be set to NULL_TREE and the caller
@@ -8361,11 +8238,10 @@ vect_is_simple_use (tree operand, gimple
    scalar operand.  */
 
 bool
-vect_is_simple_use_1 (tree operand, gimple *stmt, vec_info *vinfo,
-		      gimple **def_stmt,
-		      tree *def, enum vect_def_type *dt, tree *vectype)
+vect_is_simple_use (tree operand, vec_info *vinfo,
+		    gimple **def_stmt, enum vect_def_type *dt, tree *vectype)
 {
-  if (!vect_is_simple_use (operand, stmt, vinfo, def_stmt, def, dt))
+  if (!vect_is_simple_use (operand, vinfo, def_stmt, dt))
     return false;
 
   /* Now get a vector type if the def is internal, otherwise supply
@@ -8506,6 +8382,16 @@ supportable_widening_operation (enum tre
       c2 = VEC_WIDEN_MULT_HI_EXPR;
       break;
 
+    case DOT_PROD_EXPR:
+      c1 = DOT_PROD_EXPR;
+      c2 = DOT_PROD_EXPR;
+      break;
+
+    case SAD_EXPR:
+      c1 = SAD_EXPR;
+      c2 = SAD_EXPR;
+      break;
+
     case VEC_WIDEN_MULT_EVEN_EXPR:
       /* Support the recursion induced just above.  */
       c1 = VEC_WIDEN_MULT_EVEN_EXPR;
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	(revision 228806)
+++ gcc/tree-vectorizer.h	(working copy)
@@ -932,10 +932,10 @@ extern bool vect_can_advance_ivs_p (loop
 extern unsigned int current_vector_size;
 extern tree get_vectype_for_scalar_type (tree);
 extern tree get_same_sized_vectype (tree, tree);
-extern bool vect_is_simple_use (tree, gimple *, vec_info *, gimple **,
-                                tree *,  enum vect_def_type *);
-extern bool vect_is_simple_use_1 (tree, gimple *, vec_info *, gimple **,
-				  tree *,  enum vect_def_type *, tree *);
+extern bool vect_is_simple_use (tree, vec_info *, gimple **,
+                                enum vect_def_type *);
+extern bool vect_is_simple_use (tree, vec_info *, gimple **,
+				enum vect_def_type *, tree *);
 extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
 					    tree, enum tree_code *,
 					    enum tree_code *, int *,
@@ -962,7 +962,7 @@ extern unsigned record_stmt_cost (stmt_v
 extern void vect_finish_stmt_generation (gimple *, gimple *,
                                          gimple_stmt_iterator *);
 extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
-extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *);
+extern tree vect_get_vec_def_for_operand (tree, gimple *);
 extern tree vect_init_vector (gimple *, tree, tree,
                               gimple_stmt_iterator *);
 extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2015-10-14  8:32 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-14  8:32 UTC (permalink / raw)
  To: gcc-patches


Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-10-14  Richard Biener  <rguenther@suse.de>

	* tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
	Reset info at start.
	(vect_analyze_group_access_1): Add debug print.
	* tree-vect-loop.c (vect_get_single_scalar_iteration_cost): Rename ...
	(vect_compute_single_scalar_iteration_cost): ... to this.
	(vect_analyze_loop_2): Adjust.
	* tree-vect-slp.c (struct _slp_oprnd_info): Move from ...
	* tree-vectorizer.h: ... here.
	(add_stmt_info_to_vec): Remove.
	* tree-vect-stmts.c (record_stmt_cost): Inline add_stmt_info_to_vec.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c	(revision 228759)
--- gcc/tree-vect-data-refs.c	(working copy)
*************** vect_enhance_data_refs_alignment (loop_v
*** 1352,1357 ****
--- 1352,1361 ----
      dump_printf_loc (MSG_NOTE, vect_location,
                       "=== vect_enhance_data_refs_alignment ===\n");
  
+   /* Reset data so we can safely be called multiple times.  */
+   LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).truncate (0);
+   LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) = 0;
+ 
    /* While cost model enhancements are expected in the future, the high level
       view of the code at this time is as follows:
  
*************** vect_analyze_group_access_1 (struct data
*** 2151,2156 ****
--- 2155,2164 ----
                    return false;
                  }
  
+ 	      if (dump_enabled_p ())
+ 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ 				 "Two or more load stmts share the same dr.\n");
+ 
                /* For load use the same data-ref load.  */
                GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
  
Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c	(revision 228759)
--- gcc/tree-vect-loop.c	(working copy)
*************** destroy_loop_vec_info (loop_vec_info loo
*** 1043,1049 ****
  
  /* Calculate the cost of one scalar iteration of the loop.  */
  static void
! vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
--- 1043,1049 ----
  
  /* Calculate the cost of one scalar iteration of the loop.  */
  static void
! vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
*************** vect_analyze_loop_2 (loop_vec_info loop_
*** 1739,1745 ****
      }
  
    /* Compute the scalar iteration cost.  */
!   vect_get_single_scalar_iteration_cost (loop_vinfo);
  
    /* This pass will decide on using loop versioning and/or loop peeling in
       order to enhance the alignment of data references in the loop.  */
--- 1739,1745 ----
      }
  
    /* Compute the scalar iteration cost.  */
!   vect_compute_single_scalar_iteration_cost (loop_vinfo);
  
    /* This pass will decide on using loop versioning and/or loop peeling in
       order to enhance the alignment of data references in the loop.  */
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c	(revision 228759)
--- gcc/tree-vect-slp.c	(working copy)
*************** vect_create_new_slp_node (vec<gimple *>
*** 135,140 ****
--- 135,157 ----
  }
  
  
+ /* This structure is used in creation of an SLP tree.  Each instance
+    corresponds to the same operand in a group of scalar stmts in an SLP
+    node.  */
+ typedef struct _slp_oprnd_info
+ {
+   /* Def-stmts for the operands.  */
+   vec<gimple *> def_stmts;
+   /* Information about the first statement, its vector def-type, type, the
+      operand itself in case it's constant, and an indication if it's a pattern
+      stmt.  */
+   enum vect_def_type first_dt;
+   tree first_op_type;
+   bool first_pattern;
+   bool second_pattern;
+ } *slp_oprnd_info;
+ 
+ 
  /* Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each
     operand.  */
  static vec<slp_oprnd_info> 
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c	(revision 228759)
--- gcc/tree-vect-stmts.c	(working copy)
*************** record_stmt_cost (stmt_vector_for_cost *
*** 94,105 ****
    if (body_cost_vec)
      {
        tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
!       add_stmt_info_to_vec (body_cost_vec, count, kind,
! 			    stmt_info ? STMT_VINFO_STMT (stmt_info) : NULL,
! 			    misalign);
        return (unsigned)
  	(builtin_vectorization_cost (kind, vectype, misalign) * count);
- 	 
      }
    else
      return add_stmt_cost (stmt_info->vinfo->target_cost_data,
--- 94,105 ----
    if (body_cost_vec)
      {
        tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
!       stmt_info_for_cost si = { count, kind,
! 			        stmt_info ? STMT_VINFO_STMT (stmt_info) : NULL,
! 				misalign };
!       body_cost_vec->safe_push (si);
        return (unsigned)
  	(builtin_vectorization_cost (kind, vectype, misalign) * count);
      }
    else
      return add_stmt_cost (stmt_info->vinfo->target_cost_data,
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h	(revision 228759)
--- gcc/tree-vectorizer.h	(working copy)
*************** struct stmt_info_for_cost {
*** 73,93 ****
    int misalign;
  };
  
- 
  typedef vec<stmt_info_for_cost> stmt_vector_for_cost;
  
- static inline void
- add_stmt_info_to_vec (stmt_vector_for_cost *stmt_cost_vec, int count,
- 		      enum vect_cost_for_stmt kind, gimple *stmt, int misalign)
- {
-   stmt_info_for_cost si;
-   si.count = count;
-   si.kind = kind;
-   si.stmt = stmt;
-   si.misalign = misalign;
-   stmt_cost_vec->safe_push (si);
- }
- 
  /************************************************************************
    SLP
   ************************************************************************/
--- 73,80 ----
*************** typedef struct _slp_instance {
*** 145,166 ****
  #define SLP_TREE_LOAD_PERMUTATION(S)             (S)->load_permutation
  #define SLP_TREE_TWO_OPERATORS(S)		 (S)->two_operators
  
- /* This structure is used in creation of an SLP tree.  Each instance
-    corresponds to the same operand in a group of scalar stmts in an SLP
-    node.  */
- typedef struct _slp_oprnd_info
- {
-   /* Def-stmts for the operands.  */
-   vec<gimple *> def_stmts;
-   /* Information about the first statement, its vector def-type, type, the
-      operand itself in case it's constant, and an indication if it's a pattern
-      stmt.  */
-   enum vect_def_type first_dt;
-   tree first_op_type;
-   bool first_pattern;
-   bool second_pattern;
- } *slp_oprnd_info;
- 
  
  
  /* This struct is used to store the information of a data reference,
--- 132,137 ----

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2015-10-12  8:30 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-12  8:30 UTC (permalink / raw)
  To: gcc-patches


Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-10-12  Richard Biener  <rguenther@suse.de>

	* tree-vect-loop.c (vect_analyze_loop_operations): Move cost
	related code ...
	(vect_analyze_loop_2): ... here.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 228644)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -1430,17 +1430,10 @@ vect_analyze_loop_operations (loop_vec_i
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
   int nbbs = loop->num_nodes;
-  unsigned int vectorization_factor;
   int i;
   stmt_vec_info stmt_info;
   bool need_to_vectorize = false;
-  int min_profitable_iters;
-  int min_scalar_loop_bound;
-  unsigned int th;
   bool ok;
-  HOST_WIDE_INT max_niter;
-  HOST_WIDE_INT estimated_niter;
-  int min_profitable_estimate;
 
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
@@ -1585,94 +1578,6 @@ vect_analyze_loop_operations (loop_vec_i
       return false;
     }
 
-  vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
-  gcc_assert (vectorization_factor != 0);
-
-  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ())
-    dump_printf_loc (MSG_NOTE, vect_location,
-		     "vectorization_factor = %d, niters = "
-		     HOST_WIDE_INT_PRINT_DEC "\n", vectorization_factor,
-		     LOOP_VINFO_INT_NITERS (loop_vinfo));
-
-  if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
-       && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
-      || ((max_niter = max_stmt_executions_int (loop)) != -1
-	  && (unsigned HOST_WIDE_INT) max_niter < vectorization_factor))
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: iteration count too small.\n");
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: iteration count smaller than "
-			 "vectorization factor.\n");
-      return false;
-    }
-
-  /* Analyze cost.  Decide if worth while to vectorize.  */
-
-  vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters,
-				      &min_profitable_estimate);
-  LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
-
-  if (min_profitable_iters < 0)
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: vectorization not profitable.\n");
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: vector version will never be "
-			 "profitable.\n");
-      return false;
-    }
-
-  min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
-                            * vectorization_factor) - 1);
-
-
-  /* Use the cost model only if it is more conservative than user specified
-     threshold.  */
-
-  th = (unsigned) min_scalar_loop_bound;
-  if (min_profitable_iters
-      && (!min_scalar_loop_bound
-          || min_profitable_iters > min_scalar_loop_bound))
-    th = (unsigned) min_profitable_iters;
-
-  LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th;
-
-  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
-      && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: vectorization not profitable.\n");
-      if (dump_enabled_p ())
-        dump_printf_loc (MSG_NOTE, vect_location,
-			 "not vectorized: iteration count smaller than user "
-			 "specified loop bound parameter or minimum profitable "
-			 "iterations (whichever is more conservative).\n");
-      return false;
-    }
-
-  if ((estimated_niter = estimated_stmt_executions_int (loop)) != -1
-      && ((unsigned HOST_WIDE_INT) estimated_niter
-          <= MAX (th, (unsigned)min_profitable_estimate)))
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			 "not vectorized: estimated iteration count too "
-                         "small.\n");
-      if (dump_enabled_p ())
-        dump_printf_loc (MSG_NOTE, vect_location,
-			 "not vectorized: estimated iteration count smaller "
-                         "than specified loop bound parameter or minimum "
-                         "profitable iterations (whichever is more "
-                         "conservative).\n");
-      return false;
-    }
-
   return true;
 }
 
@@ -1688,7 +1593,6 @@ vect_analyze_loop_2 (loop_vec_info loop_
   bool ok;
   int max_vf = MAX_VECTORIZATION_FACTOR;
   int min_vf = 2;
-  unsigned int th;
   unsigned int n_stmts = 0;
 
   /* Find all data references in the loop (which correspond to vdefs/vuses)
@@ -1786,6 +1690,33 @@ vect_analyze_loop_2 (loop_vec_info loop_
       vect_update_vf_for_slp (loop_vinfo);
     }
 
+  /* Now the vectorization factor is final.  */
+  unsigned vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+  gcc_assert (vectorization_factor != 0);
+
+  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ())
+    dump_printf_loc (MSG_NOTE, vect_location,
+		     "vectorization_factor = %d, niters = "
+		     HOST_WIDE_INT_PRINT_DEC "\n", vectorization_factor,
+		     LOOP_VINFO_INT_NITERS (loop_vinfo));
+
+  HOST_WIDE_INT max_niter
+    = max_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+  if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+       && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
+      || (max_niter != -1
+	  && (unsigned HOST_WIDE_INT) max_niter < vectorization_factor))
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: iteration count too small.\n");
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: iteration count smaller than "
+			 "vectorization factor.\n");
+      return false;
+    }
+
   /* Analyze the alignment of the data-refs in the loop.
      Fail if a data reference is found that cannot be vectorized.  */
 
@@ -1851,6 +1782,70 @@ vect_analyze_loop_2 (loop_vec_info loop_
       return false;
     }
 
+  /* Analyze cost.  Decide if worth while to vectorize.  */
+  int min_profitable_estimate, min_profitable_iters;
+  vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters,
+				      &min_profitable_estimate);
+  LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
+
+  if (min_profitable_iters < 0)
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: vectorization not profitable.\n");
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: vector version will never be "
+			 "profitable.\n");
+      return false;
+    }
+
+  int min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
+				* vectorization_factor) - 1);
+
+  /* Use the cost model only if it is more conservative than user specified
+     threshold.  */
+  unsigned th = (unsigned) min_scalar_loop_bound;
+  if (min_profitable_iters
+      && (!min_scalar_loop_bound
+          || min_profitable_iters > min_scalar_loop_bound))
+    th = (unsigned) min_profitable_iters;
+
+  LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th;
+
+  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+      && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: vectorization not profitable.\n");
+      if (dump_enabled_p ())
+        dump_printf_loc (MSG_NOTE, vect_location,
+			 "not vectorized: iteration count smaller than user "
+			 "specified loop bound parameter or minimum profitable "
+			 "iterations (whichever is more conservative).\n");
+      return false;
+    }
+
+  HOST_WIDE_INT estimated_niter
+    = estimated_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+  if (estimated_niter != -1
+      && ((unsigned HOST_WIDE_INT) estimated_niter
+          <= MAX (th, (unsigned)min_profitable_estimate)))
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "not vectorized: estimated iteration count too "
+                         "small.\n");
+      if (dump_enabled_p ())
+        dump_printf_loc (MSG_NOTE, vect_location,
+			 "not vectorized: estimated iteration count smaller "
+                         "than specified loop bound parameter or minimum "
+                         "profitable iterations (whichever is more "
+                         "conservative).\n");
+      return false;
+    }
+
   /* Decide whether we need to create an epilogue loop to handle
      remaining scalar iterations.  */
   th = ((LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) + 1)
@@ -1873,8 +1868,7 @@ vect_analyze_loop_2 (loop_vec_info loop_
                   the epilogue is unnecessary.  */
 	       && ((!LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)
 	            && !LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
-                   || (unsigned HOST_WIDE_INT)max_stmt_executions_int
-		        (LOOP_VINFO_LOOP (loop_vinfo)) > th)))
+                   || (unsigned HOST_WIDE_INT) max_niter > th)))
     LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = true;
 
   /* If an epilogue loop is required make sure we can create one.  */
@@ -1896,6 +1890,9 @@ vect_analyze_loop_2 (loop_vec_info loop_
         }
     }
 
+  gcc_assert (vectorization_factor
+	      == (unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+
   return true;
 }
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2013-04-18 14:16 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2013-04-18 14:16 UTC (permalink / raw)
  To: gcc-patches


While trying to remove some restrictions I came along more TLC
opportunities.

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

Richard.

2013-04-18  Richard Biener  <rguenther@suse.de>

	* tree-vect-data-refs.c (vect_analyze_group_access): Properly
	handle negative step.  Remove redundant checks.
	(vect_create_data_ref_ptr): Avoid ICEs with non-constant steps.
	* tree-vect-stmts.c (vectorizable_load): Instead of asserting
	for negative step and grouped loads fail to vectorize.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c.orig	2013-04-18 12:17:03.000000000 +0200
--- gcc/tree-vect-data-refs.c	2013-04-18 12:17:14.430103903 +0200
*************** vect_analyze_group_access (struct data_r
*** 2024,2030 ****
  
    /* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
       size of the interleaving group (including gaps).  */
!   groupsize = dr_step / type_size;
  
    /* Not consecutive access is possible only if it is a part of interleaving.  */
    if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
--- 2024,2030 ----
  
    /* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
       size of the interleaving group (including gaps).  */
!   groupsize = absu_hwi (dr_step) / type_size;
  
    /* Not consecutive access is possible only if it is a part of interleaving.  */
    if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
*************** vect_analyze_group_access (struct data_r
*** 2094,2103 ****
        gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
        struct data_reference *data_ref = dr;
        unsigned int count = 1;
-       tree next_step;
        tree prev_init = DR_INIT (data_ref);
        gimple prev = stmt;
!       HOST_WIDE_INT diff, count_in_bytes, gaps = 0;
  
        while (next)
          {
--- 2094,2103 ----
        gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
        struct data_reference *data_ref = dr;
        unsigned int count = 1;
        tree prev_init = DR_INIT (data_ref);
        gimple prev = stmt;
!       HOST_WIDE_INT diff, gaps = 0;
!       unsigned HOST_WIDE_INT count_in_bytes;
  
        while (next)
          {
*************** vect_analyze_group_access (struct data_r
*** 2126,2143 ****
              }
  
            prev = next;
  
!           /* Check that all the accesses have the same STEP.  */
!           next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
!           if (tree_int_cst_compare (step, next_step))
!             {
!               if (dump_enabled_p ())
!                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
!                                  "not consecutive access in interleaving");
!               return false;
!             }
  
-           data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
            /* Check that the distance between two accesses is equal to the type
               size. Otherwise, we have gaps.  */
            diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
--- 2126,2136 ----
              }
  
            prev = next;
+           data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
  
! 	  /* All group members have the same STEP by construction.  */
! 	  gcc_checking_assert (operand_equal_p (DR_STEP (data_ref), step, 0));
  
            /* Check that the distance between two accesses is equal to the type
               size. Otherwise, we have gaps.  */
            diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
*************** vect_analyze_group_access (struct data_r
*** 2175,2181 ****
  
        /* Check that the size of the interleaving (including gaps) is not
           greater than STEP.  */
!       if (dr_step && dr_step < count_in_bytes + gaps * type_size)
          {
            if (dump_enabled_p ())
              {
--- 2168,2175 ----
  
        /* Check that the size of the interleaving (including gaps) is not
           greater than STEP.  */
!       if (dr_step != 0
! 	  && absu_hwi (dr_step) < count_in_bytes + gaps * type_size)
          {
            if (dump_enabled_p ())
              {
*************** vect_analyze_group_access (struct data_r
*** 2188,2194 ****
  
        /* Check that the size of the interleaving is equal to STEP for stores,
           i.e., that there are no gaps.  */
!       if (dr_step && dr_step != count_in_bytes)
          {
            if (DR_IS_READ (dr))
              {
--- 2182,2189 ----
  
        /* Check that the size of the interleaving is equal to STEP for stores,
           i.e., that there are no gaps.  */
!       if (dr_step != 0
! 	  && absu_hwi (dr_step) != count_in_bytes)
          {
            if (DR_IS_READ (dr))
              {
*************** vect_analyze_group_access (struct data_r
*** 2208,2214 ****
          }
  
        /* Check that STEP is a multiple of type size.  */
!       if (dr_step && (dr_step % type_size) != 0)
          {
            if (dump_enabled_p ())
              {
--- 2203,2210 ----
          }
  
        /* Check that STEP is a multiple of type size.  */
!       if (dr_step != 0
! 	  && (dr_step % type_size) != 0)
          {
            if (dump_enabled_p ())
              {
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3520,3526 ****
    tree aptr;
    gimple_stmt_iterator incr_gsi;
    bool insert_after;
-   bool negative;
    tree indx_before_incr, indx_after_incr;
    gimple incr;
    tree step;
--- 3520,3525 ----
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3550,3560 ****
    else
      step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
  
!   if (tree_int_cst_compare (step, size_zero_node) == 0)
      *inv_p = true;
    else
      *inv_p = false;
-   negative = tree_int_cst_compare (step, size_zero_node) < 0;
  
    /* Create an expression for the first address accessed by this load
       in LOOP.  */
--- 3549,3558 ----
    else
      step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
  
!   if (integer_zerop (step))
      *inv_p = true;
    else
      *inv_p = false;
  
    /* Create an expression for the first address accessed by this load
       in LOOP.  */
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3693,3710 ****
    else
      {
        /* The step of the aggregate pointer is the type size.  */
!       tree step = TYPE_SIZE_UNIT (aggr_type);
        /* One exception to the above is when the scalar step of the load in
  	 LOOP is zero. In this case the step here is also zero.  */
        if (*inv_p)
! 	step = size_zero_node;
!       else if (negative)
! 	step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step);
  
        standard_iv_increment_position (loop, &incr_gsi, &insert_after);
  
        create_iv (aggr_ptr_init,
! 		 fold_convert (aggr_ptr_type, step),
  		 aggr_ptr, loop, &incr_gsi, insert_after,
  		 &indx_before_incr, &indx_after_incr);
        incr = gsi_stmt (incr_gsi);
--- 3691,3708 ----
    else
      {
        /* The step of the aggregate pointer is the type size.  */
!       tree iv_step = TYPE_SIZE_UNIT (aggr_type);
        /* One exception to the above is when the scalar step of the load in
  	 LOOP is zero. In this case the step here is also zero.  */
        if (*inv_p)
! 	iv_step = size_zero_node;
!       else if (tree_int_cst_sgn (step) == -1)
! 	iv_step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv_step), iv_step);
  
        standard_iv_increment_position (loop, &incr_gsi, &insert_after);
  
        create_iv (aggr_ptr_init,
! 		 fold_convert (aggr_ptr_type, iv_step),
  		 aggr_ptr, loop, &incr_gsi, insert_after,
  		 &indx_before_incr, &indx_after_incr);
        incr = gsi_stmt (incr_gsi);
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c.orig	2013-04-18 12:17:03.000000000 +0200
--- gcc/tree-vect-stmts.c	2013-04-18 12:18:47.745157947 +0200
*************** vectorizable_load (gimple stmt, gimple_s
*** 4465,4471 ****
  
        if (negative)
  	{
! 	  gcc_assert (!grouped_load);
  	  alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
  	  if (alignment_support_scheme != dr_aligned
  	      && alignment_support_scheme != dr_unaligned_supported)
--- 4479,4491 ----
  
        if (negative)
  	{
! 	  if (grouped_load)
! 	    {
! 	      if (dump_enabled_p ())
! 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
! 				 "negative step for group load not supported");
! 	      return false;
! 	    }
  	  alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
  	  if (alignment_support_scheme != dr_aligned
  	      && alignment_support_scheme != dr_unaligned_supported)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] More vectorizer TLC
@ 2013-04-09 14:53 Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2013-04-09 14:53 UTC (permalink / raw)
  To: gcc-patches


This gets rid of slp_void_p and moves vect_get_place_in_interleaving_chain
next to its only user.

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

Richard.

2013-04-09  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (slp_void_p): Remove.
	(slp_tree): Typedef before _slp_tree declaration.
	(struct _slp_tree): Use a vector of slp_tree as children.
	(vect_get_place_in_interleaving_chain): Remove.
	* tree-vect-data-refs.c (vect_get_place_in_interleaving_chain):
	Move ...
	* tree-vect-slp.c (vect_get_place_in_interleaving_chain): ... here
	and make static.
	(vect_free_slp_tree, vect_print_slp_tree, vect_mark_slp_stmts,
	vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts,
	vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations,
	vect_schedule_slp_instance, vect_remove_slp_scalar_calls):
	Use slp_node instead of slp_void_p and adjust.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c	(revision 197621)
--- gcc/tree-vect-data-refs.c	(working copy)
*************** vect_get_smallest_scalar_type (gimple st
*** 129,159 ****
  }
  
  
- /* Find the place of the data-ref in STMT in the interleaving chain that starts
-    from FIRST_STMT.  Return -1 if the data-ref is not a part of the chain.  */
- 
- int
- vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt)
- {
-   gimple next_stmt = first_stmt;
-   int result = 0;
- 
-   if (first_stmt != GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
-     return -1;
- 
-   while (next_stmt && next_stmt != stmt)
-     {
-       result++;
-       next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
-     }
- 
-   if (next_stmt)
-     return result;
-   else
-     return -1;
- }
- 
- 
  /* Check if data references pointed by DR_I and DR_J are same or
     belong to same interleaving group.  Return FALSE if drs are
     different, otherwise return TRUE.  */
--- 129,134 ----
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c	(revision 197621)
--- gcc/tree-vect-slp.c	(working copy)
*************** static void
*** 67,79 ****
  vect_free_slp_tree (slp_tree node)
  {
    int i;
!   slp_void_p child;
  
    if (!node)
      return;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_free_slp_tree ((slp_tree) child);
  
    SLP_TREE_CHILDREN (node).release ();
    SLP_TREE_SCALAR_STMTS (node).release ();
--- 67,79 ----
  vect_free_slp_tree (slp_tree node)
  {
    int i;
!   slp_tree child;
  
    if (!node)
      return;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_free_slp_tree (child);
  
    SLP_TREE_CHILDREN (node).release ();
    SLP_TREE_SCALAR_STMTS (node).release ();
*************** vect_free_oprnd_info (vec<slp_oprnd_info
*** 168,173 ****
--- 168,198 ----
  }
  
  
+ /* Find the place of the data-ref in STMT in the interleaving chain that starts
+    from FIRST_STMT.  Return -1 if the data-ref is not a part of the chain.  */
+ 
+ static int
+ vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt)
+ {
+   gimple next_stmt = first_stmt;
+   int result = 0;
+ 
+   if (first_stmt != GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
+     return -1;
+ 
+   do
+     {
+       if (next_stmt == stmt)
+ 	return result;
+       result++;
+       next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
+     }
+   while (next_stmt);
+ 
+   return -1;
+ }
+ 
+ 
  /* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
     they are of a valid type and that they match the defs of the first stmt of
     the SLP group (stored in OPRNDS_INFO).  */
*************** vect_print_slp_tree (int dump_kind, slp_
*** 991,997 ****
  {
    int i;
    gimple stmt;
!   slp_void_p child;
  
    if (!node)
      return;
--- 1016,1022 ----
  {
    int i;
    gimple stmt;
!   slp_tree child;
  
    if (!node)
      return;
*************** vect_print_slp_tree (int dump_kind, slp_
*** 1005,1011 ****
    dump_printf (dump_kind, "\n");
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_print_slp_tree (dump_kind, (slp_tree) child);
  }
  
  
--- 1030,1036 ----
    dump_printf (dump_kind, "\n");
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_print_slp_tree (dump_kind, child);
  }
  
  
*************** vect_mark_slp_stmts (slp_tree node, enum
*** 1019,1025 ****
  {
    int i;
    gimple stmt;
!   slp_void_p child;
  
    if (!node)
      return;
--- 1044,1050 ----
  {
    int i;
    gimple stmt;
!   slp_tree child;
  
    if (!node)
      return;
*************** vect_mark_slp_stmts (slp_tree node, enum
*** 1029,1035 ****
        STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_mark_slp_stmts ((slp_tree) child, mark, j);
  }
  
  
--- 1054,1060 ----
        STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_mark_slp_stmts (child, mark, j);
  }
  
  
*************** vect_mark_slp_stmts_relevant (slp_tree n
*** 1041,1047 ****
    int i;
    gimple stmt;
    stmt_vec_info stmt_info;
!   slp_void_p child;
  
    if (!node)
      return;
--- 1066,1072 ----
    int i;
    gimple stmt;
    stmt_vec_info stmt_info;
!   slp_tree child;
  
    if (!node)
      return;
*************** vect_mark_slp_stmts_relevant (slp_tree n
*** 1055,1061 ****
      }
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_mark_slp_stmts_relevant ((slp_tree) child);
  }
  
  
--- 1080,1086 ----
      }
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_mark_slp_stmts_relevant (child);
  }
  
  
*************** vect_slp_rearrange_stmts (slp_tree node,
*** 1129,1154 ****
  {
    gimple stmt;
    vec<gimple> tmp_stmts;
!   unsigned int index, i;
!   slp_void_p child;
! 
!   if (!node)
!     return;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_slp_rearrange_stmts ((slp_tree) child, group_size, permutation);
  
    gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ());
    tmp_stmts.create (group_size);
! 
!   for (i = 0; i < group_size; i++)
!     tmp_stmts.safe_push (NULL);
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
!     {
!       index = permutation[i];
!       tmp_stmts[index] = stmt;
!     }
  
    SLP_TREE_SCALAR_STMTS (node).release ();
    SLP_TREE_SCALAR_STMTS (node) = tmp_stmts;
--- 1154,1171 ----
  {
    gimple stmt;
    vec<gimple> tmp_stmts;
!   unsigned int i;
!   slp_tree child;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_slp_rearrange_stmts (child, group_size, permutation);
  
    gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ());
    tmp_stmts.create (group_size);
!   tmp_stmts.quick_grow_cleared (group_size);
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
!     tmp_stmts[permutation[i]] = stmt;
  
    SLP_TREE_SCALAR_STMTS (node).release ();
    SLP_TREE_SCALAR_STMTS (node) = tmp_stmts;
*************** vect_detect_hybrid_slp_stmts (slp_tree n
*** 1824,1830 ****
    imm_use_iterator imm_iter;
    gimple use_stmt;
    stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
!   slp_void_p child;
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
    struct loop *loop = NULL;
    bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
--- 1841,1847 ----
    imm_use_iterator imm_iter;
    gimple use_stmt;
    stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
!   slp_tree child;
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
    struct loop *loop = NULL;
    bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
*************** vect_detect_hybrid_slp_stmts (slp_tree n
*** 1855,1861 ****
  	  vect_mark_slp_stmts (node, hybrid, i);
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_detect_hybrid_slp_stmts ((slp_tree) child);
  }
  
  
--- 1872,1878 ----
  	  vect_mark_slp_stmts (node, hybrid, i);
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_detect_hybrid_slp_stmts (child);
  }
  
  
*************** vect_slp_analyze_node_operations (bb_vec
*** 1953,1965 ****
    bool dummy;
    int i;
    gimple stmt;
!   slp_void_p child;
  
    if (!node)
      return true;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     if (!vect_slp_analyze_node_operations (bb_vinfo, (slp_tree) child))
        return false;
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
--- 1970,1982 ----
    bool dummy;
    int i;
    gimple stmt;
!   slp_tree child;
  
    if (!node)
      return true;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     if (!vect_slp_analyze_node_operations (bb_vinfo, child))
        return false;
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
*************** vect_schedule_slp_instance (slp_tree nod
*** 3014,3027 ****
    tree vectype;
    int i;
    slp_tree loads_node;
!   slp_void_p child;
  
    if (!node)
      return false;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_schedule_slp_instance ((slp_tree) child, instance,
!                                 vectorization_factor);
  
    stmt = SLP_TREE_SCALAR_STMTS (node)[0];
    stmt_info = vinfo_for_stmt (stmt);
--- 3031,3043 ----
    tree vectype;
    int i;
    slp_tree loads_node;
!   slp_tree child;
  
    if (!node)
      return false;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_schedule_slp_instance (child, instance, vectorization_factor);
  
    stmt = SLP_TREE_SCALAR_STMTS (node)[0];
    stmt_info = vinfo_for_stmt (stmt);
*************** vect_remove_slp_scalar_calls (slp_tree n
*** 3111,3117 ****
    gimple stmt, new_stmt;
    gimple_stmt_iterator gsi;
    int i;
!   slp_void_p child;
    tree lhs;
    stmt_vec_info stmt_info;
  
--- 3127,3133 ----
    gimple stmt, new_stmt;
    gimple_stmt_iterator gsi;
    int i;
!   slp_tree child;
    tree lhs;
    stmt_vec_info stmt_info;
  
*************** vect_remove_slp_scalar_calls (slp_tree n
*** 3119,3125 ****
      return;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_remove_slp_scalar_calls ((slp_tree) child);
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
      {
--- 3135,3141 ----
      return;
  
    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
!     vect_remove_slp_scalar_calls (child);
  
    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
      {
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h	(revision 197621)
--- gcc/tree-vectorizer.h	(working copy)
*************** add_stmt_info_to_vec (stmt_vector_for_co
*** 97,109 ****
  /************************************************************************
    SLP
   ************************************************************************/
! typedef void *slp_void_p;
  
  /* A computation tree of an SLP instance.  Each node corresponds to a group of
     stmts to be packed in a SIMD stmt.  */
! typedef struct _slp_tree {
    /* Nodes that contain def-stmts of this node statements operands.  */
!   vec<slp_void_p> children;
    /* A group of scalar stmts to be vectorized together.  */
    vec<gimple> stmts;
    /* Vectorized stmt/s.  */
--- 97,109 ----
  /************************************************************************
    SLP
   ************************************************************************/
! typedef struct _slp_tree *slp_tree;
  
  /* A computation tree of an SLP instance.  Each node corresponds to a group of
     stmts to be packed in a SIMD stmt.  */
! struct _slp_tree {
    /* Nodes that contain def-stmts of this node statements operands.  */
!   vec<slp_tree> children;
    /* A group of scalar stmts to be vectorized together.  */
    vec<gimple> stmts;
    /* Vectorized stmt/s.  */
*************** typedef struct _slp_tree {
*** 113,119 ****
       scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
       divided by vector size.  */
    unsigned int vec_stmts_size;
! } *slp_tree;
  
  
  /* SLP instance is a sequence of stmts in a loop that can be packed into
--- 113,119 ----
       scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
       divided by vector size.  */
    unsigned int vec_stmts_size;
! };
  
  
  /* SLP instance is a sequence of stmts in a loop that can be packed into
*************** extern tree vect_setup_realignment (gimp
*** 941,947 ****
  extern void vect_transform_grouped_load (gimple, vec<tree> , int,
                                           gimple_stmt_iterator *);
  extern void vect_record_grouped_load_vectors (gimple, vec<tree> );
- extern int vect_get_place_in_interleaving_chain (gimple, gimple);
  extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
  extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
                                                    tree, struct loop *);
--- 941,946 ----

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-10-15 12:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-13  8:38 [PATCH] More vectorizer TLC Richard Biener
  -- strict thread matches above, loose matches on Subject: below --
2015-10-15 11:37 Richard Biener
2015-10-15 12:15 ` Richard Biener
2015-10-14 13:56 Richard Biener
2015-10-14  8:32 Richard Biener
2015-10-12  8:30 Richard Biener
2013-04-18 14:16 Richard Biener
2013-04-09 14:53 Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).