File: | build/gcc/tree-ssa-forwprop.cc |
Warning: | line 1260, column 8 4th function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Forward propagation of expressions for single use variables. | |||
2 | Copyright (C) 2004-2023 Free Software Foundation, Inc. | |||
3 | ||||
4 | This file is part of GCC. | |||
5 | ||||
6 | GCC is free software; you can redistribute it and/or modify | |||
7 | it under the terms of the GNU General Public License as published by | |||
8 | the Free Software Foundation; either version 3, or (at your option) | |||
9 | any later version. | |||
10 | ||||
11 | GCC is distributed in the hope that it will be useful, | |||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
14 | GNU General Public License for more details. | |||
15 | ||||
16 | You should have received a copy of the GNU General Public License | |||
17 | along with GCC; see the file COPYING3. If not see | |||
18 | <http://www.gnu.org/licenses/>. */ | |||
19 | ||||
20 | #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 "cfghooks.h" | |||
28 | #include "tree-pass.h" | |||
29 | #include "ssa.h" | |||
30 | #include "expmed.h" | |||
31 | #include "optabs-query.h" | |||
32 | #include "gimple-pretty-print.h" | |||
33 | #include "fold-const.h" | |||
34 | #include "stor-layout.h" | |||
35 | #include "gimple-iterator.h" | |||
36 | #include "gimple-fold.h" | |||
37 | #include "tree-eh.h" | |||
38 | #include "gimplify.h" | |||
39 | #include "gimplify-me.h" | |||
40 | #include "tree-cfg.h" | |||
41 | #include "expr.h" | |||
42 | #include "tree-dfa.h" | |||
43 | #include "tree-ssa-propagate.h" | |||
44 | #include "tree-ssa-dom.h" | |||
45 | #include "tree-ssa-strlen.h" | |||
46 | #include "builtins.h" | |||
47 | #include "tree-cfgcleanup.h" | |||
48 | #include "cfganal.h" | |||
49 | #include "optabs-tree.h" | |||
50 | #include "tree-vector-builder.h" | |||
51 | #include "vec-perm-indices.h" | |||
52 | #include "internal-fn.h" | |||
53 | #include "cgraph.h" | |||
54 | #include "tree-ssa.h" | |||
55 | #include "gimple-range.h" | |||
56 | ||||
57 | /* This pass propagates the RHS of assignment statements into use | |||
58 | sites of the LHS of the assignment. It's basically a specialized | |||
59 | form of tree combination. It is hoped all of this can disappear | |||
60 | when we have a generalized tree combiner. | |||
61 | ||||
62 | One class of common cases we handle is forward propagating a single use | |||
63 | variable into a COND_EXPR. | |||
64 | ||||
65 | bb0: | |||
66 | x = a COND b; | |||
67 | if (x) goto ... else goto ... | |||
68 | ||||
69 | Will be transformed into: | |||
70 | ||||
71 | bb0: | |||
72 | if (a COND b) goto ... else goto ... | |||
73 | ||||
74 | Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1). | |||
75 | ||||
76 | Or (assuming c1 and c2 are constants): | |||
77 | ||||
78 | bb0: | |||
79 | x = a + c1; | |||
80 | if (x EQ/NEQ c2) goto ... else goto ... | |||
81 | ||||
82 | Will be transformed into: | |||
83 | ||||
84 | bb0: | |||
85 | if (a EQ/NEQ (c2 - c1)) goto ... else goto ... | |||
86 | ||||
87 | Similarly for x = a - c1. | |||
88 | ||||
89 | Or | |||
90 | ||||
91 | bb0: | |||
92 | x = !a | |||
93 | if (x) goto ... else goto ... | |||
94 | ||||
95 | Will be transformed into: | |||
96 | ||||
97 | bb0: | |||
98 | if (a == 0) goto ... else goto ... | |||
99 | ||||
100 | Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1). | |||
101 | For these cases, we propagate A into all, possibly more than one, | |||
102 | COND_EXPRs that use X. | |||
103 | ||||
104 | Or | |||
105 | ||||
106 | bb0: | |||
107 | x = (typecast) a | |||
108 | if (x) goto ... else goto ... | |||
109 | ||||
110 | Will be transformed into: | |||
111 | ||||
112 | bb0: | |||
113 | if (a != 0) goto ... else goto ... | |||
114 | ||||
115 | (Assuming a is an integral type and x is a boolean or x is an | |||
116 | integral and a is a boolean.) | |||
117 | ||||
118 | Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1). | |||
119 | For these cases, we propagate A into all, possibly more than one, | |||
120 | COND_EXPRs that use X. | |||
121 | ||||
122 | In addition to eliminating the variable and the statement which assigns | |||
123 | a value to the variable, we may be able to later thread the jump without | |||
124 | adding insane complexity in the dominator optimizer. | |||
125 | ||||
126 | Also note these transformations can cascade. We handle this by having | |||
127 | a worklist of COND_EXPR statements to examine. As we make a change to | |||
128 | a statement, we put it back on the worklist to examine on the next | |||
129 | iteration of the main loop. | |||
130 | ||||
131 | A second class of propagation opportunities arises for ADDR_EXPR | |||
132 | nodes. | |||
133 | ||||
134 | ptr = &x->y->z; | |||
135 | res = *ptr; | |||
136 | ||||
137 | Will get turned into | |||
138 | ||||
139 | res = x->y->z; | |||
140 | ||||
141 | Or | |||
142 | ptr = (type1*)&type2var; | |||
143 | res = *ptr | |||
144 | ||||
145 | Will get turned into (if type1 and type2 are the same size | |||
146 | and neither have volatile on them): | |||
147 | res = VIEW_CONVERT_EXPR<type1>(type2var) | |||
148 | ||||
149 | Or | |||
150 | ||||
151 | ptr = &x[0]; | |||
152 | ptr2 = ptr + <constant>; | |||
153 | ||||
154 | Will get turned into | |||
155 | ||||
156 | ptr2 = &x[constant/elementsize]; | |||
157 | ||||
158 | Or | |||
159 | ||||
160 | ptr = &x[0]; | |||
161 | offset = index * element_size; | |||
162 | offset_p = (pointer) offset; | |||
163 | ptr2 = ptr + offset_p | |||
164 | ||||
165 | Will get turned into: | |||
166 | ||||
167 | ptr2 = &x[index]; | |||
168 | ||||
169 | Or | |||
170 | ssa = (int) decl | |||
171 | res = ssa & 1 | |||
172 | ||||
173 | Provided that decl has known alignment >= 2, will get turned into | |||
174 | ||||
175 | res = 0 | |||
176 | ||||
177 | We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to | |||
178 | allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent | |||
179 | {NOT_EXPR,NEG_EXPR}. | |||
180 | ||||
181 | This will (of course) be extended as other needs arise. */ | |||
182 | ||||
183 | static bool forward_propagate_addr_expr (tree, tree, bool); | |||
184 | ||||
185 | /* Set to true if we delete dead edges during the optimization. */ | |||
186 | static bool cfg_changed; | |||
187 | ||||
188 | static tree rhs_to_tree (tree type, gimple *stmt); | |||
189 | ||||
190 | static bitmap to_purge; | |||
191 | ||||
192 | /* Const-and-copy lattice. */ | |||
193 | static vec<tree> lattice; | |||
194 | ||||
195 | /* Set the lattice entry for NAME to VAL. */ | |||
196 | static void | |||
197 | fwprop_set_lattice_val (tree name, tree val) | |||
198 | { | |||
199 | if (TREE_CODE (name)((enum tree_code) (name)->base.code) == SSA_NAME) | |||
200 | { | |||
201 | if (SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 201, __FUNCTION__, (SSA_NAME)))->base.u.version >= lattice.length ()) | |||
202 | { | |||
203 | lattice.reserve (num_ssa_names(vec_safe_length ((cfun + 0)->gimple_df->ssa_names)) - lattice.length ()); | |||
204 | lattice.quick_grow_cleared (num_ssa_names(vec_safe_length ((cfun + 0)->gimple_df->ssa_names))); | |||
205 | } | |||
206 | lattice[SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 206, __FUNCTION__, (SSA_NAME)))->base.u.version] = val; | |||
207 | } | |||
208 | } | |||
209 | ||||
210 | /* Invalidate the lattice entry for NAME, done when releasing SSA names. */ | |||
211 | static void | |||
212 | fwprop_invalidate_lattice (tree name) | |||
213 | { | |||
214 | if (name | |||
215 | && TREE_CODE (name)((enum tree_code) (name)->base.code) == SSA_NAME | |||
216 | && SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 216, __FUNCTION__, (SSA_NAME)))->base.u.version < lattice.length ()) | |||
217 | lattice[SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 217, __FUNCTION__, (SSA_NAME)))->base.u.version] = NULL_TREE(tree) nullptr; | |||
218 | } | |||
219 | ||||
220 | ||||
221 | /* Get the statement we can propagate from into NAME skipping | |||
222 | trivial copies. Returns the statement which defines the | |||
223 | propagation source or NULL_TREE if there is no such one. | |||
224 | If SINGLE_USE_ONLY is set considers only sources which have | |||
225 | a single use chain up to NAME. If SINGLE_USE_P is non-null, | |||
226 | it is set to whether the chain to NAME is a single use chain | |||
227 | or not. SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set. */ | |||
228 | ||||
229 | static gimple * | |||
230 | get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p) | |||
231 | { | |||
232 | bool single_use = true; | |||
233 | ||||
234 | do { | |||
235 | gimple *def_stmt = SSA_NAME_DEF_STMT (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 235, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
236 | ||||
237 | if (!has_single_use (name)) | |||
238 | { | |||
239 | single_use = false; | |||
240 | if (single_use_only) | |||
241 | return NULLnullptr; | |||
242 | } | |||
243 | ||||
244 | /* If name is defined by a PHI node or is the default def, bail out. */ | |||
245 | if (!is_gimple_assign (def_stmt)) | |||
246 | return NULLnullptr; | |||
247 | ||||
248 | /* If def_stmt is a simple copy, continue looking. */ | |||
249 | if (gimple_assign_rhs_code (def_stmt) == SSA_NAME) | |||
250 | name = gimple_assign_rhs1 (def_stmt); | |||
251 | else | |||
252 | { | |||
253 | if (!single_use_only && single_use_p) | |||
254 | *single_use_p = single_use; | |||
255 | ||||
256 | return def_stmt; | |||
257 | } | |||
258 | } while (1); | |||
259 | } | |||
260 | ||||
261 | /* Checks if the destination ssa name in DEF_STMT can be used as | |||
262 | propagation source. Returns true if so, otherwise false. */ | |||
263 | ||||
264 | static bool | |||
265 | can_propagate_from (gimple *def_stmt) | |||
266 | { | |||
267 | gcc_assert (is_gimple_assign (def_stmt))((void)(!(is_gimple_assign (def_stmt)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 267, __FUNCTION__), 0 : 0)); | |||
268 | ||||
269 | /* If the rhs has side-effects we cannot propagate from it. */ | |||
270 | if (gimple_has_volatile_ops (def_stmt)) | |||
271 | return false; | |||
272 | ||||
273 | /* If the rhs is a load we cannot propagate from it. */ | |||
274 | if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))tree_code_type_tmpl <0>::tree_code_type[(int) (gimple_assign_rhs_code (def_stmt))] == tcc_reference | |||
275 | || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))tree_code_type_tmpl <0>::tree_code_type[(int) (gimple_assign_rhs_code (def_stmt))] == tcc_declaration) | |||
276 | return false; | |||
277 | ||||
278 | /* Constants can be always propagated. */ | |||
279 | if (gimple_assign_single_p (def_stmt) | |||
280 | && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))) | |||
281 | return true; | |||
282 | ||||
283 | /* We cannot propagate ssa names that occur in abnormal phi nodes. */ | |||
284 | if (stmt_references_abnormal_ssa_name (def_stmt)) | |||
285 | return false; | |||
286 | ||||
287 | /* If the definition is a conversion of a pointer to a function type, | |||
288 | then we cannot apply optimizations as some targets require | |||
289 | function pointers to be canonicalized and in this case this | |||
290 | optimization could eliminate a necessary canonicalization. */ | |||
291 | if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))((gimple_assign_rhs_code (def_stmt)) == NOP_EXPR || (gimple_assign_rhs_code (def_stmt)) == CONVERT_EXPR)) | |||
292 | { | |||
293 | tree rhs = gimple_assign_rhs1 (def_stmt); | |||
294 | if (POINTER_TYPE_P (TREE_TYPE (rhs))(((enum tree_code) (((contains_struct_check ((rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 294, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 294, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ) | |||
295 | && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs)))((enum tree_code) (((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 295, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 295, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE) | |||
296 | return false; | |||
297 | } | |||
298 | ||||
299 | return true; | |||
300 | } | |||
301 | ||||
302 | /* Remove a chain of dead statements starting at the definition of | |||
303 | NAME. The chain is linked via the first operand of the defining statements. | |||
304 | If NAME was replaced in its only use then this function can be used | |||
305 | to clean up dead stmts. The function handles already released SSA | |||
306 | names gracefully. | |||
307 | Returns true if cleanup-cfg has to run. */ | |||
308 | ||||
309 | static bool | |||
310 | remove_prop_source_from_use (tree name) | |||
311 | { | |||
312 | gimple_stmt_iterator gsi; | |||
313 | gimple *stmt; | |||
314 | bool cfg_changed = false; | |||
315 | ||||
316 | do { | |||
317 | basic_block bb; | |||
318 | ||||
319 | if (SSA_NAME_IN_FREE_LIST (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 319, __FUNCTION__, (SSA_NAME)))->base.nothrow_flag | |||
320 | || SSA_NAME_IS_DEFAULT_DEF (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 320, __FUNCTION__, (SSA_NAME)))->base.default_def_flag | |||
321 | || !has_zero_uses (name)) | |||
322 | return cfg_changed; | |||
323 | ||||
324 | stmt = SSA_NAME_DEF_STMT (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 324, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
325 | if (gimple_code (stmt) == GIMPLE_PHI | |||
326 | || gimple_has_side_effects (stmt)) | |||
327 | return cfg_changed; | |||
328 | ||||
329 | bb = gimple_bb (stmt); | |||
330 | gsi = gsi_for_stmt (stmt); | |||
331 | unlink_stmt_vdef (stmt); | |||
332 | if (gsi_remove (&gsi, true)) | |||
333 | bitmap_set_bit (to_purge, bb->index); | |||
334 | fwprop_invalidate_lattice (gimple_get_lhs (stmt)); | |||
335 | release_defs (stmt); | |||
336 | ||||
337 | name = is_gimple_assign (stmt) ? gimple_assign_rhs1 (stmt) : NULL_TREE(tree) nullptr; | |||
338 | } while (name && TREE_CODE (name)((enum tree_code) (name)->base.code) == SSA_NAME); | |||
339 | ||||
340 | return cfg_changed; | |||
341 | } | |||
342 | ||||
343 | /* Return the rhs of a gassign *STMT in a form of a single tree, | |||
344 | converted to type TYPE. | |||
345 | ||||
346 | This should disappear, but is needed so we can combine expressions and use | |||
347 | the fold() interfaces. Long term, we need to develop folding and combine | |||
348 | routines that deal with gimple exclusively . */ | |||
349 | ||||
350 | static tree | |||
351 | rhs_to_tree (tree type, gimple *stmt) | |||
352 | { | |||
353 | location_t loc = gimple_location (stmt); | |||
354 | enum tree_code code = gimple_assign_rhs_code (stmt); | |||
355 | switch (get_gimple_rhs_class (code)) | |||
356 | { | |||
357 | case GIMPLE_TERNARY_RHS: | |||
358 | return fold_build3_loc (loc, code, type, gimple_assign_rhs1 (stmt), | |||
359 | gimple_assign_rhs2 (stmt), | |||
360 | gimple_assign_rhs3 (stmt)); | |||
361 | case GIMPLE_BINARY_RHS: | |||
362 | return fold_build2_loc (loc, code, type, gimple_assign_rhs1 (stmt), | |||
363 | gimple_assign_rhs2 (stmt)); | |||
364 | case GIMPLE_UNARY_RHS: | |||
365 | return build1 (code, type, gimple_assign_rhs1 (stmt)); | |||
366 | case GIMPLE_SINGLE_RHS: | |||
367 | return gimple_assign_rhs1 (stmt); | |||
368 | default: | |||
369 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 369, __FUNCTION__)); | |||
370 | } | |||
371 | } | |||
372 | ||||
373 | /* Combine OP0 CODE OP1 in the context of a COND_EXPR. Returns | |||
374 | the folded result in a form suitable for COND_EXPR_COND or | |||
375 | NULL_TREE, if there is no suitable simplified form. If | |||
376 | INVARIANT_ONLY is true only gimple_min_invariant results are | |||
377 | considered simplified. */ | |||
378 | ||||
379 | static tree | |||
380 | combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type, | |||
381 | tree op0, tree op1, bool invariant_only) | |||
382 | { | |||
383 | tree t; | |||
384 | ||||
385 | gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison)((void)(!(tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_comparison) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 385, __FUNCTION__), 0 : 0)); | |||
386 | ||||
387 | fold_defer_overflow_warnings (); | |||
388 | t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1); | |||
389 | if (!t) | |||
390 | { | |||
391 | fold_undefer_overflow_warnings (false, NULLnullptr, 0); | |||
392 | return NULL_TREE(tree) nullptr; | |||
393 | } | |||
394 | ||||
395 | /* Require that we got a boolean type out if we put one in. */ | |||
396 | gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type))((void)(!(((enum tree_code) (((contains_struct_check ((t), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 396, __FUNCTION__))->typed.type))->base.code) == ((enum tree_code) (type)->base.code)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 396, __FUNCTION__), 0 : 0)); | |||
397 | ||||
398 | /* Canonicalize the combined condition for use in a COND_EXPR. */ | |||
399 | t = canonicalize_cond_expr_cond (t); | |||
400 | ||||
401 | /* Bail out if we required an invariant but didn't get one. */ | |||
402 | if (!t || (invariant_only && !is_gimple_min_invariant (t))) | |||
403 | { | |||
404 | fold_undefer_overflow_warnings (false, NULLnullptr, 0); | |||
405 | return NULL_TREE(tree) nullptr; | |||
406 | } | |||
407 | ||||
408 | bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow); | |||
409 | fold_undefer_overflow_warnings (!nowarn, stmt, 0); | |||
410 | ||||
411 | return t; | |||
412 | } | |||
413 | ||||
414 | /* Combine the comparison OP0 CODE OP1 at LOC with the defining statements | |||
415 | of its operand. Return a new comparison tree or NULL_TREE if there | |||
416 | were no simplifying combines. */ | |||
417 | ||||
418 | static tree | |||
419 | forward_propagate_into_comparison_1 (gimple *stmt, | |||
420 | enum tree_code code, tree type, | |||
421 | tree op0, tree op1) | |||
422 | { | |||
423 | tree tmp = NULL_TREE(tree) nullptr; | |||
424 | tree rhs0 = NULL_TREE(tree) nullptr, rhs1 = NULL_TREE(tree) nullptr; | |||
425 | bool single_use0_p = false, single_use1_p = false; | |||
426 | ||||
427 | /* For comparisons use the first operand, that is likely to | |||
428 | simplify comparisons against constants. */ | |||
429 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == SSA_NAME) | |||
430 | { | |||
431 | gimple *def_stmt = get_prop_source_stmt (op0, false, &single_use0_p); | |||
432 | if (def_stmt && can_propagate_from (def_stmt)) | |||
433 | { | |||
434 | enum tree_code def_code = gimple_assign_rhs_code (def_stmt); | |||
435 | bool invariant_only_p = !single_use0_p; | |||
436 | ||||
437 | rhs0 = rhs_to_tree (TREE_TYPE (op1)((contains_struct_check ((op1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 437, __FUNCTION__))->typed.type), def_stmt); | |||
438 | ||||
439 | /* Always combine comparisons or conversions from booleans. */ | |||
440 | if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) == INTEGER_CST | |||
441 | && ((CONVERT_EXPR_CODE_P (def_code)((def_code) == NOP_EXPR || (def_code) == CONVERT_EXPR) | |||
442 | && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs0, 0)))((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((rhs0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 442, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 442, __FUNCTION__))->typed.type))->base.code) | |||
443 | == BOOLEAN_TYPE) | |||
444 | || TREE_CODE_CLASS (def_code)tree_code_type_tmpl <0>::tree_code_type[(int) (def_code )] == tcc_comparison)) | |||
445 | invariant_only_p = false; | |||
446 | ||||
447 | tmp = combine_cond_expr_cond (stmt, code, type, | |||
448 | rhs0, op1, invariant_only_p); | |||
449 | if (tmp) | |||
450 | return tmp; | |||
451 | } | |||
452 | } | |||
453 | ||||
454 | /* If that wasn't successful, try the second operand. */ | |||
455 | if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) == SSA_NAME) | |||
456 | { | |||
457 | gimple *def_stmt = get_prop_source_stmt (op1, false, &single_use1_p); | |||
458 | if (def_stmt && can_propagate_from (def_stmt)) | |||
459 | { | |||
460 | rhs1 = rhs_to_tree (TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 460, __FUNCTION__))->typed.type), def_stmt); | |||
461 | tmp = combine_cond_expr_cond (stmt, code, type, | |||
462 | op0, rhs1, !single_use1_p); | |||
463 | if (tmp) | |||
464 | return tmp; | |||
465 | } | |||
466 | } | |||
467 | ||||
468 | /* If that wasn't successful either, try both operands. */ | |||
469 | if (rhs0 != NULL_TREE(tree) nullptr | |||
470 | && rhs1 != NULL_TREE(tree) nullptr) | |||
471 | tmp = combine_cond_expr_cond (stmt, code, type, | |||
472 | rhs0, rhs1, | |||
473 | !(single_use0_p && single_use1_p)); | |||
474 | ||||
475 | return tmp; | |||
476 | } | |||
477 | ||||
478 | /* Propagate from the ssa name definition statements of the assignment | |||
479 | from a comparison at *GSI into the conditional if that simplifies it. | |||
480 | Returns 1 if the stmt was modified and 2 if the CFG needs cleanup, | |||
481 | otherwise returns 0. */ | |||
482 | ||||
483 | static int | |||
484 | forward_propagate_into_comparison (gimple_stmt_iterator *gsi) | |||
485 | { | |||
486 | gimple *stmt = gsi_stmt (*gsi); | |||
487 | tree tmp; | |||
488 | bool cfg_changed = false; | |||
489 | tree type = TREE_TYPE (gimple_assign_lhs (stmt))((contains_struct_check ((gimple_assign_lhs (stmt)), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 489, __FUNCTION__))->typed.type); | |||
490 | tree rhs1 = gimple_assign_rhs1 (stmt); | |||
491 | tree rhs2 = gimple_assign_rhs2 (stmt); | |||
492 | ||||
493 | /* Combine the comparison with defining statements. */ | |||
494 | tmp = forward_propagate_into_comparison_1 (stmt, | |||
495 | gimple_assign_rhs_code (stmt), | |||
496 | type, rhs1, rhs2); | |||
497 | if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp)((contains_struct_check ((tmp), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 497, __FUNCTION__))->typed.type))) | |||
498 | { | |||
499 | gimple_assign_set_rhs_from_tree (gsi, tmp); | |||
500 | fold_stmt (gsi); | |||
501 | update_stmt (gsi_stmt (*gsi)); | |||
502 | ||||
503 | if (TREE_CODE (rhs1)((enum tree_code) (rhs1)->base.code) == SSA_NAME) | |||
504 | cfg_changed |= remove_prop_source_from_use (rhs1); | |||
505 | if (TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) == SSA_NAME) | |||
506 | cfg_changed |= remove_prop_source_from_use (rhs2); | |||
507 | return cfg_changed ? 2 : 1; | |||
508 | } | |||
509 | ||||
510 | return 0; | |||
511 | } | |||
512 | ||||
513 | /* Propagate from the ssa name definition statements of COND_EXPR | |||
514 | in GIMPLE_COND statement STMT into the conditional if that simplifies it. | |||
515 | Returns zero if no statement was changed, one if there were | |||
516 | changes and two if cfg_cleanup needs to run. */ | |||
517 | ||||
518 | static int | |||
519 | forward_propagate_into_gimple_cond (gcond *stmt) | |||
520 | { | |||
521 | tree tmp; | |||
522 | enum tree_code code = gimple_cond_code (stmt); | |||
523 | bool cfg_changed = false; | |||
524 | tree rhs1 = gimple_cond_lhs (stmt); | |||
525 | tree rhs2 = gimple_cond_rhs (stmt); | |||
526 | ||||
527 | /* We can do tree combining on SSA_NAME and comparison expressions. */ | |||
528 | if (TREE_CODE_CLASS (gimple_cond_code (stmt))tree_code_type_tmpl <0>::tree_code_type[(int) (gimple_cond_code (stmt))] != tcc_comparison) | |||
529 | return 0; | |||
530 | ||||
531 | tmp = forward_propagate_into_comparison_1 (stmt, code, | |||
532 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | |||
533 | rhs1, rhs2); | |||
534 | if (tmp | |||
535 | && is_gimple_condexpr_for_cond (tmp)) | |||
536 | { | |||
537 | if (dump_file) | |||
538 | { | |||
539 | fprintf (dump_file, " Replaced '"); | |||
540 | print_gimple_expr (dump_file, stmt, 0); | |||
541 | fprintf (dump_file, "' with '"); | |||
542 | print_generic_expr (dump_file, tmp); | |||
543 | fprintf (dump_file, "'\n"); | |||
544 | } | |||
545 | ||||
546 | gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp)); | |||
547 | update_stmt (stmt); | |||
548 | ||||
549 | if (TREE_CODE (rhs1)((enum tree_code) (rhs1)->base.code) == SSA_NAME) | |||
550 | cfg_changed |= remove_prop_source_from_use (rhs1); | |||
551 | if (TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) == SSA_NAME) | |||
552 | cfg_changed |= remove_prop_source_from_use (rhs2); | |||
553 | return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1; | |||
554 | } | |||
555 | ||||
556 | /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */ | |||
557 | if ((TREE_CODE (TREE_TYPE (rhs1))((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 557, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE | |||
558 | || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))(((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 558, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 558, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 558, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
559 | && TYPE_PRECISION (TREE_TYPE (rhs1))((tree_class_check ((((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 559, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 559, __FUNCTION__))->type_common.precision) == 1)) | |||
560 | && ((code == EQ_EXPR | |||
561 | && integer_zerop (rhs2)) | |||
562 | || (code == NE_EXPR | |||
563 | && integer_onep (rhs2)))) | |||
564 | { | |||
565 | basic_block bb = gimple_bb (stmt); | |||
566 | gimple_cond_set_code (stmt, NE_EXPR); | |||
567 | gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 567, __FUNCTION__))->typed.type))); | |||
568 | EDGE_SUCC (bb, 0)(*(bb)->succs)[(0)]->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); | |||
569 | EDGE_SUCC (bb, 1)(*(bb)->succs)[(1)]->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); | |||
570 | return 1; | |||
571 | } | |||
572 | ||||
573 | return 0; | |||
574 | } | |||
575 | ||||
576 | /* We've just substituted an ADDR_EXPR into stmt. Update all the | |||
577 | relevant data structures to match. */ | |||
578 | ||||
579 | static void | |||
580 | tidy_after_forward_propagate_addr (gimple *stmt) | |||
581 | { | |||
582 | /* We may have turned a trapping insn into a non-trapping insn. */ | |||
583 | if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) | |||
584 | bitmap_set_bit (to_purge, gimple_bb (stmt)->index); | |||
585 | ||||
586 | if (TREE_CODE (gimple_assign_rhs1 (stmt))((enum tree_code) (gimple_assign_rhs1 (stmt))->base.code) == ADDR_EXPR) | |||
587 | recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt)); | |||
588 | } | |||
589 | ||||
590 | /* NAME is a SSA_NAME representing DEF_RHS which is of the form | |||
591 | ADDR_EXPR <whatever>. | |||
592 | ||||
593 | Try to forward propagate the ADDR_EXPR into the use USE_STMT. | |||
594 | Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF | |||
595 | node or for recovery of array indexing from pointer arithmetic. | |||
596 | ||||
597 | Return true if the propagation was successful (the propagation can | |||
598 | be not totally successful, yet things may have been changed). */ | |||
599 | ||||
600 | static bool | |||
601 | forward_propagate_addr_expr_1 (tree name, tree def_rhs, | |||
602 | gimple_stmt_iterator *use_stmt_gsi, | |||
603 | bool single_use_p) | |||
604 | { | |||
605 | tree lhs, rhs, rhs2, array_ref; | |||
606 | gimple *use_stmt = gsi_stmt (*use_stmt_gsi); | |||
607 | enum tree_code rhs_code; | |||
608 | bool res = true; | |||
609 | ||||
610 | gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR)((void)(!(((enum tree_code) (def_rhs)->base.code) == ADDR_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 610, __FUNCTION__), 0 : 0)); | |||
611 | ||||
612 | lhs = gimple_assign_lhs (use_stmt); | |||
613 | rhs_code = gimple_assign_rhs_code (use_stmt); | |||
614 | rhs = gimple_assign_rhs1 (use_stmt); | |||
615 | ||||
616 | /* Do not perform copy-propagation but recurse through copy chains. */ | |||
617 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME | |||
618 | && rhs_code == SSA_NAME) | |||
619 | return forward_propagate_addr_expr (lhs, def_rhs, single_use_p); | |||
620 | ||||
621 | /* The use statement could be a conversion. Recurse to the uses of the | |||
622 | lhs as copyprop does not copy through pointer to integer to pointer | |||
623 | conversions and FRE does not catch all cases either. | |||
624 | Treat the case of a single-use name and | |||
625 | a conversion to def_rhs type separate, though. */ | |||
626 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME | |||
627 | && CONVERT_EXPR_CODE_P (rhs_code)((rhs_code) == NOP_EXPR || (rhs_code) == CONVERT_EXPR)) | |||
628 | { | |||
629 | /* If there is a point in a conversion chain where the types match | |||
630 | so we can remove a conversion re-materialize the address here | |||
631 | and stop. */ | |||
632 | if (single_use_p | |||
633 | && useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 633, __FUNCTION__))->typed.type), TREE_TYPE (def_rhs)((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 633, __FUNCTION__))->typed.type))) | |||
634 | { | |||
635 | gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs)); | |||
636 | gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs)((enum tree_code) (def_rhs)->base.code)); | |||
637 | return true; | |||
638 | } | |||
639 | ||||
640 | /* Else recurse if the conversion preserves the address value. */ | |||
641 | if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 641, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 641, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 641, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
642 | || POINTER_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 642, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 642, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) | |||
643 | && (TYPE_PRECISION (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 643, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 643, __FUNCTION__))->type_common.precision) | |||
644 | >= TYPE_PRECISION (TREE_TYPE (def_rhs))((tree_class_check ((((contains_struct_check ((def_rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 644, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 644, __FUNCTION__))->type_common.precision))) | |||
645 | return forward_propagate_addr_expr (lhs, def_rhs, single_use_p); | |||
646 | ||||
647 | return false; | |||
648 | } | |||
649 | ||||
650 | /* If this isn't a conversion chain from this on we only can propagate | |||
651 | into compatible pointer contexts. */ | |||
652 | if (!types_compatible_p (TREE_TYPE (name)((contains_struct_check ((name), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 652, __FUNCTION__))->typed.type), TREE_TYPE (def_rhs)((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 652, __FUNCTION__))->typed.type))) | |||
653 | return false; | |||
654 | ||||
655 | /* Propagate through constant pointer adjustments. */ | |||
656 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME | |||
657 | && rhs_code == POINTER_PLUS_EXPR | |||
658 | && rhs == name | |||
659 | && TREE_CODE (gimple_assign_rhs2 (use_stmt))((enum tree_code) (gimple_assign_rhs2 (use_stmt))->base.code ) == INTEGER_CST) | |||
660 | { | |||
661 | tree new_def_rhs; | |||
662 | /* As we come here with non-invariant addresses in def_rhs we need | |||
663 | to make sure we can build a valid constant offsetted address | |||
664 | for further propagation. Simply rely on fold building that | |||
665 | and check after the fact. */ | |||
666 | new_def_rhs = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (rhs)),fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type), def_rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], gimple_assign_rhs2 (use_stmt)) ) | |||
667 | def_rhs,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type), def_rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], gimple_assign_rhs2 (use_stmt)) ) | |||
668 | fold_convert (ptr_type_node,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type), def_rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], gimple_assign_rhs2 (use_stmt)) ) | |||
669 | gimple_assign_rhs2 (use_stmt)))fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 666, __FUNCTION__))->typed.type), def_rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], gimple_assign_rhs2 (use_stmt)) ); | |||
670 | if (TREE_CODE (new_def_rhs)((enum tree_code) (new_def_rhs)->base.code) == MEM_REF | |||
671 | && !is_gimple_mem_ref_addr (TREE_OPERAND (new_def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((new_def_rhs ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 671, __FUNCTION__))))))) | |||
672 | return false; | |||
673 | new_def_rhs = build1 (ADDR_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 673, __FUNCTION__))->typed.type), new_def_rhs); | |||
674 | ||||
675 | /* Recurse. If we could propagate into all uses of lhs do not | |||
676 | bother to replace into the current use but just pretend we did. */ | |||
677 | if (forward_propagate_addr_expr (lhs, new_def_rhs, single_use_p)) | |||
678 | return true; | |||
679 | ||||
680 | if (useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 680, __FUNCTION__))->typed.type), | |||
681 | TREE_TYPE (new_def_rhs)((contains_struct_check ((new_def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 681, __FUNCTION__))->typed.type))) | |||
682 | gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs)((enum tree_code) (new_def_rhs)->base.code), | |||
683 | new_def_rhs); | |||
684 | else if (is_gimple_min_invariant (new_def_rhs)) | |||
685 | gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR, new_def_rhs); | |||
686 | else | |||
687 | return false; | |||
688 | gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt)((void)(!(gsi_stmt (*use_stmt_gsi) == use_stmt) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 688, __FUNCTION__), 0 : 0)); | |||
689 | update_stmt (use_stmt); | |||
690 | return true; | |||
691 | } | |||
692 | ||||
693 | /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. | |||
694 | ADDR_EXPR will not appear on the LHS. */ | |||
695 | tree *lhsp = gimple_assign_lhs_ptr (use_stmt); | |||
696 | while (handled_component_p (*lhsp)) | |||
697 | lhsp = &TREE_OPERAND (*lhsp, 0)(*((const_cast<tree*> (tree_operand_check ((*lhsp), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 697, __FUNCTION__))))); | |||
698 | lhs = *lhsp; | |||
699 | ||||
700 | /* Now see if the LHS node is a MEM_REF using NAME. If so, | |||
701 | propagate the ADDR_EXPR into the use of NAME and fold the result. */ | |||
702 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == MEM_REF | |||
703 | && TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 703, __FUNCTION__))))) == name) | |||
704 | { | |||
705 | tree def_rhs_base; | |||
706 | poly_int64 def_rhs_offset; | |||
707 | /* If the address is invariant we can always fold it. */ | |||
708 | if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 708, __FUNCTION__))))), | |||
709 | &def_rhs_offset))) | |||
710 | { | |||
711 | poly_offset_int off = mem_ref_offset (lhs); | |||
712 | tree new_ptr; | |||
713 | off += def_rhs_offset; | |||
714 | if (TREE_CODE (def_rhs_base)((enum tree_code) (def_rhs_base)->base.code) == MEM_REF) | |||
715 | { | |||
716 | off += mem_ref_offset (def_rhs_base); | |||
717 | new_ptr = TREE_OPERAND (def_rhs_base, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs_base ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 717, __FUNCTION__))))); | |||
718 | } | |||
719 | else | |||
720 | new_ptr = build_fold_addr_expr (def_rhs_base)build_fold_addr_expr_loc (((location_t) 0), (def_rhs_base)); | |||
721 | TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 721, __FUNCTION__))))) = new_ptr; | |||
722 | TREE_OPERAND (lhs, 1)(*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 722, __FUNCTION__))))) | |||
723 | = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (lhs, 1))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 723, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 723, __FUNCTION__))->typed.type), off); | |||
724 | tidy_after_forward_propagate_addr (use_stmt); | |||
725 | /* Continue propagating into the RHS if this was not the only use. */ | |||
726 | if (single_use_p) | |||
727 | return true; | |||
728 | } | |||
729 | /* If the LHS is a plain dereference and the value type is the same as | |||
730 | that of the pointed-to type of the address we can put the | |||
731 | dereferenced address on the LHS preserving the original alias-type. */ | |||
732 | else if (integer_zerop (TREE_OPERAND (lhs, 1)(*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 732, __FUNCTION__)))))) | |||
733 | && ((gimple_assign_lhs (use_stmt) == lhs | |||
734 | && useless_type_conversion_p | |||
735 | (TREE_TYPE (TREE_OPERAND (def_rhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((def_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 735, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 735, __FUNCTION__))->typed.type), | |||
736 | TREE_TYPE (gimple_assign_rhs1 (use_stmt))((contains_struct_check ((gimple_assign_rhs1 (use_stmt)), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 736, __FUNCTION__))->typed.type))) | |||
737 | || types_compatible_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 737, __FUNCTION__))->typed.type), | |||
738 | TREE_TYPE (TREE_OPERAND (def_rhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((def_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 738, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 738, __FUNCTION__))->typed.type))) | |||
739 | /* Don't forward anything into clobber stmts if it would result | |||
740 | in the lhs no longer being a MEM_REF. */ | |||
741 | && (!gimple_clobber_p (use_stmt) | |||
742 | || TREE_CODE (TREE_OPERAND (def_rhs, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((def_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 742, __FUNCTION__))))))->base.code) == MEM_REF)) | |||
743 | { | |||
744 | tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 744, __FUNCTION__))))); | |||
745 | tree new_offset, new_base, saved, new_lhs; | |||
746 | while (handled_component_p (*def_rhs_basep)) | |||
747 | def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0)(*((const_cast<tree*> (tree_operand_check ((*def_rhs_basep ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 747, __FUNCTION__))))); | |||
748 | saved = *def_rhs_basep; | |||
749 | if (TREE_CODE (*def_rhs_basep)((enum tree_code) (*def_rhs_basep)->base.code) == MEM_REF) | |||
750 | { | |||
751 | new_base = TREE_OPERAND (*def_rhs_basep, 0)(*((const_cast<tree*> (tree_operand_check ((*def_rhs_basep ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 751, __FUNCTION__))))); | |||
752 | new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),fold_convert_loc (((location_t) 0), ((contains_struct_check ( ((*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 752, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 752, __FUNCTION__))->typed.type), (*((const_cast<tree *> (tree_operand_check ((*def_rhs_basep), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 753, __FUNCTION__)))))) | |||
753 | TREE_OPERAND (*def_rhs_basep, 1))fold_convert_loc (((location_t) 0), ((contains_struct_check ( ((*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 752, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 752, __FUNCTION__))->typed.type), (*((const_cast<tree *> (tree_operand_check ((*def_rhs_basep), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 753, __FUNCTION__)))))); | |||
754 | } | |||
755 | else | |||
756 | { | |||
757 | new_base = build_fold_addr_expr (*def_rhs_basep)build_fold_addr_expr_loc (((location_t) 0), (*def_rhs_basep)); | |||
758 | new_offset = TREE_OPERAND (lhs, 1)(*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 758, __FUNCTION__))))); | |||
759 | } | |||
760 | *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep)((contains_struct_check ((*def_rhs_basep), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 760, __FUNCTION__))->typed.type), | |||
761 | new_base, new_offset); | |||
762 | TREE_THIS_VOLATILE (*def_rhs_basep)((*def_rhs_basep)->base.volatile_flag) = TREE_THIS_VOLATILE (lhs)((lhs)->base.volatile_flag); | |||
763 | TREE_SIDE_EFFECTS (*def_rhs_basep)((non_type_check ((*def_rhs_basep), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 763, __FUNCTION__))->base.side_effects_flag) = TREE_SIDE_EFFECTS (lhs)((non_type_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 763, __FUNCTION__))->base.side_effects_flag); | |||
764 | TREE_THIS_NOTRAP (*def_rhs_basep)((tree_check5 ((*def_rhs_basep), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 764, __FUNCTION__, (INDIRECT_REF), (MEM_REF), (TARGET_MEM_REF ), (ARRAY_REF), (ARRAY_RANGE_REF)))->base.nothrow_flag) = TREE_THIS_NOTRAP (lhs)((tree_check5 ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 764, __FUNCTION__, (INDIRECT_REF), (MEM_REF), (TARGET_MEM_REF ), (ARRAY_REF), (ARRAY_RANGE_REF)))->base.nothrow_flag); | |||
765 | new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 765, __FUNCTION__)))))); | |||
766 | *lhsp = new_lhs; | |||
767 | TREE_THIS_VOLATILE (new_lhs)((new_lhs)->base.volatile_flag) = TREE_THIS_VOLATILE (lhs)((lhs)->base.volatile_flag); | |||
768 | TREE_SIDE_EFFECTS (new_lhs)((non_type_check ((new_lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 768, __FUNCTION__))->base.side_effects_flag) = TREE_SIDE_EFFECTS (lhs)((non_type_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 768, __FUNCTION__))->base.side_effects_flag); | |||
769 | *def_rhs_basep = saved; | |||
770 | tidy_after_forward_propagate_addr (use_stmt); | |||
771 | /* Continue propagating into the RHS if this was not the | |||
772 | only use. */ | |||
773 | if (single_use_p) | |||
774 | return true; | |||
775 | } | |||
776 | else | |||
777 | /* We can have a struct assignment dereferencing our name twice. | |||
778 | Note that we didn't propagate into the lhs to not falsely | |||
779 | claim we did when propagating into the rhs. */ | |||
780 | res = false; | |||
781 | } | |||
782 | ||||
783 | /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR | |||
784 | nodes from the RHS. */ | |||
785 | tree *rhsp = gimple_assign_rhs1_ptr (use_stmt); | |||
786 | if (TREE_CODE (*rhsp)((enum tree_code) (*rhsp)->base.code) == ADDR_EXPR) | |||
787 | rhsp = &TREE_OPERAND (*rhsp, 0)(*((const_cast<tree*> (tree_operand_check ((*rhsp), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 787, __FUNCTION__))))); | |||
788 | while (handled_component_p (*rhsp)) | |||
789 | rhsp = &TREE_OPERAND (*rhsp, 0)(*((const_cast<tree*> (tree_operand_check ((*rhsp), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 789, __FUNCTION__))))); | |||
790 | rhs = *rhsp; | |||
791 | ||||
792 | /* Now see if the RHS node is a MEM_REF using NAME. If so, | |||
793 | propagate the ADDR_EXPR into the use of NAME and fold the result. */ | |||
794 | if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == MEM_REF | |||
795 | && TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 795, __FUNCTION__))))) == name) | |||
796 | { | |||
797 | tree def_rhs_base; | |||
798 | poly_int64 def_rhs_offset; | |||
799 | if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 799, __FUNCTION__))))), | |||
800 | &def_rhs_offset))) | |||
801 | { | |||
802 | poly_offset_int off = mem_ref_offset (rhs); | |||
803 | tree new_ptr; | |||
804 | off += def_rhs_offset; | |||
805 | if (TREE_CODE (def_rhs_base)((enum tree_code) (def_rhs_base)->base.code) == MEM_REF) | |||
806 | { | |||
807 | off += mem_ref_offset (def_rhs_base); | |||
808 | new_ptr = TREE_OPERAND (def_rhs_base, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs_base ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 808, __FUNCTION__))))); | |||
809 | } | |||
810 | else | |||
811 | new_ptr = build_fold_addr_expr (def_rhs_base)build_fold_addr_expr_loc (((location_t) 0), (def_rhs_base)); | |||
812 | TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 812, __FUNCTION__))))) = new_ptr; | |||
813 | TREE_OPERAND (rhs, 1)(*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 813, __FUNCTION__))))) | |||
814 | = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 814, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 814, __FUNCTION__))->typed.type), off); | |||
815 | fold_stmt_inplace (use_stmt_gsi); | |||
816 | tidy_after_forward_propagate_addr (use_stmt); | |||
817 | return res; | |||
818 | } | |||
819 | /* If the RHS is a plain dereference and the value type is the same as | |||
820 | that of the pointed-to type of the address we can put the | |||
821 | dereferenced address on the RHS preserving the original alias-type. */ | |||
822 | else if (integer_zerop (TREE_OPERAND (rhs, 1)(*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 822, __FUNCTION__)))))) | |||
823 | && ((gimple_assign_rhs1 (use_stmt) == rhs | |||
824 | && useless_type_conversion_p | |||
825 | (TREE_TYPE (gimple_assign_lhs (use_stmt))((contains_struct_check ((gimple_assign_lhs (use_stmt)), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 825, __FUNCTION__))->typed.type), | |||
826 | TREE_TYPE (TREE_OPERAND (def_rhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((def_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 826, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 826, __FUNCTION__))->typed.type))) | |||
827 | || types_compatible_p (TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 827, __FUNCTION__))->typed.type), | |||
828 | TREE_TYPE (TREE_OPERAND (def_rhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((def_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 828, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 828, __FUNCTION__))->typed.type)))) | |||
829 | { | |||
830 | tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 830, __FUNCTION__))))); | |||
831 | tree new_offset, new_base, saved, new_rhs; | |||
832 | while (handled_component_p (*def_rhs_basep)) | |||
833 | def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0)(*((const_cast<tree*> (tree_operand_check ((*def_rhs_basep ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 833, __FUNCTION__))))); | |||
834 | saved = *def_rhs_basep; | |||
835 | if (TREE_CODE (*def_rhs_basep)((enum tree_code) (*def_rhs_basep)->base.code) == MEM_REF) | |||
836 | { | |||
837 | new_base = TREE_OPERAND (*def_rhs_basep, 0)(*((const_cast<tree*> (tree_operand_check ((*def_rhs_basep ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 837, __FUNCTION__))))); | |||
838 | new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),fold_convert_loc (((location_t) 0), ((contains_struct_check ( ((*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 838, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 838, __FUNCTION__))->typed.type), (*((const_cast<tree *> (tree_operand_check ((*def_rhs_basep), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 839, __FUNCTION__)))))) | |||
839 | TREE_OPERAND (*def_rhs_basep, 1))fold_convert_loc (((location_t) 0), ((contains_struct_check ( ((*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 838, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 838, __FUNCTION__))->typed.type), (*((const_cast<tree *> (tree_operand_check ((*def_rhs_basep), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 839, __FUNCTION__)))))); | |||
840 | } | |||
841 | else | |||
842 | { | |||
843 | new_base = build_fold_addr_expr (*def_rhs_basep)build_fold_addr_expr_loc (((location_t) 0), (*def_rhs_basep)); | |||
844 | new_offset = TREE_OPERAND (rhs, 1)(*((const_cast<tree*> (tree_operand_check ((rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 844, __FUNCTION__))))); | |||
845 | } | |||
846 | *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep)((contains_struct_check ((*def_rhs_basep), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 846, __FUNCTION__))->typed.type), | |||
847 | new_base, new_offset); | |||
848 | TREE_THIS_VOLATILE (*def_rhs_basep)((*def_rhs_basep)->base.volatile_flag) = TREE_THIS_VOLATILE (rhs)((rhs)->base.volatile_flag); | |||
849 | TREE_SIDE_EFFECTS (*def_rhs_basep)((non_type_check ((*def_rhs_basep), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 849, __FUNCTION__))->base.side_effects_flag) = TREE_SIDE_EFFECTS (rhs)((non_type_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 849, __FUNCTION__))->base.side_effects_flag); | |||
850 | TREE_THIS_NOTRAP (*def_rhs_basep)((tree_check5 ((*def_rhs_basep), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 850, __FUNCTION__, (INDIRECT_REF), (MEM_REF), (TARGET_MEM_REF ), (ARRAY_REF), (ARRAY_RANGE_REF)))->base.nothrow_flag) = TREE_THIS_NOTRAP (rhs)((tree_check5 ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 850, __FUNCTION__, (INDIRECT_REF), (MEM_REF), (TARGET_MEM_REF ), (ARRAY_REF), (ARRAY_RANGE_REF)))->base.nothrow_flag); | |||
851 | new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 851, __FUNCTION__)))))); | |||
852 | *rhsp = new_rhs; | |||
853 | TREE_THIS_VOLATILE (new_rhs)((new_rhs)->base.volatile_flag) = TREE_THIS_VOLATILE (rhs)((rhs)->base.volatile_flag); | |||
854 | TREE_SIDE_EFFECTS (new_rhs)((non_type_check ((new_rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 854, __FUNCTION__))->base.side_effects_flag) = TREE_SIDE_EFFECTS (rhs)((non_type_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 854, __FUNCTION__))->base.side_effects_flag); | |||
855 | *def_rhs_basep = saved; | |||
856 | fold_stmt_inplace (use_stmt_gsi); | |||
857 | tidy_after_forward_propagate_addr (use_stmt); | |||
858 | return res; | |||
859 | } | |||
860 | } | |||
861 | ||||
862 | /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there | |||
863 | is nothing to do. */ | |||
864 | if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR | |||
865 | || gimple_assign_rhs1 (use_stmt) != name) | |||
866 | return false; | |||
867 | ||||
868 | /* The remaining cases are all for turning pointer arithmetic into | |||
869 | array indexing. They only apply when we have the address of | |||
870 | element zero in an array. If that is not the case then there | |||
871 | is nothing to do. */ | |||
872 | array_ref = TREE_OPERAND (def_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((def_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 872, __FUNCTION__))))); | |||
873 | if ((TREE_CODE (array_ref)((enum tree_code) (array_ref)->base.code) != ARRAY_REF | |||
874 | || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0)))((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((array_ref), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 874, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 874, __FUNCTION__))->typed.type))->base.code) != ARRAY_TYPE | |||
875 | || TREE_CODE (TREE_OPERAND (array_ref, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((array_ref), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 875, __FUNCTION__))))))->base.code) != INTEGER_CST) | |||
876 | && TREE_CODE (TREE_TYPE (array_ref))((enum tree_code) (((contains_struct_check ((array_ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 876, __FUNCTION__))->typed.type))->base.code) != ARRAY_TYPE) | |||
877 | return false; | |||
878 | ||||
879 | rhs2 = gimple_assign_rhs2 (use_stmt); | |||
880 | /* Optimize &x[C1] p+ C2 to &x p+ C3 with C3 = C1 * element_size + C2. */ | |||
881 | if (TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) == INTEGER_CST) | |||
882 | { | |||
883 | tree new_rhs = build1_loc (gimple_location (use_stmt), | |||
884 | ADDR_EXPR, TREE_TYPE (def_rhs)((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 884, __FUNCTION__))->typed.type), | |||
885 | fold_build2 (MEM_REF,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type), unshare_expr (def_rhs) , fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE ], rhs2) ) | |||
886 | TREE_TYPE (TREE_TYPE (def_rhs)),fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type), unshare_expr (def_rhs) , fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE ], rhs2) ) | |||
887 | unshare_expr (def_rhs),fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type), unshare_expr (def_rhs) , fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE ], rhs2) ) | |||
888 | fold_convert (ptr_type_node,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type), unshare_expr (def_rhs) , fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE ], rhs2) ) | |||
889 | rhs2))fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((def_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 886, __FUNCTION__))->typed.type), unshare_expr (def_rhs) , fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE ], rhs2) )); | |||
890 | gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs); | |||
891 | use_stmt = gsi_stmt (*use_stmt_gsi); | |||
892 | update_stmt (use_stmt); | |||
893 | tidy_after_forward_propagate_addr (use_stmt); | |||
894 | return true; | |||
895 | } | |||
896 | ||||
897 | return false; | |||
898 | } | |||
899 | ||||
900 | /* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>. | |||
901 | ||||
902 | Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME. | |||
903 | Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF | |||
904 | node or for recovery of array indexing from pointer arithmetic. | |||
905 | ||||
906 | PARENT_SINGLE_USE_P tells if, when in a recursive invocation, NAME was | |||
907 | the single use in the previous invocation. Pass true when calling | |||
908 | this as toplevel. | |||
909 | ||||
910 | Returns true, if all uses have been propagated into. */ | |||
911 | ||||
912 | static bool | |||
913 | forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p) | |||
914 | { | |||
915 | imm_use_iterator iter; | |||
916 | gimple *use_stmt; | |||
917 | bool all = true; | |||
918 | bool single_use_p = parent_single_use_p && has_single_use (name); | |||
919 | ||||
920 | FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse ((((use_stmt) = first_imm_use_stmt (&(iter), (name))), & (iter))); !end_imm_use_stmt_p (&(iter)); (void) ((use_stmt ) = next_imm_use_stmt (&(iter)))) | |||
921 | { | |||
922 | bool result; | |||
923 | tree use_rhs; | |||
924 | ||||
925 | /* If the use is not in a simple assignment statement, then | |||
926 | there is nothing we can do. */ | |||
927 | if (!is_gimple_assign (use_stmt)) | |||
928 | { | |||
929 | if (!is_gimple_debug (use_stmt)) | |||
930 | all = false; | |||
931 | continue; | |||
932 | } | |||
933 | ||||
934 | gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); | |||
935 | result = forward_propagate_addr_expr_1 (name, rhs, &gsi, | |||
936 | single_use_p); | |||
937 | /* If the use has moved to a different statement adjust | |||
938 | the update machinery for the old statement too. */ | |||
939 | if (use_stmt != gsi_stmt (gsi)) | |||
940 | { | |||
941 | update_stmt (use_stmt); | |||
942 | use_stmt = gsi_stmt (gsi); | |||
943 | } | |||
944 | update_stmt (use_stmt); | |||
945 | all &= result; | |||
946 | ||||
947 | /* Remove intermediate now unused copy and conversion chains. */ | |||
948 | use_rhs = gimple_assign_rhs1 (use_stmt); | |||
949 | if (result | |||
950 | && TREE_CODE (gimple_assign_lhs (use_stmt))((enum tree_code) (gimple_assign_lhs (use_stmt))->base.code ) == SSA_NAME | |||
951 | && TREE_CODE (use_rhs)((enum tree_code) (use_rhs)->base.code) == SSA_NAME | |||
952 | && has_zero_uses (gimple_assign_lhs (use_stmt))) | |||
953 | { | |||
954 | gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); | |||
955 | fwprop_invalidate_lattice (gimple_get_lhs (use_stmt)); | |||
956 | release_defs (use_stmt); | |||
957 | gsi_remove (&gsi, true); | |||
958 | } | |||
959 | } | |||
960 | ||||
961 | return all && has_zero_uses (name); | |||
962 | } | |||
963 | ||||
964 | ||||
965 | /* Helper function for simplify_gimple_switch. Remove case labels that | |||
966 | have values outside the range of the new type. */ | |||
967 | ||||
968 | static void | |||
969 | simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type) | |||
970 | { | |||
971 | unsigned int branch_num = gimple_switch_num_labels (stmt); | |||
972 | auto_vec<tree> labels (branch_num); | |||
973 | unsigned int i, len; | |||
974 | ||||
975 | /* Collect the existing case labels in a VEC, and preprocess it as if | |||
976 | we are gimplifying a GENERIC SWITCH_EXPR. */ | |||
977 | for (i = 1; i < branch_num; i++) | |||
978 | labels.quick_push (gimple_switch_label (stmt, i)); | |||
979 | preprocess_case_label_vec_for_gimple (labels, index_type, NULLnullptr); | |||
980 | ||||
981 | /* If any labels were removed, replace the existing case labels | |||
982 | in the GIMPLE_SWITCH statement with the correct ones. | |||
983 | Note that the type updates were done in-place on the case labels, | |||
984 | so we only have to replace the case labels in the GIMPLE_SWITCH | |||
985 | if the number of labels changed. */ | |||
986 | len = labels.length (); | |||
987 | if (len < branch_num - 1) | |||
988 | { | |||
989 | bitmap target_blocks; | |||
990 | edge_iterator ei; | |||
991 | edge e; | |||
992 | ||||
993 | /* Corner case: *all* case labels have been removed as being | |||
994 | out-of-range for INDEX_TYPE. Push one label and let the | |||
995 | CFG cleanups deal with this further. */ | |||
996 | if (len == 0) | |||
997 | { | |||
998 | tree label, elt; | |||
999 | ||||
1000 | label = CASE_LABEL (gimple_switch_default_label (stmt))(*((const_cast<tree*> (tree_operand_check (((tree_check ((gimple_switch_default_label (stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1000, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1000, __FUNCTION__))))); | |||
1001 | elt = build_case_label (build_int_cst (index_type, 0), NULLnullptr, label); | |||
1002 | labels.quick_push (elt); | |||
1003 | len = 1; | |||
1004 | } | |||
1005 | ||||
1006 | for (i = 0; i < labels.length (); i++) | |||
1007 | gimple_switch_set_label (stmt, i + 1, labels[i]); | |||
1008 | for (i++ ; i < branch_num; i++) | |||
1009 | gimple_switch_set_label (stmt, i, NULL_TREE(tree) nullptr); | |||
1010 | gimple_switch_set_num_labels (stmt, len + 1); | |||
1011 | ||||
1012 | /* Cleanup any edges that are now dead. */ | |||
1013 | target_blocks = BITMAP_ALLOCbitmap_alloc (NULLnullptr); | |||
1014 | for (i = 0; i < gimple_switch_num_labels (stmt); i++) | |||
1015 | { | |||
1016 | tree elt = gimple_switch_label (stmt, i); | |||
1017 | basic_block target = label_to_block (cfun(cfun + 0), CASE_LABEL (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check ((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1017, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1017, __FUNCTION__)))))); | |||
1018 | bitmap_set_bit (target_blocks, target->index); | |||
1019 | } | |||
1020 | for (ei = ei_start (gimple_bb (stmt)->succs)ei_start_1 (&(gimple_bb (stmt)->succs)); (e = ei_safe_edge (ei)); ) | |||
1021 | { | |||
1022 | if (! bitmap_bit_p (target_blocks, e->dest->index)) | |||
1023 | { | |||
1024 | remove_edge (e); | |||
1025 | cfg_changed = true; | |||
1026 | free_dominance_info (CDI_DOMINATORS); | |||
1027 | } | |||
1028 | else | |||
1029 | ei_next (&ei); | |||
1030 | } | |||
1031 | BITMAP_FREE (target_blocks)((void) (bitmap_obstack_free ((bitmap) target_blocks), (target_blocks ) = (bitmap) nullptr)); | |||
1032 | } | |||
1033 | } | |||
1034 | ||||
1035 | /* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of | |||
1036 | the condition which we may be able to optimize better. */ | |||
1037 | ||||
1038 | static bool | |||
1039 | simplify_gimple_switch (gswitch *stmt) | |||
1040 | { | |||
1041 | /* The optimization that we really care about is removing unnecessary | |||
1042 | casts. That will let us do much better in propagating the inferred | |||
1043 | constant at the switch target. */ | |||
1044 | tree cond = gimple_switch_index (stmt); | |||
1045 | if (TREE_CODE (cond)((enum tree_code) (cond)->base.code) == SSA_NAME) | |||
1046 | { | |||
1047 | gimple *def_stmt = SSA_NAME_DEF_STMT (cond)(tree_check ((cond), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1047, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1048 | if (gimple_assign_cast_p (def_stmt)) | |||
1049 | { | |||
1050 | tree def = gimple_assign_rhs1 (def_stmt); | |||
1051 | if (TREE_CODE (def)((enum tree_code) (def)->base.code) != SSA_NAME) | |||
1052 | return false; | |||
1053 | ||||
1054 | /* If we have an extension or sign-change that preserves the | |||
1055 | values we check against then we can copy the source value into | |||
1056 | the switch. */ | |||
1057 | tree ti = TREE_TYPE (def)((contains_struct_check ((def), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1057, __FUNCTION__))->typed.type); | |||
1058 | if (INTEGRAL_TYPE_P (ti)(((enum tree_code) (ti)->base.code) == ENUMERAL_TYPE || (( enum tree_code) (ti)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (ti)->base.code) == INTEGER_TYPE) | |||
1059 | && TYPE_PRECISION (ti)((tree_class_check ((ti), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1059, __FUNCTION__))->type_common.precision) <= TYPE_PRECISION (TREE_TYPE (cond))((tree_class_check ((((contains_struct_check ((cond), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1059, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1059, __FUNCTION__))->type_common.precision)) | |||
1060 | { | |||
1061 | size_t n = gimple_switch_num_labels (stmt); | |||
1062 | tree min = NULL_TREE(tree) nullptr, max = NULL_TREE(tree) nullptr; | |||
1063 | if (n > 1) | |||
1064 | { | |||
1065 | min = CASE_LOW (gimple_switch_label (stmt, 1))(*((const_cast<tree*> (tree_operand_check (((tree_check ((gimple_switch_label (stmt, 1)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1065, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1065, __FUNCTION__))))); | |||
1066 | if (CASE_HIGH (gimple_switch_label (stmt, n - 1))(*((const_cast<tree*> (tree_operand_check (((tree_check ((gimple_switch_label (stmt, n - 1)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1066, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1066, __FUNCTION__)))))) | |||
1067 | max = CASE_HIGH (gimple_switch_label (stmt, n - 1))(*((const_cast<tree*> (tree_operand_check (((tree_check ((gimple_switch_label (stmt, n - 1)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1067, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1067, __FUNCTION__))))); | |||
1068 | else | |||
1069 | max = CASE_LOW (gimple_switch_label (stmt, n - 1))(*((const_cast<tree*> (tree_operand_check (((tree_check ((gimple_switch_label (stmt, n - 1)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1069, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1069, __FUNCTION__))))); | |||
1070 | } | |||
1071 | if ((!min || int_fits_type_p (min, ti)) | |||
1072 | && (!max || int_fits_type_p (max, ti))) | |||
1073 | { | |||
1074 | gimple_switch_set_index (stmt, def); | |||
1075 | simplify_gimple_switch_label_vec (stmt, ti); | |||
1076 | update_stmt (stmt); | |||
1077 | return true; | |||
1078 | } | |||
1079 | } | |||
1080 | } | |||
1081 | } | |||
1082 | ||||
1083 | return false; | |||
1084 | } | |||
1085 | ||||
1086 | /* For pointers p2 and p1 return p2 - p1 if the | |||
1087 | difference is known and constant, otherwise return NULL. */ | |||
1088 | ||||
1089 | static tree | |||
1090 | constant_pointer_difference (tree p1, tree p2) | |||
1091 | { | |||
1092 | int i, j; | |||
1093 | #define CPD_ITERATIONS5 5 | |||
1094 | tree exps[2][CPD_ITERATIONS5]; | |||
1095 | tree offs[2][CPD_ITERATIONS5]; | |||
1096 | int cnt[2]; | |||
1097 | ||||
1098 | for (i = 0; i < 2; i++) | |||
1099 | { | |||
1100 | tree p = i ? p1 : p2; | |||
1101 | tree off = size_zero_nodeglobal_trees[TI_SIZE_ZERO]; | |||
1102 | gimple *stmt; | |||
1103 | enum tree_code code; | |||
1104 | ||||
1105 | /* For each of p1 and p2 we need to iterate at least | |||
1106 | twice, to handle ADDR_EXPR directly in p1/p2, | |||
1107 | SSA_NAME with ADDR_EXPR or POINTER_PLUS_EXPR etc. | |||
1108 | on definition's stmt RHS. Iterate a few extra times. */ | |||
1109 | j = 0; | |||
1110 | do | |||
1111 | { | |||
1112 | if (!POINTER_TYPE_P (TREE_TYPE (p))(((enum tree_code) (((contains_struct_check ((p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1112, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((p), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1112, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) | |||
1113 | break; | |||
1114 | if (TREE_CODE (p)((enum tree_code) (p)->base.code) == ADDR_EXPR) | |||
1115 | { | |||
1116 | tree q = TREE_OPERAND (p, 0)(*((const_cast<tree*> (tree_operand_check ((p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1116, __FUNCTION__))))); | |||
1117 | poly_int64 offset; | |||
1118 | tree base = get_addr_base_and_unit_offset (q, &offset); | |||
1119 | if (base) | |||
1120 | { | |||
1121 | q = base; | |||
1122 | if (maybe_ne (offset, 0)) | |||
1123 | off = size_binop (PLUS_EXPR, off, size_int (offset))size_binop_loc (((location_t) 0), PLUS_EXPR, off, size_int_kind (offset, stk_sizetype)); | |||
1124 | } | |||
1125 | if (TREE_CODE (q)((enum tree_code) (q)->base.code) == MEM_REF | |||
1126 | && TREE_CODE (TREE_OPERAND (q, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((q), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1126, __FUNCTION__))))))->base.code) == SSA_NAME) | |||
1127 | { | |||
1128 | p = TREE_OPERAND (q, 0)(*((const_cast<tree*> (tree_operand_check ((q), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1128, __FUNCTION__))))); | |||
1129 | off = size_binop (PLUS_EXPR, off,size_binop_loc (((location_t) 0), PLUS_EXPR, off, wide_int_to_tree (sizetype_tab[(int) stk_sizetype], mem_ref_offset (q))) | |||
1130 | wide_int_to_tree (sizetype,size_binop_loc (((location_t) 0), PLUS_EXPR, off, wide_int_to_tree (sizetype_tab[(int) stk_sizetype], mem_ref_offset (q))) | |||
1131 | mem_ref_offset (q)))size_binop_loc (((location_t) 0), PLUS_EXPR, off, wide_int_to_tree (sizetype_tab[(int) stk_sizetype], mem_ref_offset (q))); | |||
1132 | } | |||
1133 | else | |||
1134 | { | |||
1135 | exps[i][j] = q; | |||
1136 | offs[i][j++] = off; | |||
1137 | break; | |||
1138 | } | |||
1139 | } | |||
1140 | if (TREE_CODE (p)((enum tree_code) (p)->base.code) != SSA_NAME) | |||
1141 | break; | |||
1142 | exps[i][j] = p; | |||
1143 | offs[i][j++] = off; | |||
1144 | if (j == CPD_ITERATIONS5) | |||
1145 | break; | |||
1146 | stmt = SSA_NAME_DEF_STMT (p)(tree_check ((p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1146, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1147 | if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != p) | |||
1148 | break; | |||
1149 | code = gimple_assign_rhs_code (stmt); | |||
1150 | if (code == POINTER_PLUS_EXPR) | |||
1151 | { | |||
1152 | if (TREE_CODE (gimple_assign_rhs2 (stmt))((enum tree_code) (gimple_assign_rhs2 (stmt))->base.code) != INTEGER_CST) | |||
1153 | break; | |||
1154 | off = size_binop (PLUS_EXPR, off, gimple_assign_rhs2 (stmt))size_binop_loc (((location_t) 0), PLUS_EXPR, off, gimple_assign_rhs2 (stmt)); | |||
1155 | p = gimple_assign_rhs1 (stmt); | |||
1156 | } | |||
1157 | else if (code == ADDR_EXPR || CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR)) | |||
1158 | p = gimple_assign_rhs1 (stmt); | |||
1159 | else | |||
1160 | break; | |||
1161 | } | |||
1162 | while (1); | |||
1163 | cnt[i] = j; | |||
1164 | } | |||
1165 | ||||
1166 | for (i = 0; i < cnt[0]; i++) | |||
1167 | for (j = 0; j < cnt[1]; j++) | |||
1168 | if (exps[0][i] == exps[1][j]) | |||
1169 | return size_binop (MINUS_EXPR, offs[0][i], offs[1][j])size_binop_loc (((location_t) 0), MINUS_EXPR, offs[0][i], offs [1][j]); | |||
1170 | ||||
1171 | return NULL_TREE(tree) nullptr; | |||
1172 | } | |||
1173 | ||||
1174 | /* *GSI_P is a GIMPLE_CALL to a builtin function. | |||
1175 | Optimize | |||
1176 | memcpy (p, "abcd", 4); | |||
1177 | memset (p + 4, ' ', 3); | |||
1178 | into | |||
1179 | memcpy (p, "abcd ", 7); | |||
1180 | call if the latter can be stored by pieces during expansion. | |||
1181 | ||||
1182 | Optimize | |||
1183 | memchr ("abcd", a, 4) == 0; | |||
1184 | or | |||
1185 | memchr ("abcd", a, 4) != 0; | |||
1186 | to | |||
1187 | (a == 'a' || a == 'b' || a == 'c' || a == 'd') == 0 | |||
1188 | or | |||
1189 | (a == 'a' || a == 'b' || a == 'c' || a == 'd') != 0 | |||
1190 | ||||
1191 | Also canonicalize __atomic_fetch_op (p, x, y) op x | |||
1192 | to __atomic_op_fetch (p, x, y) or | |||
1193 | __atomic_op_fetch (p, x, y) iop x | |||
1194 | to __atomic_fetch_op (p, x, y) when possible (also __sync). */ | |||
1195 | ||||
1196 | static bool | |||
1197 | simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2) | |||
1198 | { | |||
1199 | gimple *stmt1, *stmt2 = gsi_stmt (*gsi_p); | |||
1200 | enum built_in_function other_atomic = END_BUILTINS; | |||
1201 | enum tree_code atomic_op = ERROR_MARK; | |||
1202 | tree vuse = gimple_vuse (stmt2); | |||
1203 | if (vuse == NULLnullptr) | |||
| ||||
1204 | return false; | |||
1205 | stmt1 = SSA_NAME_DEF_STMT (vuse)(tree_check ((vuse), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1205, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1206 | ||||
1207 | tree res; | |||
1208 | ||||
1209 | switch (DECL_FUNCTION_CODE (callee2)) | |||
1210 | { | |||
1211 | case BUILT_IN_MEMCHR: | |||
1212 | if (gimple_call_num_args (stmt2) == 3 | |||
1213 | && (res = gimple_call_lhs (stmt2)) != nullptr | |||
1214 | && use_in_zero_equality (res) != nullptr | |||
1215 | && CHAR_BIT8 == 8 | |||
1216 | && BITS_PER_UNIT(8) == 8) | |||
1217 | { | |||
1218 | tree ptr = gimple_call_arg (stmt2, 0); | |||
1219 | if (TREE_CODE (ptr)((enum tree_code) (ptr)->base.code) != ADDR_EXPR | |||
1220 | || TREE_CODE (TREE_OPERAND (ptr, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((ptr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1220, __FUNCTION__))))))->base.code) != STRING_CST) | |||
1221 | break; | |||
1222 | unsigned HOST_WIDE_INTlong slen | |||
1223 | = TREE_STRING_LENGTH (TREE_OPERAND (ptr, 0))((tree_check (((*((const_cast<tree*> (tree_operand_check ((ptr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1223, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1223, __FUNCTION__, (STRING_CST)))->string.length); | |||
1224 | /* It must be a non-empty string constant. */ | |||
1225 | if (slen < 2) | |||
1226 | break; | |||
1227 | /* For -Os, only simplify strings with a single character. */ | |||
1228 | if (!optimize_bb_for_speed_p (gimple_bb (stmt2)) | |||
1229 | && slen > 2) | |||
1230 | break; | |||
1231 | tree size = gimple_call_arg (stmt2, 2); | |||
1232 | /* Size must be a constant which is <= UNITS_PER_WORD and | |||
1233 | <= the string length. */ | |||
1234 | if (TREE_CODE (size)((enum tree_code) (size)->base.code) != INTEGER_CST || integer_zerop (size)) | |||
1235 | break; | |||
1236 | ||||
1237 | if (!tree_fits_uhwi_p (size)) | |||
1238 | break; | |||
1239 | ||||
1240 | unsigned HOST_WIDE_INTlong sz = tree_to_uhwi (size); | |||
1241 | if (sz > UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) != 0) ? 8 : 4) || sz >= slen) | |||
1242 | break; | |||
1243 | ||||
1244 | tree ch = gimple_call_arg (stmt2, 1); | |||
1245 | location_t loc = gimple_location (stmt2); | |||
1246 | if (!useless_type_conversion_p (char_type_nodeinteger_types[itk_char], | |||
1247 | TREE_TYPE (ch)((contains_struct_check ((ch), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1247, __FUNCTION__))->typed.type))) | |||
1248 | ch = fold_convert_loc (loc, char_type_nodeinteger_types[itk_char], ch); | |||
1249 | const char *p = TREE_STRING_POINTER (TREE_OPERAND (ptr, 0))((const char *)((tree_check (((*((const_cast<tree*> (tree_operand_check ((ptr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1249, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1249, __FUNCTION__, (STRING_CST)))->string.str)); | |||
1250 | unsigned int isize = sz; | |||
1251 | tree *op = XALLOCAVEC (tree, isize)((tree *) __builtin_alloca(sizeof (tree) * (isize))); | |||
1252 | for (unsigned int i = 0; i < isize; i++) | |||
1253 | { | |||
1254 | op[i] = build_int_cst (char_type_nodeinteger_types[itk_char], p[i]); | |||
1255 | op[i] = fold_build2_loc (loc, EQ_EXPR, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | |||
1256 | op[i], ch); | |||
1257 | } | |||
1258 | for (unsigned int i = isize - 1; i >= 1; i--) | |||
1259 | op[i - 1] = fold_convert_loc (loc, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | |||
1260 | fold_build2_loc (loc, | |||
| ||||
1261 | BIT_IOR_EXPR, | |||
1262 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | |||
1263 | op[i - 1], | |||
1264 | op[i])); | |||
1265 | res = fold_convert_loc (loc, TREE_TYPE (res)((contains_struct_check ((res), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1265, __FUNCTION__))->typed.type), op[0]); | |||
1266 | gimplify_and_update_call_from_tree (gsi_p, res); | |||
1267 | return true; | |||
1268 | } | |||
1269 | break; | |||
1270 | ||||
1271 | case BUILT_IN_MEMSET: | |||
1272 | if (gimple_call_num_args (stmt2) != 3 | |||
1273 | || gimple_call_lhs (stmt2) | |||
1274 | || CHAR_BIT8 != 8 | |||
1275 | || BITS_PER_UNIT(8) != 8) | |||
1276 | break; | |||
1277 | else | |||
1278 | { | |||
1279 | tree callee1; | |||
1280 | tree ptr1, src1, str1, off1, len1, lhs1; | |||
1281 | tree ptr2 = gimple_call_arg (stmt2, 0); | |||
1282 | tree val2 = gimple_call_arg (stmt2, 1); | |||
1283 | tree len2 = gimple_call_arg (stmt2, 2); | |||
1284 | tree diff, vdef, new_str_cst; | |||
1285 | gimple *use_stmt; | |||
1286 | unsigned int ptr1_align; | |||
1287 | unsigned HOST_WIDE_INTlong src_len; | |||
1288 | char *src_buf; | |||
1289 | use_operand_p use_p; | |||
1290 | ||||
1291 | if (!tree_fits_shwi_p (val2) | |||
1292 | || !tree_fits_uhwi_p (len2) | |||
1293 | || compare_tree_int (len2, 1024) == 1) | |||
1294 | break; | |||
1295 | if (is_gimple_call (stmt1)) | |||
1296 | { | |||
1297 | /* If first stmt is a call, it needs to be memcpy | |||
1298 | or mempcpy, with string literal as second argument and | |||
1299 | constant length. */ | |||
1300 | callee1 = gimple_call_fndecl (stmt1); | |||
1301 | if (callee1 == NULL_TREE(tree) nullptr | |||
1302 | || !fndecl_built_in_p (callee1, BUILT_IN_NORMAL) | |||
1303 | || gimple_call_num_args (stmt1) != 3) | |||
1304 | break; | |||
1305 | if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY | |||
1306 | && DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMPCPY) | |||
1307 | break; | |||
1308 | ptr1 = gimple_call_arg (stmt1, 0); | |||
1309 | src1 = gimple_call_arg (stmt1, 1); | |||
1310 | len1 = gimple_call_arg (stmt1, 2); | |||
1311 | lhs1 = gimple_call_lhs (stmt1); | |||
1312 | if (!tree_fits_uhwi_p (len1)) | |||
1313 | break; | |||
1314 | str1 = string_constant (src1, &off1, NULLnullptr, NULLnullptr); | |||
1315 | if (str1 == NULL_TREE(tree) nullptr) | |||
1316 | break; | |||
1317 | if (!tree_fits_uhwi_p (off1) | |||
1318 | || compare_tree_int (off1, TREE_STRING_LENGTH (str1)((tree_check ((str1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1318, __FUNCTION__, (STRING_CST)))->string.length) - 1) > 0 | |||
1319 | || compare_tree_int (len1, TREE_STRING_LENGTH (str1)((tree_check ((str1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1319, __FUNCTION__, (STRING_CST)))->string.length) | |||
1320 | - tree_to_uhwi (off1)) > 0 | |||
1321 | || TREE_CODE (TREE_TYPE (str1))((enum tree_code) (((contains_struct_check ((str1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1321, __FUNCTION__))->typed.type))->base.code) != ARRAY_TYPE | |||
1322 | || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((str1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((((contains_struct_check ((str1), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type)) : (((contains_struct_check ((((contains_struct_check ((str1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1322, __FUNCTION__))->typed.type))->type_common.mode) | |||
1323 | != TYPE_MODE (char_type_node)((((enum tree_code) ((tree_class_check ((integer_types[itk_char ]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1323, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (integer_types[itk_char]) : (integer_types[itk_char])->type_common .mode)) | |||
1324 | break; | |||
1325 | } | |||
1326 | else if (gimple_assign_single_p (stmt1)) | |||
1327 | { | |||
1328 | /* Otherwise look for length 1 memcpy optimized into | |||
1329 | assignment. */ | |||
1330 | ptr1 = gimple_assign_lhs (stmt1); | |||
1331 | src1 = gimple_assign_rhs1 (stmt1); | |||
1332 | if (TREE_CODE (ptr1)((enum tree_code) (ptr1)->base.code) != MEM_REF | |||
1333 | || TYPE_MODE (TREE_TYPE (ptr1))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((ptr1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1333, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1333, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((ptr1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1333, __FUNCTION__))->typed.type)) : (((contains_struct_check ((ptr1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1333, __FUNCTION__))->typed.type))->type_common.mode) != TYPE_MODE (char_type_node)((((enum tree_code) ((tree_class_check ((integer_types[itk_char ]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1333, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (integer_types[itk_char]) : (integer_types[itk_char])->type_common .mode) | |||
1334 | || !tree_fits_shwi_p (src1)) | |||
1335 | break; | |||
1336 | ptr1 = build_fold_addr_expr (ptr1)build_fold_addr_expr_loc (((location_t) 0), (ptr1)); | |||
1337 | STRIP_USELESS_TYPE_CONVERSION (ptr1)(ptr1) = tree_ssa_strip_useless_type_conversions (ptr1); | |||
1338 | callee1 = NULL_TREE(tree) nullptr; | |||
1339 | len1 = size_one_nodeglobal_trees[TI_SIZE_ONE]; | |||
1340 | lhs1 = NULL_TREE(tree) nullptr; | |||
1341 | off1 = size_zero_nodeglobal_trees[TI_SIZE_ZERO]; | |||
1342 | str1 = NULL_TREE(tree) nullptr; | |||
1343 | } | |||
1344 | else | |||
1345 | break; | |||
1346 | ||||
1347 | diff = constant_pointer_difference (ptr1, ptr2); | |||
1348 | if (diff == NULLnullptr && lhs1 != NULLnullptr) | |||
1349 | { | |||
1350 | diff = constant_pointer_difference (lhs1, ptr2); | |||
1351 | if (DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY | |||
1352 | && diff != NULLnullptr) | |||
1353 | diff = size_binop (PLUS_EXPR, diff,size_binop_loc (((location_t) 0), PLUS_EXPR, diff, fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_sizetype], len1)) | |||
1354 | fold_convert (sizetype, len1))size_binop_loc (((location_t) 0), PLUS_EXPR, diff, fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_sizetype], len1)); | |||
1355 | } | |||
1356 | /* If the difference between the second and first destination pointer | |||
1357 | is not constant, or is bigger than memcpy length, bail out. */ | |||
1358 | if (diff == NULLnullptr | |||
1359 | || !tree_fits_uhwi_p (diff) | |||
1360 | || tree_int_cst_lt (len1, diff) | |||
1361 | || compare_tree_int (diff, 1024) == 1) | |||
1362 | break; | |||
1363 | ||||
1364 | /* Use maximum of difference plus memset length and memcpy length | |||
1365 | as the new memcpy length, if it is too big, bail out. */ | |||
1366 | src_len = tree_to_uhwi (diff); | |||
1367 | src_len += tree_to_uhwi (len2); | |||
1368 | if (src_len < tree_to_uhwi (len1)) | |||
1369 | src_len = tree_to_uhwi (len1); | |||
1370 | if (src_len > 1024) | |||
1371 | break; | |||
1372 | ||||
1373 | /* If mempcpy value is used elsewhere, bail out, as mempcpy | |||
1374 | with bigger length will return different result. */ | |||
1375 | if (lhs1 != NULL_TREE(tree) nullptr | |||
1376 | && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY | |||
1377 | && (TREE_CODE (lhs1)((enum tree_code) (lhs1)->base.code) != SSA_NAME | |||
1378 | || !single_imm_use (lhs1, &use_p, &use_stmt) | |||
1379 | || use_stmt != stmt2)) | |||
1380 | break; | |||
1381 | ||||
1382 | /* If anything reads memory in between memcpy and memset | |||
1383 | call, the modified memcpy call might change it. */ | |||
1384 | vdef = gimple_vdef (stmt1); | |||
1385 | if (vdef != NULLnullptr | |||
1386 | && (!single_imm_use (vdef, &use_p, &use_stmt) | |||
1387 | || use_stmt != stmt2)) | |||
1388 | break; | |||
1389 | ||||
1390 | ptr1_align = get_pointer_alignment (ptr1); | |||
1391 | /* Construct the new source string literal. */ | |||
1392 | src_buf = XALLOCAVEC (char, src_len + 1)((char *) __builtin_alloca(sizeof (char) * (src_len + 1))); | |||
1393 | if (callee1) | |||
1394 | memcpy (src_buf, | |||
1395 | TREE_STRING_POINTER (str1)((const char *)((tree_check ((str1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1395, __FUNCTION__, (STRING_CST)))->string.str)) + tree_to_uhwi (off1), | |||
1396 | tree_to_uhwi (len1)); | |||
1397 | else | |||
1398 | src_buf[0] = tree_to_shwi (src1); | |||
1399 | memset (src_buf + tree_to_uhwi (diff), | |||
1400 | tree_to_shwi (val2), tree_to_uhwi (len2)); | |||
1401 | src_buf[src_len] = '\0'; | |||
1402 | /* Neither builtin_strncpy_read_str nor builtin_memcpy_read_str | |||
1403 | handle embedded '\0's. */ | |||
1404 | if (strlen (src_buf) != src_len) | |||
1405 | break; | |||
1406 | rtl_profile_for_bb (gimple_bb (stmt2)); | |||
1407 | /* If the new memcpy wouldn't be emitted by storing the literal | |||
1408 | by pieces, this optimization might enlarge .rodata too much, | |||
1409 | as commonly used string literals couldn't be shared any | |||
1410 | longer. */ | |||
1411 | if (!can_store_by_pieces (src_len, | |||
1412 | builtin_strncpy_read_str, | |||
1413 | src_buf, ptr1_align, false)) | |||
1414 | break; | |||
1415 | ||||
1416 | new_str_cst = build_string_literal (src_len, src_buf); | |||
1417 | if (callee1) | |||
1418 | { | |||
1419 | /* If STMT1 is a mem{,p}cpy call, adjust it and remove | |||
1420 | memset call. */ | |||
1421 | if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY) | |||
1422 | gimple_call_set_lhs (stmt1, NULL_TREE(tree) nullptr); | |||
1423 | gimple_call_set_arg (stmt1, 1, new_str_cst); | |||
1424 | gimple_call_set_arg (stmt1, 2, | |||
1425 | build_int_cst (TREE_TYPE (len1)((contains_struct_check ((len1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1425, __FUNCTION__))->typed.type), src_len)); | |||
1426 | update_stmt (stmt1); | |||
1427 | unlink_stmt_vdef (stmt2); | |||
1428 | gsi_replace (gsi_p, gimple_build_nop (), false); | |||
1429 | fwprop_invalidate_lattice (gimple_get_lhs (stmt2)); | |||
1430 | release_defs (stmt2); | |||
1431 | if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY) | |||
1432 | { | |||
1433 | fwprop_invalidate_lattice (lhs1); | |||
1434 | release_ssa_name (lhs1); | |||
1435 | } | |||
1436 | return true; | |||
1437 | } | |||
1438 | else | |||
1439 | { | |||
1440 | /* Otherwise, if STMT1 is length 1 memcpy optimized into | |||
1441 | assignment, remove STMT1 and change memset call into | |||
1442 | memcpy call. */ | |||
1443 | gimple_stmt_iterator gsi = gsi_for_stmt (stmt1); | |||
1444 | ||||
1445 | if (!is_gimple_val (ptr1)) | |||
1446 | ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE(tree) nullptr, | |||
1447 | true, GSI_SAME_STMT); | |||
1448 | tree fndecl = builtin_decl_explicit (BUILT_IN_MEMCPY); | |||
1449 | gimple_call_set_fndecl (stmt2, fndecl); | |||
1450 | gimple_call_set_fntype (as_a <gcall *> (stmt2), | |||
1451 | TREE_TYPE (fndecl)((contains_struct_check ((fndecl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1451, __FUNCTION__))->typed.type)); | |||
1452 | gimple_call_set_arg (stmt2, 0, ptr1); | |||
1453 | gimple_call_set_arg (stmt2, 1, new_str_cst); | |||
1454 | gimple_call_set_arg (stmt2, 2, | |||
1455 | build_int_cst (TREE_TYPE (len2)((contains_struct_check ((len2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1455, __FUNCTION__))->typed.type), src_len)); | |||
1456 | unlink_stmt_vdef (stmt1); | |||
1457 | gsi_remove (&gsi, true); | |||
1458 | fwprop_invalidate_lattice (gimple_get_lhs (stmt1)); | |||
1459 | release_defs (stmt1); | |||
1460 | update_stmt (stmt2); | |||
1461 | return false; | |||
1462 | } | |||
1463 | } | |||
1464 | break; | |||
1465 | ||||
1466 | #define CASE_ATOMIC(NAME, OTHER, OP) \ | |||
1467 | case BUILT_IN_##NAME##_1: \ | |||
1468 | case BUILT_IN_##NAME##_2: \ | |||
1469 | case BUILT_IN_##NAME##_4: \ | |||
1470 | case BUILT_IN_##NAME##_8: \ | |||
1471 | case BUILT_IN_##NAME##_16: \ | |||
1472 | atomic_op = OP; \ | |||
1473 | other_atomic \ | |||
1474 | = (enum built_in_function) (BUILT_IN_##OTHER##_1 \ | |||
1475 | + (DECL_FUNCTION_CODE (callee2) \ | |||
1476 | - BUILT_IN_##NAME##_1)); \ | |||
1477 | goto handle_atomic_fetch_op; | |||
1478 | ||||
1479 | CASE_ATOMIC (ATOMIC_FETCH_ADD, ATOMIC_ADD_FETCH, PLUS_EXPR) | |||
1480 | CASE_ATOMIC (ATOMIC_FETCH_SUB, ATOMIC_SUB_FETCH, MINUS_EXPR) | |||
1481 | CASE_ATOMIC (ATOMIC_FETCH_AND, ATOMIC_AND_FETCH, BIT_AND_EXPR) | |||
1482 | CASE_ATOMIC (ATOMIC_FETCH_XOR, ATOMIC_XOR_FETCH, BIT_XOR_EXPR) | |||
1483 | CASE_ATOMIC (ATOMIC_FETCH_OR, ATOMIC_OR_FETCH, BIT_IOR_EXPR) | |||
1484 | ||||
1485 | CASE_ATOMIC (SYNC_FETCH_AND_ADD, SYNC_ADD_AND_FETCH, PLUS_EXPR) | |||
1486 | CASE_ATOMIC (SYNC_FETCH_AND_SUB, SYNC_SUB_AND_FETCH, MINUS_EXPR) | |||
1487 | CASE_ATOMIC (SYNC_FETCH_AND_AND, SYNC_AND_AND_FETCH, BIT_AND_EXPR) | |||
1488 | CASE_ATOMIC (SYNC_FETCH_AND_XOR, SYNC_XOR_AND_FETCH, BIT_XOR_EXPR) | |||
1489 | CASE_ATOMIC (SYNC_FETCH_AND_OR, SYNC_OR_AND_FETCH, BIT_IOR_EXPR) | |||
1490 | ||||
1491 | CASE_ATOMIC (ATOMIC_ADD_FETCH, ATOMIC_FETCH_ADD, MINUS_EXPR) | |||
1492 | CASE_ATOMIC (ATOMIC_SUB_FETCH, ATOMIC_FETCH_SUB, PLUS_EXPR) | |||
1493 | CASE_ATOMIC (ATOMIC_XOR_FETCH, ATOMIC_FETCH_XOR, BIT_XOR_EXPR) | |||
1494 | ||||
1495 | CASE_ATOMIC (SYNC_ADD_AND_FETCH, SYNC_FETCH_AND_ADD, MINUS_EXPR) | |||
1496 | CASE_ATOMIC (SYNC_SUB_AND_FETCH, SYNC_FETCH_AND_SUB, PLUS_EXPR) | |||
1497 | CASE_ATOMIC (SYNC_XOR_AND_FETCH, SYNC_FETCH_AND_XOR, BIT_XOR_EXPR) | |||
1498 | ||||
1499 | #undef CASE_ATOMIC | |||
1500 | ||||
1501 | handle_atomic_fetch_op: | |||
1502 | if (gimple_call_num_args (stmt2) >= 2 && gimple_call_lhs (stmt2)) | |||
1503 | { | |||
1504 | tree lhs2 = gimple_call_lhs (stmt2), lhsc = lhs2; | |||
1505 | tree arg = gimple_call_arg (stmt2, 1); | |||
1506 | gimple *use_stmt, *cast_stmt = NULLnullptr; | |||
1507 | use_operand_p use_p; | |||
1508 | tree ndecl = builtin_decl_explicit (other_atomic); | |||
1509 | ||||
1510 | if (ndecl == NULL_TREE(tree) nullptr || !single_imm_use (lhs2, &use_p, &use_stmt)) | |||
1511 | break; | |||
1512 | ||||
1513 | if (gimple_assign_cast_p (use_stmt)) | |||
1514 | { | |||
1515 | cast_stmt = use_stmt; | |||
1516 | lhsc = gimple_assign_lhs (cast_stmt); | |||
1517 | if (lhsc == NULL_TREE(tree) nullptr | |||
1518 | || !INTEGRAL_TYPE_P (TREE_TYPE (lhsc))(((enum tree_code) (((contains_struct_check ((lhsc), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1518, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((lhsc), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1518, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((lhsc), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1518, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1519 | || (TYPE_PRECISION (TREE_TYPE (lhsc))((tree_class_check ((((contains_struct_check ((lhsc), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1519, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1519, __FUNCTION__))->type_common.precision) | |||
1520 | != TYPE_PRECISION (TREE_TYPE (lhs2))((tree_class_check ((((contains_struct_check ((lhs2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1520, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1520, __FUNCTION__))->type_common.precision)) | |||
1521 | || !single_imm_use (lhsc, &use_p, &use_stmt)) | |||
1522 | { | |||
1523 | use_stmt = cast_stmt; | |||
1524 | cast_stmt = NULLnullptr; | |||
1525 | lhsc = lhs2; | |||
1526 | } | |||
1527 | } | |||
1528 | ||||
1529 | bool ok = false; | |||
1530 | tree oarg = NULL_TREE(tree) nullptr; | |||
1531 | enum tree_code ccode = ERROR_MARK; | |||
1532 | tree crhs1 = NULL_TREE(tree) nullptr, crhs2 = NULL_TREE(tree) nullptr; | |||
1533 | if (is_gimple_assign (use_stmt) | |||
1534 | && gimple_assign_rhs_code (use_stmt) == atomic_op) | |||
1535 | { | |||
1536 | if (gimple_assign_rhs1 (use_stmt) == lhsc) | |||
1537 | oarg = gimple_assign_rhs2 (use_stmt); | |||
1538 | else if (atomic_op != MINUS_EXPR) | |||
1539 | oarg = gimple_assign_rhs1 (use_stmt); | |||
1540 | } | |||
1541 | else if (atomic_op == MINUS_EXPR | |||
1542 | && is_gimple_assign (use_stmt) | |||
1543 | && gimple_assign_rhs_code (use_stmt) == PLUS_EXPR | |||
1544 | && TREE_CODE (arg)((enum tree_code) (arg)->base.code) == INTEGER_CST | |||
1545 | && (TREE_CODE (gimple_assign_rhs2 (use_stmt))((enum tree_code) (gimple_assign_rhs2 (use_stmt))->base.code ) | |||
1546 | == INTEGER_CST)) | |||
1547 | { | |||
1548 | tree a = fold_convert (TREE_TYPE (lhs2), arg)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1548, __FUNCTION__))->typed.type), arg); | |||
1549 | tree o = fold_convert (TREE_TYPE (lhs2),fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1549, __FUNCTION__))->typed.type), gimple_assign_rhs2 (use_stmt )) | |||
1550 | gimple_assign_rhs2 (use_stmt))fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1549, __FUNCTION__))->typed.type), gimple_assign_rhs2 (use_stmt )); | |||
1551 | if (wi::to_wide (a) == wi::neg (wi::to_wide (o))) | |||
1552 | ok = true; | |||
1553 | } | |||
1554 | else if (atomic_op == BIT_AND_EXPR || atomic_op == BIT_IOR_EXPR) | |||
1555 | ; | |||
1556 | else if (gimple_code (use_stmt) == GIMPLE_COND) | |||
1557 | { | |||
1558 | ccode = gimple_cond_code (use_stmt); | |||
1559 | crhs1 = gimple_cond_lhs (use_stmt); | |||
1560 | crhs2 = gimple_cond_rhs (use_stmt); | |||
1561 | } | |||
1562 | else if (is_gimple_assign (use_stmt)) | |||
1563 | { | |||
1564 | if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS) | |||
1565 | { | |||
1566 | ccode = gimple_assign_rhs_code (use_stmt); | |||
1567 | crhs1 = gimple_assign_rhs1 (use_stmt); | |||
1568 | crhs2 = gimple_assign_rhs2 (use_stmt); | |||
1569 | } | |||
1570 | else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR) | |||
1571 | { | |||
1572 | tree cond = gimple_assign_rhs1 (use_stmt); | |||
1573 | if (COMPARISON_CLASS_P (cond)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (cond)->base.code))] == tcc_comparison)) | |||
1574 | { | |||
1575 | ccode = TREE_CODE (cond)((enum tree_code) (cond)->base.code); | |||
1576 | crhs1 = TREE_OPERAND (cond, 0)(*((const_cast<tree*> (tree_operand_check ((cond), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1576, __FUNCTION__))))); | |||
1577 | crhs2 = TREE_OPERAND (cond, 1)(*((const_cast<tree*> (tree_operand_check ((cond), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1577, __FUNCTION__))))); | |||
1578 | } | |||
1579 | } | |||
1580 | } | |||
1581 | if (ccode == EQ_EXPR || ccode == NE_EXPR) | |||
1582 | { | |||
1583 | /* Deal with x - y == 0 or x ^ y == 0 | |||
1584 | being optimized into x == y and x + cst == 0 | |||
1585 | into x == -cst. */ | |||
1586 | tree o = NULL_TREE(tree) nullptr; | |||
1587 | if (crhs1 == lhsc) | |||
1588 | o = crhs2; | |||
1589 | else if (crhs2 == lhsc) | |||
1590 | o = crhs1; | |||
1591 | if (o && atomic_op != PLUS_EXPR) | |||
1592 | oarg = o; | |||
1593 | else if (o | |||
1594 | && TREE_CODE (o)((enum tree_code) (o)->base.code) == INTEGER_CST | |||
1595 | && TREE_CODE (arg)((enum tree_code) (arg)->base.code) == INTEGER_CST) | |||
1596 | { | |||
1597 | tree a = fold_convert (TREE_TYPE (lhs2), arg)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1597, __FUNCTION__))->typed.type), arg); | |||
1598 | o = fold_convert (TREE_TYPE (lhs2), o)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1598, __FUNCTION__))->typed.type), o); | |||
1599 | if (wi::to_wide (a) == wi::neg (wi::to_wide (o))) | |||
1600 | ok = true; | |||
1601 | } | |||
1602 | } | |||
1603 | if (oarg && !ok) | |||
1604 | { | |||
1605 | if (operand_equal_p (arg, oarg, 0)) | |||
1606 | ok = true; | |||
1607 | else if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == SSA_NAME | |||
1608 | && TREE_CODE (oarg)((enum tree_code) (oarg)->base.code) == SSA_NAME) | |||
1609 | { | |||
1610 | tree oarg2 = oarg; | |||
1611 | if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (oarg)(tree_check ((oarg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1611, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt)) | |||
1612 | { | |||
1613 | gimple *g = SSA_NAME_DEF_STMT (oarg)(tree_check ((oarg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1613, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1614 | oarg2 = gimple_assign_rhs1 (g); | |||
1615 | if (TREE_CODE (oarg2)((enum tree_code) (oarg2)->base.code) != SSA_NAME | |||
1616 | || !INTEGRAL_TYPE_P (TREE_TYPE (oarg2))(((enum tree_code) (((contains_struct_check ((oarg2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1616, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((oarg2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1616, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((oarg2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1616, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1617 | || (TYPE_PRECISION (TREE_TYPE (oarg2))((tree_class_check ((((contains_struct_check ((oarg2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1617, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1617, __FUNCTION__))->type_common.precision) | |||
1618 | != TYPE_PRECISION (TREE_TYPE (oarg))((tree_class_check ((((contains_struct_check ((oarg), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1618, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1618, __FUNCTION__))->type_common.precision))) | |||
1619 | oarg2 = oarg; | |||
1620 | } | |||
1621 | if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg)(tree_check ((arg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1621, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt)) | |||
1622 | { | |||
1623 | gimple *g = SSA_NAME_DEF_STMT (arg)(tree_check ((arg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1623, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1624 | tree rhs1 = gimple_assign_rhs1 (g); | |||
1625 | /* Handle e.g. | |||
1626 | x.0_1 = (long unsigned int) x_4(D); | |||
1627 | _2 = __atomic_fetch_add_8 (&vlong, x.0_1, 0); | |||
1628 | _3 = (long int) _2; | |||
1629 | _7 = x_4(D) + _3; */ | |||
1630 | if (rhs1 == oarg || rhs1 == oarg2) | |||
1631 | ok = true; | |||
1632 | /* Handle e.g. | |||
1633 | x.18_1 = (short unsigned int) x_5(D); | |||
1634 | _2 = (int) x.18_1; | |||
1635 | _3 = __atomic_fetch_xor_2 (&vshort, _2, 0); | |||
1636 | _4 = (short int) _3; | |||
1637 | _8 = x_5(D) ^ _4; | |||
1638 | This happens only for char/short. */ | |||
1639 | else if (TREE_CODE (rhs1)((enum tree_code) (rhs1)->base.code) == SSA_NAME | |||
1640 | && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))(((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1640, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1640, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1640, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1641 | && (TYPE_PRECISION (TREE_TYPE (rhs1))((tree_class_check ((((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1641, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1641, __FUNCTION__))->type_common.precision) | |||
1642 | == TYPE_PRECISION (TREE_TYPE (lhs2))((tree_class_check ((((contains_struct_check ((lhs2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1642, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1642, __FUNCTION__))->type_common.precision))) | |||
1643 | { | |||
1644 | g = SSA_NAME_DEF_STMT (rhs1)(tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1644, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1645 | if (gimple_assign_cast_p (g) | |||
1646 | && (gimple_assign_rhs1 (g) == oarg | |||
1647 | || gimple_assign_rhs1 (g) == oarg2)) | |||
1648 | ok = true; | |||
1649 | } | |||
1650 | } | |||
1651 | if (!ok && arg == oarg2) | |||
1652 | /* Handle e.g. | |||
1653 | _1 = __sync_fetch_and_add_4 (&v, x_5(D)); | |||
1654 | _2 = (int) _1; | |||
1655 | x.0_3 = (int) x_5(D); | |||
1656 | _7 = _2 + x.0_3; */ | |||
1657 | ok = true; | |||
1658 | } | |||
1659 | } | |||
1660 | ||||
1661 | if (ok) | |||
1662 | { | |||
1663 | tree new_lhs = make_ssa_name (TREE_TYPE (lhs2)((contains_struct_check ((lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1663, __FUNCTION__))->typed.type)); | |||
1664 | gimple_call_set_lhs (stmt2, new_lhs); | |||
1665 | gimple_call_set_fndecl (stmt2, ndecl); | |||
1666 | gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); | |||
1667 | if (ccode == ERROR_MARK) | |||
1668 | gimple_assign_set_rhs_with_ops (&gsi, cast_stmt | |||
1669 | ? NOP_EXPR : SSA_NAME, | |||
1670 | new_lhs); | |||
1671 | else | |||
1672 | { | |||
1673 | crhs1 = new_lhs; | |||
1674 | crhs2 = build_zero_cst (TREE_TYPE (lhs2)((contains_struct_check ((lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1674, __FUNCTION__))->typed.type)); | |||
1675 | if (gimple_code (use_stmt) == GIMPLE_COND) | |||
1676 | { | |||
1677 | gcond *cond_stmt = as_a <gcond *> (use_stmt); | |||
1678 | gimple_cond_set_lhs (cond_stmt, crhs1); | |||
1679 | gimple_cond_set_rhs (cond_stmt, crhs2); | |||
1680 | } | |||
1681 | else if (gimple_assign_rhs_class (use_stmt) | |||
1682 | == GIMPLE_BINARY_RHS) | |||
1683 | { | |||
1684 | gimple_assign_set_rhs1 (use_stmt, crhs1); | |||
1685 | gimple_assign_set_rhs2 (use_stmt, crhs2); | |||
1686 | } | |||
1687 | else | |||
1688 | { | |||
1689 | gcc_checking_assert (gimple_assign_rhs_code (use_stmt)((void)(!(gimple_assign_rhs_code (use_stmt) == COND_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1690, __FUNCTION__), 0 : 0)) | |||
1690 | == COND_EXPR)((void)(!(gimple_assign_rhs_code (use_stmt) == COND_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1690, __FUNCTION__), 0 : 0)); | |||
1691 | tree cond = build2 (ccode, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | |||
1692 | crhs1, crhs2); | |||
1693 | gimple_assign_set_rhs1 (use_stmt, cond); | |||
1694 | } | |||
1695 | } | |||
1696 | update_stmt (use_stmt); | |||
1697 | if (atomic_op != BIT_AND_EXPR | |||
1698 | && atomic_op != BIT_IOR_EXPR | |||
1699 | && !stmt_ends_bb_p (stmt2)) | |||
1700 | { | |||
1701 | /* For the benefit of debug stmts, emit stmt(s) to set | |||
1702 | lhs2 to the value it had from the new builtin. | |||
1703 | E.g. if it was previously: | |||
1704 | lhs2 = __atomic_fetch_add_8 (ptr, arg, 0); | |||
1705 | emit: | |||
1706 | new_lhs = __atomic_add_fetch_8 (ptr, arg, 0); | |||
1707 | lhs2 = new_lhs - arg; | |||
1708 | We also keep cast_stmt if any in the IL for | |||
1709 | the same reasons. | |||
1710 | These stmts will be DCEd later and proper debug info | |||
1711 | will be emitted. | |||
1712 | This is only possible for reversible operations | |||
1713 | (+/-/^) and without -fnon-call-exceptions. */ | |||
1714 | gsi = gsi_for_stmt (stmt2); | |||
1715 | tree type = TREE_TYPE (lhs2)((contains_struct_check ((lhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1715, __FUNCTION__))->typed.type); | |||
1716 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == INTEGER_CST) | |||
1717 | arg = fold_convert (type, arg)fold_convert_loc (((location_t) 0), type, arg); | |||
1718 | else if (!useless_type_conversion_p (type, TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1718, __FUNCTION__))->typed.type))) | |||
1719 | { | |||
1720 | tree narg = make_ssa_name (type); | |||
1721 | gimple *g = gimple_build_assign (narg, NOP_EXPR, arg); | |||
1722 | gsi_insert_after (&gsi, g, GSI_NEW_STMT); | |||
1723 | arg = narg; | |||
1724 | } | |||
1725 | enum tree_code rcode; | |||
1726 | switch (atomic_op) | |||
1727 | { | |||
1728 | case PLUS_EXPR: rcode = MINUS_EXPR; break; | |||
1729 | case MINUS_EXPR: rcode = PLUS_EXPR; break; | |||
1730 | case BIT_XOR_EXPR: rcode = atomic_op; break; | |||
1731 | default: gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1731, __FUNCTION__)); | |||
1732 | } | |||
1733 | gimple *g = gimple_build_assign (lhs2, rcode, new_lhs, arg); | |||
1734 | gsi_insert_after (&gsi, g, GSI_NEW_STMT); | |||
1735 | update_stmt (stmt2); | |||
1736 | } | |||
1737 | else | |||
1738 | { | |||
1739 | /* For e.g. | |||
1740 | lhs2 = __atomic_fetch_or_8 (ptr, arg, 0); | |||
1741 | after we change it to | |||
1742 | new_lhs = __atomic_or_fetch_8 (ptr, arg, 0); | |||
1743 | there is no way to find out the lhs2 value (i.e. | |||
1744 | what the atomic memory contained before the operation), | |||
1745 | values of some bits are lost. We have checked earlier | |||
1746 | that we don't have any non-debug users except for what | |||
1747 | we are already changing, so we need to reset the | |||
1748 | debug stmts and remove the cast_stmt if any. */ | |||
1749 | imm_use_iterator iter; | |||
1750 | FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs2)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse ((((use_stmt) = first_imm_use_stmt (&(iter), (lhs2))), & (iter))); !end_imm_use_stmt_p (&(iter)); (void) ((use_stmt ) = next_imm_use_stmt (&(iter)))) | |||
1751 | if (use_stmt != cast_stmt) | |||
1752 | { | |||
1753 | gcc_assert (is_gimple_debug (use_stmt))((void)(!(is_gimple_debug (use_stmt)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1753, __FUNCTION__), 0 : 0)); | |||
1754 | gimple_debug_bind_reset_value (use_stmt); | |||
1755 | update_stmt (use_stmt); | |||
1756 | } | |||
1757 | if (cast_stmt) | |||
1758 | { | |||
1759 | gsi = gsi_for_stmt (cast_stmt); | |||
1760 | gsi_remove (&gsi, true); | |||
1761 | } | |||
1762 | update_stmt (stmt2); | |||
1763 | release_ssa_name (lhs2); | |||
1764 | } | |||
1765 | } | |||
1766 | } | |||
1767 | break; | |||
1768 | ||||
1769 | default: | |||
1770 | break; | |||
1771 | } | |||
1772 | return false; | |||
1773 | } | |||
1774 | ||||
1775 | /* Given a ssa_name in NAME see if it was defined by an assignment and | |||
1776 | set CODE to be the code and ARG1 to the first operand on the rhs and ARG2 | |||
1777 | to the second operand on the rhs. */ | |||
1778 | ||||
1779 | static inline void | |||
1780 | defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2) | |||
1781 | { | |||
1782 | gimple *def; | |||
1783 | enum tree_code code1; | |||
1784 | tree arg11; | |||
1785 | tree arg21; | |||
1786 | tree arg31; | |||
1787 | enum gimple_rhs_class grhs_class; | |||
1788 | ||||
1789 | code1 = TREE_CODE (name)((enum tree_code) (name)->base.code); | |||
1790 | arg11 = name; | |||
1791 | arg21 = NULL_TREE(tree) nullptr; | |||
1792 | arg31 = NULL_TREE(tree) nullptr; | |||
1793 | grhs_class = get_gimple_rhs_class (code1); | |||
1794 | ||||
1795 | if (code1 == SSA_NAME) | |||
1796 | { | |||
1797 | def = SSA_NAME_DEF_STMT (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1797, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1798 | ||||
1799 | if (def && is_gimple_assign (def) | |||
1800 | && can_propagate_from (def)) | |||
1801 | { | |||
1802 | code1 = gimple_assign_rhs_code (def); | |||
1803 | arg11 = gimple_assign_rhs1 (def); | |||
1804 | arg21 = gimple_assign_rhs2 (def); | |||
1805 | arg31 = gimple_assign_rhs3 (def); | |||
1806 | } | |||
1807 | } | |||
1808 | else if (grhs_class != GIMPLE_SINGLE_RHS) | |||
1809 | code1 = ERROR_MARK; | |||
1810 | ||||
1811 | *code = code1; | |||
1812 | *arg1 = arg11; | |||
1813 | if (arg2) | |||
1814 | *arg2 = arg21; | |||
1815 | if (arg31) | |||
1816 | *code = ERROR_MARK; | |||
1817 | } | |||
1818 | ||||
1819 | ||||
1820 | /* Recognize rotation patterns. Return true if a transformation | |||
1821 | applied, otherwise return false. | |||
1822 | ||||
1823 | We are looking for X with unsigned type T with bitsize B, OP being | |||
1824 | +, | or ^, some type T2 wider than T. For: | |||
1825 | (X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B | |||
1826 | ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B | |||
1827 | ||||
1828 | transform these into: | |||
1829 | X r<< CNT1 | |||
1830 | ||||
1831 | Or for: | |||
1832 | (X << Y) OP (X >> (B - Y)) | |||
1833 | (X << (int) Y) OP (X >> (int) (B - Y)) | |||
1834 | ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y))) | |||
1835 | ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y))) | |||
1836 | (X << Y) | (X >> ((-Y) & (B - 1))) | |||
1837 | (X << (int) Y) | (X >> (int) ((-Y) & (B - 1))) | |||
1838 | ((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1)))) | |||
1839 | ((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1)))) | |||
1840 | ||||
1841 | transform these into (last 2 only if ranger can prove Y < B | |||
1842 | or Y = N * B): | |||
1843 | X r<< Y | |||
1844 | or | |||
1845 | X r<< (& & (B - 1)) | |||
1846 | The latter for the forms with T2 wider than T if ranger can't prove Y < B. | |||
1847 | ||||
1848 | Or for: | |||
1849 | (X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1))) | |||
1850 | (X << (int) (Y & (B - 1))) | (X >> (int) ((-Y) & (B - 1))) | |||
1851 | ((T) ((T2) X << (Y & (B - 1)))) | ((T) ((T2) X >> ((-Y) & (B - 1)))) | |||
1852 | ((T) ((T2) X << (int) (Y & (B - 1)))) \ | |||
1853 | | ((T) ((T2) X >> (int) ((-Y) & (B - 1)))) | |||
1854 | ||||
1855 | transform these into: | |||
1856 | X r<< (Y & (B - 1)) | |||
1857 | ||||
1858 | Note, in the patterns with T2 type, the type of OP operands | |||
1859 | might be even a signed type, but should have precision B. | |||
1860 | Expressions with & (B - 1) should be recognized only if B is | |||
1861 | a power of 2. */ | |||
1862 | ||||
1863 | static bool | |||
1864 | simplify_rotate (gimple_stmt_iterator *gsi) | |||
1865 | { | |||
1866 | gimple *stmt = gsi_stmt (*gsi); | |||
1867 | tree arg[2], rtype, rotcnt = NULL_TREE(tree) nullptr; | |||
1868 | tree def_arg1[2], def_arg2[2]; | |||
1869 | enum tree_code def_code[2]; | |||
1870 | tree lhs; | |||
1871 | int i; | |||
1872 | bool swapped_p = false; | |||
1873 | gimple *g; | |||
1874 | gimple *def_arg_stmt[2] = { NULLnullptr, NULLnullptr }; | |||
1875 | int wider_prec = 0; | |||
1876 | bool add_masking = false; | |||
1877 | ||||
1878 | arg[0] = gimple_assign_rhs1 (stmt); | |||
1879 | arg[1] = gimple_assign_rhs2 (stmt); | |||
1880 | rtype = TREE_TYPE (arg[0])((contains_struct_check ((arg[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1880, __FUNCTION__))->typed.type); | |||
1881 | ||||
1882 | /* Only create rotates in complete modes. Other cases are not | |||
1883 | expanded properly. */ | |||
1884 | if (!INTEGRAL_TYPE_P (rtype)(((enum tree_code) (rtype)->base.code) == ENUMERAL_TYPE || ((enum tree_code) (rtype)->base.code) == BOOLEAN_TYPE || ( (enum tree_code) (rtype)->base.code) == INTEGER_TYPE) | |||
1885 | || !type_has_mode_precision_p (rtype)) | |||
1886 | return false; | |||
1887 | ||||
1888 | for (i = 0; i < 2; i++) | |||
1889 | { | |||
1890 | defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]); | |||
1891 | if (TREE_CODE (arg[i])((enum tree_code) (arg[i])->base.code) == SSA_NAME) | |||
1892 | def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i])(tree_check ((arg[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1892, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1893 | } | |||
1894 | ||||
1895 | /* Look through narrowing (or same precision) conversions. */ | |||
1896 | if (CONVERT_EXPR_CODE_P (def_code[0])((def_code[0]) == NOP_EXPR || (def_code[0]) == CONVERT_EXPR) | |||
1897 | && CONVERT_EXPR_CODE_P (def_code[1])((def_code[1]) == NOP_EXPR || (def_code[1]) == CONVERT_EXPR) | |||
1898 | && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))(((enum tree_code) (((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1898, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[0]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1898, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[0]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1898, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1899 | && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))(((enum tree_code) (((contains_struct_check ((def_arg1[1]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1899, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[1]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1899, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[1]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1899, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1900 | && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1900, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1900, __FUNCTION__))->type_common.precision) | |||
1901 | == TYPE_PRECISION (TREE_TYPE (def_arg1[1]))((tree_class_check ((((contains_struct_check ((def_arg1[1]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1901, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1901, __FUNCTION__))->type_common.precision) | |||
1902 | && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1902, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1902, __FUNCTION__))->type_common.precision) >= TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1902, __FUNCTION__))->type_common.precision) | |||
1903 | && has_single_use (arg[0]) | |||
1904 | && has_single_use (arg[1])) | |||
1905 | { | |||
1906 | wider_prec = TYPE_PRECISION (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1906, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1906, __FUNCTION__))->type_common.precision); | |||
1907 | for (i = 0; i < 2; i++) | |||
1908 | { | |||
1909 | arg[i] = def_arg1[i]; | |||
1910 | defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]); | |||
1911 | if (TREE_CODE (arg[i])((enum tree_code) (arg[i])->base.code) == SSA_NAME) | |||
1912 | def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i])(tree_check ((arg[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1912, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1913 | } | |||
1914 | } | |||
1915 | else | |||
1916 | { | |||
1917 | /* Handle signed rotate; the RSHIFT_EXPR has to be done | |||
1918 | in unsigned type but LSHIFT_EXPR could be signed. */ | |||
1919 | i = (def_code[0] == LSHIFT_EXPR || def_code[0] == RSHIFT_EXPR); | |||
1920 | if (CONVERT_EXPR_CODE_P (def_code[i])((def_code[i]) == NOP_EXPR || (def_code[i]) == CONVERT_EXPR) | |||
1921 | && (def_code[1 - i] == LSHIFT_EXPR || def_code[1 - i] == RSHIFT_EXPR) | |||
1922 | && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[i]))(((enum tree_code) (((contains_struct_check ((def_arg1[i]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1922, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[i]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1922, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((def_arg1[i]) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1922, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1923 | && TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1923, __FUNCTION__))->type_common.precision) == TYPE_PRECISION (TREE_TYPE (def_arg1[i]))((tree_class_check ((((contains_struct_check ((def_arg1[i]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1923, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1923, __FUNCTION__))->type_common.precision) | |||
1924 | && has_single_use (arg[i])) | |||
1925 | { | |||
1926 | arg[i] = def_arg1[i]; | |||
1927 | defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]); | |||
1928 | if (TREE_CODE (arg[i])((enum tree_code) (arg[i])->base.code) == SSA_NAME) | |||
1929 | def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i])(tree_check ((arg[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1929, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
1930 | } | |||
1931 | } | |||
1932 | ||||
1933 | /* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR. */ | |||
1934 | for (i = 0; i < 2; i++) | |||
1935 | if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR) | |||
1936 | return false; | |||
1937 | else if (!has_single_use (arg[i])) | |||
1938 | return false; | |||
1939 | if (def_code[0] == def_code[1]) | |||
1940 | return false; | |||
1941 | ||||
1942 | /* If we've looked through narrowing conversions before, look through | |||
1943 | widening conversions from unsigned type with the same precision | |||
1944 | as rtype here. */ | |||
1945 | if (TYPE_PRECISION (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1945, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1945, __FUNCTION__))->type_common.precision) != TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1945, __FUNCTION__))->type_common.precision)) | |||
1946 | for (i = 0; i < 2; i++) | |||
1947 | { | |||
1948 | tree tem; | |||
1949 | enum tree_code code; | |||
1950 | defcodefor_name (def_arg1[i], &code, &tem, NULLnullptr); | |||
1951 | if (!CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
1952 | || !INTEGRAL_TYPE_P (TREE_TYPE (tem))(((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1952, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1952, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1952, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1953 | || TYPE_PRECISION (TREE_TYPE (tem))((tree_class_check ((((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1953, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1953, __FUNCTION__))->type_common.precision) != TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1953, __FUNCTION__))->type_common.precision)) | |||
1954 | return false; | |||
1955 | def_arg1[i] = tem; | |||
1956 | } | |||
1957 | /* Both shifts have to use the same first operand. */ | |||
1958 | if (!operand_equal_for_phi_arg_p (def_arg1[0], def_arg1[1]) | |||
1959 | || !types_compatible_p (TREE_TYPE (def_arg1[0])((contains_struct_check ((def_arg1[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1959, __FUNCTION__))->typed.type), | |||
1960 | TREE_TYPE (def_arg1[1])((contains_struct_check ((def_arg1[1]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1960, __FUNCTION__))->typed.type))) | |||
1961 | { | |||
1962 | if ((TYPE_PRECISION (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1962, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1962, __FUNCTION__))->type_common.precision) | |||
1963 | != TYPE_PRECISION (TREE_TYPE (def_arg1[1]))((tree_class_check ((((contains_struct_check ((def_arg1[1]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1963, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1963, __FUNCTION__))->type_common.precision)) | |||
1964 | || (TYPE_UNSIGNED (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1964, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1964, __FUNCTION__))->base.u.bits.unsigned_flag) | |||
1965 | == TYPE_UNSIGNED (TREE_TYPE (def_arg1[1]))((tree_class_check ((((contains_struct_check ((def_arg1[1]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1965, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1965, __FUNCTION__))->base.u.bits.unsigned_flag))) | |||
1966 | return false; | |||
1967 | ||||
1968 | /* Handle signed rotate; the RSHIFT_EXPR has to be done | |||
1969 | in unsigned type but LSHIFT_EXPR could be signed. */ | |||
1970 | i = def_code[0] != RSHIFT_EXPR; | |||
1971 | if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[i]))((tree_class_check ((((contains_struct_check ((def_arg1[i]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1971, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1971, __FUNCTION__))->base.u.bits.unsigned_flag)) | |||
1972 | return false; | |||
1973 | ||||
1974 | tree tem; | |||
1975 | enum tree_code code; | |||
1976 | defcodefor_name (def_arg1[i], &code, &tem, NULLnullptr); | |||
1977 | if (!CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
1978 | || !INTEGRAL_TYPE_P (TREE_TYPE (tem))(((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1978, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1978, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1978, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
1979 | || TYPE_PRECISION (TREE_TYPE (tem))((tree_class_check ((((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1979, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1979, __FUNCTION__))->type_common.precision) != TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1979, __FUNCTION__))->type_common.precision)) | |||
1980 | return false; | |||
1981 | def_arg1[i] = tem; | |||
1982 | if (!operand_equal_for_phi_arg_p (def_arg1[0], def_arg1[1]) | |||
1983 | || !types_compatible_p (TREE_TYPE (def_arg1[0])((contains_struct_check ((def_arg1[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1983, __FUNCTION__))->typed.type), | |||
1984 | TREE_TYPE (def_arg1[1])((contains_struct_check ((def_arg1[1]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1984, __FUNCTION__))->typed.type))) | |||
1985 | return false; | |||
1986 | } | |||
1987 | else if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0]))((tree_class_check ((((contains_struct_check ((def_arg1[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1987, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1987, __FUNCTION__))->base.u.bits.unsigned_flag)) | |||
1988 | return false; | |||
1989 | ||||
1990 | /* CNT1 + CNT2 == B case above. */ | |||
1991 | if (tree_fits_uhwi_p (def_arg2[0]) | |||
1992 | && tree_fits_uhwi_p (def_arg2[1]) | |||
1993 | && tree_to_uhwi (def_arg2[0]) | |||
1994 | + tree_to_uhwi (def_arg2[1]) == TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 1994, __FUNCTION__))->type_common.precision)) | |||
1995 | rotcnt = def_arg2[0]; | |||
1996 | else if (TREE_CODE (def_arg2[0])((enum tree_code) (def_arg2[0])->base.code) != SSA_NAME | |||
1997 | || TREE_CODE (def_arg2[1])((enum tree_code) (def_arg2[1])->base.code) != SSA_NAME) | |||
1998 | return false; | |||
1999 | else | |||
2000 | { | |||
2001 | tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2]; | |||
2002 | enum tree_code cdef_code[2]; | |||
2003 | gimple *def_arg_alt_stmt[2] = { NULLnullptr, NULLnullptr }; | |||
2004 | int check_range = 0; | |||
2005 | gimple *check_range_stmt = NULLnullptr; | |||
2006 | /* Look through conversion of the shift count argument. | |||
2007 | The C/C++ FE cast any shift count argument to integer_type_node. | |||
2008 | The only problem might be if the shift count type maximum value | |||
2009 | is equal or smaller than number of bits in rtype. */ | |||
2010 | for (i = 0; i < 2; i++) | |||
2011 | { | |||
2012 | def_arg2_alt[i] = def_arg2[i]; | |||
2013 | defcodefor_name (def_arg2[i], &cdef_code[i], | |||
2014 | &cdef_arg1[i], &cdef_arg2[i]); | |||
2015 | if (CONVERT_EXPR_CODE_P (cdef_code[i])((cdef_code[i]) == NOP_EXPR || (cdef_code[i]) == CONVERT_EXPR ) | |||
2016 | && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))(((enum tree_code) (((contains_struct_check ((cdef_arg1[i]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2016, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((cdef_arg1[i] ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2016, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((cdef_arg1[i] ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2016, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
2017 | && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))((tree_class_check ((((contains_struct_check ((cdef_arg1[i]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2017, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2017, __FUNCTION__))->type_common.precision) | |||
2018 | > floor_log2 (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2018, __FUNCTION__))->type_common.precision)) | |||
2019 | && type_has_mode_precision_p (TREE_TYPE (cdef_arg1[i])((contains_struct_check ((cdef_arg1[i]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2019, __FUNCTION__))->typed.type))) | |||
2020 | { | |||
2021 | def_arg2_alt[i] = cdef_arg1[i]; | |||
2022 | if (TREE_CODE (def_arg2[i])((enum tree_code) (def_arg2[i])->base.code) == SSA_NAME) | |||
2023 | def_arg_alt_stmt[i] = SSA_NAME_DEF_STMT (def_arg2[i])(tree_check ((def_arg2[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2023, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
2024 | defcodefor_name (def_arg2_alt[i], &cdef_code[i], | |||
2025 | &cdef_arg1[i], &cdef_arg2[i]); | |||
2026 | } | |||
2027 | else | |||
2028 | def_arg_alt_stmt[i] = def_arg_stmt[i]; | |||
2029 | } | |||
2030 | for (i = 0; i < 2; i++) | |||
2031 | /* Check for one shift count being Y and the other B - Y, | |||
2032 | with optional casts. */ | |||
2033 | if (cdef_code[i] == MINUS_EXPR | |||
2034 | && tree_fits_shwi_p (cdef_arg1[i]) | |||
2035 | && tree_to_shwi (cdef_arg1[i]) == TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2035, __FUNCTION__))->type_common.precision) | |||
2036 | && TREE_CODE (cdef_arg2[i])((enum tree_code) (cdef_arg2[i])->base.code) == SSA_NAME) | |||
2037 | { | |||
2038 | tree tem; | |||
2039 | enum tree_code code; | |||
2040 | ||||
2041 | if (cdef_arg2[i] == def_arg2[1 - i] | |||
2042 | || cdef_arg2[i] == def_arg2_alt[1 - i]) | |||
2043 | { | |||
2044 | rotcnt = cdef_arg2[i]; | |||
2045 | check_range = -1; | |||
2046 | if (cdef_arg2[i] == def_arg2[1 - i]) | |||
2047 | check_range_stmt = def_arg_stmt[1 - i]; | |||
2048 | else | |||
2049 | check_range_stmt = def_arg_alt_stmt[1 - i]; | |||
2050 | break; | |||
2051 | } | |||
2052 | defcodefor_name (cdef_arg2[i], &code, &tem, NULLnullptr); | |||
2053 | if (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
2054 | && INTEGRAL_TYPE_P (TREE_TYPE (tem))(((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2054, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2054, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2054, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
2055 | && TYPE_PRECISION (TREE_TYPE (tem))((tree_class_check ((((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2055, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2055, __FUNCTION__))->type_common.precision) | |||
2056 | > floor_log2 (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2056, __FUNCTION__))->type_common.precision)) | |||
2057 | && type_has_mode_precision_p (TREE_TYPE (tem)((contains_struct_check ((tem), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2057, __FUNCTION__))->typed.type)) | |||
2058 | && (tem == def_arg2[1 - i] | |||
2059 | || tem == def_arg2_alt[1 - i])) | |||
2060 | { | |||
2061 | rotcnt = tem; | |||
2062 | check_range = -1; | |||
2063 | if (tem == def_arg2[1 - i]) | |||
2064 | check_range_stmt = def_arg_stmt[1 - i]; | |||
2065 | else | |||
2066 | check_range_stmt = def_arg_alt_stmt[1 - i]; | |||
2067 | break; | |||
2068 | } | |||
2069 | } | |||
2070 | /* The above sequence isn't safe for Y being 0, | |||
2071 | because then one of the shifts triggers undefined behavior. | |||
2072 | This alternative is safe even for rotation count of 0. | |||
2073 | One shift count is Y and the other (-Y) & (B - 1). | |||
2074 | Or one shift count is Y & (B - 1) and the other (-Y) & (B - 1). */ | |||
2075 | else if (cdef_code[i] == BIT_AND_EXPR | |||
2076 | && pow2p_hwi (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2076, __FUNCTION__))->type_common.precision)) | |||
2077 | && tree_fits_shwi_p (cdef_arg2[i]) | |||
2078 | && tree_to_shwi (cdef_arg2[i]) | |||
2079 | == TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2079, __FUNCTION__))->type_common.precision) - 1 | |||
2080 | && TREE_CODE (cdef_arg1[i])((enum tree_code) (cdef_arg1[i])->base.code) == SSA_NAME | |||
2081 | && gimple_assign_rhs_code (stmt) == BIT_IOR_EXPR) | |||
2082 | { | |||
2083 | tree tem; | |||
2084 | enum tree_code code; | |||
2085 | ||||
2086 | defcodefor_name (cdef_arg1[i], &code, &tem, NULLnullptr); | |||
2087 | if (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
2088 | && INTEGRAL_TYPE_P (TREE_TYPE (tem))(((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2088, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2088, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2088, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
2089 | && TYPE_PRECISION (TREE_TYPE (tem))((tree_class_check ((((contains_struct_check ((tem), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2089, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2089, __FUNCTION__))->type_common.precision) | |||
2090 | > floor_log2 (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2090, __FUNCTION__))->type_common.precision)) | |||
2091 | && type_has_mode_precision_p (TREE_TYPE (tem)((contains_struct_check ((tem), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2091, __FUNCTION__))->typed.type))) | |||
2092 | defcodefor_name (tem, &code, &tem, NULLnullptr); | |||
2093 | ||||
2094 | if (code == NEGATE_EXPR) | |||
2095 | { | |||
2096 | if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i]) | |||
2097 | { | |||
2098 | rotcnt = tem; | |||
2099 | check_range = 1; | |||
2100 | if (tem == def_arg2[1 - i]) | |||
2101 | check_range_stmt = def_arg_stmt[1 - i]; | |||
2102 | else | |||
2103 | check_range_stmt = def_arg_alt_stmt[1 - i]; | |||
2104 | break; | |||
2105 | } | |||
2106 | tree tem2; | |||
2107 | defcodefor_name (tem, &code, &tem2, NULLnullptr); | |||
2108 | if (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
2109 | && INTEGRAL_TYPE_P (TREE_TYPE (tem2))(((enum tree_code) (((contains_struct_check ((tem2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2109, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2109, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2109, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
2110 | && TYPE_PRECISION (TREE_TYPE (tem2))((tree_class_check ((((contains_struct_check ((tem2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2110, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2110, __FUNCTION__))->type_common.precision) | |||
2111 | > floor_log2 (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2111, __FUNCTION__))->type_common.precision)) | |||
2112 | && type_has_mode_precision_p (TREE_TYPE (tem2)((contains_struct_check ((tem2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2112, __FUNCTION__))->typed.type))) | |||
2113 | { | |||
2114 | if (tem2 == def_arg2[1 - i] | |||
2115 | || tem2 == def_arg2_alt[1 - i]) | |||
2116 | { | |||
2117 | rotcnt = tem2; | |||
2118 | check_range = 1; | |||
2119 | if (tem2 == def_arg2[1 - i]) | |||
2120 | check_range_stmt = def_arg_stmt[1 - i]; | |||
2121 | else | |||
2122 | check_range_stmt = def_arg_alt_stmt[1 - i]; | |||
2123 | break; | |||
2124 | } | |||
2125 | } | |||
2126 | else | |||
2127 | tem2 = NULL_TREE(tree) nullptr; | |||
2128 | ||||
2129 | if (cdef_code[1 - i] == BIT_AND_EXPR | |||
2130 | && tree_fits_shwi_p (cdef_arg2[1 - i]) | |||
2131 | && tree_to_shwi (cdef_arg2[1 - i]) | |||
2132 | == TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2132, __FUNCTION__))->type_common.precision) - 1 | |||
2133 | && TREE_CODE (cdef_arg1[1 - i])((enum tree_code) (cdef_arg1[1 - i])->base.code) == SSA_NAME) | |||
2134 | { | |||
2135 | if (tem == cdef_arg1[1 - i] | |||
2136 | || tem2 == cdef_arg1[1 - i]) | |||
2137 | { | |||
2138 | rotcnt = def_arg2[1 - i]; | |||
2139 | break; | |||
2140 | } | |||
2141 | tree tem3; | |||
2142 | defcodefor_name (cdef_arg1[1 - i], &code, &tem3, NULLnullptr); | |||
2143 | if (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
2144 | && INTEGRAL_TYPE_P (TREE_TYPE (tem3))(((enum tree_code) (((contains_struct_check ((tem3), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2144, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((tem3), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2144, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((tem3), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2144, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) | |||
2145 | && TYPE_PRECISION (TREE_TYPE (tem3))((tree_class_check ((((contains_struct_check ((tem3), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2145, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2145, __FUNCTION__))->type_common.precision) | |||
2146 | > floor_log2 (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2146, __FUNCTION__))->type_common.precision)) | |||
2147 | && type_has_mode_precision_p (TREE_TYPE (tem3)((contains_struct_check ((tem3), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2147, __FUNCTION__))->typed.type))) | |||
2148 | { | |||
2149 | if (tem == tem3 || tem2 == tem3) | |||
2150 | { | |||
2151 | rotcnt = def_arg2[1 - i]; | |||
2152 | break; | |||
2153 | } | |||
2154 | } | |||
2155 | } | |||
2156 | } | |||
2157 | } | |||
2158 | if (check_range && wider_prec > TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2158, __FUNCTION__))->type_common.precision)) | |||
2159 | { | |||
2160 | if (TREE_CODE (rotcnt)((enum tree_code) (rotcnt)->base.code) != SSA_NAME) | |||
2161 | return false; | |||
2162 | int_range_max r; | |||
2163 | range_query *q = get_range_query (cfun(cfun + 0)); | |||
2164 | if (q == get_global_range_query ()) | |||
2165 | q = enable_ranger (cfun(cfun + 0)); | |||
2166 | if (!q->range_of_expr (r, rotcnt, check_range_stmt)) | |||
2167 | { | |||
2168 | if (check_range > 0) | |||
2169 | return false; | |||
2170 | r.set_varying (TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2170, __FUNCTION__))->typed.type)); | |||
2171 | } | |||
2172 | int prec = TYPE_PRECISION (TREE_TYPE (rotcnt))((tree_class_check ((((contains_struct_check ((rotcnt), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2172, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2172, __FUNCTION__))->type_common.precision); | |||
2173 | signop sign = TYPE_SIGN (TREE_TYPE (rotcnt))((signop) ((tree_class_check ((((contains_struct_check ((rotcnt ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2173, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2173, __FUNCTION__))->base.u.bits.unsigned_flag)); | |||
2174 | wide_int min = wide_int::from (TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2174, __FUNCTION__))->type_common.precision), prec, sign); | |||
2175 | wide_int max = wide_int::from (wider_prec - 1, prec, sign); | |||
2176 | if (check_range < 0) | |||
2177 | max = min; | |||
2178 | int_range<1> r2 (TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2178, __FUNCTION__))->typed.type), min, max); | |||
2179 | r.intersect (r2); | |||
2180 | if (!r.undefined_p ()) | |||
2181 | { | |||
2182 | if (check_range > 0) | |||
2183 | { | |||
2184 | int_range_max r3; | |||
2185 | for (int i = TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2185, __FUNCTION__))->type_common.precision) + 1; i < wider_prec; | |||
2186 | i += TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2186, __FUNCTION__))->type_common.precision)) | |||
2187 | { | |||
2188 | int j = i + TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2188, __FUNCTION__))->type_common.precision) - 2; | |||
2189 | min = wide_int::from (i, prec, sign); | |||
2190 | max = wide_int::from (MIN (j, wider_prec - 1)((j) < (wider_prec - 1) ? (j) : (wider_prec - 1)), | |||
2191 | prec, sign); | |||
2192 | int_range<1> r4 (TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2192, __FUNCTION__))->typed.type), min, max); | |||
2193 | r3.union_ (r4); | |||
2194 | } | |||
2195 | r.intersect (r3); | |||
2196 | if (!r.undefined_p ()) | |||
2197 | return false; | |||
2198 | } | |||
2199 | add_masking = true; | |||
2200 | } | |||
2201 | } | |||
2202 | if (rotcnt == NULL_TREE(tree) nullptr) | |||
2203 | return false; | |||
2204 | swapped_p = i != 1; | |||
2205 | } | |||
2206 | ||||
2207 | if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0])((contains_struct_check ((def_arg2[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2207, __FUNCTION__))->typed.type), | |||
2208 | TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2208, __FUNCTION__))->typed.type))) | |||
2209 | { | |||
2210 | g = gimple_build_assign (make_ssa_name (TREE_TYPE (def_arg2[0])((contains_struct_check ((def_arg2[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2210, __FUNCTION__))->typed.type)), | |||
2211 | NOP_EXPR, rotcnt); | |||
2212 | gsi_insert_before (gsi, g, GSI_SAME_STMT); | |||
2213 | rotcnt = gimple_assign_lhs (g); | |||
2214 | } | |||
2215 | if (add_masking) | |||
2216 | { | |||
2217 | g = gimple_build_assign (make_ssa_name (TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2217, __FUNCTION__))->typed.type)), | |||
2218 | BIT_AND_EXPR, rotcnt, | |||
2219 | build_int_cst (TREE_TYPE (rotcnt)((contains_struct_check ((rotcnt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2219, __FUNCTION__))->typed.type), | |||
2220 | TYPE_PRECISION (rtype)((tree_class_check ((rtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2220, __FUNCTION__))->type_common.precision) - 1)); | |||
2221 | gsi_insert_before (gsi, g, GSI_SAME_STMT); | |||
2222 | rotcnt = gimple_assign_lhs (g); | |||
2223 | } | |||
2224 | lhs = gimple_assign_lhs (stmt); | |||
2225 | if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])((contains_struct_check ((def_arg1[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2225, __FUNCTION__))->typed.type))) | |||
2226 | lhs = make_ssa_name (TREE_TYPE (def_arg1[0])((contains_struct_check ((def_arg1[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2226, __FUNCTION__))->typed.type)); | |||
2227 | g = gimple_build_assign (lhs, | |||
2228 | ((def_code[0] == LSHIFT_EXPR) ^ swapped_p) | |||
2229 | ? LROTATE_EXPR : RROTATE_EXPR, def_arg1[0], rotcnt); | |||
2230 | if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])((contains_struct_check ((def_arg1[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2230, __FUNCTION__))->typed.type))) | |||
2231 | { | |||
2232 | gsi_insert_before (gsi, g, GSI_SAME_STMT); | |||
2233 | g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, lhs); | |||
2234 | } | |||
2235 | gsi_replace (gsi, g, false); | |||
2236 | return true; | |||
2237 | } | |||
2238 | ||||
2239 | ||||
2240 | /* Check whether an array contains a valid ctz table. */ | |||
2241 | static bool | |||
2242 | check_ctz_array (tree ctor, unsigned HOST_WIDE_INTlong mulc, | |||
2243 | HOST_WIDE_INTlong &zero_val, unsigned shift, unsigned bits) | |||
2244 | { | |||
2245 | tree elt, idx; | |||
2246 | unsigned HOST_WIDE_INTlong i, mask; | |||
2247 | unsigned matched = 0; | |||
2248 | ||||
2249 | mask = ((HOST_WIDE_INT_1U1UL << (bits - shift)) - 1) << shift; | |||
2250 | ||||
2251 | zero_val = 0; | |||
2252 | ||||
2253 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, elt)for (i = 0; (i >= vec_safe_length (((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2253, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (elt = (*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2253, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (idx = (*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2253, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) | |||
2254 | { | |||
2255 | if (TREE_CODE (idx)((enum tree_code) (idx)->base.code) != INTEGER_CST || TREE_CODE (elt)((enum tree_code) (elt)->base.code) != INTEGER_CST) | |||
2256 | return false; | |||
2257 | if (i > bits * 2) | |||
2258 | return false; | |||
2259 | ||||
2260 | unsigned HOST_WIDE_INTlong index = tree_to_shwi (idx); | |||
2261 | HOST_WIDE_INTlong val = tree_to_shwi (elt); | |||
2262 | ||||
2263 | if (index == 0) | |||
2264 | { | |||
2265 | zero_val = val; | |||
2266 | matched++; | |||
2267 | } | |||
2268 | ||||
2269 | if (val >= 0 && val < bits && (((mulc << val) & mask) >> shift) == index) | |||
2270 | matched++; | |||
2271 | ||||
2272 | if (matched > bits) | |||
2273 | return true; | |||
2274 | } | |||
2275 | ||||
2276 | return false; | |||
2277 | } | |||
2278 | ||||
2279 | /* Check whether a string contains a valid ctz table. */ | |||
2280 | static bool | |||
2281 | check_ctz_string (tree string, unsigned HOST_WIDE_INTlong mulc, | |||
2282 | HOST_WIDE_INTlong &zero_val, unsigned shift, unsigned bits) | |||
2283 | { | |||
2284 | unsigned HOST_WIDE_INTlong len = TREE_STRING_LENGTH (string)((tree_check ((string), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2284, __FUNCTION__, (STRING_CST)))->string.length); | |||
2285 | unsigned HOST_WIDE_INTlong mask; | |||
2286 | unsigned matched = 0; | |||
2287 | const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (string)((const char *)((tree_check ((string), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2287, __FUNCTION__, (STRING_CST)))->string.str)); | |||
2288 | ||||
2289 | if (len < bits || len > bits * 2) | |||
2290 | return false; | |||
2291 | ||||
2292 | mask = ((HOST_WIDE_INT_1U1UL << (bits - shift)) - 1) << shift; | |||
2293 | ||||
2294 | zero_val = p[0]; | |||
2295 | ||||
2296 | for (unsigned i = 0; i < len; i++) | |||
2297 | if (p[i] < bits && (((mulc << p[i]) & mask) >> shift) == i) | |||
2298 | matched++; | |||
2299 | ||||
2300 | return matched == bits; | |||
2301 | } | |||
2302 | ||||
2303 | /* Recognize count trailing zeroes idiom. | |||
2304 | The canonical form is array[((x & -x) * C) >> SHIFT] where C is a magic | |||
2305 | constant which when multiplied by a power of 2 creates a unique value | |||
2306 | in the top 5 or 6 bits. This is then indexed into a table which maps it | |||
2307 | to the number of trailing zeroes. Array[0] is returned so the caller can | |||
2308 | emit an appropriate sequence depending on whether ctz (0) is defined on | |||
2309 | the target. */ | |||
2310 | static bool | |||
2311 | optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc, | |||
2312 | tree tshift, HOST_WIDE_INTlong &zero_val) | |||
2313 | { | |||
2314 | tree type = TREE_TYPE (array_ref)((contains_struct_check ((array_ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2314, __FUNCTION__))->typed.type); | |||
2315 | tree array = TREE_OPERAND (array_ref, 0)(*((const_cast<tree*> (tree_operand_check ((array_ref), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2315, __FUNCTION__))))); | |||
2316 | ||||
2317 | gcc_assert (TREE_CODE (mulc) == INTEGER_CST)((void)(!(((enum tree_code) (mulc)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2317, __FUNCTION__), 0 : 0)); | |||
2318 | gcc_assert (TREE_CODE (tshift) == INTEGER_CST)((void)(!(((enum tree_code) (tshift)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2318, __FUNCTION__), 0 : 0)); | |||
2319 | ||||
2320 | tree input_type = TREE_TYPE (x)((contains_struct_check ((x), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2320, __FUNCTION__))->typed.type); | |||
2321 | unsigned input_bits = tree_to_shwi (TYPE_SIZE (input_type)((tree_class_check ((input_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2321, __FUNCTION__))->type_common.size)); | |||
2322 | ||||
2323 | /* Check the array element type is not wider than 32 bits and the input is | |||
2324 | an unsigned 32-bit or 64-bit type. */ | |||
2325 | if (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2325, __FUNCTION__))->type_common.precision) > 32 || !TYPE_UNSIGNED (input_type)((tree_class_check ((input_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2325, __FUNCTION__))->base.u.bits.unsigned_flag)) | |||
2326 | return false; | |||
2327 | if (input_bits != 32 && input_bits != 64) | |||
2328 | return false; | |||
2329 | ||||
2330 | if (!direct_internal_fn_supported_p (IFN_CTZ, input_type, OPTIMIZE_FOR_BOTH)) | |||
2331 | return false; | |||
2332 | ||||
2333 | /* Check the lower bound of the array is zero. */ | |||
2334 | tree low = array_ref_low_bound (array_ref); | |||
2335 | if (!low || !integer_zerop (low)) | |||
2336 | return false; | |||
2337 | ||||
2338 | unsigned shiftval = tree_to_shwi (tshift); | |||
2339 | ||||
2340 | /* Check the shift extracts the top 5..7 bits. */ | |||
2341 | if (shiftval < input_bits - 7 || shiftval > input_bits - 5) | |||
2342 | return false; | |||
2343 | ||||
2344 | tree ctor = ctor_for_folding (array); | |||
2345 | if (!ctor) | |||
2346 | return false; | |||
2347 | ||||
2348 | unsigned HOST_WIDE_INTlong val = tree_to_uhwi (mulc); | |||
2349 | ||||
2350 | if (TREE_CODE (ctor)((enum tree_code) (ctor)->base.code) == CONSTRUCTOR) | |||
2351 | return check_ctz_array (ctor, val, zero_val, shiftval, input_bits); | |||
2352 | ||||
2353 | if (TREE_CODE (ctor)((enum tree_code) (ctor)->base.code) == STRING_CST | |||
2354 | && TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2354, __FUNCTION__))->type_common.precision) == CHAR_TYPE_SIZE(8)) | |||
2355 | return check_ctz_string (ctor, val, zero_val, shiftval, input_bits); | |||
2356 | ||||
2357 | return false; | |||
2358 | } | |||
2359 | ||||
2360 | /* Match.pd function to match the ctz expression. */ | |||
2361 | extern bool gimple_ctz_table_index (tree, tree *, tree (*)(tree)); | |||
2362 | ||||
2363 | static bool | |||
2364 | simplify_count_trailing_zeroes (gimple_stmt_iterator *gsi) | |||
2365 | { | |||
2366 | gimple *stmt = gsi_stmt (*gsi); | |||
2367 | tree array_ref = gimple_assign_rhs1 (stmt); | |||
2368 | tree res_ops[3]; | |||
2369 | HOST_WIDE_INTlong zero_val; | |||
2370 | ||||
2371 | gcc_checking_assert (TREE_CODE (array_ref) == ARRAY_REF)((void)(!(((enum tree_code) (array_ref)->base.code) == ARRAY_REF ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2371, __FUNCTION__), 0 : 0)); | |||
2372 | ||||
2373 | if (!gimple_ctz_table_index (TREE_OPERAND (array_ref, 1)(*((const_cast<tree*> (tree_operand_check ((array_ref), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2373, __FUNCTION__))))), &res_ops[0], NULLnullptr)) | |||
2374 | return false; | |||
2375 | ||||
2376 | if (optimize_count_trailing_zeroes (array_ref, res_ops[0], | |||
2377 | res_ops[1], res_ops[2], zero_val)) | |||
2378 | { | |||
2379 | tree type = TREE_TYPE (res_ops[0])((contains_struct_check ((res_ops[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2379, __FUNCTION__))->typed.type); | |||
2380 | HOST_WIDE_INTlong ctz_val = 0; | |||
2381 | HOST_WIDE_INTlong type_size = tree_to_shwi (TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2381, __FUNCTION__))->type_common.size)); | |||
2382 | bool zero_ok | |||
2383 | = CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type), ctz_val)((ctz_val) = GET_MODE_BITSIZE ((as_a <scalar_int_mode> ( (tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2383, __FUNCTION__))->type_common.mode))), ((global_options .x_ix86_isa_flags & (1UL << 23)) != 0) ? 2 : 0) == 2; | |||
2384 | ||||
2385 | /* If the input value can't be zero, don't special case ctz (0). */ | |||
2386 | if (tree_expr_nonzero_p (res_ops[0])) | |||
2387 | { | |||
2388 | zero_ok = true; | |||
2389 | zero_val = 0; | |||
2390 | ctz_val = 0; | |||
2391 | } | |||
2392 | ||||
2393 | /* Skip if there is no value defined at zero, or if we can't easily | |||
2394 | return the correct value for zero. */ | |||
2395 | if (!zero_ok) | |||
2396 | return false; | |||
2397 | if (zero_val != ctz_val && !(zero_val == 0 && ctz_val == type_size)) | |||
2398 | return false; | |||
2399 | ||||
2400 | gimple_seq seq = NULLnullptr; | |||
2401 | gimple *g; | |||
2402 | gcall *call = gimple_build_call_internal (IFN_CTZ, 1, res_ops[0]); | |||
2403 | gimple_set_location (call, gimple_location (stmt)); | |||
2404 | gimple_set_lhs (call, make_ssa_name (integer_type_nodeinteger_types[itk_int])); | |||
2405 | gimple_seq_add_stmt (&seq, call); | |||
2406 | ||||
2407 | tree prev_lhs = gimple_call_lhs (call); | |||
2408 | ||||
2409 | /* Emit ctz (x) & 31 if ctz (0) is 32 but we need to return 0. */ | |||
2410 | if (zero_val == 0 && ctz_val == type_size) | |||
2411 | { | |||
2412 | g = gimple_build_assign (make_ssa_name (integer_type_nodeinteger_types[itk_int]), | |||
2413 | BIT_AND_EXPR, prev_lhs, | |||
2414 | build_int_cst (integer_type_nodeinteger_types[itk_int], | |||
2415 | type_size - 1)); | |||
2416 | gimple_set_location (g, gimple_location (stmt)); | |||
2417 | gimple_seq_add_stmt (&seq, g); | |||
2418 | prev_lhs = gimple_assign_lhs (g); | |||
2419 | } | |||
2420 | ||||
2421 | g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, prev_lhs); | |||
2422 | gimple_seq_add_stmt (&seq, g); | |||
2423 | gsi_replace_with_seq (gsi, seq, true); | |||
2424 | return true; | |||
2425 | } | |||
2426 | ||||
2427 | return false; | |||
2428 | } | |||
2429 | ||||
2430 | ||||
2431 | /* Combine an element access with a shuffle. Returns true if there were | |||
2432 | any changes made, else it returns false. */ | |||
2433 | ||||
2434 | static bool | |||
2435 | simplify_bitfield_ref (gimple_stmt_iterator *gsi) | |||
2436 | { | |||
2437 | gimple *stmt = gsi_stmt (*gsi); | |||
2438 | gimple *def_stmt; | |||
2439 | tree op, op0, op1; | |||
2440 | tree elem_type, type; | |||
2441 | tree p, m, tem; | |||
2442 | unsigned HOST_WIDE_INTlong nelts, idx; | |||
2443 | poly_uint64 size, elem_size; | |||
2444 | enum tree_code code; | |||
2445 | ||||
2446 | op = gimple_assign_rhs1 (stmt); | |||
2447 | gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF)((void)(!(((enum tree_code) (op)->base.code) == BIT_FIELD_REF ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2447, __FUNCTION__), 0 : 0)); | |||
2448 | ||||
2449 | op0 = TREE_OPERAND (op, 0)(*((const_cast<tree*> (tree_operand_check ((op), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2449, __FUNCTION__))))); | |||
2450 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) != SSA_NAME | |||
2451 | || TREE_CODE (TREE_TYPE (op0))((enum tree_code) (((contains_struct_check ((op0), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2451, __FUNCTION__))->typed.type))->base.code) != VECTOR_TYPE) | |||
2452 | return false; | |||
2453 | ||||
2454 | def_stmt = get_prop_source_stmt (op0, false, NULLnullptr); | |||
2455 | if (!def_stmt || !can_propagate_from (def_stmt)) | |||
2456 | return false; | |||
2457 | ||||
2458 | op1 = TREE_OPERAND (op, 1)(*((const_cast<tree*> (tree_operand_check ((op), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2458, __FUNCTION__))))); | |||
2459 | code = gimple_assign_rhs_code (def_stmt); | |||
2460 | elem_type = TREE_TYPE (TREE_TYPE (op0))((contains_struct_check ((((contains_struct_check ((op0), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2460, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2460, __FUNCTION__))->typed.type); | |||
2461 | type = TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2461, __FUNCTION__))->typed.type); | |||
2462 | /* Also handle vector type. | |||
2463 | .i.e. | |||
2464 | _7 = VEC_PERM_EXPR <_1, _1, { 2, 3, 2, 3 }>; | |||
2465 | _11 = BIT_FIELD_REF <_7, 64, 0>; | |||
2466 | ||||
2467 | to | |||
2468 | ||||
2469 | _11 = BIT_FIELD_REF <_1, 64, 64>. */ | |||
2470 | ||||
2471 | size = tree_to_poly_uint64 (TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2471, __FUNCTION__))->type_common.size)); | |||
2472 | if (maybe_ne (bit_field_size (op), size)) | |||
2473 | return false; | |||
2474 | ||||
2475 | elem_size = tree_to_poly_uint64 (TYPE_SIZE (elem_type)((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2475, __FUNCTION__))->type_common.size)); | |||
2476 | if (code != VEC_PERM_EXPR | |||
2477 | || !constant_multiple_p (bit_field_offset (op), elem_size, &idx)) | |||
2478 | return false; | |||
2479 | ||||
2480 | m = gimple_assign_rhs3 (def_stmt); | |||
2481 | if (TREE_CODE (m)((enum tree_code) (m)->base.code) != VECTOR_CST | |||
2482 | || !VECTOR_CST_NELTS (m)(TYPE_VECTOR_SUBPARTS (((contains_struct_check ((m), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2482, __FUNCTION__))->typed.type))).is_constant (&nelts)) | |||
2483 | return false; | |||
2484 | ||||
2485 | /* One element. */ | |||
2486 | if (known_eq (size, elem_size)(!maybe_ne (size, elem_size))) | |||
2487 | idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx))((unsigned long) (*tree_int_cst_elt_check ((vector_cst_elt (m , idx)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2487, __FUNCTION__))) % (2 * nelts); | |||
2488 | else | |||
2489 | { | |||
2490 | unsigned HOST_WIDE_INTlong nelts_op; | |||
2491 | if (!constant_multiple_p (size, elem_size, &nelts_op) | |||
2492 | || !pow2p_hwi (nelts_op)) | |||
2493 | return false; | |||
2494 | /* Clamp vec_perm_expr index. */ | |||
2495 | unsigned start = TREE_INT_CST_LOW (vector_cst_elt (m, idx))((unsigned long) (*tree_int_cst_elt_check ((vector_cst_elt (m , idx)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2495, __FUNCTION__))) % (2 * nelts); | |||
2496 | unsigned end = TREE_INT_CST_LOW (vector_cst_elt (m, idx + nelts_op - 1))((unsigned long) (*tree_int_cst_elt_check ((vector_cst_elt (m , idx + nelts_op - 1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2496, __FUNCTION__))) | |||
2497 | % (2 * nelts); | |||
2498 | /* Be in the same vector. */ | |||
2499 | if ((start < nelts) != (end < nelts)) | |||
2500 | return false; | |||
2501 | for (unsigned HOST_WIDE_INTlong i = 1; i != nelts_op; i++) | |||
2502 | { | |||
2503 | /* Continuous area. */ | |||
2504 | if (TREE_INT_CST_LOW (vector_cst_elt (m, idx + i))((unsigned long) (*tree_int_cst_elt_check ((vector_cst_elt (m , idx + i)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2504, __FUNCTION__))) % (2 * nelts) - 1 | |||
2505 | != TREE_INT_CST_LOW (vector_cst_elt (m, idx + i - 1))((unsigned long) (*tree_int_cst_elt_check ((vector_cst_elt (m , idx + i - 1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2505, __FUNCTION__))) | |||
2506 | % (2 * nelts)) | |||
2507 | return false; | |||
2508 | } | |||
2509 | /* Alignment not worse than before. */ | |||
2510 | if (start % nelts_op) | |||
2511 | return false; | |||
2512 | idx = start; | |||
2513 | } | |||
2514 | ||||
2515 | if (idx < nelts) | |||
2516 | p = gimple_assign_rhs1 (def_stmt); | |||
2517 | else | |||
2518 | { | |||
2519 | p = gimple_assign_rhs2 (def_stmt); | |||
2520 | idx -= nelts; | |||
2521 | } | |||
2522 | ||||
2523 | tem = build3 (BIT_FIELD_REF, TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2523, __FUNCTION__))->typed.type), | |||
2524 | p, op1, bitsize_int (idx * elem_size)size_int_kind (idx * elem_size, stk_bitsizetype)); | |||
2525 | gimple_assign_set_rhs1 (stmt, tem); | |||
2526 | fold_stmt (gsi); | |||
2527 | update_stmt (gsi_stmt (*gsi)); | |||
2528 | return true; | |||
2529 | } | |||
2530 | ||||
2531 | /* Determine whether applying the 2 permutations (mask1 then mask2) | |||
2532 | gives back one of the input. */ | |||
2533 | ||||
2534 | static int | |||
2535 | is_combined_permutation_identity (tree mask1, tree mask2) | |||
2536 | { | |||
2537 | tree mask; | |||
2538 | unsigned HOST_WIDE_INTlong nelts, i, j; | |||
2539 | bool maybe_identity1 = true; | |||
2540 | bool maybe_identity2 = true; | |||
2541 | ||||
2542 | gcc_checking_assert (TREE_CODE (mask1) == VECTOR_CST((void)(!(((enum tree_code) (mask1)->base.code) == VECTOR_CST && ((enum tree_code) (mask2)->base.code) == VECTOR_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2543, __FUNCTION__), 0 : 0)) | |||
2543 | && TREE_CODE (mask2) == VECTOR_CST)((void)(!(((enum tree_code) (mask1)->base.code) == VECTOR_CST && ((enum tree_code) (mask2)->base.code) == VECTOR_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2543, __FUNCTION__), 0 : 0)); | |||
2544 | mask = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (mask1), mask1, mask1, mask2)fold_ternary_loc (((location_t) 0), VEC_PERM_EXPR, ((contains_struct_check ((mask1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2544, __FUNCTION__))->typed.type), mask1, mask1, mask2); | |||
2545 | if (mask == NULL_TREE(tree) nullptr || TREE_CODE (mask)((enum tree_code) (mask)->base.code) != VECTOR_CST) | |||
2546 | return 0; | |||
2547 | ||||
2548 | if (!VECTOR_CST_NELTS (mask)(TYPE_VECTOR_SUBPARTS (((contains_struct_check ((mask), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2548, __FUNCTION__))->typed.type))).is_constant (&nelts)) | |||
2549 | return 0; | |||
2550 | for (i = 0; i < nelts; i++) | |||
2551 | { | |||
2552 | tree val = VECTOR_CST_ELT (mask, i)vector_cst_elt (mask, i); | |||
2553 | gcc_assert (TREE_CODE (val) == INTEGER_CST)((void)(!(((enum tree_code) (val)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2553, __FUNCTION__), 0 : 0)); | |||
2554 | j = TREE_INT_CST_LOW (val)((unsigned long) (*tree_int_cst_elt_check ((val), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2554, __FUNCTION__))) & (2 * nelts - 1); | |||
2555 | if (j == i) | |||
2556 | maybe_identity2 = false; | |||
2557 | else if (j == i + nelts) | |||
2558 | maybe_identity1 = false; | |||
2559 | else | |||
2560 | return 0; | |||
2561 | } | |||
2562 | return maybe_identity1 ? 1 : maybe_identity2 ? 2 : 0; | |||
2563 | } | |||
2564 | ||||
2565 | /* Combine a shuffle with its arguments. Returns 1 if there were any | |||
2566 | changes made, 2 if cfg-cleanup needs to run. Else it returns 0. */ | |||
2567 | ||||
2568 | static int | |||
2569 | simplify_permutation (gimple_stmt_iterator *gsi) | |||
2570 | { | |||
2571 | gimple *stmt = gsi_stmt (*gsi); | |||
2572 | gimple *def_stmt = NULLnullptr; | |||
2573 | tree op0, op1, op2, op3, arg0, arg1; | |||
2574 | enum tree_code code, code2 = ERROR_MARK; | |||
2575 | bool single_use_op0 = false; | |||
2576 | ||||
2577 | gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR)((void)(!(gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2577, __FUNCTION__), 0 : 0)); | |||
2578 | ||||
2579 | op0 = gimple_assign_rhs1 (stmt); | |||
2580 | op1 = gimple_assign_rhs2 (stmt); | |||
2581 | op2 = gimple_assign_rhs3 (stmt); | |||
2582 | ||||
2583 | if (TREE_CODE (op2)((enum tree_code) (op2)->base.code) != VECTOR_CST) | |||
2584 | return 0; | |||
2585 | ||||
2586 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == VECTOR_CST) | |||
2587 | { | |||
2588 | code = VECTOR_CST; | |||
2589 | arg0 = op0; | |||
2590 | } | |||
2591 | else if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == SSA_NAME) | |||
2592 | { | |||
2593 | def_stmt = get_prop_source_stmt (op0, false, &single_use_op0); | |||
2594 | if (!def_stmt) | |||
2595 | return 0; | |||
2596 | code = gimple_assign_rhs_code (def_stmt); | |||
2597 | if (code == VIEW_CONVERT_EXPR) | |||
2598 | { | |||
2599 | tree rhs = gimple_assign_rhs1 (def_stmt); | |||
2600 | tree name = TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2600, __FUNCTION__))))); | |||
2601 | if (TREE_CODE (name)((enum tree_code) (name)->base.code) != SSA_NAME) | |||
2602 | return 0; | |||
2603 | if (!has_single_use (name)) | |||
2604 | single_use_op0 = false; | |||
2605 | /* Here we update the def_stmt through this VIEW_CONVERT_EXPR, | |||
2606 | but still keep the code to indicate it comes from | |||
2607 | VIEW_CONVERT_EXPR. */ | |||
2608 | def_stmt = SSA_NAME_DEF_STMT (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2608, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
2609 | if (!def_stmt || !is_gimple_assign (def_stmt)) | |||
2610 | return 0; | |||
2611 | if (gimple_assign_rhs_code (def_stmt) != CONSTRUCTOR) | |||
2612 | return 0; | |||
2613 | } | |||
2614 | if (!can_propagate_from (def_stmt)) | |||
2615 | return 0; | |||
2616 | arg0 = gimple_assign_rhs1 (def_stmt); | |||
2617 | } | |||
2618 | else | |||
2619 | return 0; | |||
2620 | ||||
2621 | /* Two consecutive shuffles. */ | |||
2622 | if (code == VEC_PERM_EXPR) | |||
2623 | { | |||
2624 | tree orig; | |||
2625 | int ident; | |||
2626 | ||||
2627 | if (op0 != op1) | |||
2628 | return 0; | |||
2629 | op3 = gimple_assign_rhs3 (def_stmt); | |||
2630 | if (TREE_CODE (op3)((enum tree_code) (op3)->base.code) != VECTOR_CST) | |||
2631 | return 0; | |||
2632 | ident = is_combined_permutation_identity (op3, op2); | |||
2633 | if (!ident) | |||
2634 | return 0; | |||
2635 | orig = (ident == 1) ? gimple_assign_rhs1 (def_stmt) | |||
2636 | : gimple_assign_rhs2 (def_stmt); | |||
2637 | gimple_assign_set_rhs1 (stmt, unshare_expr (orig)); | |||
2638 | gimple_assign_set_rhs_code (stmt, TREE_CODE (orig)((enum tree_code) (orig)->base.code)); | |||
2639 | gimple_set_num_ops (stmt, 2); | |||
2640 | update_stmt (stmt); | |||
2641 | return remove_prop_source_from_use (op0) ? 2 : 1; | |||
2642 | } | |||
2643 | else if (code == CONSTRUCTOR | |||
2644 | || code == VECTOR_CST | |||
2645 | || code == VIEW_CONVERT_EXPR) | |||
2646 | { | |||
2647 | if (op0 != op1) | |||
2648 | { | |||
2649 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == SSA_NAME && !single_use_op0) | |||
2650 | return 0; | |||
2651 | ||||
2652 | if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) == VECTOR_CST) | |||
2653 | arg1 = op1; | |||
2654 | else if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) == SSA_NAME) | |||
2655 | { | |||
2656 | gimple *def_stmt2 = get_prop_source_stmt (op1, true, NULLnullptr); | |||
2657 | if (!def_stmt2) | |||
2658 | return 0; | |||
2659 | code2 = gimple_assign_rhs_code (def_stmt2); | |||
2660 | if (code2 == VIEW_CONVERT_EXPR) | |||
2661 | { | |||
2662 | tree rhs = gimple_assign_rhs1 (def_stmt2); | |||
2663 | tree name = TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2663, __FUNCTION__))))); | |||
2664 | if (TREE_CODE (name)((enum tree_code) (name)->base.code) != SSA_NAME) | |||
2665 | return 0; | |||
2666 | if (!has_single_use (name)) | |||
2667 | return 0; | |||
2668 | def_stmt2 = SSA_NAME_DEF_STMT (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2668, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
2669 | if (!def_stmt2 || !is_gimple_assign (def_stmt2)) | |||
2670 | return 0; | |||
2671 | if (gimple_assign_rhs_code (def_stmt2) != CONSTRUCTOR) | |||
2672 | return 0; | |||
2673 | } | |||
2674 | else if (code2 != CONSTRUCTOR && code2 != VECTOR_CST) | |||
2675 | return 0; | |||
2676 | if (!can_propagate_from (def_stmt2)) | |||
2677 | return 0; | |||
2678 | arg1 = gimple_assign_rhs1 (def_stmt2); | |||
2679 | } | |||
2680 | else | |||
2681 | return 0; | |||
2682 | } | |||
2683 | else | |||
2684 | { | |||
2685 | /* Already used twice in this statement. */ | |||
2686 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == SSA_NAME && num_imm_uses (op0) > 2) | |||
2687 | return 0; | |||
2688 | arg1 = arg0; | |||
2689 | } | |||
2690 | ||||
2691 | /* If there are any VIEW_CONVERT_EXPRs found when finding permutation | |||
2692 | operands source, check whether it's valid to transform and prepare | |||
2693 | the required new operands. */ | |||
2694 | if (code == VIEW_CONVERT_EXPR || code2 == VIEW_CONVERT_EXPR) | |||
2695 | { | |||
2696 | /* Figure out the target vector type to which operands should be | |||
2697 | converted. If both are CONSTRUCTOR, the types should be the | |||
2698 | same, otherwise, use the one of CONSTRUCTOR. */ | |||
2699 | tree tgt_type = NULL_TREE(tree) nullptr; | |||
2700 | if (code == VIEW_CONVERT_EXPR) | |||
2701 | { | |||
2702 | gcc_assert (gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR)((void)(!(gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2702, __FUNCTION__), 0 : 0)); | |||
2703 | code = CONSTRUCTOR; | |||
2704 | tgt_type = TREE_TYPE (arg0)((contains_struct_check ((arg0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2704, __FUNCTION__))->typed.type); | |||
2705 | } | |||
2706 | if (code2 == VIEW_CONVERT_EXPR) | |||
2707 | { | |||
2708 | tree arg1_type = TREE_TYPE (arg1)((contains_struct_check ((arg1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2708, __FUNCTION__))->typed.type); | |||
2709 | if (tgt_type == NULL_TREE(tree) nullptr) | |||
2710 | tgt_type = arg1_type; | |||
2711 | else if (tgt_type != arg1_type) | |||
2712 | return 0; | |||
2713 | } | |||
2714 | ||||
2715 | if (!VECTOR_TYPE_P (tgt_type)(((enum tree_code) (tgt_type)->base.code) == VECTOR_TYPE)) | |||
2716 | return 0; | |||
2717 | tree op2_type = TREE_TYPE (op2)((contains_struct_check ((op2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2717, __FUNCTION__))->typed.type); | |||
2718 | ||||
2719 | /* Figure out the shrunk factor. */ | |||
2720 | poly_uint64 tgt_units = TYPE_VECTOR_SUBPARTS (tgt_type); | |||
2721 | poly_uint64 op2_units = TYPE_VECTOR_SUBPARTS (op2_type); | |||
2722 | if (maybe_gt (tgt_units, op2_units)maybe_lt (op2_units, tgt_units)) | |||
2723 | return 0; | |||
2724 | unsigned int factor; | |||
2725 | if (!constant_multiple_p (op2_units, tgt_units, &factor)) | |||
2726 | return 0; | |||
2727 | ||||
2728 | /* Build the new permutation control vector as target vector. */ | |||
2729 | vec_perm_builder builder; | |||
2730 | if (!tree_to_vec_perm_builder (&builder, op2)) | |||
2731 | return 0; | |||
2732 | vec_perm_indices indices (builder, 2, op2_units); | |||
2733 | vec_perm_indices new_indices; | |||
2734 | if (new_indices.new_shrunk_vector (indices, factor)) | |||
2735 | { | |||
2736 | tree mask_type = tgt_type; | |||
2737 | if (!VECTOR_INTEGER_TYPE_P (mask_type)((((enum tree_code) (mask_type)->base.code) == VECTOR_TYPE ) && ((enum tree_code) (((contains_struct_check ((mask_type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2737, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )) | |||
2738 | { | |||
2739 | tree elem_type = TREE_TYPE (mask_type)((contains_struct_check ((mask_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2739, __FUNCTION__))->typed.type); | |||
2740 | unsigned elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2740, __FUNCTION__))->type_common.size)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2740, __FUNCTION__))); | |||
2741 | tree int_type = build_nonstandard_integer_type (elem_size, 0); | |||
2742 | mask_type = build_vector_type (int_type, tgt_units); | |||
2743 | } | |||
2744 | op2 = vec_perm_indices_to_tree (mask_type, new_indices); | |||
2745 | } | |||
2746 | else | |||
2747 | return 0; | |||
2748 | ||||
2749 | /* Convert the VECTOR_CST to the appropriate vector type. */ | |||
2750 | if (tgt_type != TREE_TYPE (arg0)((contains_struct_check ((arg0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2750, __FUNCTION__))->typed.type)) | |||
2751 | arg0 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg0)fold_build1_loc (((location_t) 0), VIEW_CONVERT_EXPR, tgt_type , arg0 ); | |||
2752 | else if (tgt_type != TREE_TYPE (arg1)((contains_struct_check ((arg1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2752, __FUNCTION__))->typed.type)) | |||
2753 | arg1 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg1)fold_build1_loc (((location_t) 0), VIEW_CONVERT_EXPR, tgt_type , arg1 ); | |||
2754 | } | |||
2755 | ||||
2756 | /* VIEW_CONVERT_EXPR should be updated to CONSTRUCTOR before. */ | |||
2757 | gcc_assert (code == CONSTRUCTOR || code == VECTOR_CST)((void)(!(code == CONSTRUCTOR || code == VECTOR_CST) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2757, __FUNCTION__), 0 : 0)); | |||
2758 | ||||
2759 | /* Shuffle of a constructor. */ | |||
2760 | bool ret = false; | |||
2761 | tree res_type | |||
2762 | = build_vector_type (TREE_TYPE (TREE_TYPE (arg0))((contains_struct_check ((((contains_struct_check ((arg0), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2762, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2762, __FUNCTION__))->typed.type), | |||
2763 | TYPE_VECTOR_SUBPARTS (TREE_TYPE (op2)((contains_struct_check ((op2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2763, __FUNCTION__))->typed.type))); | |||
2764 | tree opt = fold_ternary (VEC_PERM_EXPR, res_type, arg0, arg1, op2)fold_ternary_loc (((location_t) 0), VEC_PERM_EXPR, res_type, arg0 , arg1, op2); | |||
2765 | if (!opt | |||
2766 | || (TREE_CODE (opt)((enum tree_code) (opt)->base.code) != CONSTRUCTOR && TREE_CODE (opt)((enum tree_code) (opt)->base.code) != VECTOR_CST)) | |||
2767 | return 0; | |||
2768 | /* Found VIEW_CONVERT_EXPR before, need one explicit conversion. */ | |||
2769 | if (res_type != TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2769, __FUNCTION__))->typed.type)) | |||
2770 | { | |||
2771 | tree name = make_ssa_name (TREE_TYPE (opt)((contains_struct_check ((opt), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2771, __FUNCTION__))->typed.type)); | |||
2772 | gimple *ass_stmt = gimple_build_assign (name, opt); | |||
2773 | gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT); | |||
2774 | opt = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2774, __FUNCTION__))->typed.type), name); | |||
2775 | } | |||
2776 | gimple_assign_set_rhs_from_tree (gsi, opt); | |||
2777 | update_stmt (gsi_stmt (*gsi)); | |||
2778 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) == SSA_NAME) | |||
2779 | ret = remove_prop_source_from_use (op0); | |||
2780 | if (op0 != op1 && TREE_CODE (op1)((enum tree_code) (op1)->base.code) == SSA_NAME) | |||
2781 | ret |= remove_prop_source_from_use (op1); | |||
2782 | return ret ? 2 : 1; | |||
2783 | } | |||
2784 | ||||
2785 | return 0; | |||
2786 | } | |||
2787 | ||||
2788 | /* Get the BIT_FIELD_REF definition of VAL, if any, looking through | |||
2789 | conversions with code CONV_CODE or update it if still ERROR_MARK. | |||
2790 | Return NULL_TREE if no such matching def was found. */ | |||
2791 | ||||
2792 | static tree | |||
2793 | get_bit_field_ref_def (tree val, enum tree_code &conv_code) | |||
2794 | { | |||
2795 | if (TREE_CODE (val)((enum tree_code) (val)->base.code) != SSA_NAME) | |||
2796 | return NULL_TREE(tree) nullptr ; | |||
2797 | gimple *def_stmt = get_prop_source_stmt (val, false, NULLnullptr); | |||
2798 | if (!def_stmt) | |||
2799 | return NULL_TREE(tree) nullptr; | |||
2800 | enum tree_code code = gimple_assign_rhs_code (def_stmt); | |||
2801 | if (code == FLOAT_EXPR | |||
2802 | || code == FIX_TRUNC_EXPR | |||
2803 | || CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR)) | |||
2804 | { | |||
2805 | tree op1 = gimple_assign_rhs1 (def_stmt); | |||
2806 | if (conv_code == ERROR_MARK) | |||
2807 | conv_code = code; | |||
2808 | else if (conv_code != code) | |||
2809 | return NULL_TREE(tree) nullptr; | |||
2810 | if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) != SSA_NAME) | |||
2811 | return NULL_TREE(tree) nullptr; | |||
2812 | def_stmt = SSA_NAME_DEF_STMT (op1)(tree_check ((op1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2812, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
2813 | if (! is_gimple_assign (def_stmt)) | |||
2814 | return NULL_TREE(tree) nullptr; | |||
2815 | code = gimple_assign_rhs_code (def_stmt); | |||
2816 | } | |||
2817 | if (code != BIT_FIELD_REF) | |||
2818 | return NULL_TREE(tree) nullptr; | |||
2819 | return gimple_assign_rhs1 (def_stmt); | |||
2820 | } | |||
2821 | ||||
2822 | /* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */ | |||
2823 | ||||
2824 | static bool | |||
2825 | simplify_vector_constructor (gimple_stmt_iterator *gsi) | |||
2826 | { | |||
2827 | gimple *stmt = gsi_stmt (*gsi); | |||
2828 | tree op, orig[2], type, elem_type; | |||
2829 | unsigned elem_size, i; | |||
2830 | unsigned HOST_WIDE_INTlong nelts; | |||
2831 | unsigned HOST_WIDE_INTlong refnelts; | |||
2832 | enum tree_code conv_code; | |||
2833 | constructor_elt *elt; | |||
2834 | ||||
2835 | op = gimple_assign_rhs1 (stmt); | |||
2836 | type = TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2836, __FUNCTION__))->typed.type); | |||
2837 | gcc_checking_assert (TREE_CODE (op) == CONSTRUCTOR((void)(!(((enum tree_code) (op)->base.code) == CONSTRUCTOR && ((enum tree_code) (type)->base.code) == VECTOR_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2838, __FUNCTION__), 0 : 0)) | |||
2838 | && TREE_CODE (type) == VECTOR_TYPE)((void)(!(((enum tree_code) (op)->base.code) == CONSTRUCTOR && ((enum tree_code) (type)->base.code) == VECTOR_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2838, __FUNCTION__), 0 : 0)); | |||
2839 | ||||
2840 | if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)) | |||
2841 | return false; | |||
2842 | elem_type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2842, __FUNCTION__))->typed.type); | |||
2843 | elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2843, __FUNCTION__))->type_common.size)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2843, __FUNCTION__))); | |||
2844 | ||||
2845 | orig[0] = NULLnullptr; | |||
2846 | orig[1] = NULLnullptr; | |||
2847 | conv_code = ERROR_MARK; | |||
2848 | bool maybe_ident = true; | |||
2849 | bool maybe_blend[2] = { true, true }; | |||
2850 | tree one_constant = NULL_TREE(tree) nullptr; | |||
2851 | tree one_nonconstant = NULL_TREE(tree) nullptr; | |||
2852 | auto_vec<tree> constants; | |||
2853 | constants.safe_grow_cleared (nelts, true); | |||
2854 | auto_vec<std::pair<unsigned, unsigned>, 64> elts; | |||
2855 | FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)for (i = 0; vec_safe_iterate ((((tree_check ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2855, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)), (i), &(elt)); ++(i)) | |||
2856 | { | |||
2857 | tree ref, op1; | |||
2858 | unsigned int elem; | |||
2859 | ||||
2860 | if (i >= nelts) | |||
2861 | return false; | |||
2862 | ||||
2863 | /* Look for elements extracted and possibly converted from | |||
2864 | another vector. */ | |||
2865 | op1 = get_bit_field_ref_def (elt->value, conv_code); | |||
2866 | if (op1 | |||
2867 | && TREE_CODE ((ref = TREE_OPERAND (op1, 0)))((enum tree_code) ((ref = (*((const_cast<tree*> (tree_operand_check ((op1), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2867, __FUNCTION__)))))))->base.code) == SSA_NAME | |||
2868 | && VECTOR_TYPE_P (TREE_TYPE (ref))(((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2868, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE ) | |||
2869 | && useless_type_conversion_p (TREE_TYPE (op1)((contains_struct_check ((op1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2869, __FUNCTION__))->typed.type), | |||
2870 | TREE_TYPE (TREE_TYPE (ref))((contains_struct_check ((((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2870, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2870, __FUNCTION__))->typed.type)) | |||
2871 | && constant_multiple_p (bit_field_offset (op1), | |||
2872 | bit_field_size (op1), &elem) | |||
2873 | && TYPE_VECTOR_SUBPARTS (TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2873, __FUNCTION__))->typed.type)).is_constant (&refnelts)) | |||
2874 | { | |||
2875 | unsigned int j; | |||
2876 | for (j = 0; j < 2; ++j) | |||
2877 | { | |||
2878 | if (!orig[j]) | |||
2879 | { | |||
2880 | if (j == 0 | |||
2881 | || useless_type_conversion_p (TREE_TYPE (orig[0])((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2881, __FUNCTION__))->typed.type), | |||
2882 | TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2882, __FUNCTION__))->typed.type))) | |||
2883 | break; | |||
2884 | } | |||
2885 | else if (ref == orig[j]) | |||
2886 | break; | |||
2887 | } | |||
2888 | /* Found a suitable vector element. */ | |||
2889 | if (j < 2) | |||
2890 | { | |||
2891 | orig[j] = ref; | |||
2892 | if (elem != i || j != 0) | |||
2893 | maybe_ident = false; | |||
2894 | if (elem != i) | |||
2895 | maybe_blend[j] = false; | |||
2896 | elts.safe_push (std::make_pair (j, elem)); | |||
2897 | continue; | |||
2898 | } | |||
2899 | /* Else fallthru. */ | |||
2900 | } | |||
2901 | /* Handle elements not extracted from a vector. | |||
2902 | 1. constants by permuting with constant vector | |||
2903 | 2. a unique non-constant element by permuting with a splat vector */ | |||
2904 | if (orig[1] | |||
2905 | && orig[1] != error_mark_nodeglobal_trees[TI_ERROR_MARK]) | |||
2906 | return false; | |||
2907 | orig[1] = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | |||
2908 | if (CONSTANT_CLASS_P (elt->value)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (elt->value)->base.code))] == tcc_constant)) | |||
2909 | { | |||
2910 | if (one_nonconstant) | |||
2911 | return false; | |||
2912 | if (!one_constant) | |||
2913 | one_constant = elt->value; | |||
2914 | constants[i] = elt->value; | |||
2915 | } | |||
2916 | else | |||
2917 | { | |||
2918 | if (one_constant) | |||
2919 | return false; | |||
2920 | if (!one_nonconstant) | |||
2921 | one_nonconstant = elt->value; | |||
2922 | else if (!operand_equal_p (one_nonconstant, elt->value, 0)) | |||
2923 | return false; | |||
2924 | } | |||
2925 | elts.safe_push (std::make_pair (1, i)); | |||
2926 | maybe_ident = false; | |||
2927 | } | |||
2928 | if (i < nelts) | |||
2929 | return false; | |||
2930 | ||||
2931 | if (! orig[0] | |||
2932 | || ! VECTOR_TYPE_P (TREE_TYPE (orig[0]))(((enum tree_code) (((contains_struct_check ((orig[0]), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2932, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE )) | |||
2933 | return false; | |||
2934 | refnelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0])((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2934, __FUNCTION__))->typed.type)).to_constant (); | |||
2935 | /* We currently do not handle larger destination vectors. */ | |||
2936 | if (refnelts < nelts) | |||
2937 | return false; | |||
2938 | ||||
2939 | if (maybe_ident) | |||
2940 | { | |||
2941 | tree conv_src_type | |||
2942 | = (nelts != refnelts | |||
2943 | ? (conv_code != ERROR_MARK | |||
2944 | ? build_vector_type (TREE_TYPE (TREE_TYPE (orig[0]))((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2944, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2944, __FUNCTION__))->typed.type), nelts) | |||
2945 | : type) | |||
2946 | : TREE_TYPE (orig[0])((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2946, __FUNCTION__))->typed.type)); | |||
2947 | if (conv_code != ERROR_MARK | |||
2948 | && !supportable_convert_operation (conv_code, type, conv_src_type, | |||
2949 | &conv_code)) | |||
2950 | { | |||
2951 | /* Only few targets implement direct conversion patterns so try | |||
2952 | some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR. */ | |||
2953 | optab optab; | |||
2954 | tree halfvectype, dblvectype; | |||
2955 | enum tree_code unpack_op; | |||
2956 | ||||
2957 | if (!BYTES_BIG_ENDIAN0) | |||
2958 | unpack_op = (FLOAT_TYPE_P (TREE_TYPE (type))((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2958, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) || ((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2958, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE || (((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2958, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE )) && (((enum tree_code) (((contains_struct_check ((( (contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2958, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2958, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ))) | |||
2959 | ? VEC_UNPACK_FLOAT_LO_EXPR | |||
2960 | : VEC_UNPACK_LO_EXPR); | |||
2961 | else | |||
2962 | unpack_op = (FLOAT_TYPE_P (TREE_TYPE (type))((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2962, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) || ((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2962, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE || (((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2962, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE )) && (((enum tree_code) (((contains_struct_check ((( (contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2962, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2962, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ))) | |||
2963 | ? VEC_UNPACK_FLOAT_HI_EXPR | |||
2964 | : VEC_UNPACK_HI_EXPR); | |||
2965 | ||||
2966 | /* Conversions between DFP and FP have no special tree code | |||
2967 | but we cannot handle those since all relevant vector conversion | |||
2968 | optabs only have a single mode. */ | |||
2969 | if (CONVERT_EXPR_CODE_P (conv_code)((conv_code) == NOP_EXPR || (conv_code) == CONVERT_EXPR) | |||
2970 | && FLOAT_TYPE_P (TREE_TYPE (type))((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2970, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) || ((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2970, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE || (((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2970, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE )) && (((enum tree_code) (((contains_struct_check ((( (contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2970, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2970, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ))) | |||
2971 | && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (type))((((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2971, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) && (((enum mode_class) mode_class[((((enum tree_code ) ((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2971, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2971, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2971, __FUNCTION__))->typed.type)) : (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2971, __FUNCTION__))->typed.type))->type_common.mode) ]) == MODE_DECIMAL_FLOAT)) | |||
2972 | != DECIMAL_FLOAT_TYPE_P (TREE_TYPE (conv_src_type))((((enum tree_code) (((contains_struct_check ((conv_src_type) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2972, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) && (((enum mode_class) mode_class[((((enum tree_code ) ((tree_class_check ((((contains_struct_check ((conv_src_type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2972, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2972, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((conv_src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2972, __FUNCTION__))->typed.type)) : (((contains_struct_check ((conv_src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2972, __FUNCTION__))->typed.type))->type_common.mode) ]) == MODE_DECIMAL_FLOAT)))) | |||
2973 | return false; | |||
2974 | ||||
2975 | if (CONVERT_EXPR_CODE_P (conv_code)((conv_code) == NOP_EXPR || (conv_code) == CONVERT_EXPR) | |||
2976 | && (2 * TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))((tree_class_check ((((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2976, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2976, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2976, __FUNCTION__))->type_common.precision) | |||
2977 | == TYPE_PRECISION (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2977, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2977, __FUNCTION__))->type_common.precision)) | |||
2978 | && mode_for_vector (as_a <scalar_mode> | |||
2979 | (TYPE_MODE (TREE_TYPE (TREE_TYPE (orig[0])))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((((contains_struct_check ((orig[0] ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type)) : (((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2979, __FUNCTION__))->typed.type))->type_common.mode)), | |||
2980 | nelts * 2).exists () | |||
2981 | && (dblvectype | |||
2982 | = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0]))((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2982, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2982, __FUNCTION__))->typed.type), | |||
2983 | nelts * 2)) | |||
2984 | /* Only use it for vector modes or for vector booleans | |||
2985 | represented as scalar bitmasks. See PR95528. */ | |||
2986 | && (VECTOR_MODE_P (TYPE_MODE (dblvectype))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2986, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)]) == MODE_VECTOR_UACCUM ) | |||
2987 | || VECTOR_BOOLEAN_TYPE_P (dblvectype)(((enum tree_code) (dblvectype)->base.code) == VECTOR_TYPE && ((enum tree_code) (((contains_struct_check ((dblvectype ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2987, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE )) | |||
2988 | && (optab = optab_for_tree_code (unpack_op, | |||
2989 | dblvectype, | |||
2990 | optab_default)) | |||
2991 | && (optab_handler (optab, TYPE_MODE (dblvectype)((((enum tree_code) ((tree_class_check ((dblvectype), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 2991, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (dblvectype) : (dblvectype)->type_common.mode)) | |||
2992 | != CODE_FOR_nothing)) | |||
2993 | { | |||
2994 | gimple_seq stmts = NULLnullptr; | |||
2995 | tree dbl; | |||
2996 | if (refnelts == nelts) | |||
2997 | { | |||
2998 | /* ??? Paradoxical subregs don't exist, so insert into | |||
2999 | the lower half of a wider zero vector. */ | |||
3000 | dbl = gimple_build (&stmts, BIT_INSERT_EXPR, dblvectype, | |||
3001 | build_zero_cst (dblvectype), orig[0], | |||
3002 | bitsize_zero_nodeglobal_trees[TI_BITSIZE_ZERO]); | |||
3003 | } | |||
3004 | else if (refnelts == 2 * nelts) | |||
3005 | dbl = orig[0]; | |||
3006 | else | |||
3007 | dbl = gimple_build (&stmts, BIT_FIELD_REF, dblvectype, | |||
3008 | orig[0], TYPE_SIZE (dblvectype)((tree_class_check ((dblvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3008, __FUNCTION__))->type_common.size), | |||
3009 | bitsize_zero_nodeglobal_trees[TI_BITSIZE_ZERO]); | |||
3010 | gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); | |||
3011 | gimple_assign_set_rhs_with_ops (gsi, unpack_op, dbl); | |||
3012 | } | |||
3013 | else if (CONVERT_EXPR_CODE_P (conv_code)((conv_code) == NOP_EXPR || (conv_code) == CONVERT_EXPR) | |||
3014 | && (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))((tree_class_check ((((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3014, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3014, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3014, __FUNCTION__))->type_common.precision) | |||
3015 | == 2 * TYPE_PRECISION (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3015, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3015, __FUNCTION__))->type_common.precision)) | |||
3016 | && mode_for_vector (as_a <scalar_mode> | |||
3017 | (TYPE_MODE((((enum tree_code) ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((((contains_struct_check ((orig[0] ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)) : (((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type))->type_common.mode) | |||
3018 | (TREE_TYPE (TREE_TYPE (orig[0])))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((((contains_struct_check ((orig[0] ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)) : (((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3018, __FUNCTION__))->typed.type))->type_common.mode)), | |||
3019 | nelts / 2).exists () | |||
3020 | && (halfvectype | |||
3021 | = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0]))((contains_struct_check ((((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3021, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3021, __FUNCTION__))->typed.type), | |||
3022 | nelts / 2)) | |||
3023 | /* Only use it for vector modes or for vector booleans | |||
3024 | represented as scalar bitmasks. See PR95528. */ | |||
3025 | && (VECTOR_MODE_P (TYPE_MODE (halfvectype))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3025, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)]) == MODE_VECTOR_UACCUM ) | |||
3026 | || VECTOR_BOOLEAN_TYPE_P (halfvectype)(((enum tree_code) (halfvectype)->base.code) == VECTOR_TYPE && ((enum tree_code) (((contains_struct_check ((halfvectype ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3026, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE )) | |||
3027 | && (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR, | |||
3028 | halfvectype, | |||
3029 | optab_default)) | |||
3030 | && (optab_handler (optab, TYPE_MODE (halfvectype)((((enum tree_code) ((tree_class_check ((halfvectype), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3030, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (halfvectype) : (halfvectype)->type_common.mode)) | |||
3031 | != CODE_FOR_nothing)) | |||
3032 | { | |||
3033 | gimple_seq stmts = NULLnullptr; | |||
3034 | tree low = gimple_build (&stmts, BIT_FIELD_REF, halfvectype, | |||
3035 | orig[0], TYPE_SIZE (halfvectype)((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3035, __FUNCTION__))->type_common.size), | |||
3036 | bitsize_zero_nodeglobal_trees[TI_BITSIZE_ZERO]); | |||
3037 | tree hig = gimple_build (&stmts, BIT_FIELD_REF, halfvectype, | |||
3038 | orig[0], TYPE_SIZE (halfvectype)((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3038, __FUNCTION__))->type_common.size), | |||
3039 | TYPE_SIZE (halfvectype)((tree_class_check ((halfvectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3039, __FUNCTION__))->type_common.size)); | |||
3040 | gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); | |||
3041 | gimple_assign_set_rhs_with_ops (gsi, VEC_PACK_TRUNC_EXPR, | |||
3042 | low, hig); | |||
3043 | } | |||
3044 | else | |||
3045 | return false; | |||
3046 | update_stmt (gsi_stmt (*gsi)); | |||
3047 | return true; | |||
3048 | } | |||
3049 | if (nelts != refnelts) | |||
3050 | { | |||
3051 | gassign *lowpart | |||
3052 | = gimple_build_assign (make_ssa_name (conv_src_type), | |||
3053 | build3 (BIT_FIELD_REF, conv_src_type, | |||
3054 | orig[0], TYPE_SIZE (conv_src_type)((tree_class_check ((conv_src_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3054, __FUNCTION__))->type_common.size), | |||
3055 | bitsize_zero_nodeglobal_trees[TI_BITSIZE_ZERO])); | |||
3056 | gsi_insert_before (gsi, lowpart, GSI_SAME_STMT); | |||
3057 | orig[0] = gimple_assign_lhs (lowpart); | |||
3058 | } | |||
3059 | if (conv_code == ERROR_MARK) | |||
3060 | { | |||
3061 | tree src_type = TREE_TYPE (orig[0])((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3061, __FUNCTION__))->typed.type); | |||
3062 | if (!useless_type_conversion_p (type, src_type)) | |||
3063 | { | |||
3064 | gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type),((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (src_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3066, __FUNCTION__))->typed.type), ((contains_struct_check ((src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__), 0 : 0)) | |||
3065 | TYPE_VECTOR_SUBPARTS (src_type))((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (src_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3066, __FUNCTION__))->typed.type), ((contains_struct_check ((src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__), 0 : 0)) | |||
3066 | && useless_type_conversion_p (TREE_TYPE (type),((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (src_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3066, __FUNCTION__))->typed.type), ((contains_struct_check ((src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__), 0 : 0)) | |||
3067 | TREE_TYPE (src_type)))((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (src_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3066, __FUNCTION__))->typed.type), ((contains_struct_check ((src_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3067, __FUNCTION__), 0 : 0)); | |||
3068 | tree rhs = build1 (VIEW_CONVERT_EXPR, type, orig[0]); | |||
3069 | orig[0] = make_ssa_name (type); | |||
3070 | gassign *assign = gimple_build_assign (orig[0], rhs); | |||
3071 | gsi_insert_before (gsi, assign, GSI_SAME_STMT); | |||
3072 | } | |||
3073 | gimple_assign_set_rhs_from_tree (gsi, orig[0]); | |||
3074 | } | |||
3075 | else | |||
3076 | gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0], | |||
3077 | NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); | |||
3078 | } | |||
3079 | else | |||
3080 | { | |||
3081 | /* If we combine a vector with a non-vector avoid cases where | |||
3082 | we'll obviously end up with more GIMPLE stmts which is when | |||
3083 | we'll later not fold this to a single insert into the vector | |||
3084 | and we had a single extract originally. See PR92819. */ | |||
3085 | if (nelts == 2 | |||
3086 | && refnelts > 2 | |||
3087 | && orig[1] == error_mark_nodeglobal_trees[TI_ERROR_MARK] | |||
3088 | && !maybe_blend[0]) | |||
3089 | return false; | |||
3090 | tree mask_type, perm_type, conv_src_type; | |||
3091 | perm_type = TREE_TYPE (orig[0])((contains_struct_check ((orig[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3091, __FUNCTION__))->typed.type); | |||
3092 | conv_src_type = (nelts == refnelts | |||
3093 | ? perm_type | |||
3094 | : build_vector_type (TREE_TYPE (perm_type)((contains_struct_check ((perm_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3094, __FUNCTION__))->typed.type), nelts)); | |||
3095 | if (conv_code != ERROR_MARK | |||
3096 | && !supportable_convert_operation (conv_code, type, conv_src_type, | |||
3097 | &conv_code)) | |||
3098 | return false; | |||
3099 | ||||
3100 | /* Now that we know the number of elements of the source build the | |||
3101 | permute vector. | |||
3102 | ??? When the second vector has constant values we can shuffle | |||
3103 | it and its source indexes to make the permutation supported. | |||
3104 | For now it mimics a blend. */ | |||
3105 | vec_perm_builder sel (refnelts, refnelts, 1); | |||
3106 | bool all_same_p = true; | |||
3107 | for (i = 0; i < elts.length (); ++i) | |||
3108 | { | |||
3109 | sel.quick_push (elts[i].second + elts[i].first * refnelts); | |||
3110 | all_same_p &= known_eq (sel[i], sel[0])(!maybe_ne (sel[i], sel[0])); | |||
3111 | } | |||
3112 | /* And fill the tail with "something". It's really don't care, | |||
3113 | and ideally we'd allow VEC_PERM to have a smaller destination | |||
3114 | vector. As a heuristic: | |||
3115 | ||||
3116 | (a) if what we have so far duplicates a single element, make the | |||
3117 | tail do the same | |||
3118 | ||||
3119 | (b) otherwise preserve a uniform orig[0]. This facilitates | |||
3120 | later pattern-matching of VEC_PERM_EXPR to a BIT_INSERT_EXPR. */ | |||
3121 | for (; i < refnelts; ++i) | |||
3122 | sel.quick_push (all_same_p | |||
3123 | ? sel[0] | |||
3124 | : (elts[0].second == 0 && elts[0].first == 0 | |||
3125 | ? 0 : refnelts) + i); | |||
3126 | vec_perm_indices indices (sel, orig[1] ? 2 : 1, refnelts); | |||
3127 | machine_mode vmode = TYPE_MODE (perm_type)((((enum tree_code) ((tree_class_check ((perm_type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3127, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (perm_type) : (perm_type)->type_common.mode); | |||
3128 | if (!can_vec_perm_const_p (vmode, vmode, indices)) | |||
3129 | return false; | |||
3130 | mask_type | |||
3131 | = build_vector_type (build_nonstandard_integer_type (elem_size, 1), | |||
3132 | refnelts); | |||
3133 | if (GET_MODE_CLASS (TYPE_MODE (mask_type))((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((mask_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3133, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (mask_type) : (mask_type)->type_common.mode)]) != MODE_VECTOR_INT | |||
3134 | || maybe_ne (GET_MODE_SIZE (TYPE_MODE (mask_type)((((enum tree_code) ((tree_class_check ((mask_type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3134, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (mask_type) : (mask_type)->type_common.mode)), | |||
3135 | GET_MODE_SIZE (TYPE_MODE (perm_type)((((enum tree_code) ((tree_class_check ((perm_type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3135, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (perm_type) : (perm_type)->type_common.mode)))) | |||
3136 | return false; | |||
3137 | tree op2 = vec_perm_indices_to_tree (mask_type, indices); | |||
3138 | bool converted_orig1 = false; | |||
3139 | gimple_seq stmts = NULLnullptr; | |||
3140 | if (!orig[1]) | |||
3141 | orig[1] = orig[0]; | |||
3142 | else if (orig[1] == error_mark_nodeglobal_trees[TI_ERROR_MARK] | |||
3143 | && one_nonconstant) | |||
3144 | { | |||
3145 | /* ??? We can see if we can safely convert to the original | |||
3146 | element type. */ | |||
3147 | converted_orig1 = conv_code != ERROR_MARK; | |||
3148 | orig[1] = gimple_build_vector_from_val (&stmts, UNKNOWN_LOCATION((location_t) 0), | |||
3149 | converted_orig1 | |||
3150 | ? type : perm_type, | |||
3151 | one_nonconstant); | |||
3152 | } | |||
3153 | else if (orig[1] == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | |||
3154 | { | |||
3155 | /* ??? See if we can convert the vector to the original type. */ | |||
3156 | converted_orig1 = conv_code != ERROR_MARK; | |||
3157 | unsigned n = converted_orig1 ? nelts : refnelts; | |||
3158 | tree_vector_builder vec (converted_orig1 | |||
3159 | ? type : perm_type, n, 1); | |||
3160 | for (unsigned i = 0; i < n; ++i) | |||
3161 | if (i < nelts && constants[i]) | |||
3162 | vec.quick_push (constants[i]); | |||
3163 | else | |||
3164 | /* ??? Push a don't-care value. */ | |||
3165 | vec.quick_push (one_constant); | |||
3166 | orig[1] = vec.build (); | |||
3167 | } | |||
3168 | tree blend_op2 = NULL_TREE(tree) nullptr; | |||
3169 | if (converted_orig1) | |||
3170 | { | |||
3171 | /* Make sure we can do a blend in the target type. */ | |||
3172 | vec_perm_builder sel (nelts, nelts, 1); | |||
3173 | for (i = 0; i < elts.length (); ++i) | |||
3174 | sel.quick_push (elts[i].first | |||
3175 | ? elts[i].second + nelts : i); | |||
3176 | vec_perm_indices indices (sel, 2, nelts); | |||
3177 | machine_mode vmode = TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3177, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (type) : (type)->type_common.mode); | |||
3178 | if (!can_vec_perm_const_p (vmode, vmode, indices)) | |||
3179 | return false; | |||
3180 | mask_type | |||
3181 | = build_vector_type (build_nonstandard_integer_type (elem_size, 1), | |||
3182 | nelts); | |||
3183 | if (GET_MODE_CLASS (TYPE_MODE (mask_type))((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check ((mask_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3183, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (mask_type) : (mask_type)->type_common.mode)]) != MODE_VECTOR_INT | |||
3184 | || maybe_ne (GET_MODE_SIZE (TYPE_MODE (mask_type)((((enum tree_code) ((tree_class_check ((mask_type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3184, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (mask_type) : (mask_type)->type_common.mode)), | |||
3185 | GET_MODE_SIZE (TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3185, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (type) : (type)->type_common.mode)))) | |||
3186 | return false; | |||
3187 | blend_op2 = vec_perm_indices_to_tree (mask_type, indices); | |||
3188 | } | |||
3189 | tree orig1_for_perm | |||
3190 | = converted_orig1 ? build_zero_cst (perm_type) : orig[1]; | |||
3191 | tree res = gimple_build (&stmts, VEC_PERM_EXPR, perm_type, | |||
3192 | orig[0], orig1_for_perm, op2); | |||
3193 | if (nelts != refnelts) | |||
3194 | res = gimple_build (&stmts, BIT_FIELD_REF, | |||
3195 | conv_code != ERROR_MARK ? conv_src_type : type, | |||
3196 | res, TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3196, __FUNCTION__))->type_common.size), bitsize_zero_nodeglobal_trees[TI_BITSIZE_ZERO]); | |||
3197 | if (conv_code != ERROR_MARK) | |||
3198 | res = gimple_build (&stmts, conv_code, type, res); | |||
3199 | else if (!useless_type_conversion_p (type, TREE_TYPE (res)((contains_struct_check ((res), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3199, __FUNCTION__))->typed.type))) | |||
3200 | { | |||
3201 | gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type),((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (perm_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3203, __FUNCTION__))->typed.type), ((contains_struct_check ((perm_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__), 0 : 0)) | |||
3202 | TYPE_VECTOR_SUBPARTS (perm_type))((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (perm_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3203, __FUNCTION__))->typed.type), ((contains_struct_check ((perm_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__), 0 : 0)) | |||
3203 | && useless_type_conversion_p (TREE_TYPE (type),((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (perm_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3203, __FUNCTION__))->typed.type), ((contains_struct_check ((perm_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__), 0 : 0)) | |||
3204 | TREE_TYPE (perm_type)))((void)(!((!maybe_ne (TYPE_VECTOR_SUBPARTS (type), TYPE_VECTOR_SUBPARTS (perm_type))) && useless_type_conversion_p (((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3203, __FUNCTION__))->typed.type), ((contains_struct_check ((perm_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3204, __FUNCTION__), 0 : 0)); | |||
3205 | res = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, res); | |||
3206 | } | |||
3207 | /* Blend in the actual constant. */ | |||
3208 | if (converted_orig1) | |||
3209 | res = gimple_build (&stmts, VEC_PERM_EXPR, type, | |||
3210 | res, orig[1], blend_op2); | |||
3211 | gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); | |||
3212 | gimple_assign_set_rhs_with_ops (gsi, SSA_NAME, res); | |||
3213 | } | |||
3214 | update_stmt (gsi_stmt (*gsi)); | |||
3215 | return true; | |||
3216 | } | |||
3217 | ||||
3218 | ||||
3219 | /* Rewrite the vector load at *GSI to component-wise loads if the load | |||
3220 | is only used in BIT_FIELD_REF extractions with eventual intermediate | |||
3221 | widening. */ | |||
3222 | ||||
3223 | static void | |||
3224 | optimize_vector_load (gimple_stmt_iterator *gsi) | |||
3225 | { | |||
3226 | gimple *stmt = gsi_stmt (*gsi); | |||
3227 | tree lhs = gimple_assign_lhs (stmt); | |||
3228 | tree rhs = gimple_assign_rhs1 (stmt); | |||
3229 | ||||
3230 | /* Gather BIT_FIELD_REFs to rewrite, looking through | |||
3231 | VEC_UNPACK_{LO,HI}_EXPR. */ | |||
3232 | use_operand_p use_p; | |||
3233 | imm_use_iterator iter; | |||
3234 | bool rewrite = true; | |||
3235 | auto_vec<gimple *, 8> bf_stmts; | |||
3236 | auto_vec<tree, 8> worklist; | |||
3237 | worklist.quick_push (lhs); | |||
3238 | do | |||
3239 | { | |||
3240 | tree def = worklist.pop (); | |||
3241 | unsigned HOST_WIDE_INTlong def_eltsize | |||
3242 | = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (TREE_TYPE (def))))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((((contains_struct_check ((((contains_struct_check ((def), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3242, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3242, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3242, __FUNCTION__))->type_common.size)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3242, __FUNCTION__))); | |||
3243 | FOR_EACH_IMM_USE_FAST (use_p, iter, def)for ((use_p) = first_readonly_imm_use (&(iter), (def)); ! end_readonly_imm_use_p (&(iter)); (void) ((use_p) = next_readonly_imm_use (&(iter)))) | |||
3244 | { | |||
3245 | gimple *use_stmt = USE_STMT (use_p)(use_p)->loc.stmt; | |||
3246 | if (is_gimple_debug (use_stmt)) | |||
3247 | continue; | |||
3248 | if (!is_gimple_assign (use_stmt)) | |||
3249 | { | |||
3250 | rewrite = false; | |||
3251 | break; | |||
3252 | } | |||
3253 | enum tree_code use_code = gimple_assign_rhs_code (use_stmt); | |||
3254 | tree use_rhs = gimple_assign_rhs1 (use_stmt); | |||
3255 | if (use_code == BIT_FIELD_REF | |||
3256 | && TREE_OPERAND (use_rhs, 0)(*((const_cast<tree*> (tree_operand_check ((use_rhs), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3256, __FUNCTION__))))) == def | |||
3257 | /* If its on the VEC_UNPACK_{HI,LO}_EXPR | |||
3258 | def need to verify it is element aligned. */ | |||
3259 | && (def == lhs | |||
3260 | || (known_eq (bit_field_size (use_rhs), def_eltsize)(!maybe_ne (bit_field_size (use_rhs), def_eltsize)) | |||
3261 | && constant_multiple_p (bit_field_offset (use_rhs), | |||
3262 | def_eltsize) | |||
3263 | /* We can simulate the VEC_UNPACK_{HI,LO}_EXPR | |||
3264 | via a NOP_EXPR only for integral types. | |||
3265 | ??? Support VEC_UNPACK_FLOAT_{HI,LO}_EXPR. */ | |||
3266 | && INTEGRAL_TYPE_P (TREE_TYPE (use_rhs))(((enum tree_code) (((contains_struct_check ((use_rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3266, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((use_rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3266, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((use_rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3266, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )))) | |||
3267 | { | |||
3268 | bf_stmts.safe_push (use_stmt); | |||
3269 | continue; | |||
3270 | } | |||
3271 | /* Walk through one level of VEC_UNPACK_{LO,HI}_EXPR. */ | |||
3272 | if (def == lhs | |||
3273 | && (use_code == VEC_UNPACK_HI_EXPR | |||
3274 | || use_code == VEC_UNPACK_LO_EXPR) | |||
3275 | && use_rhs == lhs) | |||
3276 | { | |||
3277 | worklist.safe_push (gimple_assign_lhs (use_stmt)); | |||
3278 | continue; | |||
3279 | } | |||
3280 | rewrite = false; | |||
3281 | break; | |||
3282 | } | |||
3283 | if (!rewrite) | |||
3284 | break; | |||
3285 | } | |||
3286 | while (!worklist.is_empty ()); | |||
3287 | ||||
3288 | if (!rewrite) | |||
3289 | { | |||
3290 | gsi_next (gsi); | |||
3291 | return; | |||
3292 | } | |||
3293 | /* We now have all ultimate uses of the load to rewrite in bf_stmts. */ | |||
3294 | ||||
3295 | /* Prepare the original ref to be wrapped in adjusted BIT_FIELD_REFs. | |||
3296 | For TARGET_MEM_REFs we have to separate the LEA from the reference. */ | |||
3297 | tree load_rhs = rhs; | |||
3298 | if (TREE_CODE (load_rhs)((enum tree_code) (load_rhs)->base.code) == TARGET_MEM_REF) | |||
3299 | { | |||
3300 | if (TREE_CODE (TREE_OPERAND (load_rhs, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((load_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3300, __FUNCTION__))))))->base.code) == ADDR_EXPR) | |||
3301 | mark_addressable (TREE_OPERAND (TREE_OPERAND (load_rhs, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((load_rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3301, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3301, __FUNCTION__)))))); | |||
3302 | tree ptrtype = build_pointer_type (TREE_TYPE (load_rhs)((contains_struct_check ((load_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3302, __FUNCTION__))->typed.type)); | |||
3303 | tree tem = make_ssa_name (ptrtype); | |||
3304 | gimple *new_stmt | |||
3305 | = gimple_build_assign (tem, build1 (ADDR_EXPR, TREE_TYPE (tem)((contains_struct_check ((tem), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3305, __FUNCTION__))->typed.type), | |||
3306 | unshare_expr (load_rhs))); | |||
3307 | gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |||
3308 | load_rhs = build2_loc (EXPR_LOCATION (load_rhs)((((load_rhs)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((load_rhs))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((load_rhs))->base.code))]) <= tcc_expression)) ? (load_rhs)->exp.locus : ((location_t) 0 )), | |||
3309 | MEM_REF, TREE_TYPE (load_rhs)((contains_struct_check ((load_rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3309, __FUNCTION__))->typed.type), tem, | |||
3310 | build_int_cst | |||
3311 | (TREE_TYPE (TREE_OPERAND (load_rhs, 1))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((load_rhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3311, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3311, __FUNCTION__))->typed.type), 0)); | |||
3312 | } | |||
3313 | ||||
3314 | /* Rewrite the BIT_FIELD_REFs to be actual loads, re-emitting them at | |||
3315 | the place of the original load. */ | |||
3316 | for (gimple *use_stmt : bf_stmts) | |||
3317 | { | |||
3318 | tree bfr = gimple_assign_rhs1 (use_stmt); | |||
3319 | tree new_rhs = unshare_expr (load_rhs); | |||
3320 | if (TREE_OPERAND (bfr, 0)(*((const_cast<tree*> (tree_operand_check ((bfr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3320, __FUNCTION__))))) != lhs) | |||
3321 | { | |||
3322 | /* When the BIT_FIELD_REF is on the promoted vector we have to | |||
3323 | adjust it and emit a conversion afterwards. */ | |||
3324 | gimple *def_stmt | |||
3325 | = SSA_NAME_DEF_STMT (TREE_OPERAND (bfr, 0))(tree_check (((*((const_cast<tree*> (tree_operand_check ((bfr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3325, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3325, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt; | |||
3326 | enum tree_code def_code | |||
3327 | = gimple_assign_rhs_code (def_stmt); | |||
3328 | ||||
3329 | /* The adjusted BIT_FIELD_REF is of the promotion source | |||
3330 | vector size and at half of the offset... */ | |||
3331 | new_rhs = fold_build3 (BIT_FIELD_REF,fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3332 | TREE_TYPE (TREE_TYPE (lhs)),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3333 | new_rhs,fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3334 | TYPE_SIZE (TREE_TYPE (TREE_TYPE (lhs))),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3335 | size_binop (EXACT_DIV_EXPR,fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3336 | TREE_OPERAND (bfr, 2),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ) | |||
3337 | bitsize_int (2)))fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3332, __FUNCTION__))->typed.type), new_rhs, ((tree_class_check ((((contains_struct_check ((((contains_struct_check ((lhs), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3334, __FUNCTION__))->type_common.size), size_binop_loc ( ((location_t) 0), EXACT_DIV_EXPR, (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3336, __FUNCTION__))))), size_int_kind (2, stk_bitsizetype) ) ); | |||
3338 | /* ... and offsetted by half of the vector if VEC_UNPACK_HI_EXPR. */ | |||
3339 | if (def_code == (!BYTES_BIG_ENDIAN0 | |||
3340 | ? VEC_UNPACK_HI_EXPR : VEC_UNPACK_LO_EXPR)) | |||
3341 | TREE_OPERAND (new_rhs, 2)(*((const_cast<tree*> (tree_operand_check ((new_rhs), ( 2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3341, __FUNCTION__))))) | |||
3342 | = size_binop (PLUS_EXPR, TREE_OPERAND (new_rhs, 2),size_binop_loc (((location_t) 0), PLUS_EXPR, (*((const_cast< tree*> (tree_operand_check ((new_rhs), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3342, __FUNCTION__))))), size_binop_loc (((location_t) 0), EXACT_DIV_EXPR , ((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->type_common.size), size_int_kind ( 2, stk_bitsizetype))) | |||
3343 | size_binop (EXACT_DIV_EXPR,size_binop_loc (((location_t) 0), PLUS_EXPR, (*((const_cast< tree*> (tree_operand_check ((new_rhs), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3342, __FUNCTION__))))), size_binop_loc (((location_t) 0), EXACT_DIV_EXPR , ((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->type_common.size), size_int_kind ( 2, stk_bitsizetype))) | |||
3344 | TYPE_SIZE (TREE_TYPE (lhs)),size_binop_loc (((location_t) 0), PLUS_EXPR, (*((const_cast< tree*> (tree_operand_check ((new_rhs), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3342, __FUNCTION__))))), size_binop_loc (((location_t) 0), EXACT_DIV_EXPR , ((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->type_common.size), size_int_kind ( 2, stk_bitsizetype))) | |||
3345 | bitsize_int (2)))size_binop_loc (((location_t) 0), PLUS_EXPR, (*((const_cast< tree*> (tree_operand_check ((new_rhs), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3342, __FUNCTION__))))), size_binop_loc (((location_t) 0), EXACT_DIV_EXPR , ((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3344, __FUNCTION__))->type_common.size), size_int_kind ( 2, stk_bitsizetype))); | |||
3346 | tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (lhs))((contains_struct_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3346, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3346, __FUNCTION__))->typed.type)); | |||
3347 | gimple *new_stmt = gimple_build_assign (tem, new_rhs); | |||
3348 | location_t loc = gimple_location (use_stmt); | |||
3349 | gimple_set_location (new_stmt, loc); | |||
3350 | gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |||
3351 | /* Perform scalar promotion. */ | |||
3352 | new_stmt = gimple_build_assign (gimple_assign_lhs (use_stmt), | |||
3353 | NOP_EXPR, tem); | |||
3354 | gimple_set_location (new_stmt, loc); | |||
3355 | gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |||
3356 | } | |||
3357 | else | |||
3358 | { | |||
3359 | /* When the BIT_FIELD_REF is on the original load result | |||
3360 | we can just wrap that. */ | |||
3361 | tree new_rhs = fold_build3 (BIT_FIELD_REF, TREE_TYPE (bfr),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((bfr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3361, __FUNCTION__))->typed.type), unshare_expr (load_rhs ), (*((const_cast<tree*> (tree_operand_check ((bfr), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3363, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3364, __FUNCTION__))))) ) | |||
3362 | unshare_expr (load_rhs),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((bfr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3361, __FUNCTION__))->typed.type), unshare_expr (load_rhs ), (*((const_cast<tree*> (tree_operand_check ((bfr), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3363, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3364, __FUNCTION__))))) ) | |||
3363 | TREE_OPERAND (bfr, 1),fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((bfr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3361, __FUNCTION__))->typed.type), unshare_expr (load_rhs ), (*((const_cast<tree*> (tree_operand_check ((bfr), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3363, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3364, __FUNCTION__))))) ) | |||
3364 | TREE_OPERAND (bfr, 2))fold_build3_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((bfr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3361, __FUNCTION__))->typed.type), unshare_expr (load_rhs ), (*((const_cast<tree*> (tree_operand_check ((bfr), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3363, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((bfr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3364, __FUNCTION__))))) ); | |||
3365 | gimple *new_stmt = gimple_build_assign (gimple_assign_lhs (use_stmt), | |||
3366 | new_rhs); | |||
3367 | location_t loc = gimple_location (use_stmt); | |||
3368 | gimple_set_location (new_stmt, loc); | |||
3369 | gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |||
3370 | } | |||
3371 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3372 | unlink_stmt_vdef (use_stmt); | |||
3373 | gsi_remove (&gsi2, true); | |||
3374 | } | |||
3375 | ||||
3376 | /* Finally get rid of the intermediate stmts. */ | |||
3377 | gimple *use_stmt; | |||
3378 | FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse ((((use_stmt) = first_imm_use_stmt (&(iter), (lhs))), & (iter))); !end_imm_use_stmt_p (&(iter)); (void) ((use_stmt ) = next_imm_use_stmt (&(iter)))) | |||
3379 | { | |||
3380 | if (is_gimple_debug (use_stmt)) | |||
3381 | { | |||
3382 | if (gimple_debug_bind_p (use_stmt)) | |||
3383 | { | |||
3384 | gimple_debug_bind_reset_value (use_stmt); | |||
3385 | update_stmt (use_stmt); | |||
3386 | } | |||
3387 | continue; | |||
3388 | } | |||
3389 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3390 | unlink_stmt_vdef (use_stmt); | |||
3391 | release_defs (use_stmt); | |||
3392 | gsi_remove (&gsi2, true); | |||
3393 | } | |||
3394 | /* And the original load. */ | |||
3395 | release_defs (stmt); | |||
3396 | gsi_remove (gsi, true); | |||
3397 | } | |||
3398 | ||||
3399 | ||||
3400 | /* Primitive "lattice" function for gimple_simplify. */ | |||
3401 | ||||
3402 | static tree | |||
3403 | fwprop_ssa_val (tree name) | |||
3404 | { | |||
3405 | /* First valueize NAME. */ | |||
3406 | if (TREE_CODE (name)((enum tree_code) (name)->base.code) == SSA_NAME | |||
3407 | && SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3407, __FUNCTION__, (SSA_NAME)))->base.u.version < lattice.length ()) | |||
3408 | { | |||
3409 | tree val = lattice[SSA_NAME_VERSION (name)(tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3409, __FUNCTION__, (SSA_NAME)))->base.u.version]; | |||
3410 | if (val) | |||
3411 | name = val; | |||
3412 | } | |||
3413 | /* We continue matching along SSA use-def edges for SSA names | |||
3414 | that are not single-use. Currently there are no patterns | |||
3415 | that would cause any issues with that. */ | |||
3416 | return name; | |||
3417 | } | |||
3418 | ||||
3419 | /* Main entry point for the forward propagation and statement combine | |||
3420 | optimizer. */ | |||
3421 | ||||
3422 | namespace { | |||
3423 | ||||
3424 | const pass_data pass_data_forwprop = | |||
3425 | { | |||
3426 | GIMPLE_PASS, /* type */ | |||
3427 | "forwprop", /* name */ | |||
3428 | OPTGROUP_NONE, /* optinfo_flags */ | |||
3429 | TV_TREE_FORWPROP, /* tv_id */ | |||
3430 | ( PROP_cfg(1 << 3) | PROP_ssa(1 << 5) ), /* properties_required */ | |||
3431 | 0, /* properties_provided */ | |||
3432 | 0, /* properties_destroyed */ | |||
3433 | 0, /* todo_flags_start */ | |||
3434 | TODO_update_ssa(1 << 11), /* todo_flags_finish */ | |||
3435 | }; | |||
3436 | ||||
3437 | class pass_forwprop : public gimple_opt_pass | |||
3438 | { | |||
3439 | public: | |||
3440 | pass_forwprop (gcc::context *ctxt) | |||
3441 | : gimple_opt_pass (pass_data_forwprop, ctxt) | |||
3442 | {} | |||
3443 | ||||
3444 | /* opt_pass methods: */ | |||
3445 | opt_pass * clone () final override { return new pass_forwprop (m_ctxt); } | |||
3446 | bool gate (function *) final override { return flag_tree_forwpropglobal_options.x_flag_tree_forwprop; } | |||
3447 | unsigned int execute (function *) final override; | |||
3448 | ||||
3449 | }; // class pass_forwprop | |||
3450 | ||||
3451 | unsigned int | |||
3452 | pass_forwprop::execute (function *fun) | |||
3453 | { | |||
3454 | unsigned int todoflags = 0; | |||
3455 | ||||
3456 | cfg_changed = false; | |||
3457 | ||||
3458 | /* Combine stmts with the stmts defining their operands. Do that | |||
3459 | in an order that guarantees visiting SSA defs before SSA uses. */ | |||
3460 | lattice.create (num_ssa_names(vec_safe_length ((cfun + 0)->gimple_df->ssa_names))); | |||
3461 | lattice.quick_grow_cleared (num_ssa_names(vec_safe_length ((cfun + 0)->gimple_df->ssa_names))); | |||
3462 | int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (fun))((int *) xmalloc (sizeof (int) * (((fun)->cfg->x_n_basic_blocks )))); | |||
3463 | int postorder_num = pre_and_rev_post_order_compute_fn (fun, NULLnullptr, | |||
3464 | postorder, false); | |||
3465 | auto_vec<gimple *, 4> to_fixup; | |||
3466 | auto_vec<gimple *, 32> to_remove; | |||
3467 | to_purge = BITMAP_ALLOCbitmap_alloc (NULLnullptr); | |||
3468 | bitmap need_ab_cleanup = BITMAP_ALLOCbitmap_alloc (NULLnullptr); | |||
3469 | for (int i = 0; i < postorder_num; ++i) | |||
3470 | { | |||
3471 | gimple_stmt_iterator gsi; | |||
3472 | basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i])((*((fun)->cfg->x_basic_block_info))[(postorder[i])]); | |||
3473 | ||||
3474 | /* Record degenerate PHIs in the lattice. */ | |||
3475 | for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); | |||
3476 | gsi_next (&si)) | |||
3477 | { | |||
3478 | gphi *phi = si.phi (); | |||
3479 | tree res = gimple_phi_result (phi); | |||
3480 | if (virtual_operand_p (res)) | |||
3481 | continue; | |||
3482 | ||||
3483 | use_operand_p use_p; | |||
3484 | ssa_op_iter it; | |||
3485 | tree first = NULL_TREE(tree) nullptr; | |||
3486 | bool all_same = true; | |||
3487 | FOR_EACH_PHI_ARG (use_p, phi, it, SSA_OP_USE)for ((use_p) = op_iter_init_phiuse (&(it), phi, 0x01); !op_iter_done (&(it)); (use_p) = op_iter_next_use (&(it))) | |||
3488 | { | |||
3489 | tree use = USE_FROM_PTR (use_p)get_use_from_ptr (use_p); | |||
3490 | if (use == res) | |||
3491 | /* The PHI result can also appear on a backedge, if so | |||
3492 | we can ignore this case for the purpose of determining | |||
3493 | the singular value. */ | |||
3494 | ; | |||
3495 | else if (! first) | |||
3496 | first = use; | |||
3497 | else if (! operand_equal_p (first, use, 0)) | |||
3498 | { | |||
3499 | all_same = false; | |||
3500 | break; | |||
3501 | } | |||
3502 | } | |||
3503 | if (all_same) | |||
3504 | { | |||
3505 | if (may_propagate_copy (res, first)) | |||
3506 | to_remove.safe_push (phi); | |||
3507 | fwprop_set_lattice_val (res, first); | |||
3508 | } | |||
3509 | } | |||
3510 | ||||
3511 | /* Apply forward propagation to all stmts in the basic-block. | |||
3512 | Note we update GSI within the loop as necessary. */ | |||
3513 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) | |||
3514 | { | |||
3515 | gimple *stmt = gsi_stmt (gsi); | |||
3516 | tree lhs, rhs; | |||
3517 | enum tree_code code; | |||
3518 | ||||
3519 | if (!is_gimple_assign (stmt)) | |||
3520 | { | |||
3521 | gsi_next (&gsi); | |||
3522 | continue; | |||
3523 | } | |||
3524 | ||||
3525 | lhs = gimple_assign_lhs (stmt); | |||
3526 | rhs = gimple_assign_rhs1 (stmt); | |||
3527 | code = gimple_assign_rhs_code (stmt); | |||
3528 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) != SSA_NAME | |||
3529 | || has_zero_uses (lhs)) | |||
3530 | { | |||
3531 | gsi_next (&gsi); | |||
3532 | continue; | |||
3533 | } | |||
3534 | ||||
3535 | /* If this statement sets an SSA_NAME to an address, | |||
3536 | try to propagate the address into the uses of the SSA_NAME. */ | |||
3537 | if ((code == ADDR_EXPR | |||
3538 | /* Handle pointer conversions on invariant addresses | |||
3539 | as well, as this is valid gimple. */ | |||
3540 | || (CONVERT_EXPR_CODE_P (code)((code) == NOP_EXPR || (code) == CONVERT_EXPR) | |||
3541 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == ADDR_EXPR | |||
3542 | && POINTER_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3542, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3542, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ))) | |||
3543 | && TREE_CODE (TREE_OPERAND (rhs, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3543, __FUNCTION__))))))->base.code) != TARGET_MEM_REF) | |||
3544 | { | |||
3545 | tree base = get_base_address (TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3545, __FUNCTION__)))))); | |||
3546 | if ((!base | |||
3547 | || !DECL_P (base)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (base)->base.code))] == tcc_declaration) | |||
3548 | || decl_address_invariant_p (base)) | |||
3549 | && !stmt_references_abnormal_ssa_name (stmt) | |||
3550 | && forward_propagate_addr_expr (lhs, rhs, true)) | |||
3551 | { | |||
3552 | fwprop_invalidate_lattice (gimple_get_lhs (stmt)); | |||
3553 | release_defs (stmt); | |||
3554 | gsi_remove (&gsi, true); | |||
3555 | } | |||
3556 | else | |||
3557 | gsi_next (&gsi); | |||
3558 | } | |||
3559 | else if (code == POINTER_PLUS_EXPR) | |||
3560 | { | |||
3561 | tree off = gimple_assign_rhs2 (stmt); | |||
3562 | if (TREE_CODE (off)((enum tree_code) (off)->base.code) == INTEGER_CST | |||
3563 | && can_propagate_from (stmt) | |||
3564 | && !simple_iv_increment_p (stmt) | |||
3565 | /* ??? Better adjust the interface to that function | |||
3566 | instead of building new trees here. */ | |||
3567 | && forward_propagate_addr_expr | |||
3568 | (lhs, | |||
3569 | build1_loc (gimple_location (stmt), | |||
3570 | ADDR_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3570, __FUNCTION__))->typed.type), | |||
3571 | fold_build2 (MEM_REF,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type), rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], off) ) | |||
3572 | TREE_TYPE (TREE_TYPE (rhs)),fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type), rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], off) ) | |||
3573 | rhs,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type), rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], off) ) | |||
3574 | fold_convert (ptr_type_node,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type), rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], off) ) | |||
3575 | off))fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3572, __FUNCTION__))->typed.type), rhs, fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE], off) )), true)) | |||
3576 | { | |||
3577 | fwprop_invalidate_lattice (gimple_get_lhs (stmt)); | |||
3578 | release_defs (stmt); | |||
3579 | gsi_remove (&gsi, true); | |||
3580 | } | |||
3581 | else if (is_gimple_min_invariant (rhs)) | |||
3582 | { | |||
3583 | /* Make sure to fold &a[0] + off_1 here. */ | |||
3584 | fold_stmt_inplace (&gsi); | |||
3585 | update_stmt (stmt); | |||
3586 | if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR) | |||
3587 | gsi_next (&gsi); | |||
3588 | } | |||
3589 | else | |||
3590 | gsi_next (&gsi); | |||
3591 | } | |||
3592 | else if (TREE_CODE (TREE_TYPE (lhs))((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3592, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE | |||
3593 | && gimple_assign_load_p (stmt) | |||
3594 | && !gimple_has_volatile_ops (stmt) | |||
3595 | && (TREE_CODE (gimple_assign_rhs1 (stmt))((enum tree_code) (gimple_assign_rhs1 (stmt))->base.code) | |||
3596 | != TARGET_MEM_REF) | |||
3597 | && !stmt_can_throw_internal (fun, stmt)) | |||
3598 | { | |||
3599 | /* Rewrite loads used only in real/imagpart extractions to | |||
3600 | component-wise loads. */ | |||
3601 | use_operand_p use_p; | |||
3602 | imm_use_iterator iter; | |||
3603 | bool rewrite = true; | |||
3604 | FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)for ((use_p) = first_readonly_imm_use (&(iter), (lhs)); ! end_readonly_imm_use_p (&(iter)); (void) ((use_p) = next_readonly_imm_use (&(iter)))) | |||
3605 | { | |||
3606 | gimple *use_stmt = USE_STMT (use_p)(use_p)->loc.stmt; | |||
3607 | if (is_gimple_debug (use_stmt)) | |||
3608 | continue; | |||
3609 | if (!is_gimple_assign (use_stmt) | |||
3610 | || (gimple_assign_rhs_code (use_stmt) != REALPART_EXPR | |||
3611 | && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR) | |||
3612 | || TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0)(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (use_stmt)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3612, __FUNCTION__))))) != lhs) | |||
3613 | { | |||
3614 | rewrite = false; | |||
3615 | break; | |||
3616 | } | |||
3617 | } | |||
3618 | if (rewrite) | |||
3619 | { | |||
3620 | gimple *use_stmt; | |||
3621 | FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse ((((use_stmt) = first_imm_use_stmt (&(iter), (lhs))), & (iter))); !end_imm_use_stmt_p (&(iter)); (void) ((use_stmt ) = next_imm_use_stmt (&(iter)))) | |||
3622 | { | |||
3623 | if (is_gimple_debug (use_stmt)) | |||
3624 | { | |||
3625 | if (gimple_debug_bind_p (use_stmt)) | |||
3626 | { | |||
3627 | gimple_debug_bind_reset_value (use_stmt); | |||
3628 | update_stmt (use_stmt); | |||
3629 | } | |||
3630 | continue; | |||
3631 | } | |||
3632 | ||||
3633 | tree new_rhs = build1 (gimple_assign_rhs_code (use_stmt), | |||
3634 | TREE_TYPE (TREE_TYPE (rhs))((contains_struct_check ((((contains_struct_check ((rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3634, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3634, __FUNCTION__))->typed.type), | |||
3635 | unshare_expr (rhs)); | |||
3636 | gimple *new_stmt | |||
3637 | = gimple_build_assign (gimple_assign_lhs (use_stmt), | |||
3638 | new_rhs); | |||
3639 | ||||
3640 | location_t loc = gimple_location (use_stmt); | |||
3641 | gimple_set_location (new_stmt, loc); | |||
3642 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3643 | unlink_stmt_vdef (use_stmt); | |||
3644 | gsi_remove (&gsi2, true); | |||
3645 | ||||
3646 | gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); | |||
3647 | } | |||
3648 | ||||
3649 | release_defs (stmt); | |||
3650 | gsi_remove (&gsi, true); | |||
3651 | } | |||
3652 | else | |||
3653 | gsi_next (&gsi); | |||
3654 | } | |||
3655 | else if (TREE_CODE (TREE_TYPE (lhs))((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3655, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE | |||
3656 | && (TYPE_MODE (TREE_TYPE (lhs))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3656, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3656, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3656, __FUNCTION__))->typed.type)) : (((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3656, __FUNCTION__))->typed.type))->type_common.mode) == BLKmode((void) 0, E_BLKmode) | |||
3657 | /* After vector lowering rewrite all loads, but | |||
3658 | initially do not since this conflicts with | |||
3659 | vector CONSTRUCTOR to shuffle optimization. */ | |||
3660 | || (fun->curr_properties & PROP_gimple_lvec(1 << 12))) | |||
3661 | && gimple_assign_load_p (stmt) | |||
3662 | && !gimple_has_volatile_ops (stmt) | |||
3663 | && !stmt_can_throw_internal (fun, stmt) | |||
3664 | && (!VAR_P (rhs)(((enum tree_code) (rhs)->base.code) == VAR_DECL) || !DECL_HARD_REGISTER (rhs)((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3664, __FUNCTION__, (VAR_DECL)))->decl_with_vis.hard_register ))) | |||
3665 | optimize_vector_load (&gsi); | |||
3666 | ||||
3667 | else if (code == COMPLEX_EXPR) | |||
3668 | { | |||
3669 | /* Rewrite stores of a single-use complex build expression | |||
3670 | to component-wise stores. */ | |||
3671 | use_operand_p use_p; | |||
3672 | gimple *use_stmt, *def1, *def2; | |||
3673 | tree rhs2; | |||
3674 | if (single_imm_use (lhs, &use_p, &use_stmt) | |||
3675 | && gimple_store_p (use_stmt) | |||
3676 | && !gimple_has_volatile_ops (use_stmt) | |||
3677 | && is_gimple_assign (use_stmt) | |||
3678 | && (TREE_CODE (gimple_assign_lhs (use_stmt))((enum tree_code) (gimple_assign_lhs (use_stmt))->base.code ) | |||
3679 | != TARGET_MEM_REF)) | |||
3680 | { | |||
3681 | tree use_lhs = gimple_assign_lhs (use_stmt); | |||
3682 | if (auto_var_p (use_lhs)) | |||
3683 | DECL_NOT_GIMPLE_REG_P (use_lhs)(contains_struct_check ((use_lhs), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3683, __FUNCTION__))->decl_common.not_gimple_reg_flag = 1; | |||
3684 | tree new_lhs = build1 (REALPART_EXPR, | |||
3685 | TREE_TYPE (TREE_TYPE (use_lhs))((contains_struct_check ((((contains_struct_check ((use_lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3685, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3685, __FUNCTION__))->typed.type), | |||
3686 | unshare_expr (use_lhs)); | |||
3687 | gimple *new_stmt = gimple_build_assign (new_lhs, rhs); | |||
3688 | location_t loc = gimple_location (use_stmt); | |||
3689 | gimple_set_location (new_stmt, loc); | |||
3690 | gimple_set_vuse (new_stmt, gimple_vuse (use_stmt)); | |||
3691 | gimple_set_vdef (new_stmt, make_ssa_name (gimple_vop (fun))); | |||
3692 | SSA_NAME_DEF_STMT (gimple_vdef (new_stmt))(tree_check ((gimple_vdef (new_stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3692, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt = new_stmt; | |||
3693 | gimple_set_vuse (use_stmt, gimple_vdef (new_stmt)); | |||
3694 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3695 | gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT); | |||
3696 | ||||
3697 | new_lhs = build1 (IMAGPART_EXPR, | |||
3698 | TREE_TYPE (TREE_TYPE (use_lhs))((contains_struct_check ((((contains_struct_check ((use_lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3698, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3698, __FUNCTION__))->typed.type), | |||
3699 | unshare_expr (use_lhs)); | |||
3700 | gimple_assign_set_lhs (use_stmt, new_lhs); | |||
3701 | gimple_assign_set_rhs1 (use_stmt, gimple_assign_rhs2 (stmt)); | |||
3702 | update_stmt (use_stmt); | |||
3703 | ||||
3704 | release_defs (stmt); | |||
3705 | gsi_remove (&gsi, true); | |||
3706 | } | |||
3707 | /* Rewrite a component-wise load of a complex to a complex | |||
3708 | load if the components are not used separately. */ | |||
3709 | else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == SSA_NAME | |||
3710 | && has_single_use (rhs) | |||
3711 | && ((rhs2 = gimple_assign_rhs2 (stmt)), true) | |||
3712 | && TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) == SSA_NAME | |||
3713 | && has_single_use (rhs2) | |||
3714 | && (def1 = SSA_NAME_DEF_STMT (rhs)(tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3714, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt, | |||
3715 | gimple_assign_load_p (def1)) | |||
3716 | && (def2 = SSA_NAME_DEF_STMT (rhs2)(tree_check ((rhs2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3716, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt, | |||
3717 | gimple_assign_load_p (def2)) | |||
3718 | && (gimple_vuse (def1) == gimple_vuse (def2)) | |||
3719 | && !gimple_has_volatile_ops (def1) | |||
3720 | && !gimple_has_volatile_ops (def2) | |||
3721 | && !stmt_can_throw_internal (fun, def1) | |||
3722 | && !stmt_can_throw_internal (fun, def2) | |||
3723 | && gimple_assign_rhs_code (def1) == REALPART_EXPR | |||
3724 | && gimple_assign_rhs_code (def2) == IMAGPART_EXPR | |||
3725 | && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (def1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3726, __FUNCTION__))))) | |||
3726 | (def1), 0)(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (def1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3726, __FUNCTION__))))), | |||
3727 | TREE_OPERAND (gimple_assign_rhs1(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (def2)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3728, __FUNCTION__))))) | |||
3728 | (def2), 0)(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (def2)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3728, __FUNCTION__))))))) | |||
3729 | { | |||
3730 | tree cl = TREE_OPERAND (gimple_assign_rhs1 (def1), 0)(*((const_cast<tree*> (tree_operand_check ((gimple_assign_rhs1 (def1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3730, __FUNCTION__))))); | |||
3731 | gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (cl)); | |||
3732 | gcc_assert (gsi_stmt (gsi) == stmt)((void)(!(gsi_stmt (gsi) == stmt) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3732, __FUNCTION__), 0 : 0)); | |||
3733 | gimple_set_vuse (stmt, gimple_vuse (def1)); | |||
3734 | gimple_set_modified (stmt, true); | |||
3735 | gimple_stmt_iterator gsi2 = gsi_for_stmt (def1); | |||
3736 | gsi_remove (&gsi, false); | |||
3737 | gsi_insert_after (&gsi2, stmt, GSI_SAME_STMT); | |||
3738 | } | |||
3739 | else | |||
3740 | gsi_next (&gsi); | |||
3741 | } | |||
3742 | else if (code == CONSTRUCTOR | |||
3743 | && VECTOR_TYPE_P (TREE_TYPE (rhs))(((enum tree_code) (((contains_struct_check ((rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3743, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE ) | |||
3744 | && TYPE_MODE (TREE_TYPE (rhs))((((enum tree_code) ((tree_class_check ((((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3744, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3744, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3744, __FUNCTION__))->typed.type)) : (((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3744, __FUNCTION__))->typed.type))->type_common.mode) == BLKmode((void) 0, E_BLKmode) | |||
3745 | && CONSTRUCTOR_NELTS (rhs)(vec_safe_length (((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3745, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) > 0 | |||
3746 | && (!VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))(((enum tree_code) (((contains_struct_check (((&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3746, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3746, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE ) | |||
3747 | || (TYPE_MODE (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))((((enum tree_code) ((tree_class_check ((((contains_struct_check (((&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (((contains_struct_check (((&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__))->typed.type)) : (((contains_struct_check (((&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3747, __FUNCTION__))->typed.type))->type_common.mode) | |||
3748 | != BLKmode((void) 0, E_BLKmode)))) | |||
3749 | { | |||
3750 | /* Rewrite stores of a single-use vector constructors | |||
3751 | to component-wise stores if the mode isn't supported. */ | |||
3752 | use_operand_p use_p; | |||
3753 | gimple *use_stmt; | |||
3754 | if (single_imm_use (lhs, &use_p, &use_stmt) | |||
3755 | && gimple_store_p (use_stmt) | |||
3756 | && !gimple_has_volatile_ops (use_stmt) | |||
3757 | && !stmt_can_throw_internal (fun, use_stmt) | |||
3758 | && is_gimple_assign (use_stmt) | |||
3759 | && (TREE_CODE (gimple_assign_lhs (use_stmt))((enum tree_code) (gimple_assign_lhs (use_stmt))->base.code ) | |||
3760 | != TARGET_MEM_REF)) | |||
3761 | { | |||
3762 | tree elt_t = TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value)((contains_struct_check (((&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3762, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3762, __FUNCTION__))->typed.type); | |||
3763 | unsigned HOST_WIDE_INTlong elt_w | |||
3764 | = tree_to_uhwi (TYPE_SIZE (elt_t)((tree_class_check ((elt_t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3764, __FUNCTION__))->type_common.size)); | |||
3765 | unsigned HOST_WIDE_INTlong n | |||
3766 | = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (rhs))((tree_class_check ((((contains_struct_check ((rhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3766, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3766, __FUNCTION__))->type_common.size)); | |||
3767 | tree use_lhs = gimple_assign_lhs (use_stmt); | |||
3768 | if (auto_var_p (use_lhs)) | |||
3769 | DECL_NOT_GIMPLE_REG_P (use_lhs)(contains_struct_check ((use_lhs), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3769, __FUNCTION__))->decl_common.not_gimple_reg_flag = 1; | |||
3770 | for (unsigned HOST_WIDE_INTlong bi = 0; bi < n; bi += elt_w) | |||
3771 | { | |||
3772 | unsigned HOST_WIDE_INTlong ci = bi / elt_w; | |||
3773 | tree new_rhs; | |||
3774 | if (ci < CONSTRUCTOR_NELTS (rhs)(vec_safe_length (((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3774, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))) | |||
3775 | new_rhs = CONSTRUCTOR_ELT (rhs, ci)(&(*((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3775, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ ci])->value; | |||
3776 | else | |||
3777 | new_rhs = build_zero_cst (elt_t); | |||
3778 | tree new_lhs = build3 (BIT_FIELD_REF, | |||
3779 | elt_t, | |||
3780 | unshare_expr (use_lhs), | |||
3781 | bitsize_int (elt_w)size_int_kind (elt_w, stk_bitsizetype), | |||
3782 | bitsize_int (bi)size_int_kind (bi, stk_bitsizetype)); | |||
3783 | gimple *new_stmt = gimple_build_assign (new_lhs, new_rhs); | |||
3784 | location_t loc = gimple_location (use_stmt); | |||
3785 | gimple_set_location (new_stmt, loc); | |||
3786 | gimple_set_vuse (new_stmt, gimple_vuse (use_stmt)); | |||
3787 | gimple_set_vdef (new_stmt, | |||
3788 | make_ssa_name (gimple_vop (fun))); | |||
3789 | SSA_NAME_DEF_STMT (gimple_vdef (new_stmt))(tree_check ((gimple_vdef (new_stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3789, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt = new_stmt; | |||
3790 | gimple_set_vuse (use_stmt, gimple_vdef (new_stmt)); | |||
3791 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3792 | gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT); | |||
3793 | } | |||
3794 | gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); | |||
3795 | unlink_stmt_vdef (use_stmt); | |||
3796 | release_defs (use_stmt); | |||
3797 | gsi_remove (&gsi2, true); | |||
3798 | release_defs (stmt); | |||
3799 | gsi_remove (&gsi, true); | |||
3800 | } | |||
3801 | else | |||
3802 | gsi_next (&gsi); | |||
3803 | } | |||
3804 | else | |||
3805 | gsi_next (&gsi); | |||
3806 | } | |||
3807 | ||||
3808 | /* Combine stmts with the stmts defining their operands. | |||
3809 | Note we update GSI within the loop as necessary. */ | |||
3810 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |||
3811 | { | |||
3812 | gimple *stmt = gsi_stmt (gsi); | |||
3813 | ||||
3814 | /* Mark stmt as potentially needing revisiting. */ | |||
3815 | gimple_set_plf (stmt, GF_PLF_1, false); | |||
3816 | ||||
3817 | bool can_make_abnormal_goto = (is_gimple_call (stmt) | |||
3818 | && stmt_can_make_abnormal_goto (stmt)); | |||
3819 | ||||
3820 | /* Substitute from our lattice. We need to do so only once. */ | |||
3821 | bool substituted_p = false; | |||
3822 | use_operand_p usep; | |||
3823 | ssa_op_iter iter; | |||
3824 | FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_USE)for (usep = op_iter_init_use (&(iter), stmt, 0x01); !op_iter_done (&(iter)); usep = op_iter_next_use (&(iter))) | |||
3825 | { | |||
3826 | tree use = USE_FROM_PTR (usep)get_use_from_ptr (usep); | |||
3827 | tree val = fwprop_ssa_val (use); | |||
3828 | if (val && val != use && may_propagate_copy (use, val)) | |||
3829 | { | |||
3830 | propagate_value (usep, val); | |||
3831 | substituted_p = true; | |||
3832 | } | |||
3833 | } | |||
3834 | if (substituted_p | |||
3835 | && is_gimple_assign (stmt) | |||
3836 | && gimple_assign_rhs_code (stmt) == ADDR_EXPR) | |||
3837 | recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt)); | |||
3838 | if (substituted_p | |||
3839 | && can_make_abnormal_goto | |||
3840 | && !stmt_can_make_abnormal_goto (stmt)) | |||
3841 | bitmap_set_bit (need_ab_cleanup, bb->index); | |||
3842 | ||||
3843 | bool changed; | |||
3844 | do | |||
3845 | { | |||
3846 | gimple *orig_stmt = stmt = gsi_stmt (gsi); | |||
3847 | bool was_noreturn = (is_gimple_call (stmt) | |||
3848 | && gimple_call_noreturn_p (stmt)); | |||
3849 | changed = false; | |||
3850 | ||||
3851 | if (fold_stmt (&gsi, fwprop_ssa_val)) | |||
3852 | { | |||
3853 | changed = true; | |||
3854 | stmt = gsi_stmt (gsi); | |||
3855 | /* Cleanup the CFG if we simplified a condition to | |||
3856 | true or false. */ | |||
3857 | if (gcond *cond = dyn_cast <gcond *> (stmt)) | |||
3858 | if (gimple_cond_true_p (cond) | |||
3859 | || gimple_cond_false_p (cond)) | |||
3860 | cfg_changed = true; | |||
3861 | } | |||
3862 | ||||
3863 | if (changed || substituted_p) | |||
3864 | { | |||
3865 | if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt)) | |||
3866 | bitmap_set_bit (to_purge, bb->index); | |||
3867 | if (!was_noreturn | |||
3868 | && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)) | |||
3869 | to_fixup.safe_push (stmt); | |||
3870 | update_stmt (stmt); | |||
3871 | substituted_p = false; | |||
3872 | } | |||
3873 | ||||
3874 | switch (gimple_code (stmt)) | |||
3875 | { | |||
3876 | case GIMPLE_ASSIGN: | |||
3877 | { | |||
3878 | tree rhs1 = gimple_assign_rhs1 (stmt); | |||
3879 | enum tree_code code = gimple_assign_rhs_code (stmt); | |||
3880 | ||||
3881 | if (TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_comparison) | |||
3882 | { | |||
3883 | int did_something; | |||
3884 | did_something = forward_propagate_into_comparison (&gsi); | |||
3885 | if (maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (gsi))) | |||
3886 | bitmap_set_bit (to_purge, bb->index); | |||
3887 | if (did_something == 2) | |||
3888 | cfg_changed = true; | |||
3889 | changed = did_something != 0; | |||
3890 | } | |||
3891 | else if ((code == PLUS_EXPR | |||
3892 | || code == BIT_IOR_EXPR | |||
3893 | || code == BIT_XOR_EXPR) | |||
3894 | && simplify_rotate (&gsi)) | |||
3895 | changed = true; | |||
3896 | else if (code == VEC_PERM_EXPR) | |||
3897 | { | |||
3898 | int did_something = simplify_permutation (&gsi); | |||
3899 | if (did_something == 2) | |||
3900 | cfg_changed = true; | |||
3901 | changed = did_something != 0; | |||
3902 | } | |||
3903 | else if (code == BIT_FIELD_REF) | |||
3904 | changed = simplify_bitfield_ref (&gsi); | |||
3905 | else if (code == CONSTRUCTOR | |||
3906 | && TREE_CODE (TREE_TYPE (rhs1))((enum tree_code) (((contains_struct_check ((rhs1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3906, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE) | |||
3907 | changed = simplify_vector_constructor (&gsi); | |||
3908 | else if (code == ARRAY_REF) | |||
3909 | changed = simplify_count_trailing_zeroes (&gsi); | |||
3910 | break; | |||
3911 | } | |||
3912 | ||||
3913 | case GIMPLE_SWITCH: | |||
3914 | changed = simplify_gimple_switch (as_a <gswitch *> (stmt)); | |||
3915 | break; | |||
3916 | ||||
3917 | case GIMPLE_COND: | |||
3918 | { | |||
3919 | int did_something = forward_propagate_into_gimple_cond | |||
3920 | (as_a <gcond *> (stmt)); | |||
3921 | if (did_something == 2) | |||
3922 | cfg_changed = true; | |||
3923 | changed = did_something != 0; | |||
3924 | break; | |||
3925 | } | |||
3926 | ||||
3927 | case GIMPLE_CALL: | |||
3928 | { | |||
3929 | tree callee = gimple_call_fndecl (stmt); | |||
3930 | if (callee != NULL_TREE(tree) nullptr | |||
3931 | && fndecl_built_in_p (callee, BUILT_IN_NORMAL)) | |||
3932 | changed = simplify_builtin_call (&gsi, callee); | |||
3933 | break; | |||
3934 | } | |||
3935 | ||||
3936 | default:; | |||
3937 | } | |||
3938 | ||||
3939 | if (changed) | |||
3940 | { | |||
3941 | /* If the stmt changed then re-visit it and the statements | |||
3942 | inserted before it. */ | |||
3943 | for (; !gsi_end_p (gsi); gsi_prev (&gsi)) | |||
3944 | if (gimple_plf (gsi_stmt (gsi), GF_PLF_1)) | |||
3945 | break; | |||
3946 | if (gsi_end_p (gsi)) | |||
3947 | gsi = gsi_start_bb (bb); | |||
3948 | else | |||
3949 | gsi_next (&gsi); | |||
3950 | } | |||
3951 | } | |||
3952 | while (changed); | |||
3953 | ||||
3954 | /* Stmt no longer needs to be revisited. */ | |||
3955 | stmt = gsi_stmt (gsi); | |||
3956 | gcc_checking_assert (!gimple_plf (stmt, GF_PLF_1))((void)(!(!gimple_plf (stmt, GF_PLF_1)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-ssa-forwprop.cc" , 3956, __FUNCTION__), 0 : 0)); | |||
3957 | gimple_set_plf (stmt, GF_PLF_1, true); | |||
3958 | ||||
3959 | /* Fill up the lattice. */ | |||
3960 | if (gimple_assign_single_p (stmt)) | |||
3961 | { | |||
3962 | tree lhs = gimple_assign_lhs (stmt); | |||
3963 | tree rhs = gimple_assign_rhs1 (stmt); | |||
3964 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME) | |||
3965 | { | |||
3966 | tree val = lhs; | |||
3967 | if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == SSA_NAME) | |||
3968 | val = fwprop_ssa_val (rhs); | |||
3969 | else if (is_gimple_min_invariant (rhs)) | |||
3970 | val = rhs; | |||
3971 | /* If we can propagate the lattice-value mark the | |||
3972 | stmt for removal. */ | |||
3973 | if (val != lhs | |||
3974 | && may_propagate_copy (lhs, val)) | |||
3975 | to_remove.safe_push (stmt); | |||
3976 | fwprop_set_lattice_val (lhs, val); | |||
3977 | } | |||
3978 | } | |||
3979 | else if (gimple_nop_p (stmt)) | |||
3980 | to_remove.safe_push (stmt); | |||
3981 | } | |||
3982 | ||||
3983 | /* Substitute in destination PHI arguments. */ | |||
3984 | edge_iterator ei; | |||
3985 | edge e; | |||
3986 | FOR_EACH_EDGE (e, ei, bb->succs)for ((ei) = ei_start_1 (&((bb->succs))); ei_cond ((ei) , &(e)); ei_next (&(ei))) | |||
3987 | for (gphi_iterator gsi = gsi_start_phis (e->dest); | |||
3988 | !gsi_end_p (gsi); gsi_next (&gsi)) | |||
3989 | { | |||
3990 | gphi *phi = gsi.phi (); | |||
3991 | use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e)gimple_phi_arg_imm_use_ptr (((phi)), ((e)->dest_idx)); | |||
3992 | tree arg = USE_FROM_PTR (use_p)get_use_from_ptr (use_p); | |||
3993 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) != SSA_NAME | |||
3994 | || virtual_operand_p (arg)) | |||
3995 | continue; | |||
3996 | tree val = fwprop_ssa_val (arg); | |||
3997 | if (val != arg | |||
3998 | && may_propagate_copy (arg, val)) | |||
3999 | propagate_value (use_p, val); | |||
4000 | } | |||
4001 | } | |||
4002 | free (postorder); | |||
4003 | lattice.release (); | |||
4004 | ||||
4005 | /* Remove stmts in reverse order to make debug stmt creation possible. */ | |||
4006 | while (!to_remove.is_empty()) | |||
4007 | { | |||
4008 | gimple *stmt = to_remove.pop (); | |||
4009 | if (dump_file && (dump_flags & TDF_DETAILS)) | |||
4010 | { | |||
4011 | fprintf (dump_file, "Removing dead stmt "); | |||
4012 | print_gimple_stmt (dump_file, stmt, 0); | |||
4013 | fprintf (dump_file, "\n"); | |||
4014 | } | |||
4015 | gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | |||
4016 | if (gimple_code (stmt) == GIMPLE_PHI) | |||
4017 | remove_phi_node (&gsi, true); | |||
4018 | else | |||
4019 | { | |||
4020 | unlink_stmt_vdef (stmt); | |||
4021 | gsi_remove (&gsi, true); | |||
4022 | release_defs (stmt); | |||
4023 | } | |||
4024 | } | |||
4025 | ||||
4026 | /* Fixup stmts that became noreturn calls. This may require splitting | |||
4027 | blocks and thus isn't possible during the walk. Do this | |||
4028 | in reverse order so we don't inadvertedly remove a stmt we want to | |||
4029 | fixup by visiting a dominating now noreturn call first. */ | |||
4030 | while (!to_fixup.is_empty ()) | |||
4031 | { | |||
4032 | gimple *stmt = to_fixup.pop (); | |||
4033 | if (dump_file && dump_flags & TDF_DETAILS) | |||
4034 | { | |||
4035 | fprintf (dump_file, "Fixing up noreturn call "); | |||
4036 | print_gimple_stmt (dump_file, stmt, 0); | |||
4037 | fprintf (dump_file, "\n"); | |||
4038 | } | |||
4039 | cfg_changed |= fixup_noreturn_call (stmt); | |||
4040 | } | |||
4041 | ||||
4042 | cfg_changed |= gimple_purge_all_dead_eh_edges (to_purge); | |||
4043 | cfg_changed |= gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup); | |||
4044 | BITMAP_FREE (to_purge)((void) (bitmap_obstack_free ((bitmap) to_purge), (to_purge) = (bitmap) nullptr)); | |||
4045 | BITMAP_FREE (need_ab_cleanup)((void) (bitmap_obstack_free ((bitmap) need_ab_cleanup), (need_ab_cleanup ) = (bitmap) nullptr)); | |||
4046 | ||||
4047 | if (get_range_query (fun) != get_global_range_query ()) | |||
4048 | disable_ranger (fun); | |||
4049 | ||||
4050 | if (cfg_changed) | |||
4051 | todoflags |= TODO_cleanup_cfg(1 << 5); | |||
4052 | ||||
4053 | return todoflags; | |||
4054 | } | |||
4055 | ||||
4056 | } // anon namespace | |||
4057 | ||||
4058 | gimple_opt_pass * | |||
4059 | make_pass_forwprop (gcc::context *ctxt) | |||
4060 | { | |||
4061 | return new pass_forwprop (ctxt); | |||
4062 | } |