diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-07 18:41:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-07 18:41:35 +0000 |
commit | b3def403fa7ae89679468b8f986cab7361c1034d (patch) | |
tree | d1df9bee6f0c02966cfbd1044066b3e1bcea9f8e /gcc/tree-vector-builder.c | |
parent | 059c18abcb9c88bb5a85eb3ce468ffa7252da230 (diff) | |
download | gcc-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.c | 47 |
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 |