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