aboutsummaryrefslogtreecommitdiff
path: root/gcc/vector-builder.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-07 18:41:59 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-07 18:41:59 +0000
commitabe73c3d32b68809628eaa3266bf98cb7352851c (patch)
treef651282f43b411a678d09f3e8beca08fb288a564 /gcc/vector-builder.h
parentb3def403fa7ae89679468b8f986cab7361c1034d (diff)
downloadgcc-abe73c3d32b68809628eaa3266bf98cb7352851c.zip
gcc-abe73c3d32b68809628eaa3266bf98cb7352851c.tar.gz
gcc-abe73c3d32b68809628eaa3266bf98cb7352851c.tar.bz2
Make gimple_build_vector take a tree_vector_builder
This patch changes gimple_build_vector so that it takes a tree_vector_builder instead of a size and a vector of trees. 2017-12-07 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * vector-builder.h (vector_builder::derived): New const overload. (vector_builder::elt): New function. * tree-vector-builder.h (tree_vector_builder::type): New function. (tree_vector_builder::apply_step): Declare. * tree-vector-builder.c (tree_vector_builder::apply_step): New function. * gimple-fold.h (tree_vector_builder): Declare. (gimple_build_vector): Take a tree_vector_builder instead of a type and vector of elements. * gimple-fold.c (gimple_build_vector): Likewise. * tree-vect-loop.c (get_initial_def_for_reduction): Update call accordingly. (get_initial_defs_for_reduction): Likewise. (vectorizable_induction): Likewise. From-SVN: r255478
Diffstat (limited to 'gcc/vector-builder.h')
-rw-r--r--gcc/vector-builder.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/vector-builder.h b/gcc/vector-builder.h
index ae30b3bb..0edd6f5 100644
--- a/gcc/vector-builder.h
+++ b/gcc/vector-builder.h
@@ -68,6 +68,10 @@ along with GCC; see the file COPYING3. If not see
given integral_p (ELT1) && integral_p (ELT2). There is no fixed
choice of StepType.
+ T apply_step (T base, unsigned int factor, StepType step) const;
+
+ Return a vector element with the value BASE + FACTOR * STEP.
+
bool can_elide_p (T elt) const;
Return true if we can drop element ELT, even if the retained
@@ -91,6 +95,7 @@ public:
unsigned int nelts_per_pattern () const { return m_nelts_per_pattern; }
unsigned int encoded_nelts () const;
bool encoded_full_vector_p () const;
+ T elt (unsigned int) const;
void finalize ();
@@ -163,6 +168,38 @@ vector_builder<T, Derived>::new_vector (unsigned int full_nelts,
this->truncate (0);
}
+/* Return the value of vector element I, which might or might not be
+ encoded explicitly. */
+
+template<typename T, typename Derived>
+T
+vector_builder<T, Derived>::elt (unsigned int i) const
+{
+ /* This only makes sense if the encoding has been fully populated. */
+ gcc_checking_assert (encoded_nelts () <= this->length ());
+
+ /* First handle elements that are already present in the underlying
+ vector, regardless of whether they're part of the encoding or not. */
+ if (i < this->length ())
+ return (*this)[i];
+
+ /* Identify the pattern that contains element I and work out the index of
+ the last encoded element for that pattern. */
+ unsigned int pattern = i % m_npatterns;
+ unsigned int count = i / m_npatterns;
+ unsigned int final_i = encoded_nelts () - m_npatterns + pattern;
+ T final = (*this)[final_i];
+
+ /* If there are no steps, the final encoded value is the right one. */
+ if (m_nelts_per_pattern <= 2)
+ return final;
+
+ /* Otherwise work out the value from the last two encoded elements. */
+ T prev = (*this)[final_i - m_npatterns];
+ return derived ()->apply_step (final, count - 2,
+ derived ()->step (prev, final));
+}
+
/* Change the encoding to NPATTERNS patterns of NELTS_PER_PATTERN each,
but without changing the underlying vector. */