+2019-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91568
+ * tree-vectorizer.h (_slp_tree::max_nunits): Add.
+ (vect_update_max_nunits): Add overload for poly_uint64.
+ * tree-vect-slp.c (vect_create_new_slp_node): Initialize it.
+ (vect_build_slp_tree): Record max_nunits into the subtree
+ and merge it upwards.
+ (vect_print_slp_tree): Print max_nunits.
+
2019-08-28 Marek Polacek <polacek@redhat.com>
Implement P1152R4: Deprecating some uses of volatile.
+2019-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91568
+ * gfortran.dg/pr91568.f: New testcase.
+
2019-08-28 Marek Polacek <polacek@redhat.com>
Implement P1152R4: Deprecating some uses of volatile.
--- /dev/null
+! { dg-do compile }
+! { dg-options "-Ofast" }
+ subroutine h3dall(z,hvec,hder,nterms)
+ complex *16 hvec(0:1),hder(0:1)
+ complex *16 z,zinv,ztmp/1.0/
+ zinv=1.0/z
+ do i=1,nterms
+ ztmp=zinv*i
+ hder(i)=hvec(i-1)-ztmp*hvec(i)
+ enddo
+ end
SLP_TREE_TWO_OPERATORS (node) = false;
SLP_TREE_DEF_TYPE (node) = vect_internal_def;
node->refcnt = 1;
+ node->max_nunits = 1;
unsigned i;
FOR_EACH_VEC_ELT (scalar_stmts, i, stmt_info)
dump_printf_loc (MSG_NOTE, vect_location, "re-using %sSLP tree %p\n",
*leader ? "" : "failed ", *leader);
if (*leader)
- (*leader)->refcnt++;
+ {
+ (*leader)->refcnt++;
+ vect_update_max_nunits (max_nunits, (*leader)->max_nunits);
+ }
return *leader;
}
+ poly_uint64 this_max_nunits = 1;
slp_tree res = vect_build_slp_tree_2 (vinfo, stmts, group_size, max_nunits,
matches, npermutes, tree_size, bst_map);
- /* Keep a reference for the bst_map use. */
if (res)
- res->refcnt++;
+ {
+ res->max_nunits = this_max_nunits;
+ vect_update_max_nunits (max_nunits, this_max_nunits);
+ /* Keep a reference for the bst_map use. */
+ res->refcnt++;
+ }
bst_map->put (stmts.copy (), res);
return res;
}
dump_metadata_t metadata (dump_kind, loc.get_impl_location ());
dump_user_location_t user_loc = loc.get_user_location ();
- dump_printf_loc (metadata, user_loc, "node%s %p\n",
+ dump_printf_loc (metadata, user_loc, "node%s %p (max_nunits=%u)\n",
SLP_TREE_DEF_TYPE (node) != vect_internal_def
- ? " (external)" : "", node);
+ ? " (external)" : "", node,
+ estimated_poly_value (node->max_nunits));
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
dump_printf_loc (metadata, user_loc, "\tstmt %d %G", i, stmt_info->stmt);
if (SLP_TREE_CHILDREN (node).is_empty ())
unsigned int vec_stmts_size;
/* Reference count in the SLP graph. */
unsigned int refcnt;
+ /* The maximum number of vector elements for the subtree rooted
+ at this node. */
+ poly_uint64 max_nunits;
/* Whether the scalar computations use two different operators. */
bool two_operators;
/* The DEF type of this node. */
}
/* Update maximum unit count *MAX_NUNITS so that it accounts for
- the number of units in vector type VECTYPE. *MAX_NUNITS can be 1
- if we haven't yet recorded any vector types. */
+ NUNITS. *MAX_NUNITS can be 1 if we haven't yet recorded anything. */
static inline void
-vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype)
+vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits)
{
/* All unit counts have the form current_vector_size * X for some
rational X, so two unit sizes must have a common multiple.
Everything is a multiple of the initial value of 1. */
- poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
*max_nunits = force_common_multiple (*max_nunits, nunits);
}
+/* Update maximum unit count *MAX_NUNITS so that it accounts for
+ the number of units in vector type VECTYPE. *MAX_NUNITS can be 1
+ if we haven't yet recorded any vector types. */
+
+static inline void
+vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype)
+{
+ vect_update_max_nunits (max_nunits, TYPE_VECTOR_SUBPARTS (vectype));
+}
+
/* Return the vectorization factor that should be used for costing
purposes while vectorizing the loop described by LOOP_VINFO.
Pick a reasonable estimate if the vectorization factor isn't