Bug Summary

File:build/gcc/tree-vect-generic.c
Warning:line 1979, column 5
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tree-vect-generic.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-error=format-diag -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -o /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2021-01-16-135054-17580-1/report-fZ4hkX.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c

1/* Lower vector operations to scalar operations.
2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 3, or (at your option) any
9later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "backend.h"
24#include "rtl.h"
25#include "tree.h"
26#include "gimple.h"
27#include "tree-pass.h"
28#include "ssa.h"
29#include "expmed.h"
30#include "optabs-tree.h"
31#include "diagnostic.h"
32#include "fold-const.h"
33#include "stor-layout.h"
34#include "langhooks.h"
35#include "tree-eh.h"
36#include "gimple-iterator.h"
37#include "gimplify-me.h"
38#include "gimplify.h"
39#include "tree-cfg.h"
40#include "tree-vector-builder.h"
41#include "vec-perm-indices.h"
42#include "insn-config.h"
43#include "tree-ssa-dce.h"
44#include "recog.h" /* FIXME: for insn_data */
45
46
47static void expand_vector_operations_1 (gimple_stmt_iterator *, bitmap);
48
49/* Return the number of elements in a vector type TYPE that we have
50 already decided needs to be expanded piecewise. We don't support
51 this kind of expansion for variable-length vectors, since we should
52 always check for target support before introducing uses of those. */
53static unsigned int
54nunits_for_known_piecewise_op (const_tree type)
55{
56 return TYPE_VECTOR_SUBPARTS (type).to_constant ();
57}
58
59/* Return true if TYPE1 has more elements than TYPE2, where either
60 type may be a vector or a scalar. */
61
62static inline bool
63subparts_gt (tree type1, tree type2)
64{
65 poly_uint64 n1 = VECTOR_TYPE_P (type1)(((enum tree_code) (type1)->base.code) == VECTOR_TYPE) ? TYPE_VECTOR_SUBPARTS (type1) : 1;
66 poly_uint64 n2 = VECTOR_TYPE_P (type2)(((enum tree_code) (type2)->base.code) == VECTOR_TYPE) ? TYPE_VECTOR_SUBPARTS (type2) : 1;
67 return known_gt (n1, n2)(!maybe_le (n1, n2));
68}
69
70/* Build a constant of type TYPE, made of VALUE's bits replicated
71 every WIDTH bits to fit TYPE's precision. */
72static tree
73build_replicated_const (tree type, unsigned int width, HOST_WIDE_INTlong value)
74{
75 int n = (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 75, __FUNCTION__))->type_common.precision)
+ HOST_BITS_PER_WIDE_INT64 - 1)
76 / HOST_BITS_PER_WIDE_INT64;
77 unsigned HOST_WIDE_INTlong low, mask;
78 HOST_WIDE_INTlong a[WIDE_INT_MAX_ELTS((160 + 64) / 64)];
79 int i;
80
81 gcc_assert (n && n <= WIDE_INT_MAX_ELTS)((void)(!(n && n <= ((160 + 64) / 64)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 81, __FUNCTION__), 0 : 0))
;
82
83 if (width == HOST_BITS_PER_WIDE_INT64)
84 low = value;
85 else
86 {
87 mask = ((HOST_WIDE_INTlong)1 << width) - 1;
88 low = (unsigned HOST_WIDE_INTlong) ~0 / mask * (value & mask);
89 }
90
91 for (i = 0; i < n; i++)
92 a[i] = low;
93
94 gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT)((void)(!(((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 94, __FUNCTION__))->type_common.precision) <= 160) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 94, __FUNCTION__), 0 : 0))
;
95 return wide_int_to_tree
96 (type, wide_int::from_array (a, n, TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 96, __FUNCTION__))->type_common.precision)
));
97}
98
99static GTY(()) tree vector_inner_type;
100static GTY(()) tree vector_last_type;
101static GTY(()) int vector_last_nunits;
102
103/* Return a suitable vector types made of SUBPARTS units each of mode
104 "word_mode" (the global variable). */
105static tree
106build_word_mode_vector_type (int nunits)
107{
108 if (!vector_inner_type)
109 vector_inner_type = lang_hooks.types.type_for_mode (word_mode, 1);
110 else if (vector_last_nunits == nunits)
111 {
112 gcc_assert (TREE_CODE (vector_last_type) == VECTOR_TYPE)((void)(!(((enum tree_code) (vector_last_type)->base.code)
== VECTOR_TYPE) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 112, __FUNCTION__), 0 : 0))
;
113 return vector_last_type;
114 }
115
116 vector_last_nunits = nunits;
117 vector_last_type = build_vector_type (vector_inner_type, nunits);
118 return vector_last_type;
119}
120
121typedef tree (*elem_op_func) (gimple_stmt_iterator *,
122 tree, tree, tree, tree, tree, enum tree_code,
123 tree);
124
125tree
126tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
127 tree t, tree bitsize, tree bitpos)
128{
129 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == SSA_NAME)
130 {
131 gimple *def_stmt = SSA_NAME_DEF_STMT (t)(tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 131, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
132 if (is_gimple_assign (def_stmt)
133 && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST
134 || (bitpos
135 && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR)))
136 t = gimple_assign_rhs1 (def_stmt);
137 }
138 if (bitpos)
139 return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
140 else
141 return gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
142}
143
144static tree
145do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
146 tree b ATTRIBUTE_UNUSED__attribute__ ((__unused__)), tree bitpos, tree bitsize,
147 enum tree_code code, tree type ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
148{
149 a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
150 return gimplify_build1 (gsi, code, inner_type, a);
151}
152
153static tree
154do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
155 tree bitpos, tree bitsize, enum tree_code code,
156 tree type ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
157{
158 if (TREE_CODE (TREE_TYPE (a))((enum tree_code) (((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 158, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
159 a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
160 if (TREE_CODE (TREE_TYPE (b))((enum tree_code) (((contains_struct_check ((b), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 160, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
161 b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
162 return gimplify_build2 (gsi, code, inner_type, a, b);
163}
164
165/* Construct expression (A[BITPOS] code B[BITPOS]) ? -1 : 0
166
167 INNER_TYPE is the type of A and B elements
168
169 returned expression is of signed integer type with the
170 size equal to the size of INNER_TYPE. */
171static tree
172do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
173 tree bitpos, tree bitsize, enum tree_code code, tree type)
174{
175 tree stype = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 175, __FUNCTION__))->typed.type)
;
176 tree cst_false = build_zero_cst (stype);
177 tree cst_true = build_all_ones_cst (stype);
178 tree cmp;
179
180 a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
181 b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
182
183 cmp = build2 (code, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], a, b);
184 return gimplify_build3 (gsi, COND_EXPR, stype, cmp, cst_true, cst_false);
185}
186
187/* Expand vector addition to scalars. This does bit twiddling
188 in order to increase parallelism:
189
190 a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
191 (a ^ b) & 0x80808080
192
193 a - b = (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
194 (a ^ ~b) & 0x80808080
195
196 -b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
197
198 This optimization should be done only if 4 vector items or more
199 fit into a word. */
200static tree
201do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
202 tree bitpos ATTRIBUTE_UNUSED__attribute__ ((__unused__)), tree bitsize ATTRIBUTE_UNUSED__attribute__ ((__unused__)),
203 enum tree_code code, tree type ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
204{
205 unsigned int width = vector_element_bits (TREE_TYPE (a)((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 205, __FUNCTION__))->typed.type)
);
206 tree inner_type = TREE_TYPE (TREE_TYPE (a))((contains_struct_check ((((contains_struct_check ((a), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 206, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 206, __FUNCTION__))->typed.type)
;
207 unsigned HOST_WIDE_INTlong max;
208 tree low_bits, high_bits, a_low, b_low, result_low, signs;
209
210 max = GET_MODE_MASK (TYPE_MODE (inner_type))mode_mask_array[((((enum tree_code) ((tree_class_check ((inner_type
), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 210, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(inner_type) : (inner_type)->type_common.mode)]
;
211 low_bits = build_replicated_const (word_type, width, max >> 1);
212 high_bits = build_replicated_const (word_type, width, max & ~(max >> 1));
213
214 a = tree_vec_extract (gsi, word_type, a, bitsize, bitpos);
215 b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
216
217 signs = gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, a, b);
218 b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
219 if (code == PLUS_EXPR)
220 a_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, a, low_bits);
221 else
222 {
223 a_low = gimplify_build2 (gsi, BIT_IOR_EXPR, word_type, a, high_bits);
224 signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, signs);
225 }
226
227 signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
228 result_low = gimplify_build2 (gsi, code, word_type, a_low, b_low);
229 return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
230}
231
232static tree
233do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
234 tree unused ATTRIBUTE_UNUSED__attribute__ ((__unused__)), tree bitpos ATTRIBUTE_UNUSED__attribute__ ((__unused__)),
235 tree bitsize ATTRIBUTE_UNUSED__attribute__ ((__unused__)),
236 enum tree_code code ATTRIBUTE_UNUSED__attribute__ ((__unused__)),
237 tree type ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
238{
239 unsigned int width = vector_element_bits (TREE_TYPE (b)((contains_struct_check ((b), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 239, __FUNCTION__))->typed.type)
);
240 tree inner_type = TREE_TYPE (TREE_TYPE (b))((contains_struct_check ((((contains_struct_check ((b), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 240, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 240, __FUNCTION__))->typed.type)
;
241 HOST_WIDE_INTlong max;
242 tree low_bits, high_bits, b_low, result_low, signs;
243
244 max = GET_MODE_MASK (TYPE_MODE (inner_type))mode_mask_array[((((enum tree_code) ((tree_class_check ((inner_type
), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 244, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(inner_type) : (inner_type)->type_common.mode)]
;
245 low_bits = build_replicated_const (word_type, width, max >> 1);
246 high_bits = build_replicated_const (word_type, width, max & ~(max >> 1));
247
248 b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
249
250 b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
251 signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, b);
252 signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
253 result_low = gimplify_build2 (gsi, MINUS_EXPR, word_type, high_bits, b_low);
254 return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
255}
256
257/* Expand a vector operation to scalars, by using many operations
258 whose type is the vector type's inner type. */
259static tree
260expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
261 tree type, tree inner_type,
262 tree a, tree b, enum tree_code code,
263 tree ret_type = NULL_TREE(tree) nullptr)
264{
265 vec<constructor_elt, va_gc> *v;
266 tree part_width = TYPE_SIZE (inner_type)((tree_class_check ((inner_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 266, __FUNCTION__))->type_common.size)
;
267 tree index = bitsize_int (0)size_int_kind (0, stk_bitsizetype);
268 int nunits = nunits_for_known_piecewise_op (type);
269 int delta = tree_to_uhwi (part_width) / vector_element_bits (type);
270 int i;
271 location_t loc = gimple_location (gsi_stmt (*gsi));
272
273 if (ret_type
274 || types_compatible_p (gimple_expr_type (gsi_stmt (*gsi)), type))
275 warning_at (loc, OPT_Wvector_operation_performance,
276 "vector operation will be expanded piecewise");
277 else
278 warning_at (loc, OPT_Wvector_operation_performance,
279 "vector operation will be expanded in parallel");
280
281 if (!ret_type)
282 ret_type = type;
283 vec_alloc (v, (nunits + delta - 1) / delta);
284 for (i = 0; i < nunits;
285 i += delta, index = int_const_binop (PLUS_EXPR, index, part_width))
286 {
287 tree result = f (gsi, inner_type, a, b, index, part_width, code,
288 ret_type);
289 constructor_elt ce = {NULL_TREE(tree) nullptr, result};
290 v->quick_push (ce);
291 }
292
293 return build_constructor (ret_type, v);
294}
295
296/* Expand a vector operation to scalars with the freedom to use
297 a scalar integer type, or to use a different size for the items
298 in the vector type. */
299static tree
300expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type,
301 tree a, tree b, enum tree_code code)
302{
303 tree result, compute_type;
304 int n_words = tree_to_uhwi (TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 304, __FUNCTION__))->type_common.size_unit)
) / UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
305 location_t loc = gimple_location (gsi_stmt (*gsi));
306
307 /* We have three strategies. If the type is already correct, just do
308 the operation an element at a time. Else, if the vector is wider than
309 one word, do it a word at a time; finally, if the vector is smaller
310 than one word, do it as a scalar. */
311 if (TYPE_MODE (TREE_TYPE (type))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 311, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 311, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 311, __FUNCTION__))->typed.type)) : (((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 311, __FUNCTION__))->typed.type))->type_common.mode)
== word_mode)
312 return expand_vector_piecewise (gsi, f,
313 type, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 313, __FUNCTION__))->typed.type)
,
314 a, b, code);
315 else if (n_words > 1)
316 {
317 tree word_type = build_word_mode_vector_type (n_words);
318 result = expand_vector_piecewise (gsi, f,
319 word_type, TREE_TYPE (word_type)((contains_struct_check ((word_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 319, __FUNCTION__))->typed.type)
,
320 a, b, code);
321 result = force_gimple_operand_gsi (gsi, result, true, NULLnullptr, true,
322 GSI_SAME_STMT);
323 }
324 else
325 {
326 /* Use a single scalar operation with a mode no wider than word_mode. */
327 scalar_int_mode mode
328 = int_mode_for_size (tree_to_uhwi (TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 328, __FUNCTION__))->type_common.size)
), 0).require ();
329 compute_type = lang_hooks.types.type_for_mode (mode, 1);
330 result = f (gsi, compute_type, a, b, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr, code, type);
331 warning_at (loc, OPT_Wvector_operation_performance,
332 "vector operation will be expanded with a "
333 "single scalar operation");
334 }
335
336 return result;
337}
338
339/* Expand a vector operation to scalars; for integer types we can use
340 special bit twiddling tricks to do the sums a word at a time, using
341 function F_PARALLEL instead of F. These tricks are done only if
342 they can process at least four items, that is, only if the vector
343 holds at least four items and if a word can hold four items. */
344static tree
345expand_vector_addition (gimple_stmt_iterator *gsi,
346 elem_op_func f, elem_op_func f_parallel,
347 tree type, tree a, tree b, enum tree_code code)
348{
349 int parts_per_word = BITS_PER_WORD((8) * (((global_options.x_ix86_isa_flags & (1UL <<
1)) != 0) ? 8 : 4))
/ vector_element_bits (type);
350
351 if (INTEGRAL_TYPE_P (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 351, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 351, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 351, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
352 && parts_per_word >= 4
353 && nunits_for_known_piecewise_op (type) >= 4)
354 return expand_vector_parallel (gsi, f_parallel,
355 type, a, b, code);
356 else
357 return expand_vector_piecewise (gsi, f,
358 type, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 358, __FUNCTION__))->typed.type)
,
359 a, b, code);
360}
361
362static bool
363expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names);
364
365/* Try to expand vector comparison expression OP0 CODE OP1 by
366 querying optab if the following expression:
367 VEC_COND_EXPR< OP0 CODE OP1, {-1,...}, {0,...}>
368 can be expanded. */
369static tree
370expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
371 tree op1, enum tree_code code,
372 bitmap dce_ssa_names)
373{
374 tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
375 use_operand_p use_p;
376 imm_use_iterator iterator;
377 bool vec_cond_expr_only = true;
378
379 /* As seen in PR95830, we should not expand comparisons that are only
380 feeding a VEC_COND_EXPR statement. */
381 auto_vec<gimple *> uses;
382 FOR_EACH_IMM_USE_FAST (use_p, iterator, lhs)for ((use_p) = first_readonly_imm_use (&(iterator), (lhs)
); !end_readonly_imm_use_p (&(iterator)); (void) ((use_p)
= next_readonly_imm_use (&(iterator))))
383 uses.safe_push (USE_STMT (use_p)(use_p)->loc.stmt);
384
385 for (unsigned i = 0; i < uses.length (); i ++)
386 {
387 gassign *use = dyn_cast<gassign *> (uses[i]);
388 if (use != NULLnullptr
389 && gimple_assign_rhs_code (use) == VEC_COND_EXPR
390 && gimple_assign_rhs1 (use) == lhs)
391 {
392 gimple_stmt_iterator it = gsi_for_stmt (use);
393 if (!expand_vector_condition (&it, dce_ssa_names))
394 {
395 vec_cond_expr_only = false;
396 break;
397 }
398 }
399 else
400 {
401 vec_cond_expr_only = false;
402 break;
403 }
404 }
405
406 if (!uses.is_empty () && vec_cond_expr_only)
407 return NULL_TREE(tree) nullptr;
408
409 tree t;
410 if (!expand_vec_cmp_expr_p (TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 410, __FUNCTION__))->typed.type)
, type, code))
411 {
412 if (VECTOR_BOOLEAN_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 412, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
413 && SCALAR_INT_MODE_P (TYPE_MODE (type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 413, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_INT || ((enum
mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 413, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_PARTIAL_INT)
414 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 414, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
415 TYPE_VECTOR_SUBPARTS (type)(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 414, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
416 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 414, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
417 (TREE_TYPE (type))))(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 417, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 414, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
)
418 {
419 tree inner_type = TREE_TYPE (TREE_TYPE (op0))((contains_struct_check ((((contains_struct_check ((op0), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 419, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 419, __FUNCTION__))->typed.type)
;
420 tree part_width = vector_element_bits_tree (TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 420, __FUNCTION__))->typed.type)
);
421 tree index = bitsize_int (0)size_int_kind (0, stk_bitsizetype);
422 int nunits = nunits_for_known_piecewise_op (TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 422, __FUNCTION__))->typed.type)
);
423 int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (type)(as_a <scalar_mode> ((tree_class_check ((type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 423, __FUNCTION__))->type_common.mode))
);
424 tree ret_type = build_nonstandard_integer_type (prec, 1);
425 tree ret_inner_type = boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE];
426 int i;
427 location_t loc = gimple_location (gsi_stmt (*gsi));
428 t = build_zero_cst (ret_type);
429
430 if (TYPE_PRECISION (ret_inner_type)((tree_class_check ((ret_inner_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 430, __FUNCTION__))->type_common.precision)
!= 1)
431 ret_inner_type = build_nonstandard_integer_type (1, 1);
432 warning_at (loc, OPT_Wvector_operation_performance,
433 "vector operation will be expanded piecewise");
434 for (i = 0; i < nunits;
435 i++, index = int_const_binop (PLUS_EXPR, index, part_width))
436 {
437 tree a = tree_vec_extract (gsi, inner_type, op0, part_width,
438 index);
439 tree b = tree_vec_extract (gsi, inner_type, op1, part_width,
440 index);
441 tree result = gimplify_build2 (gsi, code, ret_inner_type, a, b);
442 t = gimplify_build3 (gsi, BIT_INSERT_EXPR, ret_type, t, result,
443 bitsize_int (i)size_int_kind (i, stk_bitsizetype));
444 }
445 t = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
446 }
447 else
448 t = expand_vector_piecewise (gsi, do_compare, type,
449 TREE_TYPE (TREE_TYPE (op0))((contains_struct_check ((((contains_struct_check ((op0), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 449, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 449, __FUNCTION__))->typed.type)
, op0, op1,
450 code);
451 }
452 else
453 t = NULL_TREE(tree) nullptr;
454
455 return t;
456}
457
458/* Helper function of expand_vector_divmod. Gimplify a RSHIFT_EXPR in type
459 of OP0 with shift counts in SHIFTCNTS array and return the temporary holding
460 the result if successful, otherwise return NULL_TREE. */
461static tree
462add_rshift (gimple_stmt_iterator *gsi, tree type, tree op0, int *shiftcnts)
463{
464 optab op;
465 unsigned int i, nunits = nunits_for_known_piecewise_op (type);
466 bool scalar_shift = true;
467
468 for (i = 1; i < nunits; i++)
469 {
470 if (shiftcnts[i] != shiftcnts[0])
471 scalar_shift = false;
472 }
473
474 if (scalar_shift && shiftcnts[0] == 0)
475 return op0;
476
477 if (scalar_shift)
478 {
479 op = optab_for_tree_code (RSHIFT_EXPR, type, optab_scalar);
480 if (op != unknown_optab
481 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 481, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) != CODE_FOR_nothing)
482 return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0,
483 build_int_cst (NULL_TREE(tree) nullptr, shiftcnts[0]));
484 }
485
486 op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
487 if (op != unknown_optab
488 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 488, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) != CODE_FOR_nothing)
489 {
490 tree_vector_builder vec (type, nunits, 1);
491 for (i = 0; i < nunits; i++)
492 vec.quick_push (build_int_cst (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 492, __FUNCTION__))->typed.type)
, shiftcnts[i]));
493 return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0, vec.build ());
494 }
495
496 return NULL_TREE(tree) nullptr;
497}
498
499/* Try to expand integer vector division by constant using
500 widening multiply, shifts and additions. */
501static tree
502expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
503 tree op1, enum tree_code code)
504{
505 bool use_pow2 = true;
506 bool has_vector_shift = true;
507 bool use_abs_op1 = false;
508 int mode = -1, this_mode;
509 int pre_shift = -1, post_shift;
510 unsigned int nunits = nunits_for_known_piecewise_op (type);
511 int *shifts = XALLOCAVEC (int, nunits * 4)((int *) __builtin_alloca(sizeof (int) * (nunits * 4)));
512 int *pre_shifts = shifts + nunits;
513 int *post_shifts = pre_shifts + nunits;
514 int *shift_temps = post_shifts + nunits;
515 unsigned HOST_WIDE_INTlong *mulc = XALLOCAVEC (unsigned HOST_WIDE_INT, nunits)((unsigned long *) __builtin_alloca(sizeof (unsigned long) * (
nunits)))
;
516 int prec = TYPE_PRECISION (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 516, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 516, __FUNCTION__))->type_common.precision)
;
517 int dummy_int;
518 unsigned int i;
519 signop sign_p = TYPE_SIGN (TREE_TYPE (type))((signop) ((tree_class_check ((((contains_struct_check ((type
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 519, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 519, __FUNCTION__))->base.u.bits.unsigned_flag))
;
520 unsigned HOST_WIDE_INTlong mask = GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type)))mode_mask_array[((((enum tree_code) ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 520, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 520, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 520, __FUNCTION__))->typed.type)) : (((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 520, __FUNCTION__))->typed.type))->type_common.mode)]
;
521 tree cur_op, mulcst, tem;
522 optab op;
523
524 if (prec > HOST_BITS_PER_WIDE_INT64)
525 return NULL_TREE(tree) nullptr;
526
527 op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
528 if (op == unknown_optab
529 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 529, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
530 has_vector_shift = false;
531
532 /* Analysis phase. Determine if all op1 elements are either power
533 of two and it is possible to expand it using shifts (or for remainder
534 using masking). Additionally compute the multiplicative constants
535 and pre and post shifts if the division is to be expanded using
536 widening or high part multiplication plus shifts. */
537 for (i = 0; i < nunits; i++)
538 {
539 tree cst = VECTOR_CST_ELT (op1, i)vector_cst_elt (op1, i);
540 unsigned HOST_WIDE_INTlong ml;
541
542 if (TREE_CODE (cst)((enum tree_code) (cst)->base.code) != INTEGER_CST || integer_zerop (cst))
543 return NULL_TREE(tree) nullptr;
544 pre_shifts[i] = 0;
545 post_shifts[i] = 0;
546 mulc[i] = 0;
547 if (use_pow2
548 && (!integer_pow2p (cst) || tree_int_cst_sgn (cst) != 1))
549 use_pow2 = false;
550 if (use_pow2)
551 {
552 shifts[i] = tree_log2 (cst);
553 if (shifts[i] != shifts[0]
554 && code == TRUNC_DIV_EXPR
555 && !has_vector_shift)
556 use_pow2 = false;
557 }
558 if (mode == -2)
559 continue;
560 if (sign_p == UNSIGNED)
561 {
562 unsigned HOST_WIDE_INTlong mh;
563 unsigned HOST_WIDE_INTlong d = TREE_INT_CST_LOW (cst)((unsigned long) (*tree_int_cst_elt_check ((cst), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 563, __FUNCTION__)))
& mask;
564
565 if (d >= (HOST_WIDE_INT_1U1UL << (prec - 1)))
566 /* FIXME: Can transform this into op0 >= op1 ? 1 : 0. */
567 return NULL_TREE(tree) nullptr;
568
569 if (d <= 1)
570 {
571 mode = -2;
572 continue;
573 }
574
575 /* Find a suitable multiplier and right shift count
576 instead of multiplying with D. */
577 mh = choose_multiplier (d, prec, prec, &ml, &post_shift, &dummy_int);
578
579 /* If the suggested multiplier is more than SIZE bits, we can
580 do better for even divisors, using an initial right shift. */
581 if ((mh != 0 && (d & 1) == 0)
582 || (!has_vector_shift && pre_shift != -1))
583 {
584 if (has_vector_shift)
585 pre_shift = ctz_or_zero (d);
586 else if (pre_shift == -1)
587 {
588 unsigned int j;
589 for (j = 0; j < nunits; j++)
590 {
591 tree cst2 = VECTOR_CST_ELT (op1, j)vector_cst_elt (op1, j);
592 unsigned HOST_WIDE_INTlong d2;
593 int this_pre_shift;
594
595 if (!tree_fits_uhwi_p (cst2))
596 return NULL_TREE(tree) nullptr;
597 d2 = tree_to_uhwi (cst2) & mask;
598 if (d2 == 0)
599 return NULL_TREE(tree) nullptr;
600 this_pre_shift = floor_log2 (d2 & -d2);
601 if (pre_shift == -1 || this_pre_shift < pre_shift)
602 pre_shift = this_pre_shift;
603 }
604 if (i != 0 && pre_shift != 0)
605 {
606 /* Restart. */
607 i = -1U;
608 mode = -1;
609 continue;
610 }
611 }
612 if (pre_shift != 0)
613 {
614 if ((d >> pre_shift) <= 1)
615 {
616 mode = -2;
617 continue;
618 }
619 mh = choose_multiplier (d >> pre_shift, prec,
620 prec - pre_shift,
621 &ml, &post_shift, &dummy_int);
622 gcc_assert (!mh)((void)(!(!mh) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 622, __FUNCTION__), 0 : 0))
;
623 pre_shifts[i] = pre_shift;
624 }
625 }
626 if (!mh)
627 this_mode = 0;
628 else
629 this_mode = 1;
630 }
631 else
632 {
633 HOST_WIDE_INTlong d = TREE_INT_CST_LOW (cst)((unsigned long) (*tree_int_cst_elt_check ((cst), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 633, __FUNCTION__)))
;
634 unsigned HOST_WIDE_INTlong abs_d;
635
636 if (d == -1)
637 return NULL_TREE(tree) nullptr;
638
639 /* Since d might be INT_MIN, we have to cast to
640 unsigned HOST_WIDE_INT before negating to avoid
641 undefined signed overflow. */
642 abs_d = (d >= 0
643 ? (unsigned HOST_WIDE_INTlong) d
644 : - (unsigned HOST_WIDE_INTlong) d);
645
646 /* n rem d = n rem -d */
647 if (code == TRUNC_MOD_EXPR && d < 0)
648 {
649 d = abs_d;
650 use_abs_op1 = true;
651 }
652 if (abs_d == HOST_WIDE_INT_1U1UL << (prec - 1))
653 {
654 /* This case is not handled correctly below. */
655 mode = -2;
656 continue;
657 }
658 if (abs_d <= 1)
659 {
660 mode = -2;
661 continue;
662 }
663
664 choose_multiplier (abs_d, prec, prec - 1, &ml,
665 &post_shift, &dummy_int);
666 if (ml >= HOST_WIDE_INT_1U1UL << (prec - 1))
667 {
668 this_mode = 4 + (d < 0);
669 ml |= HOST_WIDE_INT_M1U-1UL << (prec - 1);
670 }
671 else
672 this_mode = 2 + (d < 0);
673 }
674 mulc[i] = ml;
675 post_shifts[i] = post_shift;
676 if ((i && !has_vector_shift && post_shifts[0] != post_shift)
677 || post_shift >= prec
678 || pre_shifts[i] >= prec)
679 this_mode = -2;
680
681 if (i == 0)
682 mode = this_mode;
683 else if (mode != this_mode)
684 mode = -2;
685 }
686
687 if (use_pow2)
688 {
689 tree addend = NULL_TREE(tree) nullptr;
690 if (sign_p == SIGNED)
691 {
692 tree uns_type;
693
694 /* Both division and remainder sequences need
695 op0 < 0 ? mask : 0 computed. It can be either computed as
696 (type) (((uns_type) (op0 >> (prec - 1))) >> (prec - shifts[i]))
697 if none of the shifts is 0, or as the conditional. */
698 for (i = 0; i < nunits; i++)
699 if (shifts[i] == 0)
700 break;
701 uns_type
702 = build_vector_type (build_nonstandard_integer_type (prec, 1),
703 nunits);
704 if (i == nunits && TYPE_MODE (uns_type)((((enum tree_code) ((tree_class_check ((uns_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 704, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(uns_type) : (uns_type)->type_common.mode)
== TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 704, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
)
705 {
706 for (i = 0; i < nunits; i++)
707 shift_temps[i] = prec - 1;
708 cur_op = add_rshift (gsi, type, op0, shift_temps);
709 if (cur_op != NULL_TREE(tree) nullptr)
710 {
711 cur_op = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
712 uns_type, cur_op);
713 for (i = 0; i < nunits; i++)
714 shift_temps[i] = prec - shifts[i];
715 cur_op = add_rshift (gsi, uns_type, cur_op, shift_temps);
716 if (cur_op != NULL_TREE(tree) nullptr)
717 addend = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
718 type, cur_op);
719 }
720 }
721 if (addend == NULL_TREE(tree) nullptr
722 && expand_vec_cond_expr_p (type, type, LT_EXPR))
723 {
724 tree zero, cst, mask_type, mask;
725 gimple *stmt, *cond;
726
727 mask_type = truth_type_for (type);
728 zero = build_zero_cst (type);
729 mask = make_ssa_name (mask_type);
730 cond = gimple_build_assign (mask, LT_EXPR, op0, zero);
731 gsi_insert_before (gsi, cond, GSI_SAME_STMT);
732 tree_vector_builder vec (type, nunits, 1);
733 for (i = 0; i < nunits; i++)
734 vec.quick_push (build_int_cst (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 734, __FUNCTION__))->typed.type)
,
735 (HOST_WIDE_INT_1U1UL
736 << shifts[i]) - 1));
737 cst = vec.build ();
738 addend = make_ssa_name (type);
739 stmt
740 = gimple_build_assign (addend, VEC_COND_EXPR, mask, cst, zero);
741 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
742 }
743 }
744 if (code == TRUNC_DIV_EXPR)
745 {
746 if (sign_p == UNSIGNED)
747 {
748 /* q = op0 >> shift; */
749 cur_op = add_rshift (gsi, type, op0, shifts);
750 if (cur_op != NULL_TREE(tree) nullptr)
751 return cur_op;
752 }
753 else if (addend != NULL_TREE(tree) nullptr)
754 {
755 /* t1 = op0 + addend;
756 q = t1 >> shift; */
757 op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
758 if (op != unknown_optab
759 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 759, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) != CODE_FOR_nothing)
760 {
761 cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0, addend);
762 cur_op = add_rshift (gsi, type, cur_op, shifts);
763 if (cur_op != NULL_TREE(tree) nullptr)
764 return cur_op;
765 }
766 }
767 }
768 else
769 {
770 tree mask;
771 tree_vector_builder vec (type, nunits, 1);
772 for (i = 0; i < nunits; i++)
773 vec.quick_push (build_int_cst (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 773, __FUNCTION__))->typed.type)
,
774 (HOST_WIDE_INT_1U1UL
775 << shifts[i]) - 1));
776 mask = vec.build ();
777 op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default);
778 if (op != unknown_optab
779 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 779, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) != CODE_FOR_nothing)
780 {
781 if (sign_p == UNSIGNED)
782 /* r = op0 & mask; */
783 return gimplify_build2 (gsi, BIT_AND_EXPR, type, op0, mask);
784 else if (addend != NULL_TREE(tree) nullptr)
785 {
786 /* t1 = op0 + addend;
787 t2 = t1 & mask;
788 r = t2 - addend; */
789 op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
790 if (op != unknown_optab
791 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 791, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
)
792 != CODE_FOR_nothing)
793 {
794 cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0,
795 addend);
796 cur_op = gimplify_build2 (gsi, BIT_AND_EXPR, type,
797 cur_op, mask);
798 op = optab_for_tree_code (MINUS_EXPR, type,
799 optab_default);
800 if (op != unknown_optab
801 && optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 801, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
)
802 != CODE_FOR_nothing)
803 return gimplify_build2 (gsi, MINUS_EXPR, type,
804 cur_op, addend);
805 }
806 }
807 }
808 }
809 }
810
811 if (mode == -2 || BYTES_BIG_ENDIAN0 != WORDS_BIG_ENDIAN0)
812 return NULL_TREE(tree) nullptr;
813
814 if (!can_mult_highpart_p (TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 814, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
, TYPE_UNSIGNED (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 814, __FUNCTION__))->base.u.bits.unsigned_flag)
))
815 return NULL_TREE(tree) nullptr;
816
817 cur_op = op0;
818
819 switch (mode)
820 {
821 case 0:
822 gcc_assert (sign_p == UNSIGNED)((void)(!(sign_p == UNSIGNED) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 822, __FUNCTION__), 0 : 0))
;
823 /* t1 = oprnd0 >> pre_shift;
824 t2 = t1 h* ml;
825 q = t2 >> post_shift; */
826 cur_op = add_rshift (gsi, type, cur_op, pre_shifts);
827 if (cur_op == NULL_TREE(tree) nullptr)
828 return NULL_TREE(tree) nullptr;
829 break;
830 case 1:
831 gcc_assert (sign_p == UNSIGNED)((void)(!(sign_p == UNSIGNED) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 831, __FUNCTION__), 0 : 0))
;
832 for (i = 0; i < nunits; i++)
833 {
834 shift_temps[i] = 1;
835 post_shifts[i]--;
836 }
837 break;
838 case 2:
839 case 3:
840 case 4:
841 case 5:
842 gcc_assert (sign_p == SIGNED)((void)(!(sign_p == SIGNED) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 842, __FUNCTION__), 0 : 0))
;
843 for (i = 0; i < nunits; i++)
844 shift_temps[i] = prec - 1;
845 break;
846 default:
847 return NULL_TREE(tree) nullptr;
848 }
849
850 tree_vector_builder vec (type, nunits, 1);
851 for (i = 0; i < nunits; i++)
852 vec.quick_push (build_int_cst (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 852, __FUNCTION__))->typed.type)
, mulc[i]));
853 mulcst = vec.build ();
854
855 cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst);
856
857 switch (mode)
858 {
859 case 0:
860 /* t1 = oprnd0 >> pre_shift;
861 t2 = t1 h* ml;
862 q = t2 >> post_shift; */
863 cur_op = add_rshift (gsi, type, cur_op, post_shifts);
864 break;
865 case 1:
866 /* t1 = oprnd0 h* ml;
867 t2 = oprnd0 - t1;
868 t3 = t2 >> 1;
869 t4 = t1 + t3;
870 q = t4 >> (post_shift - 1); */
871 op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
872 if (op == unknown_optab
873 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 873, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
874 return NULL_TREE(tree) nullptr;
875 tem = gimplify_build2 (gsi, MINUS_EXPR, type, op0, cur_op);
876 tem = add_rshift (gsi, type, tem, shift_temps);
877 op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
878 if (op == unknown_optab
879 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 879, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
880 return NULL_TREE(tree) nullptr;
881 tem = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, tem);
882 cur_op = add_rshift (gsi, type, tem, post_shifts);
883 if (cur_op == NULL_TREE(tree) nullptr)
884 return NULL_TREE(tree) nullptr;
885 break;
886 case 2:
887 case 3:
888 case 4:
889 case 5:
890 /* t1 = oprnd0 h* ml;
891 t2 = t1; [ iff (mode & 2) != 0 ]
892 t2 = t1 + oprnd0; [ iff (mode & 2) == 0 ]
893 t3 = t2 >> post_shift;
894 t4 = oprnd0 >> (prec - 1);
895 q = t3 - t4; [ iff (mode & 1) == 0 ]
896 q = t4 - t3; [ iff (mode & 1) != 0 ] */
897 if ((mode & 2) == 0)
898 {
899 op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
900 if (op == unknown_optab
901 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 901, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
902 return NULL_TREE(tree) nullptr;
903 cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, op0);
904 }
905 cur_op = add_rshift (gsi, type, cur_op, post_shifts);
906 if (cur_op == NULL_TREE(tree) nullptr)
907 return NULL_TREE(tree) nullptr;
908 tem = add_rshift (gsi, type, op0, shift_temps);
909 if (tem == NULL_TREE(tree) nullptr)
910 return NULL_TREE(tree) nullptr;
911 op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
912 if (op == unknown_optab
913 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 913, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
914 return NULL_TREE(tree) nullptr;
915 if ((mode & 1) == 0)
916 cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, cur_op, tem);
917 else
918 cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, tem, cur_op);
919 break;
920 default:
921 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 921, __FUNCTION__))
;
922 }
923
924 if (code == TRUNC_DIV_EXPR)
925 return cur_op;
926
927 /* We divided. Now finish by:
928 t1 = q * oprnd1;
929 r = oprnd0 - t1; */
930 op = optab_for_tree_code (MULT_EXPR, type, optab_default);
931 if (op == unknown_optab
932 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 932, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
933 return NULL_TREE(tree) nullptr;
934 if (use_abs_op1)
935 {
936 tree_vector_builder elts;
937 if (!elts.new_unary_operation (type, op1, false))
938 return NULL_TREE(tree) nullptr;
939 unsigned int count = elts.encoded_nelts ();
940 for (unsigned int i = 0; i < count; ++i)
941 {
942 tree elem1 = VECTOR_CST_ELT (op1, i)vector_cst_elt (op1, i);
943
944 tree elt = const_unop (ABS_EXPR, TREE_TYPE (elem1)((contains_struct_check ((elem1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 944, __FUNCTION__))->typed.type)
, elem1);
945 if (elt == NULL_TREE(tree) nullptr)
946 return NULL_TREE(tree) nullptr;
947 elts.quick_push (elt);
948 }
949 op1 = elts.build ();
950 }
951 tem = gimplify_build2 (gsi, MULT_EXPR, type, cur_op, op1);
952 op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
953 if (op == unknown_optab
954 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 954, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
955 return NULL_TREE(tree) nullptr;
956 return gimplify_build2 (gsi, MINUS_EXPR, type, op0, tem);
957}
958
959/* Expand a vector condition to scalars, by using many conditions
960 on the vector's elements. */
961
962static bool
963expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names)
964{
965 gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
966 tree type = gimple_expr_type (stmt);
967 tree a = gimple_assign_rhs1 (stmt);
968 tree a1 = a;
969 tree a2 = NULL_TREE(tree) nullptr;
970 bool a_is_comparison = false;
971 bool a_is_scalar_bitmask = false;
972 tree b = gimple_assign_rhs2 (stmt);
973 tree c = gimple_assign_rhs3 (stmt);
974 vec<constructor_elt, va_gc> *v;
975 tree constr;
976 tree inner_type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 976, __FUNCTION__))->typed.type)
;
977 tree width = vector_element_bits_tree (type);
978 tree cond_type = TREE_TYPE (TREE_TYPE (a))((contains_struct_check ((((contains_struct_check ((a), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 978, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 978, __FUNCTION__))->typed.type)
;
979 tree comp_inner_type = cond_type;
980 tree index = bitsize_int (0)size_int_kind (0, stk_bitsizetype);
981 tree comp_width = width;
982 tree comp_index = index;
983 location_t loc = gimple_location (gsi_stmt (*gsi));
984 tree_code code = TREE_CODE (a)((enum tree_code) (a)->base.code);
985 gassign *assign = NULLnullptr;
986
987 if (code == SSA_NAME)
988 {
989 assign = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (a)(tree_check ((a), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 989, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
);
990 if (assign != NULLnullptr
991 && TREE_CODE_CLASS (gimple_assign_rhs_code (assign))tree_code_type[(int) (gimple_assign_rhs_code (assign))] == tcc_comparison)
992 {
993 a_is_comparison = true;
994 a1 = gimple_assign_rhs1 (assign);
995 a2 = gimple_assign_rhs2 (assign);
996 code = gimple_assign_rhs_code (assign);
997 comp_inner_type = TREE_TYPE (TREE_TYPE (a1))((contains_struct_check ((((contains_struct_check ((a1), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 997, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 997, __FUNCTION__))->typed.type)
;
998 comp_width = vector_element_bits_tree (TREE_TYPE (a1)((contains_struct_check ((a1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 998, __FUNCTION__))->typed.type)
);
999 }
1000 }
1001
1002 if (expand_vec_cond_expr_p (type, TREE_TYPE (a1)((contains_struct_check ((a1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1002, __FUNCTION__))->typed.type)
, code))
1003 {
1004 gcc_assert (TREE_CODE (a) == SSA_NAME || TREE_CODE (a) == VECTOR_CST)((void)(!(((enum tree_code) (a)->base.code) == SSA_NAME ||
((enum tree_code) (a)->base.code) == VECTOR_CST) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1004, __FUNCTION__), 0 : 0))
;
1005 return true;
1006 }
1007
1008 /* Handle vector boolean types with bitmasks. If there is a comparison
1009 and we can expand the comparison into the vector boolean bitmask,
1010 or otherwise if it is compatible with type, we can transform
1011 vbfld_1 = x_2 < y_3 ? vbfld_4 : vbfld_5;
1012 into
1013 tmp_6 = x_2 < y_3;
1014 tmp_7 = tmp_6 & vbfld_4;
1015 tmp_8 = ~tmp_6;
1016 tmp_9 = tmp_8 & vbfld_5;
1017 vbfld_1 = tmp_7 | tmp_9;
1018 Similarly for vbfld_10 instead of x_2 < y_3. */
1019 if (VECTOR_BOOLEAN_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1019, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
1020 && SCALAR_INT_MODE_P (TYPE_MODE (type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1020, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_INT || ((enum
mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1020, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_PARTIAL_INT)
1021 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1021, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
1022 TYPE_VECTOR_SUBPARTS (type)(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1021, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
1023 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type))))(!maybe_le (TYPE_VECTOR_SUBPARTS (type) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1023, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((type), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1021, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode))))
1024 && (a_is_comparison
1025 ? useless_type_conversion_p (type, TREE_TYPE (a)((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1025, __FUNCTION__))->typed.type)
)
1026 : expand_vec_cmp_expr_p (TREE_TYPE (a1)((contains_struct_check ((a1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1026, __FUNCTION__))->typed.type)
, type, TREE_CODE (a)((enum tree_code) (a)->base.code))))
1027 {
1028 if (a_is_comparison)
1029 a = gimplify_build2 (gsi, code, type, a1, a2);
1030 a1 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a, b);
1031 a2 = gimplify_build1 (gsi, BIT_NOT_EXPR, type, a);
1032 a2 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a2, c);
1033 a = gimplify_build2 (gsi, BIT_IOR_EXPR, type, a1, a2);
1034 gimple_assign_set_rhs_from_tree (gsi, a);
1035 update_stmt (gsi_stmt (*gsi));
1036 return true;
1037 }
1038
1039 /* TODO: try and find a smaller vector type. */
1040
1041 warning_at (loc, OPT_Wvector_operation_performance,
1042 "vector condition will be expanded piecewise");
1043
1044 if (!a_is_comparison
1045 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))(((enum tree_code) (((contains_struct_check ((a), (TS_TYPED),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1045, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
&& ((enum tree_code) (((contains_struct_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1045, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1045, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
1046 && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a)))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_INT || ((enum mode_class) mode_class[((((enum tree_code
) ((tree_class_check ((((contains_struct_check ((a), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_PARTIAL_INT)
1047 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a))),(!maybe_le (TYPE_VECTOR_SUBPARTS (((contains_struct_check ((a
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1048, __FUNCTION__))->typed.type)) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type))->type_common.mode)
)))
1048 TYPE_VECTOR_SUBPARTS (TREE_TYPE (a))(!maybe_le (TYPE_VECTOR_SUBPARTS (((contains_struct_check ((a
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1048, __FUNCTION__))->typed.type)) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type))->type_common.mode)
)))
1049 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE(!maybe_le (TYPE_VECTOR_SUBPARTS (((contains_struct_check ((a
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1048, __FUNCTION__))->typed.type)) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type))->type_common.mode)
)))
1050 (TREE_TYPE (TREE_TYPE (a)))))(!maybe_le (TYPE_VECTOR_SUBPARTS (((contains_struct_check ((a
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1048, __FUNCTION__))->typed.type)) * GET_MODE_BITSIZE ((
as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1050, __FUNCTION__))->type_common.mode))), GET_MODE_BITSIZE
(((((enum tree_code) ((tree_class_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type)) : (((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1047, __FUNCTION__))->typed.type))->type_common.mode)
)))
)
1051 {
1052 a_is_scalar_bitmask = true;
1053 int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a))(as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1053, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1053, __FUNCTION__))->type_common.mode))
);
1054 tree atype = build_nonstandard_integer_type (prec, 1);
1055 a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a);
1056 }
1057
1058 int nunits = nunits_for_known_piecewise_op (type);
1059 vec_alloc (v, nunits);
1060 for (int i = 0; i < nunits; i++)
1061 {
1062 tree aa, result;
1063 tree bb = tree_vec_extract (gsi, inner_type, b, width, index);
1064 tree cc = tree_vec_extract (gsi, inner_type, c, width, index);
1065 if (a_is_comparison)
1066 {
1067 tree aa1 = tree_vec_extract (gsi, comp_inner_type, a1,
1068 comp_width, comp_index);
1069 tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2,
1070 comp_width, comp_index);
1071 aa = fold_build2 (code, cond_type, aa1, aa2)fold_build2_loc (((location_t) 0), code, cond_type, aa1, aa2 );
1072 }
1073 else if (a_is_scalar_bitmask)
1074 {
1075 wide_int w = wi::set_bit_in_zero (i, TYPE_PRECISION (TREE_TYPE (a))((tree_class_check ((((contains_struct_check ((a), (TS_TYPED)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1075, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1075, __FUNCTION__))->type_common.precision)
);
1076 result = gimplify_build2 (gsi, BIT_AND_EXPR, TREE_TYPE (a)((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1076, __FUNCTION__))->typed.type)
,
1077 a, wide_int_to_tree (TREE_TYPE (a)((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1077, __FUNCTION__))->typed.type)
, w));
1078 aa = fold_build2 (NE_EXPR, boolean_type_node, result,fold_build2_loc (((location_t) 0), NE_EXPR, global_trees[TI_BOOLEAN_TYPE
], result, build_zero_cst (((contains_struct_check ((a), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1079, __FUNCTION__))->typed.type)) )
1079 build_zero_cst (TREE_TYPE (a)))fold_build2_loc (((location_t) 0), NE_EXPR, global_trees[TI_BOOLEAN_TYPE
], result, build_zero_cst (((contains_struct_check ((a), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1079, __FUNCTION__))->typed.type)) )
;
1080 }
1081 else
1082 aa = tree_vec_extract (gsi, cond_type, a, width, index);
1083 result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
1084 constructor_elt ce = {NULL_TREE(tree) nullptr, result};
1085 v->quick_push (ce);
1086 index = int_const_binop (PLUS_EXPR, index, width);
1087 if (width == comp_width)
1088 comp_index = index;
1089 else
1090 comp_index = int_const_binop (PLUS_EXPR, comp_index, comp_width);
1091 }
1092
1093 constr = build_constructor (type, v);
1094 gimple_assign_set_rhs_from_tree (gsi, constr);
1095 update_stmt (gsi_stmt (*gsi));
1096
1097 if (a_is_comparison)
1098 bitmap_set_bit (dce_ssa_names,
1099 SSA_NAME_VERSION (gimple_assign_lhs (assign))(tree_check ((gimple_assign_lhs (assign)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1099, __FUNCTION__, (SSA_NAME)))->base.u.version
);
1100
1101 return false;
1102}
1103
1104static tree
1105expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
1106 gassign *assign, enum tree_code code,
1107 bitmap dce_ssa_names)
1108{
1109 machine_mode compute_mode = TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1109, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
;
1110
1111 /* If the compute mode is not a vector mode (hence we are not decomposing
1112 a BLKmode vector to smaller, hardware-supported vectors), we may want
1113 to expand the operations in parallel. */
1114 if (!VECTOR_MODE_P (compute_mode)(((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_BOOL
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_INT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UACCUM
)
)
1115 switch (code)
1116 {
1117 case PLUS_EXPR:
1118 case MINUS_EXPR:
1119 if (ANY_INTEGRAL_TYPE_P (type)((((enum tree_code) (type)->base.code) == ENUMERAL_TYPE ||
((enum tree_code) (type)->base.code) == BOOLEAN_TYPE || (
(enum tree_code) (type)->base.code) == INTEGER_TYPE) || ((
((enum tree_code) (type)->base.code) == COMPLEX_TYPE || ((
(enum tree_code) (type)->base.code) == VECTOR_TYPE)) &&
(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1119, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1119, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1119, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)))
&& !TYPE_OVERFLOW_TRAPS (type)(!(any_integral_type_check ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1119, __FUNCTION__))->base.u.bits.unsigned_flag &&
global_options.x_flag_trapv)
)
1120 return expand_vector_addition (gsi, do_binop, do_plus_minus, type,
1121 gimple_assign_rhs1 (assign),
1122 gimple_assign_rhs2 (assign), code);
1123 break;
1124
1125 case NEGATE_EXPR:
1126 if (ANY_INTEGRAL_TYPE_P (type)((((enum tree_code) (type)->base.code) == ENUMERAL_TYPE ||
((enum tree_code) (type)->base.code) == BOOLEAN_TYPE || (
(enum tree_code) (type)->base.code) == INTEGER_TYPE) || ((
((enum tree_code) (type)->base.code) == COMPLEX_TYPE || ((
(enum tree_code) (type)->base.code) == VECTOR_TYPE)) &&
(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1126, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1126, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1126, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)))
&& !TYPE_OVERFLOW_TRAPS (type)(!(any_integral_type_check ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1126, __FUNCTION__))->base.u.bits.unsigned_flag &&
global_options.x_flag_trapv)
)
1127 return expand_vector_addition (gsi, do_unop, do_negate, type,
1128 gimple_assign_rhs1 (assign),
1129 NULL_TREE(tree) nullptr, code);
1130 break;
1131
1132 case BIT_AND_EXPR:
1133 case BIT_IOR_EXPR:
1134 case BIT_XOR_EXPR:
1135 return expand_vector_parallel (gsi, do_binop, type,
1136 gimple_assign_rhs1 (assign),
1137 gimple_assign_rhs2 (assign), code);
1138
1139 case BIT_NOT_EXPR:
1140 return expand_vector_parallel (gsi, do_unop, type,
1141 gimple_assign_rhs1 (assign),
1142 NULL_TREE(tree) nullptr, code);
1143 case EQ_EXPR:
1144 case NE_EXPR:
1145 case GT_EXPR:
1146 case LT_EXPR:
1147 case GE_EXPR:
1148 case LE_EXPR:
1149 case UNEQ_EXPR:
1150 case UNGT_EXPR:
1151 case UNLT_EXPR:
1152 case UNGE_EXPR:
1153 case UNLE_EXPR:
1154 case LTGT_EXPR:
1155 case ORDERED_EXPR:
1156 case UNORDERED_EXPR:
1157 {
1158 tree rhs1 = gimple_assign_rhs1 (assign);
1159 tree rhs2 = gimple_assign_rhs2 (assign);
1160
1161 return expand_vector_comparison (gsi, type, rhs1, rhs2, code,
1162 dce_ssa_names);
1163 }
1164
1165 case TRUNC_DIV_EXPR:
1166 case TRUNC_MOD_EXPR:
1167 {
1168 tree rhs1 = gimple_assign_rhs1 (assign);
1169 tree rhs2 = gimple_assign_rhs2 (assign);
1170 tree ret;
1171
1172 if (!optimizeglobal_options.x_optimize
1173 || !VECTOR_INTEGER_TYPE_P (type)((((enum tree_code) (type)->base.code) == VECTOR_TYPE) &&
((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1173, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
1174 || TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) != VECTOR_CST
1175 || !VECTOR_MODE_P (TYPE_MODE (type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_BOOL ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_INT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1175, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UACCUM
)
)
1176 break;
1177
1178 ret = expand_vector_divmod (gsi, type, rhs1, rhs2, code);
1179 if (ret != NULL_TREE(tree) nullptr)
1180 return ret;
1181 break;
1182 }
1183
1184 default:
1185 break;
1186 }
1187
1188 if (TREE_CODE_CLASS (code)tree_code_type[(int) (code)] == tcc_unary)
1189 return expand_vector_piecewise (gsi, do_unop, type, compute_type,
1190 gimple_assign_rhs1 (assign),
1191 NULL_TREE(tree) nullptr, code);
1192 else
1193 return expand_vector_piecewise (gsi, do_binop, type, compute_type,
1194 gimple_assign_rhs1 (assign),
1195 gimple_assign_rhs2 (assign), code);
1196}
1197
1198/* Try to optimize
1199 a_5 = { b_7, b_7 + 3, b_7 + 6, b_7 + 9 };
1200 style stmts into:
1201 _9 = { b_7, b_7, b_7, b_7 };
1202 a_5 = _9 + { 0, 3, 6, 9 };
1203 because vector splat operation is usually more efficient
1204 than piecewise initialization of the vector. */
1205
1206static void
1207optimize_vector_constructor (gimple_stmt_iterator *gsi)
1208{
1209 gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1210 tree lhs = gimple_assign_lhs (stmt);
1211 tree rhs = gimple_assign_rhs1 (stmt);
1212 tree type = TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1212, __FUNCTION__))->typed.type)
;
1213 unsigned int i, j;
1214 unsigned HOST_WIDE_INTlong nelts;
1215 bool all_same = true;
1216 constructor_elt *elt;
1217 gimple *g;
1218 tree base = NULL_TREE(tree) nullptr;
1219 optab op;
1220
1221 if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)
1222 || nelts <= 2
1223 || CONSTRUCTOR_NELTS (rhs)(vec_safe_length (((tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1223, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
!= nelts)
1224 return;
1225 op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
1226 if (op == unknown_optab
1227 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1227, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing)
1228 return;
1229 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs), i, elt)for (i = 0; vec_safe_iterate ((((tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1229, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)),
(i), &(elt)); ++(i))
1230 if (TREE_CODE (elt->value)((enum tree_code) (elt->value)->base.code) != SSA_NAME
1231 || TREE_CODE (TREE_TYPE (elt->value))((enum tree_code) (((contains_struct_check ((elt->value), (
TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1231, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
1232 return;
1233 else
1234 {
1235 tree this_base = elt->value;
1236 if (this_base != CONSTRUCTOR_ELT (rhs, 0)(&(*((tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1236, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
0])
->value)
1237 all_same = false;
1238 for (j = 0; j < nelts + 1; j++)
1239 {
1240 g = SSA_NAME_DEF_STMT (this_base)(tree_check ((this_base), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1240, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1241 if (is_gimple_assign (g)
1242 && gimple_assign_rhs_code (g) == PLUS_EXPR
1243 && TREE_CODE (gimple_assign_rhs2 (g))((enum tree_code) (gimple_assign_rhs2 (g))->base.code) == INTEGER_CST
1244 && TREE_CODE (gimple_assign_rhs1 (g))((enum tree_code) (gimple_assign_rhs1 (g))->base.code) == SSA_NAME
1245 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g))(tree_check ((gimple_assign_rhs1 (g)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1245, __FUNCTION__, (SSA_NAME)))->base.asm_written_flag
)
1246 this_base = gimple_assign_rhs1 (g);
1247 else
1248 break;
1249 }
1250 if (i == 0)
1251 base = this_base;
1252 else if (this_base != base)
1253 return;
1254 }
1255 if (all_same)
1256 return;
1257 tree_vector_builder cst (type, nelts, 1);
1258 for (i = 0; i < nelts; i++)
1259 {
1260 tree this_base = CONSTRUCTOR_ELT (rhs, i)(&(*((tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1260, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
i])
->value;
1261 tree elt = build_zero_cst (TREE_TYPE (base)((contains_struct_check ((base), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1261, __FUNCTION__))->typed.type)
);
1262 while (this_base != base)
1263 {
1264 g = SSA_NAME_DEF_STMT (this_base)(tree_check ((this_base), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1264, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1265 elt = fold_binary (PLUS_EXPR, TREE_TYPE (base),fold_binary_loc (((location_t) 0), PLUS_EXPR, ((contains_struct_check
((base), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1265, __FUNCTION__))->typed.type), elt, gimple_assign_rhs2
(g))
1266 elt, gimple_assign_rhs2 (g))fold_binary_loc (((location_t) 0), PLUS_EXPR, ((contains_struct_check
((base), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1265, __FUNCTION__))->typed.type), elt, gimple_assign_rhs2
(g))
;
1267 if (elt == NULL_TREE(tree) nullptr
1268 || TREE_CODE (elt)((enum tree_code) (elt)->base.code) != INTEGER_CST
1269 || TREE_OVERFLOW (elt)((tree_class_check ((elt), (tcc_constant), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1269, __FUNCTION__))->base.public_flag)
)
1270 return;
1271 this_base = gimple_assign_rhs1 (g);
1272 }
1273 cst.quick_push (elt);
1274 }
1275 for (i = 0; i < nelts; i++)
1276 CONSTRUCTOR_ELT (rhs, i)(&(*((tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1276, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
i])
->value = base;
1277 g = gimple_build_assign (make_ssa_name (type), rhs);
1278 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1279 g = gimple_build_assign (lhs, PLUS_EXPR, gimple_assign_lhs (g),
1280 cst.build ());
1281 gsi_replace (gsi, g, false);
1282}
1283
1284/* Return a type for the widest vector mode whose components are of type
1285 TYPE, or NULL_TREE if none is found. */
1286
1287static tree
1288type_for_widest_vector_mode (tree type, optab op)
1289{
1290 machine_mode inner_mode = TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1290, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
;
1291 machine_mode best_mode = VOIDmode((void) 0, E_VOIDmode), mode;
1292 poly_int64 best_nunits = 0;
1293
1294 if (SCALAR_FLOAT_MODE_P (inner_mode)(((enum mode_class) mode_class[inner_mode]) == MODE_FLOAT || (
(enum mode_class) mode_class[inner_mode]) == MODE_DECIMAL_FLOAT
)
)
1295 mode = MIN_MODE_VECTOR_FLOAT;
1296 else if (SCALAR_FRACT_MODE_P (inner_mode)(((enum mode_class) mode_class[inner_mode]) == MODE_FRACT))
1297 mode = MIN_MODE_VECTOR_FRACT;
1298 else if (SCALAR_UFRACT_MODE_P (inner_mode)(((enum mode_class) mode_class[inner_mode]) == MODE_UFRACT))
1299 mode = MIN_MODE_VECTOR_UFRACT;
1300 else if (SCALAR_ACCUM_MODE_P (inner_mode)(((enum mode_class) mode_class[inner_mode]) == MODE_ACCUM))
1301 mode = MIN_MODE_VECTOR_ACCUM;
1302 else if (SCALAR_UACCUM_MODE_P (inner_mode)(((enum mode_class) mode_class[inner_mode]) == MODE_UACCUM))
1303 mode = MIN_MODE_VECTOR_UACCUM;
1304 else if (inner_mode == BImode(scalar_int_mode ((scalar_int_mode::from_int) E_BImode)))
1305 mode = MIN_MODE_VECTOR_BOOL;
1306 else
1307 mode = MIN_MODE_VECTOR_INT;
1308
1309 FOR_EACH_MODE_FROM (mode, mode)for ((mode) = (mode); mode_iterator::iterate_p (&(mode));
mode_iterator::get_wider (&(mode)))
1310 if (GET_MODE_INNER (mode)(mode_to_inner (mode)) == inner_mode
1311 && maybe_gt (GET_MODE_NUNITS (mode), best_nunits)maybe_lt (best_nunits, GET_MODE_NUNITS (mode))
1312 && optab_handler (op, mode) != CODE_FOR_nothing)
1313 best_mode = mode, best_nunits = GET_MODE_NUNITS (mode);
1314
1315 if (best_mode == VOIDmode((void) 0, E_VOIDmode))
1316 return NULL_TREE(tree) nullptr;
1317 else
1318 return build_vector_type_for_mode (type, best_mode);
1319}
1320
1321
1322/* Build a reference to the element of the vector VECT. Function
1323 returns either the element itself, either BIT_FIELD_REF, or an
1324 ARRAY_REF expression.
1325
1326 GSI is required to insert temporary variables while building a
1327 refernece to the element of the vector VECT.
1328
1329 PTMPVEC is a pointer to the temporary variable for caching
1330 purposes. In case when PTMPVEC is NULL new temporary variable
1331 will be created. */
1332static tree
1333vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec)
1334{
1335 tree vect_type, vect_elt_type;
1336 gimple *asgn;
1337 tree tmpvec;
1338 tree arraytype;
1339 bool need_asgn = true;
1340 unsigned int elements;
1341
1342 vect_type = TREE_TYPE (vect)((contains_struct_check ((vect), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1342, __FUNCTION__))->typed.type)
;
1343 vect_elt_type = TREE_TYPE (vect_type)((contains_struct_check ((vect_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1343, __FUNCTION__))->typed.type)
;
1344 elements = nunits_for_known_piecewise_op (vect_type);
1345
1346 if (TREE_CODE (idx)((enum tree_code) (idx)->base.code) == INTEGER_CST)
1347 {
1348 unsigned HOST_WIDE_INTlong index;
1349
1350 /* Given that we're about to compute a binary modulus,
1351 we don't care about the high bits of the value. */
1352 index = TREE_INT_CST_LOW (idx)((unsigned long) (*tree_int_cst_elt_check ((idx), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1352, __FUNCTION__)))
;
1353 if (!tree_fits_uhwi_p (idx) || index >= elements)
1354 {
1355 index &= elements - 1;
1356 idx = build_int_cst (TREE_TYPE (idx)((contains_struct_check ((idx), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1356, __FUNCTION__))->typed.type)
, index);
1357 }
1358
1359 /* When lowering a vector statement sequence do some easy
1360 simplification by looking through intermediate vector results. */
1361 if (TREE_CODE (vect)((enum tree_code) (vect)->base.code) == SSA_NAME)
1362 {
1363 gimple *def_stmt = SSA_NAME_DEF_STMT (vect)(tree_check ((vect), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1363, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1364 if (is_gimple_assign (def_stmt)
1365 && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST
1366 || gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR))
1367 vect = gimple_assign_rhs1 (def_stmt);
1368 }
1369
1370 if (TREE_CODE (vect)((enum tree_code) (vect)->base.code) == VECTOR_CST)
1371 return VECTOR_CST_ELT (vect, index)vector_cst_elt (vect, index);
1372 else if (TREE_CODE (vect)((enum tree_code) (vect)->base.code) == CONSTRUCTOR
1373 && (CONSTRUCTOR_NELTS (vect)(vec_safe_length (((tree_check ((vect), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1373, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
== 0
1374 || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect, 0)->value))((enum tree_code) (((contains_struct_check (((&(*((tree_check
((vect), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1374, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
0])->value), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1374, __FUNCTION__))->typed.type))->base.code)
1375 != VECTOR_TYPE))
1376 {
1377 if (index < CONSTRUCTOR_NELTS (vect)(vec_safe_length (((tree_check ((vect), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1377, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
)
1378 return CONSTRUCTOR_ELT (vect, index)(&(*((tree_check ((vect), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1378, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
index])
->value;
1379 return build_zero_cst (vect_elt_type);
1380 }
1381 else
1382 {
1383 tree size = vector_element_bits_tree (vect_type);
1384 tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (index),fold_build2_loc (((location_t) 0), MULT_EXPR, sizetype_tab[(int
) stk_bitsizetype], size_int_kind (index, stk_bitsizetype), size
)
1385 size)fold_build2_loc (((location_t) 0), MULT_EXPR, sizetype_tab[(int
) stk_bitsizetype], size_int_kind (index, stk_bitsizetype), size
)
;
1386 return fold_build3 (BIT_FIELD_REF, vect_elt_type, vect, size, pos)fold_build3_loc (((location_t) 0), BIT_FIELD_REF, vect_elt_type
, vect, size, pos )
;
1387 }
1388 }
1389
1390 if (!ptmpvec)
1391 tmpvec = create_tmp_var (vect_type, "vectmp");
1392 else if (!*ptmpvec)
1393 tmpvec = *ptmpvec = create_tmp_var (vect_type, "vectmp");
1394 else
1395 {
1396 tmpvec = *ptmpvec;
1397 need_asgn = false;
1398 }
1399
1400 if (need_asgn)
1401 {
1402 TREE_ADDRESSABLE (tmpvec)((tmpvec)->base.addressable_flag) = 1;
1403 asgn = gimple_build_assign (tmpvec, vect);
1404 gsi_insert_before (gsi, asgn, GSI_SAME_STMT);
1405 }
1406
1407 arraytype = build_array_type_nelts (vect_elt_type, elements);
1408 return build4 (ARRAY_REF, vect_elt_type,
1409 build1 (VIEW_CONVERT_EXPR, arraytype, tmpvec),
1410 idx, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr);
1411}
1412
1413/* Check if VEC_PERM_EXPR within the given setting is supported
1414 by hardware, or lower it piecewise.
1415
1416 When VEC_PERM_EXPR has the same first and second operands:
1417 VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
1418 {v0[mask[0]], v0[mask[1]], ...}
1419 MASK and V0 must have the same number of elements.
1420
1421 Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
1422 {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
1423 V0 and V1 must have the same type. MASK, V0, V1 must have the
1424 same number of arguments. */
1425
1426static void
1427lower_vec_perm (gimple_stmt_iterator *gsi)
1428{
1429 gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1430 tree mask = gimple_assign_rhs3 (stmt);
1431 tree vec0 = gimple_assign_rhs1 (stmt);
1432 tree vec1 = gimple_assign_rhs2 (stmt);
1433 tree vect_type = TREE_TYPE (vec0)((contains_struct_check ((vec0), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1433, __FUNCTION__))->typed.type)
;
1434 tree mask_type = TREE_TYPE (mask)((contains_struct_check ((mask), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1434, __FUNCTION__))->typed.type)
;
1435 tree vect_elt_type = TREE_TYPE (vect_type)((contains_struct_check ((vect_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1435, __FUNCTION__))->typed.type)
;
1436 tree mask_elt_type = TREE_TYPE (mask_type)((contains_struct_check ((mask_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1436, __FUNCTION__))->typed.type)
;
1437 unsigned HOST_WIDE_INTlong elements;
1438 vec<constructor_elt, va_gc> *v;
1439 tree constr, t, si, i_val;
1440 tree vec0tmp = NULL_TREE(tree) nullptr, vec1tmp = NULL_TREE(tree) nullptr, masktmp = NULL_TREE(tree) nullptr;
1441 bool two_operand_p = !operand_equal_p (vec0, vec1, 0);
1442 location_t loc = gimple_location (gsi_stmt (*gsi));
1443 unsigned i;
1444
1445 if (!TYPE_VECTOR_SUBPARTS (vect_type).is_constant (&elements))
1446 return;
1447
1448 if (TREE_CODE (mask)((enum tree_code) (mask)->base.code) == SSA_NAME)
1449 {
1450 gimple *def_stmt = SSA_NAME_DEF_STMT (mask)(tree_check ((mask), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1450, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1451 if (is_gimple_assign (def_stmt)
1452 && gimple_assign_rhs_code (def_stmt) == VECTOR_CST)
1453 mask = gimple_assign_rhs1 (def_stmt);
1454 }
1455
1456 vec_perm_builder sel_int;
1457
1458 if (TREE_CODE (mask)((enum tree_code) (mask)->base.code) == VECTOR_CST
1459 && tree_to_vec_perm_builder (&sel_int, mask))
1460 {
1461 vec_perm_indices indices (sel_int, 2, elements);
1462 if (can_vec_perm_const_p (TYPE_MODE (vect_type)((((enum tree_code) ((tree_class_check ((vect_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1462, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vect_type) : (vect_type)->type_common.mode)
, indices))
1463 {
1464 gimple_assign_set_rhs3 (stmt, mask);
1465 update_stmt (stmt);
1466 return;
1467 }
1468 /* Also detect vec_shr pattern - VEC_PERM_EXPR with zero
1469 vector as VEC1 and a right element shift MASK. */
1470 if (optab_handler (vec_shr_optab, TYPE_MODE (vect_type)((((enum tree_code) ((tree_class_check ((vect_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1470, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vect_type) : (vect_type)->type_common.mode)
)
1471 != CODE_FOR_nothing
1472 && TREE_CODE (vec1)((enum tree_code) (vec1)->base.code) == VECTOR_CST
1473 && initializer_zerop (vec1)
1474 && maybe_ne (indices[0], 0)
1475 && known_lt (poly_uint64 (indices[0]), elements)(!maybe_le (elements, poly_uint64 (indices[0]))))
1476 {
1477 bool ok_p = indices.series_p (0, 1, indices[0], 1);
1478 if (!ok_p)
1479 {
1480 for (i = 1; i < elements; ++i)
1481 {
1482 poly_uint64 actual = indices[i];
1483 poly_uint64 expected = i + indices[0];
1484 /* Indices into the second vector are all equivalent. */
1485 if (maybe_lt (actual, elements)
1486 ? maybe_ne (actual, expected)
1487 : maybe_lt (expected, elements))
1488 break;
1489 }
1490 ok_p = i == elements;
1491 }
1492 if (ok_p)
1493 {
1494 gimple_assign_set_rhs3 (stmt, mask);
1495 update_stmt (stmt);
1496 return;
1497 }
1498 }
1499 /* And similarly vec_shl pattern. */
1500 if (optab_handler (vec_shl_optab, TYPE_MODE (vect_type)((((enum tree_code) ((tree_class_check ((vect_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1500, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vect_type) : (vect_type)->type_common.mode)
)
1501 != CODE_FOR_nothing
1502 && TREE_CODE (vec0)((enum tree_code) (vec0)->base.code) == VECTOR_CST
1503 && initializer_zerop (vec0))
1504 {
1505 unsigned int first = 0;
1506 for (i = 0; i < elements; ++i)
1507 if (known_eq (poly_uint64 (indices[i]), elements)(!maybe_ne (poly_uint64 (indices[i]), elements)))
1508 {
1509 if (i == 0 || first)
1510 break;
1511 first = i;
1512 }
1513 else if (first
1514 ? maybe_ne (poly_uint64 (indices[i]),
1515 elements + i - first)
1516 : maybe_ge (poly_uint64 (indices[i]), elements)maybe_le (elements, poly_uint64 (indices[i])))
1517 break;
1518 if (i == elements)
1519 {
1520 gimple_assign_set_rhs3 (stmt, mask);
1521 update_stmt (stmt);
1522 return;
1523 }
1524 }
1525 }
1526 else if (can_vec_perm_var_p (TYPE_MODE (vect_type)((((enum tree_code) ((tree_class_check ((vect_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1526, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vect_type) : (vect_type)->type_common.mode)
))
1527 return;
1528
1529 warning_at (loc, OPT_Wvector_operation_performance,
1530 "vector shuffling operation will be expanded piecewise");
1531
1532 vec_alloc (v, elements);
1533 for (i = 0; i < elements; i++)
1534 {
1535 si = size_int (i)size_int_kind (i, stk_sizetype);
1536 i_val = vector_element (gsi, mask, si, &masktmp);
1537
1538 if (TREE_CODE (i_val)((enum tree_code) (i_val)->base.code) == INTEGER_CST)
1539 {
1540 unsigned HOST_WIDE_INTlong index;
1541
1542 index = TREE_INT_CST_LOW (i_val)((unsigned long) (*tree_int_cst_elt_check ((i_val), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1542, __FUNCTION__)))
;
1543 if (!tree_fits_uhwi_p (i_val) || index >= elements)
1544 i_val = build_int_cst (mask_elt_type, index & (elements - 1));
1545
1546 if (two_operand_p && (index & elements) != 0)
1547 t = vector_element (gsi, vec1, i_val, &vec1tmp);
1548 else
1549 t = vector_element (gsi, vec0, i_val, &vec0tmp);
1550
1551 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE(tree) nullptr,
1552 true, GSI_SAME_STMT);
1553 }
1554 else
1555 {
1556 tree cond = NULL_TREE(tree) nullptr, v0_val;
1557
1558 if (two_operand_p)
1559 {
1560 cond = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,fold_build2_loc (((location_t) 0), BIT_AND_EXPR, mask_elt_type
, i_val, build_int_cst (mask_elt_type, elements) )
1561 build_int_cst (mask_elt_type, elements))fold_build2_loc (((location_t) 0), BIT_AND_EXPR, mask_elt_type
, i_val, build_int_cst (mask_elt_type, elements) )
;
1562 cond = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE(tree) nullptr,
1563 true, GSI_SAME_STMT);
1564 }
1565
1566 i_val = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,fold_build2_loc (((location_t) 0), BIT_AND_EXPR, mask_elt_type
, i_val, build_int_cst (mask_elt_type, elements - 1) )
1567 build_int_cst (mask_elt_type, elements - 1))fold_build2_loc (((location_t) 0), BIT_AND_EXPR, mask_elt_type
, i_val, build_int_cst (mask_elt_type, elements - 1) )
;
1568 i_val = force_gimple_operand_gsi (gsi, i_val, true, NULL_TREE(tree) nullptr,
1569 true, GSI_SAME_STMT);
1570
1571 v0_val = vector_element (gsi, vec0, i_val, &vec0tmp);
1572 v0_val = force_gimple_operand_gsi (gsi, v0_val, true, NULL_TREE(tree) nullptr,
1573 true, GSI_SAME_STMT);
1574
1575 if (two_operand_p)
1576 {
1577 tree v1_val;
1578
1579 v1_val = vector_element (gsi, vec1, i_val, &vec1tmp);
1580 v1_val = force_gimple_operand_gsi (gsi, v1_val, true, NULL_TREE(tree) nullptr,
1581 true, GSI_SAME_STMT);
1582
1583 cond = fold_build2 (EQ_EXPR, boolean_type_node,fold_build2_loc (((location_t) 0), EQ_EXPR, global_trees[TI_BOOLEAN_TYPE
], cond, build_zero_cst (mask_elt_type) )
1584 cond, build_zero_cst (mask_elt_type))fold_build2_loc (((location_t) 0), EQ_EXPR, global_trees[TI_BOOLEAN_TYPE
], cond, build_zero_cst (mask_elt_type) )
;
1585 cond = fold_build3 (COND_EXPR, vect_elt_type,fold_build3_loc (((location_t) 0), COND_EXPR, vect_elt_type, cond
, v0_val, v1_val )
1586 cond, v0_val, v1_val)fold_build3_loc (((location_t) 0), COND_EXPR, vect_elt_type, cond
, v0_val, v1_val )
;
1587 t = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE(tree) nullptr,
1588 true, GSI_SAME_STMT);
1589 }
1590 else
1591 t = v0_val;
1592 }
1593
1594 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t)do { constructor_elt _ce___ = {(tree) nullptr, t}; vec_safe_push
((v), _ce___); } while (0)
;
1595 }
1596
1597 constr = build_constructor (vect_type, v);
1598 gimple_assign_set_rhs_from_tree (gsi, constr);
1599 update_stmt (gsi_stmt (*gsi));
1600}
1601
1602/* If OP is a uniform vector return the element it is a splat from. */
1603
1604static tree
1605ssa_uniform_vector_p (tree op)
1606{
1607 if (TREE_CODE (op)((enum tree_code) (op)->base.code) == VECTOR_CST
1608 || TREE_CODE (op)((enum tree_code) (op)->base.code) == VEC_DUPLICATE_EXPR
1609 || TREE_CODE (op)((enum tree_code) (op)->base.code) == CONSTRUCTOR)
1610 return uniform_vector_p (op);
1611 if (TREE_CODE (op)((enum tree_code) (op)->base.code) == SSA_NAME)
1612 {
1613 gimple *def_stmt = SSA_NAME_DEF_STMT (op)(tree_check ((op), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1613, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1614 if (gimple_assign_single_p (def_stmt))
1615 return uniform_vector_p (gimple_assign_rhs1 (def_stmt));
1616 }
1617 return NULL_TREE(tree) nullptr;
1618}
1619
1620/* Return type in which CODE operation with optab OP can be
1621 computed. */
1622
1623static tree
1624get_compute_type (enum tree_code code, optab op, tree type)
1625{
1626 /* For very wide vectors, try using a smaller vector mode. */
1627 tree compute_type = type;
1628 if (op
1629 && (!VECTOR_MODE_P (TYPE_MODE (type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_BOOL ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_INT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1629, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UACCUM
)
1630 || optab_handler (op, TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1630, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
) == CODE_FOR_nothing))
1631 {
1632 tree vector_compute_type
1633 = type_for_widest_vector_mode (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1633, __FUNCTION__))->typed.type)
, op);
1634 if (vector_compute_type != NULL_TREE(tree) nullptr
1635 && subparts_gt (compute_type, vector_compute_type)
1636 && maybe_ne (TYPE_VECTOR_SUBPARTS (vector_compute_type), 1U)
1637 && (optab_handler (op, TYPE_MODE (vector_compute_type)((((enum tree_code) ((tree_class_check ((vector_compute_type)
, (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1637, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vector_compute_type) : (vector_compute_type)->type_common
.mode)
)
1638 != CODE_FOR_nothing))
1639 compute_type = vector_compute_type;
1640 }
1641
1642 /* If we are breaking a BLKmode vector into smaller pieces,
1643 type_for_widest_vector_mode has already looked into the optab,
1644 so skip these checks. */
1645 if (compute_type == type)
1646 {
1647 machine_mode compute_mode = TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1647, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
;
1648 if (VECTOR_MODE_P (compute_mode)(((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_BOOL
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_INT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UACCUM
)
)
1649 {
1650 if (op && optab_handler (op, compute_mode) != CODE_FOR_nothing)
1651 return compute_type;
1652 if (code == MULT_HIGHPART_EXPR
1653 && can_mult_highpart_p (compute_mode,
1654 TYPE_UNSIGNED (compute_type)((tree_class_check ((compute_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1654, __FUNCTION__))->base.u.bits.unsigned_flag)
))
1655 return compute_type;
1656 }
1657 /* There is no operation in hardware, so fall back to scalars. */
1658 compute_type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1658, __FUNCTION__))->typed.type)
;
1659 }
1660
1661 return compute_type;
1662}
1663
1664static tree
1665do_cond (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
1666 tree bitpos, tree bitsize, enum tree_code code,
1667 tree type ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
1668{
1669 if (TREE_CODE (TREE_TYPE (a))((enum tree_code) (((contains_struct_check ((a), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1669, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
1670 a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
1671 if (TREE_CODE (TREE_TYPE (b))((enum tree_code) (((contains_struct_check ((b), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1671, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
1672 b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
1673 tree cond = gimple_assign_rhs1 (gsi_stmt (*gsi));
1674 return gimplify_build3 (gsi, code, inner_type, unshare_expr (cond), a, b);
1675}
1676
1677/* Expand a vector COND_EXPR to scalars, piecewise. */
1678static void
1679expand_vector_scalar_condition (gimple_stmt_iterator *gsi)
1680{
1681 gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1682 tree type = gimple_expr_type (stmt);
1683 tree compute_type = get_compute_type (COND_EXPR, mov_optab, type);
1684 machine_mode compute_mode = TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1684, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
;
1685 gcc_assert (compute_mode != BLKmode)((void)(!(compute_mode != ((void) 0, E_BLKmode)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1685, __FUNCTION__), 0 : 0))
;
1686 tree lhs = gimple_assign_lhs (stmt);
1687 tree rhs2 = gimple_assign_rhs2 (stmt);
1688 tree rhs3 = gimple_assign_rhs3 (stmt);
1689 tree new_rhs;
1690
1691 /* If the compute mode is not a vector mode (hence we are not decomposing
1692 a BLKmode vector to smaller, hardware-supported vectors), we may want
1693 to expand the operations in parallel. */
1694 if (!VECTOR_MODE_P (compute_mode)(((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_BOOL
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_INT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[compute_mode]) == MODE_VECTOR_UACCUM
)
)
1695 new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3,
1696 COND_EXPR);
1697 else
1698 new_rhs = expand_vector_piecewise (gsi, do_cond, type, compute_type,
1699 rhs2, rhs3, COND_EXPR);
1700 if (!useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1700, __FUNCTION__))->typed.type)
, TREE_TYPE (new_rhs)((contains_struct_check ((new_rhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1700, __FUNCTION__))->typed.type)
))
1701 new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1701, __FUNCTION__))->typed.type)
,
1702 new_rhs);
1703
1704 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
1705 way to do it is change expand_vector_operation and its callees to
1706 return a tree_code, RHS1 and RHS2 instead of a tree. */
1707 gimple_assign_set_rhs_from_tree (gsi, new_rhs);
1708 update_stmt (gsi_stmt (*gsi));
1709}
1710
1711/* Callback for expand_vector_piecewise to do VEC_CONVERT ifn call
1712 lowering. If INNER_TYPE is not a vector type, this is a scalar
1713 fallback. */
1714
1715static tree
1716do_vec_conversion (gimple_stmt_iterator *gsi, tree inner_type, tree a,
1717 tree decl, tree bitpos, tree bitsize,
1718 enum tree_code code, tree type)
1719{
1720 a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
1721 if (!VECTOR_TYPE_P (inner_type)(((enum tree_code) (inner_type)->base.code) == VECTOR_TYPE
)
)
1722 return gimplify_build1 (gsi, code, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1722, __FUNCTION__))->typed.type)
, a);
1723 if (code == CALL_EXPR)
1724 {
1725 gimple *g = gimple_build_call (decl, 1, a);
1726 tree lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (decl))((contains_struct_check ((((contains_struct_check ((decl), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1726, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1726, __FUNCTION__))->typed.type)
);
1727 gimple_call_set_lhs (g, lhs);
1728 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1729 return lhs;
1730 }
1731 else
1732 {
1733 tree outer_type = build_vector_type (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1733, __FUNCTION__))->typed.type)
,
1734 TYPE_VECTOR_SUBPARTS (inner_type));
1735 return gimplify_build1 (gsi, code, outer_type, a);
1736 }
1737}
1738
1739/* Similarly, but for narrowing conversion. */
1740
1741static tree
1742do_vec_narrow_conversion (gimple_stmt_iterator *gsi, tree inner_type, tree a,
1743 tree, tree bitpos, tree, enum tree_code code,
1744 tree type)
1745{
1746 tree itype = build_vector_type (TREE_TYPE (inner_type)((contains_struct_check ((inner_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1746, __FUNCTION__))->typed.type)
,
1747 exact_div (TYPE_VECTOR_SUBPARTS (inner_type),
1748 2));
1749 tree b = tree_vec_extract (gsi, itype, a, TYPE_SIZE (itype)((tree_class_check ((itype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1749, __FUNCTION__))->type_common.size)
, bitpos);
1750 tree c = tree_vec_extract (gsi, itype, a, TYPE_SIZE (itype)((tree_class_check ((itype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1750, __FUNCTION__))->type_common.size)
,
1751 int_const_binop (PLUS_EXPR, bitpos,
1752 TYPE_SIZE (itype)((tree_class_check ((itype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1752, __FUNCTION__))->type_common.size)
));
1753 tree outer_type = build_vector_type (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1753, __FUNCTION__))->typed.type)
,
1754 TYPE_VECTOR_SUBPARTS (inner_type));
1755 return gimplify_build2 (gsi, code, outer_type, b, c);
1756}
1757
1758/* Expand VEC_CONVERT ifn call. */
1759
1760static void
1761expand_vector_conversion (gimple_stmt_iterator *gsi)
1762{
1763 gimple *stmt = gsi_stmt (*gsi);
1764 gimple *g;
1765 tree lhs = gimple_call_lhs (stmt);
1766 if (lhs == NULL_TREE(tree) nullptr)
1
Assuming the condition is false
2
Taking false branch
1767 {
1768 g = gimple_build_nop ();
1769 gsi_replace (gsi, g, false);
1770 return;
1771 }
1772 tree arg = gimple_call_arg (stmt, 0);
1773 tree ret_type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1773, __FUNCTION__))->typed.type)
;
1774 tree arg_type = TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1774, __FUNCTION__))->typed.type)
;
1775 tree new_rhs, compute_type = TREE_TYPE (arg_type)((contains_struct_check ((arg_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1775, __FUNCTION__))->typed.type)
;
1776 enum tree_code code = NOP_EXPR;
1777 enum tree_code code1 = ERROR_MARK;
1778 enum { NARROW, NONE, WIDEN } modifier = NONE;
1779 optab optab1 = unknown_optab;
1780
1781 gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type))((void)(!((((enum tree_code) (ret_type)->base.code) == VECTOR_TYPE
) && (((enum tree_code) (arg_type)->base.code) == VECTOR_TYPE
)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1781, __FUNCTION__), 0 : 0))
;
3
Assuming field 'code' is equal to VECTOR_TYPE
4
Assuming field 'code' is equal to VECTOR_TYPE
5
'?' condition is false
1782 if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))(((enum tree_code) (((contains_struct_check ((ret_type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1782, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((ret_type), (
TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1782, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((ret_type), (
TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1782, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
6
Assuming field 'code' is not equal to ENUMERAL_TYPE
7
Assuming field 'code' is not equal to BOOLEAN_TYPE
8
Assuming field 'code' is not equal to INTEGER_TYPE
1783 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type))(((enum tree_code) (((contains_struct_check ((arg_type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1783, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
)
1784 code = FIX_TRUNC_EXPR;
1785 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type))(((enum tree_code) (((contains_struct_check ((arg_type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1785, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg_type), (
TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1785, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg_type), (
TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1785, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
9
Assuming field 'code' is not equal to ENUMERAL_TYPE
10
Assuming field 'code' is not equal to BOOLEAN_TYPE
11
Assuming field 'code' is not equal to INTEGER_TYPE
1786 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type))(((enum tree_code) (((contains_struct_check ((ret_type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1786, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
)
1787 code = FLOAT_EXPR;
1788 unsigned int ret_elt_bits = vector_element_bits (ret_type);
1789 unsigned int arg_elt_bits = vector_element_bits (arg_type);
1790 if (ret_elt_bits < arg_elt_bits)
12
Assuming 'ret_elt_bits' is >= 'arg_elt_bits'
13
Taking false branch
1791 modifier = NARROW;
1792 else if (ret_elt_bits > arg_elt_bits)
14
Assuming 'ret_elt_bits' is > 'arg_elt_bits'
15
Taking true branch
1793 modifier = WIDEN;
1794
1795 if (modifier
15.1
'modifier' is not equal to NONE
15.1
'modifier' is not equal to NONE
== NONE && (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR))
1796 {
1797 if (supportable_convert_operation (code, ret_type, arg_type, &code1))
1798 {
1799 g = gimple_build_assign (lhs, code1, arg);
1800 gsi_replace (gsi, g, false);
1801 return;
1802 }
1803 /* Can't use get_compute_type here, as supportable_convert_operation
1804 doesn't necessarily use an optab and needs two arguments. */
1805 tree vec_compute_type
1806 = type_for_widest_vector_mode (TREE_TYPE (arg_type)((contains_struct_check ((arg_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1806, __FUNCTION__))->typed.type)
, mov_optab);
1807 if (vec_compute_type
1808 && VECTOR_MODE_P (TYPE_MODE (vec_compute_type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((vec_compute_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[(((
(enum tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[(((
(enum tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[((
((enum tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[(((
(enum tree_code) ((tree_class_check ((vec_compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1808, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vec_compute_type) : (vec_compute_type)->type_common.mode
)]) == MODE_VECTOR_UACCUM)
1809 && subparts_gt (arg_type, vec_compute_type))
1810 {
1811 unsigned HOST_WIDE_INTlong nelts
1812 = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vec_compute_type));
1813 while (nelts > 1)
1814 {
1815 tree ret1_type = build_vector_type (TREE_TYPE (ret_type)((contains_struct_check ((ret_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1815, __FUNCTION__))->typed.type)
, nelts);
1816 tree arg1_type = build_vector_type (TREE_TYPE (arg_type)((contains_struct_check ((arg_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1816, __FUNCTION__))->typed.type)
, nelts);
1817 if (supportable_convert_operation (code, ret1_type, arg1_type,
1818 &code1))
1819 {
1820 new_rhs = expand_vector_piecewise (gsi, do_vec_conversion,
1821 ret_type, arg1_type, arg,
1822 NULL_TREE(tree) nullptr, code1);
1823 g = gimple_build_assign (lhs, new_rhs);
1824 gsi_replace (gsi, g, false);
1825 return;
1826 }
1827 nelts = nelts / 2;
1828 }
1829 }
1830 }
1831 else if (modifier
15.2
'modifier' is not equal to NARROW
15.2
'modifier' is not equal to NARROW
== NARROW)
16
Taking false branch
1832 {
1833 switch (code)
1834 {
1835 CASE_CONVERTcase NOP_EXPR: case CONVERT_EXPR:
1836 code1 = VEC_PACK_TRUNC_EXPR;
1837 optab1 = optab_for_tree_code (code1, arg_type, optab_default);
1838 break;
1839 case FIX_TRUNC_EXPR:
1840 code1 = VEC_PACK_FIX_TRUNC_EXPR;
1841 /* The signedness is determined from output operand. */
1842 optab1 = optab_for_tree_code (code1, ret_type, optab_default);
1843 break;
1844 case FLOAT_EXPR:
1845 code1 = VEC_PACK_FLOAT_EXPR;
1846 optab1 = optab_for_tree_code (code1, arg_type, optab_default);
1847 break;
1848 default:
1849 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1849, __FUNCTION__))
;
1850 }
1851
1852 if (optab1)
1853 compute_type = get_compute_type (code1, optab1, arg_type);
1854 enum insn_code icode1;
1855 if (VECTOR_TYPE_P (compute_type)(((enum tree_code) (compute_type)->base.code) == VECTOR_TYPE
)
1856 && ((icode1 = optab_handler (optab1, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1856, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
))
1857 != CODE_FOR_nothing)
1858 && VECTOR_MODE_P (insn_data[icode1].operand[0].mode)(((enum mode_class) mode_class[insn_data[icode1].operand[0].mode
]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[insn_data
[icode1].operand[0].mode]) == MODE_VECTOR_INT || ((enum mode_class
) mode_class[insn_data[icode1].operand[0].mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[insn_data[icode1].operand[0
].mode]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class
[insn_data[icode1].operand[0].mode]) == MODE_VECTOR_UFRACT ||
((enum mode_class) mode_class[insn_data[icode1].operand[0].mode
]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[insn_data
[icode1].operand[0].mode]) == MODE_VECTOR_UACCUM)
)
1859 {
1860 tree cretd_type
1861 = build_vector_type (TREE_TYPE (ret_type)((contains_struct_check ((ret_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1861, __FUNCTION__))->typed.type)
,
1862 TYPE_VECTOR_SUBPARTS (compute_type) * 2);
1863 if (insn_data[icode1].operand[0].mode == TYPE_MODE (cretd_type)((((enum tree_code) ((tree_class_check ((cretd_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1863, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(cretd_type) : (cretd_type)->type_common.mode)
)
1864 {
1865 if (compute_type == arg_type)
1866 {
1867 new_rhs = gimplify_build2 (gsi, code1, cretd_type,
1868 arg, build_zero_cst (arg_type));
1869 new_rhs = tree_vec_extract (gsi, ret_type, new_rhs,
1870 TYPE_SIZE (ret_type)((tree_class_check ((ret_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1870, __FUNCTION__))->type_common.size)
,
1871 bitsize_int (0)size_int_kind (0, stk_bitsizetype));
1872 g = gimple_build_assign (lhs, new_rhs);
1873 gsi_replace (gsi, g, false);
1874 return;
1875 }
1876 tree dcompute_type
1877 = build_vector_type (TREE_TYPE (compute_type)((contains_struct_check ((compute_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1877, __FUNCTION__))->typed.type)
,
1878 TYPE_VECTOR_SUBPARTS (compute_type) * 2);
1879 if (TYPE_MAIN_VARIANT (dcompute_type)((tree_class_check ((dcompute_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1879, __FUNCTION__))->type_common.main_variant)
1880 == TYPE_MAIN_VARIANT (arg_type)((tree_class_check ((arg_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1880, __FUNCTION__))->type_common.main_variant)
)
1881 new_rhs = do_vec_narrow_conversion (gsi, dcompute_type, arg,
1882 NULL_TREE(tree) nullptr, bitsize_int (0)size_int_kind (0, stk_bitsizetype),
1883 NULL_TREE(tree) nullptr, code1,
1884 ret_type);
1885 else
1886 new_rhs = expand_vector_piecewise (gsi,
1887 do_vec_narrow_conversion,
1888 arg_type, dcompute_type,
1889 arg, NULL_TREE(tree) nullptr, code1,
1890 ret_type);
1891 g = gimple_build_assign (lhs, new_rhs);
1892 gsi_replace (gsi, g, false);
1893 return;
1894 }
1895 }
1896 }
1897 else if (modifier
16.1
'modifier' is equal to WIDEN
16.1
'modifier' is equal to WIDEN
== WIDEN)
17
Taking true branch
1898 {
1899 enum tree_code code2 = ERROR_MARK;
1900 optab optab2 = unknown_optab;
1901 switch (code)
18
Control jumps to 'case NOP_EXPR:' at line 1903
1902 {
1903 CASE_CONVERTcase NOP_EXPR: case CONVERT_EXPR:
1904 code1 = VEC_UNPACK_LO_EXPR;
1905 code2 = VEC_UNPACK_HI_EXPR;
1906 break;
19
Execution continues on line 1918
1907 case FIX_TRUNC_EXPR:
1908 code1 = VEC_UNPACK_FIX_TRUNC_LO_EXPR;
1909 code2 = VEC_UNPACK_FIX_TRUNC_HI_EXPR;
1910 break;
1911 case FLOAT_EXPR:
1912 code1 = VEC_UNPACK_FLOAT_LO_EXPR;
1913 code2 = VEC_UNPACK_FLOAT_HI_EXPR;
1914 break;
1915 default:
1916 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1916, __FUNCTION__))
;
1917 }
1918 if (BYTES_BIG_ENDIAN0)
20
Taking false branch
1919 std::swap (code1, code2);
1920
1921 if (code
20.1
'code' is not equal to FIX_TRUNC_EXPR
20.1
'code' is not equal to FIX_TRUNC_EXPR
== FIX_TRUNC_EXPR)
21
Taking false branch
1922 {
1923 /* The signedness is determined from output operand. */
1924 optab1 = optab_for_tree_code (code1, ret_type, optab_default);
1925 optab2 = optab_for_tree_code (code2, ret_type, optab_default);
1926 }
1927 else
1928 {
1929 optab1 = optab_for_tree_code (code1, arg_type, optab_default);
1930 optab2 = optab_for_tree_code (code2, arg_type, optab_default);
1931 }
1932
1933 if (optab1 && optab2)
22
Assuming 'optab1' is not equal to 0
23
Assuming 'optab2' is not equal to 0
24
Taking true branch
1934 compute_type = get_compute_type (code1, optab1, arg_type);
1935
1936 enum insn_code icode1, icode2;
1937 if (VECTOR_TYPE_P (compute_type)(((enum tree_code) (compute_type)->base.code) == VECTOR_TYPE
)
25
Assuming field 'code' is equal to VECTOR_TYPE
32
Taking true branch
1938 && ((icode1 = optab_handler (optab1, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1938, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
))
26
'?' condition is true
27
Assuming the condition is true
1939 != CODE_FOR_nothing)
1940 && ((icode2 = optab_handler (optab2, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1940, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
))
28
'?' condition is true
29
Assuming the condition is true
1941 != CODE_FOR_nothing)
1942 && VECTOR_MODE_P (insn_data[icode1].operand[0].mode)(((enum mode_class) mode_class[insn_data[icode1].operand[0].mode
]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[insn_data
[icode1].operand[0].mode]) == MODE_VECTOR_INT || ((enum mode_class
) mode_class[insn_data[icode1].operand[0].mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[insn_data[icode1].operand[0
].mode]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class
[insn_data[icode1].operand[0].mode]) == MODE_VECTOR_UFRACT ||
((enum mode_class) mode_class[insn_data[icode1].operand[0].mode
]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[insn_data
[icode1].operand[0].mode]) == MODE_VECTOR_UACCUM)
30
Assuming the condition is true
1943 && (insn_data[icode1].operand[0].mode
31
Assuming 'insn_data[icode1].operand[0].mode' is equal to 'insn_data[icode2].operand[0].mode'
1944 == insn_data[icode2].operand[0].mode))
1945 {
1946 poly_uint64 nunits
1947 = exact_div (TYPE_VECTOR_SUBPARTS (compute_type), 2);
1948 tree cretd_type = build_vector_type (TREE_TYPE (ret_type)((contains_struct_check ((ret_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1948, __FUNCTION__))->typed.type)
, nunits);
1949 if (insn_data[icode1].operand[0].mode == TYPE_MODE (cretd_type)((((enum tree_code) ((tree_class_check ((cretd_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1949, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(cretd_type) : (cretd_type)->type_common.mode)
)
33
Assuming field 'code' is not equal to VECTOR_TYPE
34
'?' condition is false
35
Assuming the condition is true
36
Taking true branch
1950 {
1951 vec<constructor_elt, va_gc> *v;
1952 tree part_width = TYPE_SIZE (compute_type)((tree_class_check ((compute_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1952, __FUNCTION__))->type_common.size)
;
1953 tree index = bitsize_int (0)size_int_kind (0, stk_bitsizetype);
1954 int nunits = nunits_for_known_piecewise_op (arg_type);
1955 int delta = tree_to_uhwi (part_width) / arg_elt_bits;
1956 int i;
1957 location_t loc = gimple_location (gsi_stmt (*gsi));
1958
1959 if (compute_type != arg_type)
37
Assuming 'compute_type' is not equal to 'arg_type'
38
Taking true branch
1960 warning_at (loc, OPT_Wvector_operation_performance,
1961 "vector operation will be expanded piecewise");
1962 else
1963 {
1964 nunits = 1;
1965 delta = 1;
1966 }
1967
1968 vec_alloc (v, (nunits + delta - 1) / delta * 2);
39
Calling 'vec_alloc<constructor_elt, va_gc>'
47
Returning from 'vec_alloc<constructor_elt, va_gc>'
1969 for (i = 0; i < nunits;
48
Assuming 'i' is < 'nunits'
49
Loop condition is true. Entering loop body
1970 i += delta, index = int_const_binop (PLUS_EXPR, index,
1971 part_width))
1972 {
1973 tree a = arg;
1974 if (compute_type
49.1
'compute_type' is not equal to 'arg_type'
49.1
'compute_type' is not equal to 'arg_type'
!= arg_type)
50
Taking true branch
1975 a = tree_vec_extract (gsi, compute_type, a, part_width,
1976 index);
1977 tree result = gimplify_build1 (gsi, code1, cretd_type, a);
1978 constructor_elt ce = { NULL_TREE(tree) nullptr, result };
1979 v->quick_push (ce);
51
Called C++ object pointer is null
1980 ce.value = gimplify_build1 (gsi, code2, cretd_type, a);
1981 v->quick_push (ce);
1982 }
1983
1984 new_rhs = build_constructor (ret_type, v);
1985 g = gimple_build_assign (lhs, new_rhs);
1986 gsi_replace (gsi, g, false);
1987 return;
1988 }
1989 }
1990 }
1991
1992 new_rhs = expand_vector_piecewise (gsi, do_vec_conversion, arg_type,
1993 TREE_TYPE (arg_type)((contains_struct_check ((arg_type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 1993, __FUNCTION__))->typed.type)
, arg,
1994 NULL_TREE(tree) nullptr, code, ret_type);
1995 g = gimple_build_assign (lhs, new_rhs);
1996 gsi_replace (gsi, g, false);
1997}
1998
1999/* Process one statement. If we identify a vector operation, expand it. */
2000
2001static void
2002expand_vector_operations_1 (gimple_stmt_iterator *gsi,
2003 bitmap dce_ssa_names)
2004{
2005 tree lhs, rhs1, rhs2 = NULLnullptr, type, compute_type = NULL_TREE(tree) nullptr;
2006 enum tree_code code;
2007 optab op = unknown_optab;
2008 enum gimple_rhs_class rhs_class;
2009 tree new_rhs;
2010
2011 /* Only consider code == GIMPLE_ASSIGN. */
2012 gassign *stmt = dyn_cast <gassign *> (gsi_stmt (*gsi));
2013 if (!stmt)
2014 {
2015 if (gimple_call_internal_p (gsi_stmt (*gsi), IFN_VEC_CONVERT))
2016 expand_vector_conversion (gsi);
2017 return;
2018 }
2019
2020 code = gimple_assign_rhs_code (stmt);
2021 rhs_class = get_gimple_rhs_class (code);
2022 lhs = gimple_assign_lhs (stmt);
2023
2024 if (code == VEC_PERM_EXPR)
2025 {
2026 lower_vec_perm (gsi);
2027 return;
2028 }
2029
2030 if (code == VEC_COND_EXPR)
2031 {
2032 expand_vector_condition (gsi, dce_ssa_names);
2033 return;
2034 }
2035
2036 if (code == COND_EXPR
2037 && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt)))((enum tree_code) (((contains_struct_check ((gimple_assign_lhs
(stmt)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2037, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE
2038 && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((gimple_assign_lhs (stmt)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2038, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2038, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((gimple_assign_lhs (stmt)), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2038, __FUNCTION__))->typed.type)) : (((contains_struct_check
((gimple_assign_lhs (stmt)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2038, __FUNCTION__))->typed.type))->type_common.mode)
== BLKmode((void) 0, E_BLKmode))
2039 {
2040 expand_vector_scalar_condition (gsi);
2041 return;
2042 }
2043
2044 if (code == CONSTRUCTOR
2045 && TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME
2046 && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((((contains_struct_check ((lhs
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((((contains_struct_check ((lhs
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[(((
(enum tree_code) ((tree_class_check ((((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2046, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_UACCUM)
2047 && !gimple_clobber_p (stmt)
2048 && optimizeglobal_options.x_optimize)
2049 {
2050 optimize_vector_constructor (gsi);
2051 return;
2052 }
2053
2054 if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
2055 return;
2056
2057 rhs1 = gimple_assign_rhs1 (stmt);
2058 type = gimple_expr_type (stmt);
2059 if (rhs_class == GIMPLE_BINARY_RHS)
2060 rhs2 = gimple_assign_rhs2 (stmt);
2061
2062 if (!VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)
2063 || !VECTOR_TYPE_P (TREE_TYPE (rhs1))(((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2063, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
)
)
2064 return;
2065
2066 /* A scalar operation pretending to be a vector one. */
2067 if (VECTOR_BOOLEAN_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2067, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
2068 && !VECTOR_MODE_P (TYPE_MODE (type))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_BOOL ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_INT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2068, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_VECTOR_UACCUM
)
2069 && TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2069, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)
!= BLKmode((void) 0, E_BLKmode)
2070 && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))tree_code_type[(int) (gimple_assign_rhs_code (stmt))] != tcc_comparison
2071 || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1))(((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2071, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
&& ((enum tree_code) (((contains_struct_check ((((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2071, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2071, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
2072 && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1)))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((((contains_struct_check ((rhs1
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((((contains_struct_check ((rhs1
), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[(((
(enum tree_code) ((tree_class_check ((((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[((((
enum tree_code) ((tree_class_check ((((contains_struct_check (
(rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2072, __FUNCTION__))->typed.type))->type_common.mode)
]) == MODE_VECTOR_UACCUM)
2073 && TYPE_MODE (TREE_TYPE (rhs1))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2073, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2073, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2073, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2073, __FUNCTION__))->typed.type))->type_common.mode)
!= BLKmode((void) 0, E_BLKmode))))
2074 return;
2075
2076 /* If the vector operation is operating on all same vector elements
2077 implement it with a scalar operation and a splat if the target
2078 supports the scalar operation. */
2079 tree srhs1, srhs2 = NULL_TREE(tree) nullptr;
2080 if ((srhs1 = ssa_uniform_vector_p (rhs1)) != NULL_TREE(tree) nullptr
2081 && (rhs2 == NULL_TREE(tree) nullptr
2082 || (! VECTOR_TYPE_P (TREE_TYPE (rhs2))(((enum tree_code) (((contains_struct_check ((rhs2), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2082, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
)
2083 && (srhs2 = rhs2))
2084 || (srhs2 = ssa_uniform_vector_p (rhs2)) != NULL_TREE(tree) nullptr)
2085 /* As we query direct optabs restrict to non-convert operations. */
2086 && TYPE_MODE (TREE_TYPE (type))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type)) : (((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type))->type_common.mode)
== TYPE_MODE (TREE_TYPE (srhs1))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((srhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((srhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type)) : (((contains_struct_check
((srhs1), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2086, __FUNCTION__))->typed.type))->type_common.mode)
)
2087 {
2088 op = optab_for_tree_code (code, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2088, __FUNCTION__))->typed.type)
, optab_scalar);
2089 if (op >= FIRST_NORM_OPTAB && op <= LAST_NORM_OPTAB
2090 && optab_handler (op, TYPE_MODE (TREE_TYPE (type))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2090, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2090, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2090, __FUNCTION__))->typed.type)) : (((contains_struct_check
((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2090, __FUNCTION__))->typed.type))->type_common.mode)
) != CODE_FOR_nothing)
2091 {
2092 tree slhs = make_ssa_name (TREE_TYPE (TREE_TYPE (lhs))((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2092, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2092, __FUNCTION__))->typed.type)
);
2093 gimple *repl = gimple_build_assign (slhs, code, srhs1, srhs2);
2094 gsi_insert_before (gsi, repl, GSI_SAME_STMT);
2095 gimple_assign_set_rhs_from_tree (gsi,
2096 build_vector_from_val (type, slhs));
2097 update_stmt (stmt);
2098 return;
2099 }
2100 }
2101
2102 if (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR)
2103 || code == FLOAT_EXPR
2104 || code == FIX_TRUNC_EXPR
2105 || code == VIEW_CONVERT_EXPR)
2106 return;
2107
2108 /* The signedness is determined from input argument. */
2109 if (code == VEC_UNPACK_FLOAT_HI_EXPR
2110 || code == VEC_UNPACK_FLOAT_LO_EXPR
2111 || code == VEC_PACK_FLOAT_EXPR)
2112 {
2113 /* We do not know how to scalarize those. */
2114 return;
2115 }
2116
2117 /* For widening/narrowing vector operations, the relevant type is of the
2118 arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
2119 calculated in the same way above. */
2120 if (code == WIDEN_SUM_EXPR
2121 || code == VEC_WIDEN_PLUS_HI_EXPR
2122 || code == VEC_WIDEN_PLUS_LO_EXPR
2123 || code == VEC_WIDEN_MINUS_HI_EXPR
2124 || code == VEC_WIDEN_MINUS_LO_EXPR
2125 || code == VEC_WIDEN_MULT_HI_EXPR
2126 || code == VEC_WIDEN_MULT_LO_EXPR
2127 || code == VEC_WIDEN_MULT_EVEN_EXPR
2128 || code == VEC_WIDEN_MULT_ODD_EXPR
2129 || code == VEC_UNPACK_HI_EXPR
2130 || code == VEC_UNPACK_LO_EXPR
2131 || code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
2132 || code == VEC_UNPACK_FIX_TRUNC_LO_EXPR
2133 || code == VEC_PACK_TRUNC_EXPR
2134 || code == VEC_PACK_SAT_EXPR
2135 || code == VEC_PACK_FIX_TRUNC_EXPR
2136 || code == VEC_WIDEN_LSHIFT_HI_EXPR
2137 || code == VEC_WIDEN_LSHIFT_LO_EXPR)
2138 {
2139 /* We do not know how to scalarize those. */
2140 return;
2141 }
2142
2143 /* Choose between vector shift/rotate by vector and vector shift/rotate by
2144 scalar */
2145 if (code == LSHIFT_EXPR
2146 || code == RSHIFT_EXPR
2147 || code == LROTATE_EXPR
2148 || code == RROTATE_EXPR)
2149 {
2150 optab opv;
2151
2152 /* Check whether we have vector <op> {x,x,x,x} where x
2153 could be a scalar variable or a constant. Transform
2154 vector <op> {x,x,x,x} ==> vector <op> scalar. */
2155 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2))((((enum tree_code) (((contains_struct_check ((rhs2), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2155, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
) && ((enum tree_code) (((contains_struct_check ((((contains_struct_check
((rhs2), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2155, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2155, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
2156 {
2157 tree first;
2158
2159 if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE(tree) nullptr)
2160 {
2161 gimple_assign_set_rhs2 (stmt, first);
2162 update_stmt (stmt);
2163 rhs2 = first;
2164 }
2165 }
2166
2167 opv = optab_for_tree_code (code, type, optab_vector);
2168 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2))((((enum tree_code) (((contains_struct_check ((rhs2), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2168, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
) && ((enum tree_code) (((contains_struct_check ((((contains_struct_check
((rhs2), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2168, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2168, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
2169 op = opv;
2170 else
2171 {
2172 op = optab_for_tree_code (code, type, optab_scalar);
2173
2174 compute_type = get_compute_type (code, op, type);
2175 if (compute_type == type)
2176 return;
2177 /* The rtl expander will expand vector/scalar as vector/vector
2178 if necessary. Pick one with wider vector type. */
2179 tree compute_vtype = get_compute_type (code, opv, type);
2180 if (subparts_gt (compute_vtype, compute_type))
2181 {
2182 compute_type = compute_vtype;
2183 op = opv;
2184 }
2185 }
2186
2187 if (code == LROTATE_EXPR || code == RROTATE_EXPR)
2188 {
2189 if (compute_type == NULL_TREE(tree) nullptr)
2190 compute_type = get_compute_type (code, op, type);
2191 if (compute_type == type)
2192 return;
2193 /* Before splitting vector rotates into scalar rotates,
2194 see if we can't use vector shifts and BIT_IOR_EXPR
2195 instead. For vector by vector rotates we'd also
2196 need to check BIT_AND_EXPR and NEGATE_EXPR, punt there
2197 for now, fold doesn't seem to create such rotates anyway. */
2198 if (compute_type == TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2198, __FUNCTION__))->typed.type)
2199 && !VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2))((((enum tree_code) (((contains_struct_check ((rhs2), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2199, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
) && ((enum tree_code) (((contains_struct_check ((((contains_struct_check
((rhs2), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2199, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2199, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
2200 {
2201 optab oplv = vashl_optab, opl = ashl_optab;
2202 optab oprv = vlshr_optab, opr = lshr_optab, opo = ior_optab;
2203 tree compute_lvtype = get_compute_type (LSHIFT_EXPR, oplv, type);
2204 tree compute_rvtype = get_compute_type (RSHIFT_EXPR, oprv, type);
2205 tree compute_otype = get_compute_type (BIT_IOR_EXPR, opo, type);
2206 tree compute_ltype = get_compute_type (LSHIFT_EXPR, opl, type);
2207 tree compute_rtype = get_compute_type (RSHIFT_EXPR, opr, type);
2208 /* The rtl expander will expand vector/scalar as vector/vector
2209 if necessary. Pick one with wider vector type. */
2210 if (subparts_gt (compute_lvtype, compute_ltype))
2211 {
2212 compute_ltype = compute_lvtype;
2213 opl = oplv;
2214 }
2215 if (subparts_gt (compute_rvtype, compute_rtype))
2216 {
2217 compute_rtype = compute_rvtype;
2218 opr = oprv;
2219 }
2220 /* Pick the narrowest type from LSHIFT_EXPR, RSHIFT_EXPR and
2221 BIT_IOR_EXPR. */
2222 compute_type = compute_ltype;
2223 if (subparts_gt (compute_type, compute_rtype))
2224 compute_type = compute_rtype;
2225 if (subparts_gt (compute_type, compute_otype))
2226 compute_type = compute_otype;
2227 /* Verify all 3 operations can be performed in that type. */
2228 if (compute_type != TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2228, __FUNCTION__))->typed.type)
)
2229 {
2230 if (optab_handler (opl, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2230, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
)
2231 == CODE_FOR_nothing
2232 || optab_handler (opr, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2232, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
)
2233 == CODE_FOR_nothing
2234 || optab_handler (opo, TYPE_MODE (compute_type)((((enum tree_code) ((tree_class_check ((compute_type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2234, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(compute_type) : (compute_type)->type_common.mode)
)
2235 == CODE_FOR_nothing)
2236 compute_type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2236, __FUNCTION__))->typed.type)
;
2237 }
2238 }
2239 }
2240 }
2241 else
2242 op = optab_for_tree_code (code, type, optab_default);
2243
2244 /* Optabs will try converting a negation into a subtraction, so
2245 look for it as well. TODO: negation of floating-point vectors
2246 might be turned into an exclusive OR toggling the sign bit. */
2247 if (op == unknown_optab
2248 && code == NEGATE_EXPR
2249 && INTEGRAL_TYPE_P (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2249, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2249, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2249, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
2250 op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
2251
2252 if (compute_type == NULL_TREE(tree) nullptr)
2253 compute_type = get_compute_type (code, op, type);
2254 if (compute_type == type)
2255 return;
2256
2257 new_rhs = expand_vector_operation (gsi, type, compute_type, stmt, code,
2258 dce_ssa_names);
2259
2260 /* Leave expression untouched for later expansion. */
2261 if (new_rhs == NULL_TREE(tree) nullptr)
2262 return;
2263
2264 if (!useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2264, __FUNCTION__))->typed.type)
, TREE_TYPE (new_rhs)((contains_struct_check ((new_rhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2264, __FUNCTION__))->typed.type)
))
2265 new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-vect-generic.c"
, 2265, __FUNCTION__))->typed.type)
,
2266 new_rhs);
2267
2268 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
2269 way to do it is change expand_vector_operation and its callees to
2270 return a tree_code, RHS1 and RHS2 instead of a tree. */
2271 gimple_assign_set_rhs_from_tree (gsi, new_rhs);
2272 update_stmt (gsi_stmt (*gsi));
2273}
2274
2275/* Use this to lower vector operations introduced by the vectorizer,
2276 if it may need the bit-twiddling tricks implemented in this file. */
2277
2278static unsigned int
2279expand_vector_operations (void)
2280{
2281 gimple_stmt_iterator gsi;
2282 basic_block bb;
2283 bool cfg_changed = false;
2284
2285 auto_bitmap dce_ssa_names;
2286
2287 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
2288 {
2289 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2290 {
2291 expand_vector_operations_1 (&gsi, dce_ssa_names);
2292 /* ??? If we do not cleanup EH then we will ICE in
2293 verification. But in reality we have created wrong-code
2294 as we did not properly transition EH info and edges to
2295 the piecewise computations. */
2296 if (maybe_clean_eh_stmt (gsi_stmt (gsi))
2297 && gimple_purge_dead_eh_edges (bb))
2298 cfg_changed = true;
2299 }
2300 }
2301
2302 simple_dce_from_worklist (dce_ssa_names);
2303
2304 return cfg_changed ? TODO_cleanup_cfg(1 << 5) : 0;
2305}
2306
2307namespace {
2308
2309const pass_data pass_data_lower_vector =
2310{
2311 GIMPLE_PASS, /* type */
2312 "veclower", /* name */
2313 OPTGROUP_VEC, /* optinfo_flags */
2314 TV_NONE, /* tv_id */
2315 PROP_cfg(1 << 3), /* properties_required */
2316 PROP_gimple_lvec(1 << 12), /* properties_provided */
2317 0, /* properties_destroyed */
2318 0, /* todo_flags_start */
2319 TODO_update_ssa(1 << 11), /* todo_flags_finish */
2320};
2321
2322class pass_lower_vector : public gimple_opt_pass
2323{
2324public:
2325 pass_lower_vector (gcc::context *ctxt)
2326 : gimple_opt_pass (pass_data_lower_vector, ctxt)
2327 {}
2328
2329 /* opt_pass methods: */
2330 virtual bool gate (function *fun)
2331 {
2332 return !(fun->curr_properties & PROP_gimple_lvec(1 << 12));
2333 }
2334
2335 virtual unsigned int execute (function *)
2336 {
2337 return expand_vector_operations ();
2338 }
2339
2340}; // class pass_lower_vector
2341
2342} // anon namespace
2343
2344gimple_opt_pass *
2345make_pass_lower_vector (gcc::context *ctxt)
2346{
2347 return new pass_lower_vector (ctxt);
2348}
2349
2350namespace {
2351
2352const pass_data pass_data_lower_vector_ssa =
2353{
2354 GIMPLE_PASS, /* type */
2355 "veclower2", /* name */
2356 OPTGROUP_VEC, /* optinfo_flags */
2357 TV_NONE, /* tv_id */
2358 PROP_cfg(1 << 3), /* properties_required */
2359 PROP_gimple_lvec(1 << 12), /* properties_provided */
2360 0, /* properties_destroyed */
2361 0, /* todo_flags_start */
2362 ( TODO_update_ssa(1 << 11)
2363 | TODO_cleanup_cfg(1 << 5) ), /* todo_flags_finish */
2364};
2365
2366class pass_lower_vector_ssa : public gimple_opt_pass
2367{
2368public:
2369 pass_lower_vector_ssa (gcc::context *ctxt)
2370 : gimple_opt_pass (pass_data_lower_vector_ssa, ctxt)
2371 {}
2372
2373 /* opt_pass methods: */
2374 opt_pass * clone () { return new pass_lower_vector_ssa (m_ctxt); }
2375 virtual unsigned int execute (function *)
2376 {
2377 return expand_vector_operations ();
2378 }
2379
2380}; // class pass_lower_vector_ssa
2381
2382} // anon namespace
2383
2384gimple_opt_pass *
2385make_pass_lower_vector_ssa (gcc::context *ctxt)
2386{
2387 return new pass_lower_vector_ssa (ctxt);
2388}
2389
2390#include "gt-tree-vect-generic.h"

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h

1/* Vector API for GNU compiler.
2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#ifndef GCC_VEC_H
23#define GCC_VEC_H
24
25/* Some gen* file have no ggc support as the header file gtype-desc.h is
26 missing. Provide these definitions in case ggc.h has not been included.
27 This is not a problem because any code that runs before gengtype is built
28 will never need to use GC vectors.*/
29
30extern void ggc_free (void *);
31extern size_t ggc_round_alloc_size (size_t requested_size);
32extern void *ggc_realloc (void *, size_t MEM_STAT_DECL);
33
34/* Templated vector type and associated interfaces.
35
36 The interface functions are typesafe and use inline functions,
37 sometimes backed by out-of-line generic functions. The vectors are
38 designed to interoperate with the GTY machinery.
39
40 There are both 'index' and 'iterate' accessors. The index accessor
41 is implemented by operator[]. The iterator returns a boolean
42 iteration condition and updates the iteration variable passed by
43 reference. Because the iterator will be inlined, the address-of
44 can be optimized away.
45
46 Each operation that increases the number of active elements is
47 available in 'quick' and 'safe' variants. The former presumes that
48 there is sufficient allocated space for the operation to succeed
49 (it dies if there is not). The latter will reallocate the
50 vector, if needed. Reallocation causes an exponential increase in
51 vector size. If you know you will be adding N elements, it would
52 be more efficient to use the reserve operation before adding the
53 elements with the 'quick' operation. This will ensure there are at
54 least as many elements as you ask for, it will exponentially
55 increase if there are too few spare slots. If you want reserve a
56 specific number of slots, but do not want the exponential increase
57 (for instance, you know this is the last allocation), use the
58 reserve_exact operation. You can also create a vector of a
59 specific size from the get go.
60
61 You should prefer the push and pop operations, as they append and
62 remove from the end of the vector. If you need to remove several
63 items in one go, use the truncate operation. The insert and remove
64 operations allow you to change elements in the middle of the
65 vector. There are two remove operations, one which preserves the
66 element ordering 'ordered_remove', and one which does not
67 'unordered_remove'. The latter function copies the end element
68 into the removed slot, rather than invoke a memmove operation. The
69 'lower_bound' function will determine where to place an item in the
70 array using insert that will maintain sorted order.
71
72 Vectors are template types with three arguments: the type of the
73 elements in the vector, the allocation strategy, and the physical
74 layout to use
75
76 Four allocation strategies are supported:
77
78 - Heap: allocation is done using malloc/free. This is the
79 default allocation strategy.
80
81 - GC: allocation is done using ggc_alloc/ggc_free.
82
83 - GC atomic: same as GC with the exception that the elements
84 themselves are assumed to be of an atomic type that does
85 not need to be garbage collected. This means that marking
86 routines do not need to traverse the array marking the
87 individual elements. This increases the performance of
88 GC activities.
89
90 Two physical layouts are supported:
91
92 - Embedded: The vector is structured using the trailing array
93 idiom. The last member of the structure is an array of size
94 1. When the vector is initially allocated, a single memory
95 block is created to hold the vector's control data and the
96 array of elements. These vectors cannot grow without
97 reallocation (see discussion on embeddable vectors below).
98
99 - Space efficient: The vector is structured as a pointer to an
100 embedded vector. This is the default layout. It means that
101 vectors occupy a single word of storage before initial
102 allocation. Vectors are allowed to grow (the internal
103 pointer is reallocated but the main vector instance does not
104 need to relocate).
105
106 The type, allocation and layout are specified when the vector is
107 declared.
108
109 If you need to directly manipulate a vector, then the 'address'
110 accessor will return the address of the start of the vector. Also
111 the 'space' predicate will tell you whether there is spare capacity
112 in the vector. You will not normally need to use these two functions.
113
114 Notes on the different layout strategies
115
116 * Embeddable vectors (vec<T, A, vl_embed>)
117
118 These vectors are suitable to be embedded in other data
119 structures so that they can be pre-allocated in a contiguous
120 memory block.
121
122 Embeddable vectors are implemented using the trailing array
123 idiom, thus they are not resizeable without changing the address
124 of the vector object itself. This means you cannot have
125 variables or fields of embeddable vector type -- always use a
126 pointer to a vector. The one exception is the final field of a
127 structure, which could be a vector type.
128
129 You will have to use the embedded_size & embedded_init calls to
130 create such objects, and they will not be resizeable (so the
131 'safe' allocation variants are not available).
132
133 Properties of embeddable vectors:
134
135 - The whole vector and control data are allocated in a single
136 contiguous block. It uses the trailing-vector idiom, so
137 allocation must reserve enough space for all the elements
138 in the vector plus its control data.
139 - The vector cannot be re-allocated.
140 - The vector cannot grow nor shrink.
141 - No indirections needed for access/manipulation.
142 - It requires 2 words of storage (prior to vector allocation).
143
144
145 * Space efficient vector (vec<T, A, vl_ptr>)
146
147 These vectors can grow dynamically and are allocated together
148 with their control data. They are suited to be included in data
149 structures. Prior to initial allocation, they only take a single
150 word of storage.
151
152 These vectors are implemented as a pointer to embeddable vectors.
153 The semantics allow for this pointer to be NULL to represent
154 empty vectors. This way, empty vectors occupy minimal space in
155 the structure containing them.
156
157 Properties:
158
159 - The whole vector and control data are allocated in a single
160 contiguous block.
161 - The whole vector may be re-allocated.
162 - Vector data may grow and shrink.
163 - Access and manipulation requires a pointer test and
164 indirection.
165 - It requires 1 word of storage (prior to vector allocation).
166
167 An example of their use would be,
168
169 struct my_struct {
170 // A space-efficient vector of tree pointers in GC memory.
171 vec<tree, va_gc, vl_ptr> v;
172 };
173
174 struct my_struct *s;
175
176 if (s->v.length ()) { we have some contents }
177 s->v.safe_push (decl); // append some decl onto the end
178 for (ix = 0; s->v.iterate (ix, &elt); ix++)
179 { do something with elt }
180*/
181
182/* Support function for statistics. */
183extern void dump_vec_loc_statistics (void);
184
185/* Hashtable mapping vec addresses to descriptors. */
186extern htab_t vec_mem_usage_hash;
187
188/* Control data for vectors. This contains the number of allocated
189 and used slots inside a vector. */
190
191struct vec_prefix
192{
193 /* FIXME - These fields should be private, but we need to cater to
194 compilers that have stricter notions of PODness for types. */
195
196 /* Memory allocation support routines in vec.c. */
197 void register_overhead (void *, size_t, size_t CXX_MEM_STAT_INFO);
198 void release_overhead (void *, size_t, size_t, bool CXX_MEM_STAT_INFO);
199 static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
200 static unsigned calculate_allocation_1 (unsigned, unsigned);
201
202 /* Note that vec_prefix should be a base class for vec, but we use
203 offsetof() on vector fields of tree structures (e.g.,
204 tree_binfo::base_binfos), and offsetof only supports base types.
205
206 To compensate, we make vec_prefix a field inside vec and make
207 vec a friend class of vec_prefix so it can access its fields. */
208 template <typename, typename, typename> friend struct vec;
209
210 /* The allocator types also need access to our internals. */
211 friend struct va_gc;
212 friend struct va_gc_atomic;
213 friend struct va_heap;
214
215 unsigned m_alloc : 31;
216 unsigned m_using_auto_storage : 1;
217 unsigned m_num;
218};
219
220/* Calculate the number of slots to reserve a vector, making sure that
221 RESERVE slots are free. If EXACT grow exactly, otherwise grow
222 exponentially. PFX is the control data for the vector. */
223
224inline unsigned
225vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve,
226 bool exact)
227{
228 if (exact)
229 return (pfx ? pfx->m_num : 0) + reserve;
230 else if (!pfx)
231 return MAX (4, reserve)((4) > (reserve) ? (4) : (reserve));
232 return calculate_allocation_1 (pfx->m_alloc, pfx->m_num + reserve);
233}
234
235template<typename, typename, typename> struct vec;
236
237/* Valid vector layouts
238
239 vl_embed - Embeddable vector that uses the trailing array idiom.
240 vl_ptr - Space efficient vector that uses a pointer to an
241 embeddable vector. */
242struct vl_embed { };
243struct vl_ptr { };
244
245
246/* Types of supported allocations
247
248 va_heap - Allocation uses malloc/free.
249 va_gc - Allocation uses ggc_alloc.
250 va_gc_atomic - Same as GC, but individual elements of the array
251 do not need to be marked during collection. */
252
253/* Allocator type for heap vectors. */
254struct va_heap
255{
256 /* Heap vectors are frequently regular instances, so use the vl_ptr
257 layout for them. */
258 typedef vl_ptr default_layout;
259
260 template<typename T>
261 static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool
262 CXX_MEM_STAT_INFO);
263
264 template<typename T>
265 static void release (vec<T, va_heap, vl_embed> *&);
266};
267
268
269/* Allocator for heap memory. Ensure there are at least RESERVE free
270 slots in V. If EXACT is true, grow exactly, else grow
271 exponentially. As a special case, if the vector had not been
272 allocated and RESERVE is 0, no vector will be created. */
273
274template<typename T>
275inline void
276va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
277 MEM_STAT_DECL)
278{
279 size_t elt_size = sizeof (T);
280 unsigned alloc
281 = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
282 gcc_checking_assert (alloc)((void)(!(alloc) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 282, __FUNCTION__), 0 : 0))
;
283
284 if (GATHER_STATISTICS0 && v)
285 v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
286 v->allocated (), false);
287
288 size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
289 unsigned nelem = v ? v->length () : 0;
290 v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size));
291 v->embedded_init (alloc, nelem);
292
293 if (GATHER_STATISTICS0)
294 v->m_vecpfx.register_overhead (v, alloc, elt_size PASS_MEM_STAT);
295}
296
297
298#if GCC_VERSION(4 * 1000 + 2) >= 4007
299#pragma GCC diagnostic push
300#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
301#endif
302
303/* Free the heap space allocated for vector V. */
304
305template<typename T>
306void
307va_heap::release (vec<T, va_heap, vl_embed> *&v)
308{
309 size_t elt_size = sizeof (T);
310 if (v == NULLnullptr)
311 return;
312
313 if (GATHER_STATISTICS0)
314 v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
315 v->allocated (), true);
316 ::free (v);
317 v = NULLnullptr;
318}
319
320#if GCC_VERSION(4 * 1000 + 2) >= 4007
321#pragma GCC diagnostic pop
322#endif
323
324/* Allocator type for GC vectors. Notice that we need the structure
325 declaration even if GC is not enabled. */
326
327struct va_gc
328{
329 /* Use vl_embed as the default layout for GC vectors. Due to GTY
330 limitations, GC vectors must always be pointers, so it is more
331 efficient to use a pointer to the vl_embed layout, rather than
332 using a pointer to a pointer as would be the case with vl_ptr. */
333 typedef vl_embed default_layout;
334
335 template<typename T, typename A>
336 static void reserve (vec<T, A, vl_embed> *&, unsigned, bool
337 CXX_MEM_STAT_INFO);
338
339 template<typename T, typename A>
340 static void release (vec<T, A, vl_embed> *&v);
341};
342
343
344/* Free GC memory used by V and reset V to NULL. */
345
346template<typename T, typename A>
347inline void
348va_gc::release (vec<T, A, vl_embed> *&v)
349{
350 if (v)
351 ::ggc_free (v);
352 v = NULLnullptr;
353}
354
355
356/* Allocator for GC memory. Ensure there are at least RESERVE free
357 slots in V. If EXACT is true, grow exactly, else grow
358 exponentially. As a special case, if the vector had not been
359 allocated and RESERVE is 0, no vector will be created. */
360
361template<typename T, typename A>
362void
363va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
364 MEM_STAT_DECL)
365{
366 unsigned alloc
367 = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
368 if (!alloc)
369 {
370 ::ggc_free (v);
371 v = NULLnullptr;
372 return;
373 }
374
375 /* Calculate the amount of space we want. */
376 size_t size = vec<T, A, vl_embed>::embedded_size (alloc);
377
378 /* Ask the allocator how much space it will really give us. */
379 size = ::ggc_round_alloc_size (size);
380
381 /* Adjust the number of slots accordingly. */
382 size_t vec_offset = sizeof (vec_prefix);
383 size_t elt_size = sizeof (T);
384 alloc = (size - vec_offset) / elt_size;
385
386 /* And finally, recalculate the amount of space we ask for. */
387 size = vec_offset + alloc * elt_size;
388
389 unsigned nelem = v ? v->length () : 0;
390 v = static_cast <vec<T, A, vl_embed> *> (::ggc_realloc (v, size
391 PASS_MEM_STAT));
392 v->embedded_init (alloc, nelem);
393}
394
395
396/* Allocator type for GC vectors. This is for vectors of types
397 atomics w.r.t. collection, so allocation and deallocation is
398 completely inherited from va_gc. */
399struct va_gc_atomic : va_gc
400{
401};
402
403
404/* Generic vector template. Default values for A and L indicate the
405 most commonly used strategies.
406
407 FIXME - Ideally, they would all be vl_ptr to encourage using regular
408 instances for vectors, but the existing GTY machinery is limited
409 in that it can only deal with GC objects that are pointers
410 themselves.
411
412 This means that vector operations that need to deal with
413 potentially NULL pointers, must be provided as free
414 functions (see the vec_safe_* functions above). */
415template<typename T,
416 typename A = va_heap,
417 typename L = typename A::default_layout>
418struct GTY((user)) vec
419{
420};
421
422/* Allow C++11 range-based 'for' to work directly on vec<T>*. */
423template<typename T, typename A, typename L>
424T* begin (vec<T,A,L> *v) { return v ? v->begin () : nullptr; }
425template<typename T, typename A, typename L>
426T* end (vec<T,A,L> *v) { return v ? v->end () : nullptr; }
427template<typename T, typename A, typename L>
428const T* begin (const vec<T,A,L> *v) { return v ? v->begin () : nullptr; }
429template<typename T, typename A, typename L>
430const T* end (const vec<T,A,L> *v) { return v ? v->end () : nullptr; }
431
432/* Generic vec<> debug helpers.
433
434 These need to be instantiated for each vec<TYPE> used throughout
435 the compiler like this:
436
437 DEFINE_DEBUG_VEC (TYPE)
438
439 The reason we have a debug_helper() is because GDB can't
440 disambiguate a plain call to debug(some_vec), and it must be called
441 like debug<TYPE>(some_vec). */
442
443template<typename T>
444void
445debug_helper (vec<T> &ref)
446{
447 unsigned i;
448 for (i = 0; i < ref.length (); ++i)
449 {
450 fprintf (stderrstderr, "[%d] = ", i);
451 debug_slim (ref[i]);
452 fputc ('\n', stderrstderr);
453 }
454}
455
456/* We need a separate va_gc variant here because default template
457 argument for functions cannot be used in c++-98. Once this
458 restriction is removed, those variant should be folded with the
459 above debug_helper. */
460
461template<typename T>
462void
463debug_helper (vec<T, va_gc> &ref)
464{
465 unsigned i;
466 for (i = 0; i < ref.length (); ++i)
467 {
468 fprintf (stderrstderr, "[%d] = ", i);
469 debug_slim (ref[i]);
470 fputc ('\n', stderrstderr);
471 }
472}
473
474/* Macro to define debug(vec<T>) and debug(vec<T, va_gc>) helper
475 functions for a type T. */
476
477#define DEFINE_DEBUG_VEC(T)template void debug_helper (vec<T> &); template void
debug_helper (vec<T, va_gc> &); __attribute__ ((__used__
)) void debug (vec<T> &ref) { debug_helper <T>
(ref); } __attribute__ ((__used__)) void debug (vec<T>
*ptr) { if (ptr) debug (*ptr); else fprintf (stderr, "<nil>\n"
); } __attribute__ ((__used__)) void debug (vec<T, va_gc>
&ref) { debug_helper <T> (ref); } __attribute__ ((
__used__)) void debug (vec<T, va_gc> *ptr) { if (ptr) debug
(*ptr); else fprintf (stderr, "<nil>\n"); }
\
478 template void debug_helper (vec<T> &); \
479 template void debug_helper (vec<T, va_gc> &); \
480 /* Define the vec<T> debug functions. */ \
481 DEBUG_FUNCTION__attribute__ ((__used__)) void \
482 debug (vec<T> &ref) \
483 { \
484 debug_helper <T> (ref); \
485 } \
486 DEBUG_FUNCTION__attribute__ ((__used__)) void \
487 debug (vec<T> *ptr) \
488 { \
489 if (ptr) \
490 debug (*ptr); \
491 else \
492 fprintf (stderrstderr, "<nil>\n"); \
493 } \
494 /* Define the vec<T, va_gc> debug functions. */ \
495 DEBUG_FUNCTION__attribute__ ((__used__)) void \
496 debug (vec<T, va_gc> &ref) \
497 { \
498 debug_helper <T> (ref); \
499 } \
500 DEBUG_FUNCTION__attribute__ ((__used__)) void \
501 debug (vec<T, va_gc> *ptr) \
502 { \
503 if (ptr) \
504 debug (*ptr); \
505 else \
506 fprintf (stderrstderr, "<nil>\n"); \
507 }
508
509/* Default-construct N elements in DST. */
510
511template <typename T>
512inline void
513vec_default_construct (T *dst, unsigned n)
514{
515#ifdef BROKEN_VALUE_INITIALIZATION
516 /* Versions of GCC before 4.4 sometimes leave certain objects
517 uninitialized when value initialized, though if the type has
518 user defined default ctor, that ctor is invoked. As a workaround
519 perform clearing first and then the value initialization, which
520 fixes the case when value initialization doesn't initialize due to
521 the bugs and should initialize to all zeros, but still allows
522 vectors for types with user defined default ctor that initializes
523 some or all elements to non-zero. If T has no user defined
524 default ctor and some non-static data members have user defined
525 default ctors that initialize to non-zero the workaround will
526 still not work properly; in that case we just need to provide
527 user defined default ctor. */
528 memset (dst, '\0', sizeof (T) * n);
529#endif
530 for ( ; n; ++dst, --n)
531 ::new (static_cast<void*>(dst)) T ();
532}
533
534/* Copy-construct N elements in DST from *SRC. */
535
536template <typename T>
537inline void
538vec_copy_construct (T *dst, const T *src, unsigned n)
539{
540 for ( ; n; ++dst, ++src, --n)
541 ::new (static_cast<void*>(dst)) T (*src);
542}
543
544/* Type to provide NULL values for vec<T, A, L>. This is used to
545 provide nil initializers for vec instances. Since vec must be
546 a POD, we cannot have proper ctor/dtor for it. To initialize
547 a vec instance, you can assign it the value vNULL. This isn't
548 needed for file-scope and function-local static vectors, which
549 are zero-initialized by default. */
550struct vnull
551{
552 template <typename T, typename A, typename L>
553 CONSTEXPRconstexpr operator vec<T, A, L> () const { return vec<T, A, L>(); }
554};
555extern vnull vNULL;
556
557
558/* Embeddable vector. These vectors are suitable to be embedded
559 in other data structures so that they can be pre-allocated in a
560 contiguous memory block.
561
562 Embeddable vectors are implemented using the trailing array idiom,
563 thus they are not resizeable without changing the address of the
564 vector object itself. This means you cannot have variables or
565 fields of embeddable vector type -- always use a pointer to a
566 vector. The one exception is the final field of a structure, which
567 could be a vector type.
568
569 You will have to use the embedded_size & embedded_init calls to
570 create such objects, and they will not be resizeable (so the 'safe'
571 allocation variants are not available).
572
573 Properties:
574
575 - The whole vector and control data are allocated in a single
576 contiguous block. It uses the trailing-vector idiom, so
577 allocation must reserve enough space for all the elements
578 in the vector plus its control data.
579 - The vector cannot be re-allocated.
580 - The vector cannot grow nor shrink.
581 - No indirections needed for access/manipulation.
582 - It requires 2 words of storage (prior to vector allocation). */
583
584template<typename T, typename A>
585struct GTY((user)) vec<T, A, vl_embed>
586{
587public:
588 unsigned allocated (void) const { return m_vecpfx.m_alloc; }
589 unsigned length (void) const { return m_vecpfx.m_num; }
590 bool is_empty (void) const { return m_vecpfx.m_num == 0; }
591 T *address (void) { return m_vecdata; }
592 const T *address (void) const { return m_vecdata; }
593 T *begin () { return address (); }
594 const T *begin () const { return address (); }
595 T *end () { return address () + length (); }
596 const T *end () const { return address () + length (); }
597 const T &operator[] (unsigned) const;
598 T &operator[] (unsigned);
599 T &last (void);
600 bool space (unsigned) const;
601 bool iterate (unsigned, T *) const;
602 bool iterate (unsigned, T **) const;
603 vec *copy (ALONE_CXX_MEM_STAT_INFO) const;
604 void splice (const vec &);
605 void splice (const vec *src);
606 T *quick_push (const T &);
607 T &pop (void);
608 void truncate (unsigned);
609 void quick_insert (unsigned, const T &);
610 void ordered_remove (unsigned);
611 void unordered_remove (unsigned);
612 void block_remove (unsigned, unsigned);
613 void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *));
614 void sort (int (*) (const void *, const void *, void *), void *);
615 T *bsearch (const void *key, int (*compar)(const void *, const void *));
616 T *bsearch (const void *key,
617 int (*compar)(const void *, const void *, void *), void *);
618 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
619 bool contains (const T &search) const;
620 static size_t embedded_size (unsigned);
621 void embedded_init (unsigned, unsigned = 0, unsigned = 0);
622 void quick_grow (unsigned len);
623 void quick_grow_cleared (unsigned len);
624
625 /* vec class can access our internal data and functions. */
626 template <typename, typename, typename> friend struct vec;
627
628 /* The allocator types also need access to our internals. */
629 friend struct va_gc;
630 friend struct va_gc_atomic;
631 friend struct va_heap;
632
633 /* FIXME - These fields should be private, but we need to cater to
634 compilers that have stricter notions of PODness for types. */
635 vec_prefix m_vecpfx;
636 T m_vecdata[1];
637};
638
639
640/* Convenience wrapper functions to use when dealing with pointers to
641 embedded vectors. Some functionality for these vectors must be
642 provided via free functions for these reasons:
643
644 1- The pointer may be NULL (e.g., before initial allocation).
645
646 2- When the vector needs to grow, it must be reallocated, so
647 the pointer will change its value.
648
649 Because of limitations with the current GC machinery, all vectors
650 in GC memory *must* be pointers. */
651
652
653/* If V contains no room for NELEMS elements, return false. Otherwise,
654 return true. */
655template<typename T, typename A>
656inline bool
657vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems)
658{
659 return v ? v->space (nelems) : nelems == 0;
660}
661
662
663/* If V is NULL, return 0. Otherwise, return V->length(). */
664template<typename T, typename A>
665inline unsigned
666vec_safe_length (const vec<T, A, vl_embed> *v)
667{
668 return v ? v->length () : 0;
669}
670
671
672/* If V is NULL, return NULL. Otherwise, return V->address(). */
673template<typename T, typename A>
674inline T *
675vec_safe_address (vec<T, A, vl_embed> *v)
676{
677 return v ? v->address () : NULLnullptr;
678}
679
680
681/* If V is NULL, return true. Otherwise, return V->is_empty(). */
682template<typename T, typename A>
683inline bool
684vec_safe_is_empty (vec<T, A, vl_embed> *v)
685{
686 return v ? v->is_empty () : true;
687}
688
689/* If V does not have space for NELEMS elements, call
690 V->reserve(NELEMS, EXACT). */
691template<typename T, typename A>
692inline bool
693vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false
694 CXX_MEM_STAT_INFO)
695{
696 bool extend = nelems ? !vec_safe_space (v, nelems) : false;
42
Assuming 'nelems' is 0
43
'?' condition is false
697 if (extend
43.1
'extend' is false
43.1
'extend' is false
)
44
Taking false branch
698 A::reserve (v, nelems, exact PASS_MEM_STAT);
699 return extend;
45
Returning without writing to 'v'
700}
701
702template<typename T, typename A>
703inline bool
704vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems
705 CXX_MEM_STAT_INFO)
706{
707 return vec_safe_reserve (v, nelems, true PASS_MEM_STAT);
708}
709
710
711/* Allocate GC memory for V with space for NELEMS slots. If NELEMS
712 is 0, V is initialized to NULL. */
713
714template<typename T, typename A>
715inline void
716vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems CXX_MEM_STAT_INFO)
717{
718 v = NULLnullptr;
40
Null pointer value stored to 'v'
719 vec_safe_reserve (v, nelems, false PASS_MEM_STAT);
41
Calling 'vec_safe_reserve<constructor_elt, va_gc>'
46
Returning from 'vec_safe_reserve<constructor_elt, va_gc>'
720}
721
722
723/* Free the GC memory allocated by vector V and set it to NULL. */
724
725template<typename T, typename A>
726inline void
727vec_free (vec<T, A, vl_embed> *&v)
728{
729 A::release (v);
730}
731
732
733/* Grow V to length LEN. Allocate it, if necessary. */
734template<typename T, typename A>
735inline void
736vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
737 bool exact = false CXX_MEM_STAT_INFO)
738{
739 unsigned oldlen = vec_safe_length (v);
740 gcc_checking_assert (len >= oldlen)((void)(!(len >= oldlen) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 740, __FUNCTION__), 0 : 0))
;
741 vec_safe_reserve (v, len - oldlen, exact PASS_MEM_STAT);
742 v->quick_grow (len);
743}
744
745
746/* If V is NULL, allocate it. Call V->safe_grow_cleared(LEN). */
747template<typename T, typename A>
748inline void
749vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
750 bool exact = false CXX_MEM_STAT_INFO)
751{
752 unsigned oldlen = vec_safe_length (v);
753 vec_safe_grow (v, len, exact PASS_MEM_STAT);
754 vec_default_construct (v->address () + oldlen, len - oldlen);
755}
756
757
758/* Assume V is not NULL. */
759
760template<typename T>
761inline void
762vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
763 unsigned len, bool exact = false CXX_MEM_STAT_INFO)
764{
765 v->safe_grow_cleared (len, exact PASS_MEM_STAT);
766}
767
768/* If V does not have space for NELEMS elements, call
769 V->reserve(NELEMS, EXACT). */
770
771template<typename T>
772inline bool
773vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false
774 CXX_MEM_STAT_INFO)
775{
776 return v->reserve (nelems, exact);
777}
778
779
780/* If V is NULL return false, otherwise return V->iterate(IX, PTR). */
781template<typename T, typename A>
782inline bool
783vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr)
784{
785 if (v)
786 return v->iterate (ix, ptr);
787 else
788 {
789 *ptr = 0;
790 return false;
791 }
792}
793
794template<typename T, typename A>
795inline bool
796vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr)
797{
798 if (v)
799 return v->iterate (ix, ptr);
800 else
801 {
802 *ptr = 0;
803 return false;
804 }
805}
806
807
808/* If V has no room for one more element, reallocate it. Then call
809 V->quick_push(OBJ). */
810template<typename T, typename A>
811inline T *
812vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
813{
814 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
815 return v->quick_push (obj);
816}
817
818
819/* if V has no room for one more element, reallocate it. Then call
820 V->quick_insert(IX, OBJ). */
821template<typename T, typename A>
822inline void
823vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
824 CXX_MEM_STAT_INFO)
825{
826 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
827 v->quick_insert (ix, obj);
828}
829
830
831/* If V is NULL, do nothing. Otherwise, call V->truncate(SIZE). */
832template<typename T, typename A>
833inline void
834vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size)
835{
836 if (v)
837 v->truncate (size);
838}
839
840
841/* If SRC is not NULL, return a pointer to a copy of it. */
842template<typename T, typename A>
843inline vec<T, A, vl_embed> *
844vec_safe_copy (vec<T, A, vl_embed> *src CXX_MEM_STAT_INFO)
845{
846 return src ? src->copy (ALONE_PASS_MEM_STAT) : NULLnullptr;
847}
848
849/* Copy the elements from SRC to the end of DST as if by memcpy.
850 Reallocate DST, if necessary. */
851template<typename T, typename A>
852inline void
853vec_safe_splice (vec<T, A, vl_embed> *&dst, const vec<T, A, vl_embed> *src
854 CXX_MEM_STAT_INFO)
855{
856 unsigned src_len = vec_safe_length (src);
857 if (src_len)
858 {
859 vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len
860 PASS_MEM_STAT);
861 dst->splice (*src);
862 }
863}
864
865/* Return true if SEARCH is an element of V. Note that this is O(N) in the
866 size of the vector and so should be used with care. */
867
868template<typename T, typename A>
869inline bool
870vec_safe_contains (vec<T, A, vl_embed> *v, const T &search)
871{
872 return v ? v->contains (search) : false;
873}
874
875/* Index into vector. Return the IX'th element. IX must be in the
876 domain of the vector. */
877
878template<typename T, typename A>
879inline const T &
880vec<T, A, vl_embed>::operator[] (unsigned ix) const
881{
882 gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 882, __FUNCTION__), 0 : 0))
;
883 return m_vecdata[ix];
884}
885
886template<typename T, typename A>
887inline T &
888vec<T, A, vl_embed>::operator[] (unsigned ix)
889{
890 gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 890, __FUNCTION__), 0 : 0))
;
891 return m_vecdata[ix];
892}
893
894
895/* Get the final element of the vector, which must not be empty. */
896
897template<typename T, typename A>
898inline T &
899vec<T, A, vl_embed>::last (void)
900{
901 gcc_checking_assert (m_vecpfx.m_num > 0)((void)(!(m_vecpfx.m_num > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 901, __FUNCTION__), 0 : 0))
;
902 return (*this)[m_vecpfx.m_num - 1];
903}
904
905
906/* If this vector has space for NELEMS additional entries, return
907 true. You usually only need to use this if you are doing your
908 own vector reallocation, for instance on an embedded vector. This
909 returns true in exactly the same circumstances that vec::reserve
910 will. */
911
912template<typename T, typename A>
913inline bool
914vec<T, A, vl_embed>::space (unsigned nelems) const
915{
916 return m_vecpfx.m_alloc - m_vecpfx.m_num >= nelems;
917}
918
919
920/* Return iteration condition and update PTR to point to the IX'th
921 element of this vector. Use this to iterate over the elements of a
922 vector as follows,
923
924 for (ix = 0; vec<T, A>::iterate (v, ix, &ptr); ix++)
925 continue; */
926
927template<typename T, typename A>
928inline bool
929vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const
930{
931 if (ix < m_vecpfx.m_num)
932 {
933 *ptr = m_vecdata[ix];
934 return true;
935 }
936 else
937 {
938 *ptr = 0;
939 return false;
940 }
941}
942
943
944/* Return iteration condition and update *PTR to point to the
945 IX'th element of this vector. Use this to iterate over the
946 elements of a vector as follows,
947
948 for (ix = 0; v->iterate (ix, &ptr); ix++)
949 continue;
950
951 This variant is for vectors of objects. */
952
953template<typename T, typename A>
954inline bool
955vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const
956{
957 if (ix < m_vecpfx.m_num)
958 {
959 *ptr = CONST_CAST (T *, &m_vecdata[ix])(const_cast<T *> ((&m_vecdata[ix])));
960 return true;
961 }
962 else
963 {
964 *ptr = 0;
965 return false;
966 }
967}
968
969
970/* Return a pointer to a copy of this vector. */
971
972template<typename T, typename A>
973inline vec<T, A, vl_embed> *
974vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECLvoid) const
975{
976 vec<T, A, vl_embed> *new_vec = NULLnullptr;
977 unsigned len = length ();
978 if (len)
979 {
980 vec_alloc (new_vec, len PASS_MEM_STAT);
981 new_vec->embedded_init (len, len);
982 vec_copy_construct (new_vec->address (), m_vecdata, len);
983 }
984 return new_vec;
985}
986
987
988/* Copy the elements from SRC to the end of this vector as if by memcpy.
989 The vector must have sufficient headroom available. */
990
991template<typename T, typename A>
992inline void
993vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> &src)
994{
995 unsigned len = src.length ();
996 if (len)
997 {
998 gcc_checking_assert (space (len))((void)(!(space (len)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 998, __FUNCTION__), 0 : 0))
;
999 vec_copy_construct (end (), src.address (), len);
1000 m_vecpfx.m_num += len;
1001 }
1002}
1003
1004template<typename T, typename A>
1005inline void
1006vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> *src)
1007{
1008 if (src)
1009 splice (*src);
1010}
1011
1012
1013/* Push OBJ (a new element) onto the end of the vector. There must be
1014 sufficient space in the vector. Return a pointer to the slot
1015 where OBJ was inserted. */
1016
1017template<typename T, typename A>
1018inline T *
1019vec<T, A, vl_embed>::quick_push (const T &obj)
1020{
1021 gcc_checking_assert (space (1))((void)(!(space (1)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1021, __FUNCTION__), 0 : 0))
;
1022 T *slot = &m_vecdata[m_vecpfx.m_num++];
1023 *slot = obj;
1024 return slot;
1025}
1026
1027
1028/* Pop and return the last element off the end of the vector. */
1029
1030template<typename T, typename A>
1031inline T &
1032vec<T, A, vl_embed>::pop (void)
1033{
1034 gcc_checking_assert (length () > 0)((void)(!(length () > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1034, __FUNCTION__), 0 : 0))
;
1035 return m_vecdata[--m_vecpfx.m_num];
1036}
1037
1038
1039/* Set the length of the vector to SIZE. The new length must be less
1040 than or equal to the current length. This is an O(1) operation. */
1041
1042template<typename T, typename A>
1043inline void
1044vec<T, A, vl_embed>::truncate (unsigned size)
1045{
1046 gcc_checking_assert (length () >= size)((void)(!(length () >= size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1046, __FUNCTION__), 0 : 0))
;
1047 m_vecpfx.m_num = size;
1048}
1049
1050
1051/* Insert an element, OBJ, at the IXth position of this vector. There
1052 must be sufficient space. */
1053
1054template<typename T, typename A>
1055inline void
1056vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj)
1057{
1058 gcc_checking_assert (length () < allocated ())((void)(!(length () < allocated ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1058, __FUNCTION__), 0 : 0))
;
1059 gcc_checking_assert (ix <= length ())((void)(!(ix <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1059, __FUNCTION__), 0 : 0))
;
1060 T *slot = &m_vecdata[ix];
1061 memmove (slot + 1, slot, (m_vecpfx.m_num++ - ix) * sizeof (T));
1062 *slot = obj;
1063}
1064
1065
1066/* Remove an element from the IXth position of this vector. Ordering of
1067 remaining elements is preserved. This is an O(N) operation due to
1068 memmove. */
1069
1070template<typename T, typename A>
1071inline void
1072vec<T, A, vl_embed>::ordered_remove (unsigned ix)
1073{
1074 gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1074, __FUNCTION__), 0 : 0))
;
1075 T *slot = &m_vecdata[ix];
1076 memmove (slot, slot + 1, (--m_vecpfx.m_num - ix) * sizeof (T));
1077}
1078
1079
1080/* Remove elements in [START, END) from VEC for which COND holds. Ordering of
1081 remaining elements is preserved. This is an O(N) operation. */
1082
1083#define VEC_ORDERED_REMOVE_IF_FROM_TO(vec, read_index, write_index, \{ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1084, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (start); read_index < (end); ++read_index) { elem_ptr =
&(vec)[read_index]; bool remove_p = (cond); if (remove_p
) continue; if (read_index != write_index) (vec)[write_index]
= (vec)[read_index]; write_index++; } if (read_index - write_index
> 0) (vec).block_remove (write_index, read_index - write_index
); }
1084 elem_ptr, start, end, cond){ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1084, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (start); read_index < (end); ++read_index) { elem_ptr =
&(vec)[read_index]; bool remove_p = (cond); if (remove_p
) continue; if (read_index != write_index) (vec)[write_index]
= (vec)[read_index]; write_index++; } if (read_index - write_index
> 0) (vec).block_remove (write_index, read_index - write_index
); }
\
1085 { \
1086 gcc_assert ((end) <= (vec).length ())((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1086, __FUNCTION__), 0 : 0))
; \
1087 for (read_index = write_index = (start); read_index < (end); \
1088 ++read_index) \
1089 { \
1090 elem_ptr = &(vec)[read_index]; \
1091 bool remove_p = (cond); \
1092 if (remove_p) \
1093 continue; \
1094 \
1095 if (read_index != write_index) \
1096 (vec)[write_index] = (vec)[read_index]; \
1097 \
1098 write_index++; \
1099 } \
1100 \
1101 if (read_index - write_index > 0) \
1102 (vec).block_remove (write_index, read_index - write_index); \
1103 }
1104
1105
1106/* Remove elements from VEC for which COND holds. Ordering of remaining
1107 elements is preserved. This is an O(N) operation. */
1108
1109#define VEC_ORDERED_REMOVE_IF(vec, read_index, write_index, elem_ptr, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1110, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1110 cond){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1110, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
\
1111 VEC_ORDERED_REMOVE_IF_FROM_TO ((vec), read_index, write_index, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1112, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1112 elem_ptr, 0, (vec).length (), (cond)){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1112, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1113
1114/* Remove an element from the IXth position of this vector. Ordering of
1115 remaining elements is destroyed. This is an O(1) operation. */
1116
1117template<typename T, typename A>
1118inline void
1119vec<T, A, vl_embed>::unordered_remove (unsigned ix)
1120{
1121 gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1121, __FUNCTION__), 0 : 0))
;
1122 m_vecdata[ix] = m_vecdata[--m_vecpfx.m_num];
1123}
1124
1125
1126/* Remove LEN elements starting at the IXth. Ordering is retained.
1127 This is an O(N) operation due to memmove. */
1128
1129template<typename T, typename A>
1130inline void
1131vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len)
1132{
1133 gcc_checking_assert (ix + len <= length ())((void)(!(ix + len <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1133, __FUNCTION__), 0 : 0))
;
1134 T *slot = &m_vecdata[ix];
1135 m_vecpfx.m_num -= len;
1136 memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T));
1137}
1138
1139
1140/* Sort the contents of this vector with qsort. CMP is the comparison
1141 function to pass to qsort. */
1142
1143template<typename T, typename A>
1144inline void
1145vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))qsort (int (*cmp) (const void *, const void *))
1146{
1147 if (length () > 1)
1148 gcc_qsort (address (), length (), sizeof (T), cmp);
1149}
1150
1151/* Sort the contents of this vector with qsort. CMP is the comparison
1152 function to pass to qsort. */
1153
1154template<typename T, typename A>
1155inline void
1156vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *),
1157 void *data)
1158{
1159 if (length () > 1)
1160 gcc_sort_r (address (), length (), sizeof (T), cmp, data);
1161}
1162
1163
1164/* Search the contents of the sorted vector with a binary search.
1165 CMP is the comparison function to pass to bsearch. */
1166
1167template<typename T, typename A>
1168inline T *
1169vec<T, A, vl_embed>::bsearch (const void *key,
1170 int (*compar) (const void *, const void *))
1171{
1172 const void *base = this->address ();
1173 size_t nmemb = this->length ();
1174 size_t size = sizeof (T);
1175 /* The following is a copy of glibc stdlib-bsearch.h. */
1176 size_t l, u, idx;
1177 const void *p;
1178 int comparison;
1179
1180 l = 0;
1181 u = nmemb;
1182 while (l < u)
1183 {
1184 idx = (l + u) / 2;
1185 p = (const void *) (((const char *) base) + (idx * size));
1186 comparison = (*compar) (key, p);
1187 if (comparison < 0)
1188 u = idx;
1189 else if (comparison > 0)
1190 l = idx + 1;
1191 else
1192 return (T *)const_cast<void *>(p);
1193 }
1194
1195 return NULLnullptr;
1196}
1197
1198/* Search the contents of the sorted vector with a binary search.
1199 CMP is the comparison function to pass to bsearch. */
1200
1201template<typename T, typename A>
1202inline T *
1203vec<T, A, vl_embed>::bsearch (const void *key,
1204 int (*compar) (const void *, const void *,
1205 void *), void *data)
1206{
1207 const void *base = this->address ();
1208 size_t nmemb = this->length ();
1209 size_t size = sizeof (T);
1210 /* The following is a copy of glibc stdlib-bsearch.h. */
1211 size_t l, u, idx;
1212 const void *p;
1213 int comparison;
1214
1215 l = 0;
1216 u = nmemb;
1217 while (l < u)
1218 {
1219 idx = (l + u) / 2;
1220 p = (const void *) (((const char *) base) + (idx * size));
1221 comparison = (*compar) (key, p, data);
1222 if (comparison < 0)
1223 u = idx;
1224 else if (comparison > 0)
1225 l = idx + 1;
1226 else
1227 return (T *)const_cast<void *>(p);
1228 }
1229
1230 return NULLnullptr;
1231}
1232
1233/* Return true if SEARCH is an element of V. Note that this is O(N) in the
1234 size of the vector and so should be used with care. */
1235
1236template<typename T, typename A>
1237inline bool
1238vec<T, A, vl_embed>::contains (const T &search) const
1239{
1240 unsigned int len = length ();
1241 for (unsigned int i = 0; i < len; i++)
1242 if ((*this)[i] == search)
1243 return true;
1244
1245 return false;
1246}
1247
1248/* Find and return the first position in which OBJ could be inserted
1249 without changing the ordering of this vector. LESSTHAN is a
1250 function that returns true if the first argument is strictly less
1251 than the second. */
1252
1253template<typename T, typename A>
1254unsigned
1255vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1256 const
1257{
1258 unsigned int len = length ();
1259 unsigned int half, middle;
1260 unsigned int first = 0;
1261 while (len > 0)
1262 {
1263 half = len / 2;
1264 middle = first;
1265 middle += half;
1266 T middle_elem = (*this)[middle];
1267 if (lessthan (middle_elem, obj))
1268 {
1269 first = middle;
1270 ++first;
1271 len = len - half - 1;
1272 }
1273 else
1274 len = half;
1275 }
1276 return first;
1277}
1278
1279
1280/* Return the number of bytes needed to embed an instance of an
1281 embeddable vec inside another data structure.
1282
1283 Use these methods to determine the required size and initialization
1284 of a vector V of type T embedded within another structure (as the
1285 final member):
1286
1287 size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc);
1288 void v->embedded_init (unsigned alloc, unsigned num);
1289
1290 These allow the caller to perform the memory allocation. */
1291
1292template<typename T, typename A>
1293inline size_t
1294vec<T, A, vl_embed>::embedded_size (unsigned alloc)
1295{
1296 struct alignas (T) U { char data[sizeof (T)]; };
1297 typedef vec<U, A, vl_embed> vec_embedded;
1298 typedef typename std::conditional<std::is_standard_layout<T>::value,
1299 vec, vec_embedded>::type vec_stdlayout;
1300 static_assert (sizeof (vec_stdlayout) == sizeof (vec), "");
1301 static_assert (alignof (vec_stdlayout) == alignof (vec), "");
1302 return offsetof (vec_stdlayout, m_vecdata)__builtin_offsetof(vec_stdlayout, m_vecdata) + alloc * sizeof (T);
1303}
1304
1305
1306/* Initialize the vector to contain room for ALLOC elements and
1307 NUM active elements. */
1308
1309template<typename T, typename A>
1310inline void
1311vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num, unsigned aut)
1312{
1313 m_vecpfx.m_alloc = alloc;
1314 m_vecpfx.m_using_auto_storage = aut;
1315 m_vecpfx.m_num = num;
1316}
1317
1318
1319/* Grow the vector to a specific length. LEN must be as long or longer than
1320 the current length. The new elements are uninitialized. */
1321
1322template<typename T, typename A>
1323inline void
1324vec<T, A, vl_embed>::quick_grow (unsigned len)
1325{
1326 gcc_checking_assert (length () <= len && len <= m_vecpfx.m_alloc)((void)(!(length () <= len && len <= m_vecpfx.m_alloc
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1326, __FUNCTION__), 0 : 0))
;
1327 m_vecpfx.m_num = len;
1328}
1329
1330
1331/* Grow the vector to a specific length. LEN must be as long or longer than
1332 the current length. The new elements are initialized to zero. */
1333
1334template<typename T, typename A>
1335inline void
1336vec<T, A, vl_embed>::quick_grow_cleared (unsigned len)
1337{
1338 unsigned oldlen = length ();
1339 size_t growby = len - oldlen;
1340 quick_grow (len);
1341 if (growby != 0)
1342 vec_default_construct (address () + oldlen, growby);
1343}
1344
1345/* Garbage collection support for vec<T, A, vl_embed>. */
1346
1347template<typename T>
1348void
1349gt_ggc_mx (vec<T, va_gc> *v)
1350{
1351 extern void gt_ggc_mx (T &);
1352 for (unsigned i = 0; i < v->length (); i++)
1353 gt_ggc_mx ((*v)[i]);
1354}
1355
1356template<typename T>
1357void
1358gt_ggc_mx (vec<T, va_gc_atomic, vl_embed> *v ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
1359{
1360 /* Nothing to do. Vectors of atomic types wrt GC do not need to
1361 be traversed. */
1362}
1363
1364
1365/* PCH support for vec<T, A, vl_embed>. */
1366
1367template<typename T, typename A>
1368void
1369gt_pch_nx (vec<T, A, vl_embed> *v)
1370{
1371 extern void gt_pch_nx (T &);
1372 for (unsigned i = 0; i < v->length (); i++)
1373 gt_pch_nx ((*v)[i]);
1374}
1375
1376template<typename T, typename A>
1377void
1378gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1379{
1380 for (unsigned i = 0; i < v->length (); i++)
1381 op (&((*v)[i]), cookie);
1382}
1383
1384template<typename T, typename A>
1385void
1386gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1387{
1388 extern void gt_pch_nx (T *, gt_pointer_operator, void *);
1389 for (unsigned i = 0; i < v->length (); i++)
1390 gt_pch_nx (&((*v)[i]), op, cookie);
1391}
1392
1393
1394/* Space efficient vector. These vectors can grow dynamically and are
1395 allocated together with their control data. They are suited to be
1396 included in data structures. Prior to initial allocation, they
1397 only take a single word of storage.
1398
1399 These vectors are implemented as a pointer to an embeddable vector.
1400 The semantics allow for this pointer to be NULL to represent empty
1401 vectors. This way, empty vectors occupy minimal space in the
1402 structure containing them.
1403
1404 Properties:
1405
1406 - The whole vector and control data are allocated in a single
1407 contiguous block.
1408 - The whole vector may be re-allocated.
1409 - Vector data may grow and shrink.
1410 - Access and manipulation requires a pointer test and
1411 indirection.
1412 - It requires 1 word of storage (prior to vector allocation).
1413
1414
1415 Limitations:
1416
1417 These vectors must be PODs because they are stored in unions.
1418 (http://en.wikipedia.org/wiki/Plain_old_data_structures).
1419 As long as we use C++03, we cannot have constructors nor
1420 destructors in classes that are stored in unions. */
1421
1422template<typename T>
1423struct vec<T, va_heap, vl_ptr>
1424{
1425public:
1426 /* Memory allocation and deallocation for the embedded vector.
1427 Needed because we cannot have proper ctors/dtors defined. */
1428 void create (unsigned nelems CXX_MEM_STAT_INFO);
1429 void release (void);
1430
1431 /* Vector operations. */
1432 bool exists (void) const
1433 { return m_vec != NULLnullptr; }
1434
1435 bool is_empty (void) const
1436 { return m_vec ? m_vec->is_empty () : true; }
1437
1438 unsigned length (void) const
1439 { return m_vec ? m_vec->length () : 0; }
1440
1441 T *address (void)
1442 { return m_vec ? m_vec->m_vecdata : NULLnullptr; }
1443
1444 const T *address (void) const
1445 { return m_vec ? m_vec->m_vecdata : NULLnullptr; }
1446
1447 T *begin () { return address (); }
1448 const T *begin () const { return address (); }
1449 T *end () { return begin () + length (); }
1450 const T *end () const { return begin () + length (); }
1451 const T &operator[] (unsigned ix) const
1452 { return (*m_vec)[ix]; }
1453
1454 bool operator!=(const vec &other) const
1455 { return !(*this == other); }
1456
1457 bool operator==(const vec &other) const
1458 { return address () == other.address (); }
1459
1460 T &operator[] (unsigned ix)
1461 { return (*m_vec)[ix]; }
1462
1463 T &last (void)
1464 { return m_vec->last (); }
1465
1466 bool space (int nelems) const
1467 { return m_vec ? m_vec->space (nelems) : nelems == 0; }
1468
1469 bool iterate (unsigned ix, T *p) const;
1470 bool iterate (unsigned ix, T **p) const;
1471 vec copy (ALONE_CXX_MEM_STAT_INFO) const;
1472 bool reserve (unsigned, bool = false CXX_MEM_STAT_INFO);
1473 bool reserve_exact (unsigned CXX_MEM_STAT_INFO);
1474 void splice (const vec &);
1475 void safe_splice (const vec & CXX_MEM_STAT_INFO);
1476 T *quick_push (const T &);
1477 T *safe_push (const T &CXX_MEM_STAT_INFO);
1478 T &pop (void);
1479 void truncate (unsigned);
1480 void safe_grow (unsigned, bool = false CXX_MEM_STAT_INFO);
1481 void safe_grow_cleared (unsigned, bool = false CXX_MEM_STAT_INFO);
1482 void quick_grow (unsigned);
1483 void quick_grow_cleared (unsigned);
1484 void quick_insert (unsigned, const T &);
1485 void safe_insert (unsigned, const T & CXX_MEM_STAT_INFO);
1486 void ordered_remove (unsigned);
1487 void unordered_remove (unsigned);
1488 void block_remove (unsigned, unsigned);
1489 void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *));
1490 void sort (int (*) (const void *, const void *, void *), void *);
1491 T *bsearch (const void *key, int (*compar)(const void *, const void *));
1492 T *bsearch (const void *key,
1493 int (*compar)(const void *, const void *, void *), void *);
1494 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
1495 bool contains (const T &search) const;
1496 void reverse (void);
1497
1498 bool using_auto_storage () const;
1499
1500 /* FIXME - This field should be private, but we need to cater to
1501 compilers that have stricter notions of PODness for types. */
1502 vec<T, va_heap, vl_embed> *m_vec;
1503};
1504
1505
1506/* auto_vec is a subclass of vec that automatically manages creating and
1507 releasing the internal vector. If N is non zero then it has N elements of
1508 internal storage. The default is no internal storage, and you probably only
1509 want to ask for internal storage for vectors on the stack because if the
1510 size of the vector is larger than the internal storage that space is wasted.
1511 */
1512template<typename T, size_t N = 0>
1513class auto_vec : public vec<T, va_heap>
1514{
1515public:
1516 auto_vec ()
1517 {
1518 m_auto.embedded_init (MAX (N, 2)((N) > (2) ? (N) : (2)), 0, 1);
1519 this->m_vec = &m_auto;
1520 }
1521
1522 auto_vec (size_t s)
1523 {
1524 if (s > N)
1525 {
1526 this->create (s);
1527 return;
1528 }
1529
1530 m_auto.embedded_init (MAX (N, 2)((N) > (2) ? (N) : (2)), 0, 1);
1531 this->m_vec = &m_auto;
1532 }
1533
1534 ~auto_vec ()
1535 {
1536 this->release ();
1537 }
1538
1539private:
1540 vec<T, va_heap, vl_embed> m_auto;
1541 T m_data[MAX (N - 1, 1)((N - 1) > (1) ? (N - 1) : (1))];
1542};
1543
1544/* auto_vec is a sub class of vec whose storage is released when it is
1545 destroyed. */
1546template<typename T>
1547class auto_vec<T, 0> : public vec<T, va_heap>
1548{
1549public:
1550 auto_vec () { this->m_vec = NULLnullptr; }
1551 auto_vec (size_t n) { this->create (n); }
1552 ~auto_vec () { this->release (); }
1553
1554 auto_vec (vec<T, va_heap>&& r)
1555 {
1556 gcc_assert (!r.using_auto_storage ())((void)(!(!r.using_auto_storage ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1556, __FUNCTION__), 0 : 0))
;
1557 this->m_vec = r.m_vec;
1558 r.m_vec = NULLnullptr;
1559 }
1560 auto_vec& operator= (vec<T, va_heap>&& r)
1561 {
1562 gcc_assert (!r.using_auto_storage ())((void)(!(!r.using_auto_storage ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1562, __FUNCTION__), 0 : 0))
;
1563 this->release ();
1564 this->m_vec = r.m_vec;
1565 r.m_vec = NULLnullptr;
1566 return *this;
1567 }
1568};
1569
1570
1571/* Allocate heap memory for pointer V and create the internal vector
1572 with space for NELEMS elements. If NELEMS is 0, the internal
1573 vector is initialized to empty. */
1574
1575template<typename T>
1576inline void
1577vec_alloc (vec<T> *&v, unsigned nelems CXX_MEM_STAT_INFO)
1578{
1579 v = new vec<T>;
1580 v->create (nelems PASS_MEM_STAT);
1581}
1582
1583
1584/* A subclass of auto_vec <char *> that frees all of its elements on
1585 deletion. */
1586
1587class auto_string_vec : public auto_vec <char *>
1588{
1589 public:
1590 ~auto_string_vec ();
1591};
1592
1593/* A subclass of auto_vec <T *> that deletes all of its elements on
1594 destruction.
1595
1596 This is a crude way for a vec to "own" the objects it points to
1597 and clean up automatically.
1598
1599 For example, no attempt is made to delete elements when an item
1600 within the vec is overwritten.
1601
1602 We can't rely on gnu::unique_ptr within a container,
1603 since we can't rely on move semantics in C++98. */
1604
1605template <typename T>
1606class auto_delete_vec : public auto_vec <T *>
1607{
1608 public:
1609 auto_delete_vec () {}
1610 auto_delete_vec (size_t s) : auto_vec <T *> (s) {}
1611
1612 ~auto_delete_vec ();
1613
1614private:
1615 DISABLE_COPY_AND_ASSIGN(auto_delete_vec)auto_delete_vec (const auto_delete_vec&) = delete; void operator
= (const auto_delete_vec &) = delete
;
1616};
1617
1618/* Conditionally allocate heap memory for VEC and its internal vector. */
1619
1620template<typename T>
1621inline void
1622vec_check_alloc (vec<T, va_heap> *&vec, unsigned nelems CXX_MEM_STAT_INFO)
1623{
1624 if (!vec)
1625 vec_alloc (vec, nelems PASS_MEM_STAT);
1626}
1627
1628
1629/* Free the heap memory allocated by vector V and set it to NULL. */
1630
1631template<typename T>
1632inline void
1633vec_free (vec<T> *&v)
1634{
1635 if (v == NULLnullptr)
1636 return;
1637
1638 v->release ();
1639 delete v;
1640 v = NULLnullptr;
1641}
1642
1643
1644/* Return iteration condition and update PTR to point to the IX'th
1645 element of this vector. Use this to iterate over the elements of a
1646 vector as follows,
1647
1648 for (ix = 0; v.iterate (ix, &ptr); ix++)
1649 continue; */
1650
1651template<typename T>
1652inline bool
1653vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T *ptr) const
1654{
1655 if (m_vec)
1656 return m_vec->iterate (ix, ptr);
1657 else
1658 {
1659 *ptr = 0;
1660 return false;
1661 }
1662}
1663
1664
1665/* Return iteration condition and update *PTR to point to the
1666 IX'th element of this vector. Use this to iterate over the
1667 elements of a vector as follows,
1668
1669 for (ix = 0; v->iterate (ix, &ptr); ix++)
1670 continue;
1671
1672 This variant is for vectors of objects. */
1673
1674template<typename T>
1675inline bool
1676vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T **ptr) const
1677{
1678 if (m_vec)
1679 return m_vec->iterate (ix, ptr);
1680 else
1681 {
1682 *ptr = 0;
1683 return false;
1684 }
1685}
1686
1687
1688/* Convenience macro for forward iteration. */
1689#define FOR_EACH_VEC_ELT(V, I, P)for (I = 0; (V).iterate ((I), &(P)); ++(I)) \
1690 for (I = 0; (V).iterate ((I), &(P)); ++(I))
1691
1692#define FOR_EACH_VEC_SAFE_ELT(V, I, P)for (I = 0; vec_safe_iterate ((V), (I), &(P)); ++(I)) \
1693 for (I = 0; vec_safe_iterate ((V), (I), &(P)); ++(I))
1694
1695/* Likewise, but start from FROM rather than 0. */
1696#define FOR_EACH_VEC_ELT_FROM(V, I, P, FROM)for (I = (FROM); (V).iterate ((I), &(P)); ++(I)) \
1697 for (I = (FROM); (V).iterate ((I), &(P)); ++(I))
1698
1699/* Convenience macro for reverse iteration. */
1700#define FOR_EACH_VEC_ELT_REVERSE(V, I, P)for (I = (V).length () - 1; (V).iterate ((I), &(P)); (I)--
)
\
1701 for (I = (V).length () - 1; \
1702 (V).iterate ((I), &(P)); \
1703 (I)--)
1704
1705#define FOR_EACH_VEC_SAFE_ELT_REVERSE(V, I, P)for (I = vec_safe_length (V) - 1; vec_safe_iterate ((V), (I),
&(P)); (I)--)
\
1706 for (I = vec_safe_length (V) - 1; \
1707 vec_safe_iterate ((V), (I), &(P)); \
1708 (I)--)
1709
1710/* auto_string_vec's dtor, freeing all contained strings, automatically
1711 chaining up to ~auto_vec <char *>, which frees the internal buffer. */
1712
1713inline
1714auto_string_vec::~auto_string_vec ()
1715{
1716 int i;
1717 char *str;
1718 FOR_EACH_VEC_ELT (*this, i, str)for (i = 0; (*this).iterate ((i), &(str)); ++(i))
1719 free (str);
1720}
1721
1722/* auto_delete_vec's dtor, deleting all contained items, automatically
1723 chaining up to ~auto_vec <T*>, which frees the internal buffer. */
1724
1725template <typename T>
1726inline
1727auto_delete_vec<T>::~auto_delete_vec ()
1728{
1729 int i;
1730 T *item;
1731 FOR_EACH_VEC_ELT (*this, i, item)for (i = 0; (*this).iterate ((i), &(item)); ++(i))
1732 delete item;
1733}
1734
1735
1736/* Return a copy of this vector. */
1737
1738template<typename T>
1739inline vec<T, va_heap, vl_ptr>
1740vec<T, va_heap, vl_ptr>::copy (ALONE_MEM_STAT_DECLvoid) const
1741{
1742 vec<T, va_heap, vl_ptr> new_vec = vNULL;
1743 if (length ())
1744 new_vec.m_vec = m_vec->copy (ALONE_PASS_MEM_STAT);
1745 return new_vec;
1746}
1747
1748
1749/* Ensure that the vector has at least RESERVE slots available (if
1750 EXACT is false), or exactly RESERVE slots available (if EXACT is
1751 true).
1752
1753 This may create additional headroom if EXACT is false.
1754
1755 Note that this can cause the embedded vector to be reallocated.
1756 Returns true iff reallocation actually occurred. */
1757
1758template<typename T>
1759inline bool
1760vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
1761{
1762 if (space (nelems))
1763 return false;
1764
1765 /* For now play a game with va_heap::reserve to hide our auto storage if any,
1766 this is necessary because it doesn't have enough information to know the
1767 embedded vector is in auto storage, and so should not be freed. */
1768 vec<T, va_heap, vl_embed> *oldvec = m_vec;
1769 unsigned int oldsize = 0;
1770 bool handle_auto_vec = m_vec && using_auto_storage ();
1771 if (handle_auto_vec)
1772 {
1773 m_vec = NULLnullptr;
1774 oldsize = oldvec->length ();
1775 nelems += oldsize;
1776 }
1777
1778 va_heap::reserve (m_vec, nelems, exact PASS_MEM_STAT);
1779 if (handle_auto_vec)
1780 {
1781 vec_copy_construct (m_vec->address (), oldvec->address (), oldsize);
1782 m_vec->m_vecpfx.m_num = oldsize;
1783 }
1784
1785 return true;
1786}
1787
1788
1789/* Ensure that this vector has exactly NELEMS slots available. This
1790 will not create additional headroom. Note this can cause the
1791 embedded vector to be reallocated. Returns true iff reallocation
1792 actually occurred. */
1793
1794template<typename T>
1795inline bool
1796vec<T, va_heap, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
1797{
1798 return reserve (nelems, true PASS_MEM_STAT);
1799}
1800
1801
1802/* Create the internal vector and reserve NELEMS for it. This is
1803 exactly like vec::reserve, but the internal vector is
1804 unconditionally allocated from scratch. The old one, if it
1805 existed, is lost. */
1806
1807template<typename T>
1808inline void
1809vec<T, va_heap, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
1810{
1811 m_vec = NULLnullptr;
1812 if (nelems > 0)
1813 reserve_exact (nelems PASS_MEM_STAT);
1814}
1815
1816
1817/* Free the memory occupied by the embedded vector. */
1818
1819template<typename T>
1820inline void
1821vec<T, va_heap, vl_ptr>::release (void)
1822{
1823 if (!m_vec)
1824 return;
1825
1826 if (using_auto_storage ())
1827 {
1828 m_vec->m_vecpfx.m_num = 0;
1829 return;
1830 }
1831
1832 va_heap::release (m_vec);
1833}
1834
1835/* Copy the elements from SRC to the end of this vector as if by memcpy.
1836 SRC and this vector must be allocated with the same memory
1837 allocation mechanism. This vector is assumed to have sufficient
1838 headroom available. */
1839
1840template<typename T>
1841inline void
1842vec<T, va_heap, vl_ptr>::splice (const vec<T, va_heap, vl_ptr> &src)
1843{
1844 if (src.length ())
1845 m_vec->splice (*(src.m_vec));
1846}
1847
1848
1849/* Copy the elements in SRC to the end of this vector as if by memcpy.
1850 SRC and this vector must be allocated with the same mechanism.
1851 If there is not enough headroom in this vector, it will be reallocated
1852 as needed. */
1853
1854template<typename T>
1855inline void
1856vec<T, va_heap, vl_ptr>::safe_splice (const vec<T, va_heap, vl_ptr> &src
1857 MEM_STAT_DECL)
1858{
1859 if (src.length ())
1860 {
1861 reserve_exact (src.length ());
1862 splice (src);
1863 }
1864}
1865
1866
1867/* Push OBJ (a new element) onto the end of the vector. There must be
1868 sufficient space in the vector. Return a pointer to the slot
1869 where OBJ was inserted. */
1870
1871template<typename T>
1872inline T *
1873vec<T, va_heap, vl_ptr>::quick_push (const T &obj)
1874{
1875 return m_vec->quick_push (obj);
1876}
1877
1878
1879/* Push a new element OBJ onto the end of this vector. Reallocates
1880 the embedded vector, if needed. Return a pointer to the slot where
1881 OBJ was inserted. */
1882
1883template<typename T>
1884inline T *
1885vec<T, va_heap, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
1886{
1887 reserve (1, false PASS_MEM_STAT);
1888 return quick_push (obj);
1889}
1890
1891
1892/* Pop and return the last element off the end of the vector. */
1893
1894template<typename T>
1895inline T &
1896vec<T, va_heap, vl_ptr>::pop (void)
1897{
1898 return m_vec->pop ();
1899}
1900
1901
1902/* Set the length of the vector to LEN. The new length must be less
1903 than or equal to the current length. This is an O(1) operation. */
1904
1905template<typename T>
1906inline void
1907vec<T, va_heap, vl_ptr>::truncate (unsigned size)
1908{
1909 if (m_vec)
1910 m_vec->truncate (size);
1911 else
1912 gcc_checking_assert (size == 0)((void)(!(size == 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1912, __FUNCTION__), 0 : 0))
;
1913}
1914
1915
1916/* Grow the vector to a specific length. LEN must be as long or
1917 longer than the current length. The new elements are
1918 uninitialized. Reallocate the internal vector, if needed. */
1919
1920template<typename T>
1921inline void
1922vec<T, va_heap, vl_ptr>::safe_grow (unsigned len, bool exact MEM_STAT_DECL)
1923{
1924 unsigned oldlen = length ();
1925 gcc_checking_assert (oldlen <= len)((void)(!(oldlen <= len) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1925, __FUNCTION__), 0 : 0))
;
1926 reserve (len - oldlen, exact PASS_MEM_STAT);
1927 if (m_vec)
1928 m_vec->quick_grow (len);
1929 else
1930 gcc_checking_assert (len == 0)((void)(!(len == 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1930, __FUNCTION__), 0 : 0))
;
1931}
1932
1933
1934/* Grow the embedded vector to a specific length. LEN must be as
1935 long or longer than the current length. The new elements are
1936 initialized to zero. Reallocate the internal vector, if needed. */
1937
1938template<typename T>
1939inline void
1940vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len, bool exact
1941 MEM_STAT_DECL)
1942{
1943 unsigned oldlen = length ();
1944 size_t growby = len - oldlen;
1945 safe_grow (len, exact PASS_MEM_STAT);
1946 if (growby != 0)
1947 vec_default_construct (address () + oldlen, growby);
1948}
1949
1950
1951/* Same as vec::safe_grow but without reallocation of the internal vector.
1952 If the vector cannot be extended, a runtime assertion will be triggered. */
1953
1954template<typename T>
1955inline void
1956vec<T, va_heap, vl_ptr>::quick_grow (unsigned len)
1957{
1958 gcc_checking_assert (m_vec)((void)(!(m_vec) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1958, __FUNCTION__), 0 : 0))
;
1959 m_vec->quick_grow (len);
1960}
1961
1962
1963/* Same as vec::quick_grow_cleared but without reallocation of the
1964 internal vector. If the vector cannot be extended, a runtime
1965 assertion will be triggered. */
1966
1967template<typename T>
1968inline void
1969vec<T, va_heap, vl_ptr>::quick_grow_cleared (unsigned len)
1970{
1971 gcc_checking_assert (m_vec)((void)(!(m_vec) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1971, __FUNCTION__), 0 : 0))
;
1972 m_vec->quick_grow_cleared (len);
1973}
1974
1975
1976/* Insert an element, OBJ, at the IXth position of this vector. There
1977 must be sufficient space. */
1978
1979template<typename T>
1980inline void
1981vec<T, va_heap, vl_ptr>::quick_insert (unsigned ix, const T &obj)
1982{
1983 m_vec->quick_insert (ix, obj);
1984}
1985
1986
1987/* Insert an element, OBJ, at the IXth position of the vector.
1988 Reallocate the embedded vector, if necessary. */
1989
1990template<typename T>
1991inline void
1992vec<T, va_heap, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
1993{
1994 reserve (1, false PASS_MEM_STAT);
1995 quick_insert (ix, obj);
1996}
1997
1998
1999/* Remove an element from the IXth position of this vector. Ordering of
2000 remaining elements is preserved. This is an O(N) operation due to
2001 a memmove. */
2002
2003template<typename T>
2004inline void
2005vec<T, va_heap, vl_ptr>::ordered_remove (unsigned ix)
2006{
2007 m_vec->ordered_remove (ix);
2008}
2009
2010
2011/* Remove an element from the IXth position of this vector. Ordering
2012 of remaining elements is destroyed. This is an O(1) operation. */
2013
2014template<typename T>
2015inline void
2016vec<T, va_heap, vl_ptr>::unordered_remove (unsigned ix)
2017{
2018 m_vec->unordered_remove (ix);
2019}
2020
2021
2022/* Remove LEN elements starting at the IXth. Ordering is retained.
2023 This is an O(N) operation due to memmove. */
2024
2025template<typename T>
2026inline void
2027vec<T, va_heap, vl_ptr>::block_remove (unsigned ix, unsigned len)
2028{
2029 m_vec->block_remove (ix, len);
2030}
2031
2032
2033/* Sort the contents of this vector with qsort. CMP is the comparison
2034 function to pass to qsort. */
2035
2036template<typename T>
2037inline void
2038vec<T, va_heap, vl_ptr>::qsort (int (*cmp) (const void *, const void *))qsort (int (*cmp) (const void *, const void *))
2039{
2040 if (m_vec)
2041 m_vec->qsort (cmp)qsort (cmp);
2042}
2043
2044/* Sort the contents of this vector with qsort. CMP is the comparison
2045 function to pass to qsort. */
2046
2047template<typename T>
2048inline void
2049vec<T, va_heap, vl_ptr>::sort (int (*cmp) (const void *, const void *,
2050 void *), void *data)
2051{
2052 if (m_vec)
2053 m_vec->sort (cmp, data);
2054}
2055
2056
2057/* Search the contents of the sorted vector with a binary search.
2058 CMP is the comparison function to pass to bsearch. */
2059
2060template<typename T>
2061inline T *
2062vec<T, va_heap, vl_ptr>::bsearch (const void *key,
2063 int (*cmp) (const void *, const void *))
2064{
2065 if (m_vec)
2066 return m_vec->bsearch (key, cmp);
2067 return NULLnullptr;
2068}
2069
2070/* Search the contents of the sorted vector with a binary search.
2071 CMP is the comparison function to pass to bsearch. */
2072
2073template<typename T>
2074inline T *
2075vec<T, va_heap, vl_ptr>::bsearch (const void *key,
2076 int (*cmp) (const void *, const void *,
2077 void *), void *data)
2078{
2079 if (m_vec)
2080 return m_vec->bsearch (key, cmp, data);
2081 return NULLnullptr;
2082}
2083
2084
2085/* Find and return the first position in which OBJ could be inserted
2086 without changing the ordering of this vector. LESSTHAN is a
2087 function that returns true if the first argument is strictly less
2088 than the second. */
2089
2090template<typename T>
2091inline unsigned
2092vec<T, va_heap, vl_ptr>::lower_bound (T obj,
2093 bool (*lessthan)(const T &, const T &))
2094 const
2095{
2096 return m_vec ? m_vec->lower_bound (obj, lessthan) : 0;
2097}
2098
2099/* Return true if SEARCH is an element of V. Note that this is O(N) in the
2100 size of the vector and so should be used with care. */
2101
2102template<typename T>
2103inline bool
2104vec<T, va_heap, vl_ptr>::contains (const T &search) const
2105{
2106 return m_vec ? m_vec->contains (search) : false;
2107}
2108
2109/* Reverse content of the vector. */
2110
2111template<typename T>
2112inline void
2113vec<T, va_heap, vl_ptr>::reverse (void)
2114{
2115 unsigned l = length ();
2116 T *ptr = address ();
2117
2118 for (unsigned i = 0; i < l / 2; i++)
2119 std::swap (ptr[i], ptr[l - i - 1]);
2120}
2121
2122template<typename T>
2123inline bool
2124vec<T, va_heap, vl_ptr>::using_auto_storage () const
2125{
2126 return m_vec->m_vecpfx.m_using_auto_storage;
2127}
2128
2129/* Release VEC and call release of all element vectors. */
2130
2131template<typename T>
2132inline void
2133release_vec_vec (vec<vec<T> > &vec)
2134{
2135 for (unsigned i = 0; i < vec.length (); i++)
2136 vec[i].release ();
2137
2138 vec.release ();
2139}
2140
2141// Provide a subset of the std::span functionality. (We can't use std::span
2142// itself because it's a C++20 feature.)
2143//
2144// In addition, provide an invalid value that is distinct from all valid
2145// sequences (including the empty sequence). This can be used to return
2146// failure without having to use std::optional.
2147//
2148// There is no operator bool because it would be ambiguous whether it is
2149// testing for a valid value or an empty sequence.
2150template<typename T>
2151class array_slice
2152{
2153 template<typename OtherT> friend class array_slice;
2154
2155public:
2156 using value_type = T;
2157 using iterator = T *;
2158 using const_iterator = const T *;
2159
2160 array_slice () : m_base (nullptr), m_size (0) {}
2161
2162 template<typename OtherT>
2163 array_slice (array_slice<OtherT> other)
2164 : m_base (other.m_base), m_size (other.m_size) {}
2165
2166 array_slice (iterator base, unsigned int size)
2167 : m_base (base), m_size (size) {}
2168
2169 template<size_t N>
2170 array_slice (T (&array)[N]) : m_base (array), m_size (N) {}
2171
2172 template<typename OtherT>
2173 array_slice (const vec<OtherT> &v)
2174 : m_base (v.address ()), m_size (v.length ()) {}
2175
2176 iterator begin () { return m_base; }
2177 iterator end () { return m_base + m_size; }
2178
2179 const_iterator begin () const { return m_base; }
2180 const_iterator end () const { return m_base + m_size; }
2181
2182 value_type &front ();
2183 value_type &back ();
2184 value_type &operator[] (unsigned int i);
2185
2186 const value_type &front () const;
2187 const value_type &back () const;
2188 const value_type &operator[] (unsigned int i) const;
2189
2190 size_t size () const { return m_size; }
2191 size_t size_bytes () const { return m_size * sizeof (T); }
2192 bool empty () const { return m_size == 0; }
2193
2194 // An invalid array_slice that represents a failed operation. This is
2195 // distinct from an empty slice, which is a valid result in some contexts.
2196 static array_slice invalid () { return { nullptr, ~0U }; }
2197
2198 // True if the array is valid, false if it is an array like INVALID.
2199 bool is_valid () const { return m_base || m_size == 0; }
2200
2201private:
2202 iterator m_base;
2203 unsigned int m_size;
2204};
2205
2206template<typename T>
2207inline typename array_slice<T>::value_type &
2208array_slice<T>::front ()
2209{
2210 gcc_checking_assert (m_size)((void)(!(m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2210, __FUNCTION__), 0 : 0))
;
2211 return m_base[0];
2212}
2213
2214template<typename T>
2215inline const typename array_slice<T>::value_type &
2216array_slice<T>::front () const
2217{
2218 gcc_checking_assert (m_size)((void)(!(m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2218, __FUNCTION__), 0 : 0))
;
2219 return m_base[0];
2220}
2221
2222template<typename T>
2223inline typename array_slice<T>::value_type &
2224array_slice<T>::back ()
2225{
2226 gcc_checking_assert (m_size)((void)(!(m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2226, __FUNCTION__), 0 : 0))
;
2227 return m_base[m_size - 1];
2228}
2229
2230template<typename T>
2231inline const typename array_slice<T>::value_type &
2232array_slice<T>::back () const
2233{
2234 gcc_checking_assert (m_size)((void)(!(m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2234, __FUNCTION__), 0 : 0))
;
2235 return m_base[m_size - 1];
2236}
2237
2238template<typename T>
2239inline typename array_slice<T>::value_type &
2240array_slice<T>::operator[] (unsigned int i)
2241{
2242 gcc_checking_assert (i < m_size)((void)(!(i < m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2242, __FUNCTION__), 0 : 0))
;
2243 return m_base[i];
2244}
2245
2246template<typename T>
2247inline const typename array_slice<T>::value_type &
2248array_slice<T>::operator[] (unsigned int i) const
2249{
2250 gcc_checking_assert (i < m_size)((void)(!(i < m_size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 2250, __FUNCTION__), 0 : 0))
;
2251 return m_base[i];
2252}
2253
2254template<typename T>
2255array_slice<T>
2256make_array_slice (T *base, unsigned int size)
2257{
2258 return array_slice<T> (base, size);
2259}
2260
2261#if (GCC_VERSION(4 * 1000 + 2) >= 3000)
2262# pragma GCC poison m_vec m_vecpfx m_vecdata
2263#endif
2264
2265#endif // GCC_VEC_H