aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vector-builder.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-07 18:41:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-07 18:41:35 +0000
commitb3def403fa7ae89679468b8f986cab7361c1034d (patch)
treed1df9bee6f0c02966cfbd1044066b3e1bcea9f8e /gcc/tree-vector-builder.c
parent059c18abcb9c88bb5a85eb3ce468ffa7252da230 (diff)
downloadgcc-b3def403fa7ae89679468b8f986cab7361c1034d.zip
gcc-b3def403fa7ae89679468b8f986cab7361c1034d.tar.gz
gcc-b3def403fa7ae89679468b8f986cab7361c1034d.tar.bz2
Use tree_vector_builder::new_binary_operation for folding
This patch makes fold-const.c operate directly on the VECTOR_CST encoding when folding an operation that has two VECTOR_CST inputs. 2017-12-07 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * tree-vector-builder.h (tree_vector_builder::new_binary_operation): Declare. * tree-vector-builder.c (tree_vector_builder::new_binary_operation): New function. * fold-const.c (fold_relational_const): Use it. (const_binop): Likewise. Check that both input vectors have the same number of elements, thus excluding things like WIDEN_SUM. Check whether it is possible to operate directly on the encodings of stepped inputs. From-SVN: r255477
Diffstat (limited to 'gcc/tree-vector-builder.c')
-rw-r--r--gcc/tree-vector-builder.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/tree-vector-builder.c b/gcc/tree-vector-builder.c
index 708bf0e..a8a9897 100644
--- a/gcc/tree-vector-builder.c
+++ b/gcc/tree-vector-builder.c
@@ -49,6 +49,53 @@ tree_vector_builder::new_unary_operation (tree type, tree t,
return true;
}
+/* Try to start building a new vector of type TYPE that holds the result of
+ a binary operation on VECTOR_CSTs T1 and T2. ALLOW_STEPPED_P is true if
+ the operation can handle stepped encodings directly, without having to
+ expand the full sequence.
+
+ Return true if the operation is possible. Leave the builder unchanged
+ otherwise. */
+
+bool
+tree_vector_builder::new_binary_operation (tree type, tree t1, tree t2,
+ bool allow_stepped_p)
+{
+ unsigned int full_nelts = TYPE_VECTOR_SUBPARTS (type);
+ gcc_assert (full_nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1))
+ && full_nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2)));
+ /* Conceptually we split the patterns in T1 and T2 until we have
+ an equal number for both. Each split pattern requires the same
+ number of elements per pattern as the original. E.g. splitting:
+
+ { 1, 2, 3, ... }
+
+ into two gives:
+
+ { 1, 3, 5, ... }
+ { 2, 4, 6, ... }
+
+ while splitting:
+
+ { 1, 0, ... }
+
+ into two gives:
+
+ { 1, 0, ... }
+ { 0, 0, ... }. */
+ unsigned int npatterns = least_common_multiple (VECTOR_CST_NPATTERNS (t1),
+ VECTOR_CST_NPATTERNS (t2));
+ unsigned int nelts_per_pattern = MAX (VECTOR_CST_NELTS_PER_PATTERN (t1),
+ VECTOR_CST_NELTS_PER_PATTERN (t2));
+ if (!allow_stepped_p && nelts_per_pattern > 2)
+ {
+ npatterns = full_nelts;
+ nelts_per_pattern = 1;
+ }
+ new_vector (type, npatterns, nelts_per_pattern);
+ return true;
+}
+
/* Return a VECTOR_CST for the current constant. */
tree