Branch data Line data Source code
1 : : /* A class for building vector tree constants.
2 : : Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #ifndef GCC_TREE_VECTOR_BUILDER_H
21 : : #define GCC_TREE_VECTOR_BUILDER_H
22 : :
23 : : #include "vector-builder.h"
24 : :
25 : : /* This class is used to build VECTOR_CSTs from a sequence of elements.
26 : : See vector_builder for more details. */
27 : 6234733 : class tree_vector_builder : public vector_builder<tree, tree,
28 : : tree_vector_builder>
29 : : {
30 : : typedef vector_builder<tree, tree, tree_vector_builder> parent;
31 : : friend class vector_builder<tree, tree, tree_vector_builder>;
32 : :
33 : : public:
34 : 2725412 : tree_vector_builder () : m_type (0) {}
35 : : tree_vector_builder (tree, unsigned int, unsigned int);
36 : : tree build ();
37 : :
38 : 138726 : tree type () const { return m_type; }
39 : :
40 : : void new_vector (tree, unsigned int, unsigned int);
41 : :
42 : : private:
43 : : bool equal_p (const_tree, const_tree) const;
44 : : bool allow_steps_p () const;
45 : : bool integral_p (const_tree) const;
46 : : wide_int step (const_tree, const_tree) const;
47 : : tree apply_step (tree, unsigned int, const wide_int &) const;
48 : : bool can_elide_p (const_tree) const;
49 : : void note_representative (tree *, tree);
50 : :
51 : 151632 : static poly_uint64 shape_nelts (const_tree t)
52 : 151632 : { return TYPE_VECTOR_SUBPARTS (t); }
53 : 257032 : static poly_uint64 nelts_of (const_tree t)
54 : 257032 : { return VECTOR_CST_NELTS (t); }
55 : 257032 : static unsigned int npatterns_of (const_tree t)
56 : 257032 : { return VECTOR_CST_NPATTERNS (t); }
57 : 257032 : static unsigned int nelts_per_pattern_of (const_tree t)
58 : 257032 : { return VECTOR_CST_NELTS_PER_PATTERN (t); }
59 : :
60 : : tree m_type;
61 : : };
62 : :
63 : : /* Create a new builder for a vector of type TYPE. Initially encode the
64 : : value as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements
65 : : each. */
66 : :
67 : : inline
68 : 3510756 : tree_vector_builder::tree_vector_builder (tree type, unsigned int npatterns,
69 : 3510756 : unsigned int nelts_per_pattern)
70 : : {
71 : 3510756 : new_vector (type, npatterns, nelts_per_pattern);
72 : 3510756 : }
73 : :
74 : : /* Start building a new vector of type TYPE. Initially encode the value
75 : : as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each. */
76 : :
77 : : inline void
78 : 4206332 : tree_vector_builder::new_vector (tree type, unsigned int npatterns,
79 : : unsigned int nelts_per_pattern)
80 : : {
81 : 4206332 : m_type = type;
82 : 4206332 : parent::new_vector (TYPE_VECTOR_SUBPARTS (type), npatterns,
83 : : nelts_per_pattern);
84 : 4206332 : }
85 : :
86 : : /* Return true if elements I1 and I2 are equal. */
87 : :
88 : : inline bool
89 : 4091445 : tree_vector_builder::equal_p (const_tree elt1, const_tree elt2) const
90 : : {
91 : 4091445 : return operand_equal_p (elt1, elt2, OEP_BITWISE);
92 : : }
93 : :
94 : : /* Return true if a stepped representation is OK. We don't allow
95 : : linear series for anything other than integers, to avoid problems
96 : : with rounding. */
97 : :
98 : : inline bool
99 : 974676 : tree_vector_builder::allow_steps_p () const
100 : : {
101 : 974676 : return INTEGRAL_TYPE_P (TREE_TYPE (m_type));
102 : : }
103 : :
104 : : /* Return true if ELT can be interpreted as an integer. */
105 : :
106 : : inline bool
107 : 3371511 : tree_vector_builder::integral_p (const_tree elt) const
108 : : {
109 : 1123837 : return TREE_CODE (elt) == INTEGER_CST;
110 : : }
111 : :
112 : : /* Return the value of element ELT2 minus the value of element ELT1.
113 : : Both elements are known to be INTEGER_CSTs. */
114 : :
115 : : inline wide_int
116 : 2247674 : tree_vector_builder::step (const_tree elt1, const_tree elt2) const
117 : : {
118 : 2247674 : return wi::to_wide (elt2) - wi::to_wide (elt1);
119 : : }
120 : :
121 : : /* Return true if we can drop element ELT, even if the retained elements
122 : : are different. Return false if this would mean losing overflow
123 : : information. */
124 : :
125 : : inline bool
126 : 281848 : tree_vector_builder::can_elide_p (const_tree elt) const
127 : : {
128 : 281848 : return !CONSTANT_CLASS_P (elt) || !TREE_OVERFLOW (elt);
129 : : }
130 : :
131 : : /* Record that ELT2 is being elided, given that ELT1_PTR points to the last
132 : : encoded element for the containing pattern. */
133 : :
134 : : inline void
135 : 1938441 : tree_vector_builder::note_representative (tree *elt1_ptr, tree elt2)
136 : : {
137 : 1938441 : if (TREE_OVERFLOW_P (elt2))
138 : : {
139 : 7 : gcc_assert (operand_equal_p (*elt1_ptr, elt2, 0));
140 : 7 : if (!TREE_OVERFLOW (elt2))
141 : 0 : *elt1_ptr = elt2;
142 : : }
143 : 1938441 : }
144 : :
145 : : #endif
|