1 1.1 mrg /* A representation of vector permutation indices. 2 1.1.1.4 mrg Copyright (C) 2017-2022 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg This file is part of GCC. 5 1.1 mrg 6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 7 1.1 mrg the terms of the GNU General Public License as published by the Free 8 1.1 mrg Software Foundation; either version 3, or (at your option) any later 9 1.1 mrg version. 10 1.1 mrg 11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 1.1 mrg for more details. 15 1.1 mrg 16 1.1 mrg You should have received a copy of the GNU General Public License 17 1.1 mrg along with GCC; see the file COPYING3. If not see 18 1.1 mrg <http://www.gnu.org/licenses/>. */ 19 1.1 mrg 20 1.1 mrg #ifndef GCC_VEC_PERN_INDICES_H 21 1.1 mrg #define GCC_VEC_PERN_INDICES_H 1 22 1.1 mrg 23 1.1 mrg #include "int-vector-builder.h" 24 1.1 mrg 25 1.1 mrg /* A vector_builder for building constant permutation vectors. 26 1.1 mrg The elements do not need to be clamped to a particular range 27 1.1 mrg of input elements. */ 28 1.1 mrg typedef int_vector_builder<poly_int64> vec_perm_builder; 29 1.1 mrg 30 1.1 mrg /* This class represents a constant permutation vector, such as that used 31 1.1 mrg as the final operand to a VEC_PERM_EXPR. 32 1.1 mrg 33 1.1 mrg Permutation vectors select indices modulo the number of input elements, 34 1.1 mrg and the class canonicalizes each permutation vector for a particular 35 1.1 mrg number of input vectors and for a particular number of elements per 36 1.1 mrg input. For example, the gimple statements: 37 1.1 mrg 38 1.1 mrg _1 = VEC_PERM_EXPR <a, a, { 0, 2, 4, 6, 0, 2, 4, 6 }>; 39 1.1 mrg _2 = VEC_PERM_EXPR <a, a, { 0, 2, 4, 6, 8, 10, 12, 14 }>; 40 1.1 mrg _3 = VEC_PERM_EXPR <a, a, { 0, 2, 20, 22, 24, 2, 4, 14 }>; 41 1.1 mrg 42 1.1 mrg effectively have only a single vector input "a". If "a" has 8 43 1.1 mrg elements, the indices select elements modulo 8, which makes all three 44 1.1 mrg VEC_PERM_EXPRs equivalent. The canonical form is for the indices to be 45 1.1 mrg in the range [0, number of input elements - 1], so the class treats the 46 1.1 mrg second and third permutation vectors as though they had been the first. 47 1.1 mrg 48 1.1 mrg The class copes with cases in which the input and output vectors have 49 1.1 mrg different numbers of elements. */ 50 1.1 mrg class vec_perm_indices 51 1.1 mrg { 52 1.1 mrg typedef poly_int64 element_type; 53 1.1 mrg 54 1.1 mrg public: 55 1.1 mrg vec_perm_indices (); 56 1.1 mrg vec_perm_indices (const vec_perm_builder &, unsigned int, poly_uint64); 57 1.1 mrg 58 1.1 mrg void new_vector (const vec_perm_builder &, unsigned int, poly_uint64); 59 1.1 mrg void new_expanded_vector (const vec_perm_indices &, unsigned int); 60 1.1.1.4 mrg bool new_shrunk_vector (const vec_perm_indices &, unsigned int); 61 1.1 mrg void rotate_inputs (int delta); 62 1.1 mrg 63 1.1 mrg /* Return the underlying vector encoding. */ 64 1.1 mrg const vec_perm_builder &encoding () const { return m_encoding; } 65 1.1 mrg 66 1.1 mrg /* Return the number of output elements. This is called length () 67 1.1 mrg so that we present a more vec-like interface. */ 68 1.1 mrg poly_uint64 length () const { return m_encoding.full_nelts (); } 69 1.1 mrg 70 1.1 mrg /* Return the number of input vectors being permuted. */ 71 1.1 mrg unsigned int ninputs () const { return m_ninputs; } 72 1.1 mrg 73 1.1 mrg /* Return the number of elements in each input vector. */ 74 1.1 mrg poly_uint64 nelts_per_input () const { return m_nelts_per_input; } 75 1.1 mrg 76 1.1 mrg /* Return the total number of input elements. */ 77 1.1 mrg poly_uint64 input_nelts () const { return m_ninputs * m_nelts_per_input; } 78 1.1 mrg 79 1.1 mrg element_type clamp (element_type) const; 80 1.1 mrg element_type operator[] (unsigned int i) const; 81 1.1 mrg bool series_p (unsigned int, unsigned int, element_type, element_type) const; 82 1.1 mrg bool all_in_range_p (element_type, element_type) const; 83 1.1 mrg bool all_from_input_p (unsigned int) const; 84 1.1 mrg 85 1.1 mrg private: 86 1.1 mrg vec_perm_indices (const vec_perm_indices &); 87 1.1 mrg 88 1.1 mrg vec_perm_builder m_encoding; 89 1.1 mrg unsigned int m_ninputs; 90 1.1 mrg poly_uint64 m_nelts_per_input; 91 1.1 mrg }; 92 1.1 mrg 93 1.1 mrg bool tree_to_vec_perm_builder (vec_perm_builder *, tree); 94 1.1 mrg tree vec_perm_indices_to_tree (tree, const vec_perm_indices &); 95 1.1 mrg rtx vec_perm_indices_to_rtx (machine_mode, const vec_perm_indices &); 96 1.1 mrg 97 1.1 mrg inline 98 1.1 mrg vec_perm_indices::vec_perm_indices () 99 1.1 mrg : m_ninputs (0), 100 1.1 mrg m_nelts_per_input (0) 101 1.1 mrg { 102 1.1 mrg } 103 1.1 mrg 104 1.1 mrg /* Construct a permutation vector that selects between NINPUTS vector 105 1.1 mrg inputs that have NELTS_PER_INPUT elements each. Take the elements of 106 1.1 mrg the new vector from ELEMENTS, clamping each one to be in range. */ 107 1.1 mrg 108 1.1 mrg inline 109 1.1 mrg vec_perm_indices::vec_perm_indices (const vec_perm_builder &elements, 110 1.1 mrg unsigned int ninputs, 111 1.1 mrg poly_uint64 nelts_per_input) 112 1.1 mrg { 113 1.1 mrg new_vector (elements, ninputs, nelts_per_input); 114 1.1 mrg } 115 1.1 mrg 116 1.1 mrg /* Return the canonical value for permutation vector element ELT, 117 1.1 mrg taking into account the current number of input elements. */ 118 1.1 mrg 119 1.1 mrg inline vec_perm_indices::element_type 120 1.1 mrg vec_perm_indices::clamp (element_type elt) const 121 1.1 mrg { 122 1.1 mrg element_type limit = input_nelts (), elem_within_input; 123 1.1 mrg HOST_WIDE_INT input; 124 1.1 mrg if (!can_div_trunc_p (elt, limit, &input, &elem_within_input)) 125 1.1 mrg return elt; 126 1.1 mrg 127 1.1 mrg /* Treat negative elements as counting from the end. This only matters 128 1.1 mrg if the vector size is not a power of 2. */ 129 1.1 mrg if (known_lt (elem_within_input, 0)) 130 1.1 mrg return elem_within_input + limit; 131 1.1 mrg 132 1.1 mrg return elem_within_input; 133 1.1 mrg } 134 1.1 mrg 135 1.1 mrg /* Return the value of vector element I, which might or might not be 136 1.1 mrg explicitly encoded. */ 137 1.1 mrg 138 1.1 mrg inline vec_perm_indices::element_type 139 1.1 mrg vec_perm_indices::operator[] (unsigned int i) const 140 1.1 mrg { 141 1.1 mrg return clamp (m_encoding.elt (i)); 142 1.1 mrg } 143 1.1 mrg 144 1.1 mrg /* Return true if the permutation vector only selects elements from 145 1.1 mrg input I. */ 146 1.1 mrg 147 1.1 mrg inline bool 148 1.1 mrg vec_perm_indices::all_from_input_p (unsigned int i) const 149 1.1 mrg { 150 1.1 mrg return all_in_range_p (i * m_nelts_per_input, m_nelts_per_input); 151 1.1 mrg } 152 1.1 mrg 153 1.1 mrg #endif 154