Line data Source code
1 : /* SCC value numbering for trees
2 : Copyright (C) 2006-2026 Free Software Foundation, Inc.
3 : Contributed by Daniel Berlin <dan@dberlin.org>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "rtl.h"
26 : #include "tree.h"
27 : #include "gimple.h"
28 : #include "ssa.h"
29 : #include "expmed.h"
30 : #include "insn-config.h"
31 : #include "memmodel.h"
32 : #include "emit-rtl.h"
33 : #include "cgraph.h"
34 : #include "gimple-pretty-print.h"
35 : #include "splay-tree-utils.h"
36 : #include "alias.h"
37 : #include "fold-const.h"
38 : #include "stor-layout.h"
39 : #include "cfganal.h"
40 : #include "tree-inline.h"
41 : #include "internal-fn.h"
42 : #include "gimple-iterator.h"
43 : #include "gimple-fold.h"
44 : #include "tree-eh.h"
45 : #include "flags.h"
46 : #include "dojump.h"
47 : #include "explow.h"
48 : #include "calls.h"
49 : #include "varasm.h"
50 : #include "stmt.h"
51 : #include "expr.h"
52 : #include "tree-dfa.h"
53 : #include "tree-ssa.h"
54 : #include "dumpfile.h"
55 : #include "cfgloop.h"
56 : #include "tree-ssa-propagate.h"
57 : #include "tree-cfg.h"
58 : #include "domwalk.h"
59 : #include "gimple-match.h"
60 : #include "stringpool.h"
61 : #include "attribs.h"
62 : #include "tree-pass.h"
63 : #include "statistics.h"
64 : #include "langhooks.h"
65 : #include "ipa-utils.h"
66 : #include "dbgcnt.h"
67 : #include "tree-cfgcleanup.h"
68 : #include "tree-ssa-loop.h"
69 : #include "tree-scalar-evolution.h"
70 : #include "tree-ssa-loop-niter.h"
71 : #include "builtins.h"
72 : #include "fold-const-call.h"
73 : #include "ipa-modref-tree.h"
74 : #include "ipa-modref.h"
75 : #include "tree-ssa-sccvn.h"
76 : #include "alloc-pool.h"
77 : #include "symbol-summary.h"
78 : #include "sreal.h"
79 : #include "ipa-cp.h"
80 : #include "ipa-prop.h"
81 : #include "target.h"
82 :
83 : /* This algorithm is based on the SCC algorithm presented by Keith
84 : Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
85 : (http://citeseer.ist.psu.edu/41805.html). In
86 : straight line code, it is equivalent to a regular hash based value
87 : numbering that is performed in reverse postorder.
88 :
89 : For code with cycles, there are two alternatives, both of which
90 : require keeping the hashtables separate from the actual list of
91 : value numbers for SSA names.
92 :
93 : 1. Iterate value numbering in an RPO walk of the blocks, removing
94 : all the entries from the hashtable after each iteration (but
95 : keeping the SSA name->value number mapping between iterations).
96 : Iterate until it does not change.
97 :
98 : 2. Perform value numbering as part of an SCC walk on the SSA graph,
99 : iterating only the cycles in the SSA graph until they do not change
100 : (using a separate, optimistic hashtable for value numbering the SCC
101 : operands).
102 :
103 : The second is not just faster in practice (because most SSA graph
104 : cycles do not involve all the variables in the graph), it also has
105 : some nice properties.
106 :
107 : One of these nice properties is that when we pop an SCC off the
108 : stack, we are guaranteed to have processed all the operands coming from
109 : *outside of that SCC*, so we do not need to do anything special to
110 : ensure they have value numbers.
111 :
112 : Another nice property is that the SCC walk is done as part of a DFS
113 : of the SSA graph, which makes it easy to perform combining and
114 : simplifying operations at the same time.
115 :
116 : The code below is deliberately written in a way that makes it easy
117 : to separate the SCC walk from the other work it does.
118 :
119 : In order to propagate constants through the code, we track which
120 : expressions contain constants, and use those while folding. In
121 : theory, we could also track expressions whose value numbers are
122 : replaced, in case we end up folding based on expression
123 : identities.
124 :
125 : In order to value number memory, we assign value numbers to vuses.
126 : This enables us to note that, for example, stores to the same
127 : address of the same value from the same starting memory states are
128 : equivalent.
129 : TODO:
130 :
131 : 1. We can iterate only the changing portions of the SCC's, but
132 : I have not seen an SCC big enough for this to be a win.
133 : 2. If you differentiate between phi nodes for loops and phi nodes
134 : for if-then-else, you can properly consider phi nodes in different
135 : blocks for equivalence.
136 : 3. We could value number vuses in more cases, particularly, whole
137 : structure copies.
138 : */
139 :
140 : /* There's no BB_EXECUTABLE but we can use BB_VISITED. */
141 : #define BB_EXECUTABLE BB_VISITED
142 :
143 : static vn_lookup_kind default_vn_walk_kind;
144 :
145 : /* vn_nary_op hashtable helpers. */
146 :
147 : struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s>
148 : {
149 : typedef vn_nary_op_s *compare_type;
150 : static inline hashval_t hash (const vn_nary_op_s *);
151 : static inline bool equal (const vn_nary_op_s *, const vn_nary_op_s *);
152 : };
153 :
154 : /* Return the computed hashcode for nary operation P1. */
155 :
156 : inline hashval_t
157 779889705 : vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
158 : {
159 779889705 : return vno1->hashcode;
160 : }
161 :
162 : /* Compare nary operations P1 and P2 and return true if they are
163 : equivalent. */
164 :
165 : inline bool
166 989477813 : vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
167 : {
168 989477813 : return vno1 == vno2 || vn_nary_op_eq (vno1, vno2);
169 : }
170 :
171 : typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type;
172 : typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;
173 :
174 :
175 : /* vn_phi hashtable helpers. */
176 :
177 : static int
178 : vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
179 :
180 : struct vn_phi_hasher : nofree_ptr_hash <vn_phi_s>
181 : {
182 : static inline hashval_t hash (const vn_phi_s *);
183 : static inline bool equal (const vn_phi_s *, const vn_phi_s *);
184 : };
185 :
186 : /* Return the computed hashcode for phi operation P1. */
187 :
188 : inline hashval_t
189 25753860 : vn_phi_hasher::hash (const vn_phi_s *vp1)
190 : {
191 25753860 : return vp1->hashcode;
192 : }
193 :
194 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
195 :
196 : inline bool
197 46421140 : vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
198 : {
199 46421140 : return vp1 == vp2 || vn_phi_eq (vp1, vp2);
200 : }
201 :
202 : typedef hash_table<vn_phi_hasher> vn_phi_table_type;
203 : typedef vn_phi_table_type::iterator vn_phi_iterator_type;
204 :
205 :
206 : /* Compare two reference operands P1 and P2 for equality. Return true if
207 : they are equal, and false otherwise. */
208 :
209 : static int
210 26486894 : vn_reference_op_eq (const void *p1, const void *p2)
211 : {
212 26486894 : const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
213 26486894 : const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
214 :
215 26486894 : return (vro1->opcode == vro2->opcode
216 : /* We do not care for differences in type qualification. */
217 26485092 : && (vro1->type == vro2->type
218 1244311 : || (vro1->type && vro2->type
219 1244311 : && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
220 1244311 : TYPE_MAIN_VARIANT (vro2->type))))
221 25480674 : && expressions_equal_p (vro1->op0, vro2->op0)
222 25433019 : && expressions_equal_p (vro1->op1, vro2->op1)
223 25433019 : && expressions_equal_p (vro1->op2, vro2->op2)
224 51919913 : && (vro1->opcode != CALL_EXPR || vro1->clique == vro2->clique));
225 : }
226 :
227 : /* Free a reference operation structure VP. */
228 :
229 : static inline void
230 0 : free_reference (vn_reference_s *vr)
231 : {
232 0 : vr->operands.release ();
233 : }
234 :
235 :
236 : /* vn_reference hashtable helpers. */
237 :
238 : struct vn_reference_hasher : nofree_ptr_hash <vn_reference_s>
239 : {
240 : static inline hashval_t hash (const vn_reference_s *);
241 : static inline bool equal (const vn_reference_s *, const vn_reference_s *);
242 : };
243 :
244 : /* Return the hashcode for a given reference operation P1. */
245 :
246 : inline hashval_t
247 3788164630 : vn_reference_hasher::hash (const vn_reference_s *vr1)
248 : {
249 3788164630 : return vr1->hashcode;
250 : }
251 :
252 : inline bool
253 4509959111 : vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
254 : {
255 4509959111 : return v == c || vn_reference_eq (v, c);
256 : }
257 :
258 : typedef hash_table<vn_reference_hasher> vn_reference_table_type;
259 : typedef vn_reference_table_type::iterator vn_reference_iterator_type;
260 :
261 : /* Pretty-print OPS to OUTFILE. */
262 :
263 : void
264 287 : print_vn_reference_ops (FILE *outfile, const vec<vn_reference_op_s> ops)
265 : {
266 287 : vn_reference_op_t vro;
267 287 : unsigned int i;
268 287 : fprintf (outfile, "{");
269 1591 : for (i = 0; ops.iterate (i, &vro); i++)
270 : {
271 1017 : bool closebrace = false;
272 1017 : if (vro->opcode != SSA_NAME
273 803 : && TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
274 : {
275 803 : fprintf (outfile, "%s", get_tree_code_name (vro->opcode));
276 803 : if (vro->op0 || vro->opcode == CALL_EXPR)
277 : {
278 803 : fprintf (outfile, "<");
279 803 : closebrace = true;
280 : }
281 : }
282 1017 : if (vro->opcode == MEM_REF || vro->opcode == TARGET_MEM_REF)
283 275 : fprintf (outfile, "(A%d)", TYPE_ALIGN (vro->type));
284 1017 : if (vro->op0 || vro->opcode == CALL_EXPR)
285 : {
286 1017 : if (!vro->op0)
287 0 : fprintf (outfile, internal_fn_name ((internal_fn)vro->clique));
288 : else
289 : {
290 1017 : if (vro->opcode == MEM_REF || vro->opcode == TARGET_MEM_REF)
291 : {
292 275 : fprintf (outfile, "(");
293 275 : print_generic_expr (outfile, TREE_TYPE (vro->op0));
294 275 : fprintf (outfile, ")");
295 : }
296 1017 : print_generic_expr (outfile, vro->op0);
297 : }
298 1017 : if (vro->op1)
299 : {
300 185 : fprintf (outfile, ",");
301 185 : print_generic_expr (outfile, vro->op1);
302 : }
303 1017 : if (vro->op2)
304 : {
305 185 : fprintf (outfile, ",");
306 185 : print_generic_expr (outfile, vro->op2);
307 : }
308 : }
309 1017 : if (closebrace)
310 803 : fprintf (outfile, ">");
311 1017 : if (i != ops.length () - 1)
312 730 : fprintf (outfile, ",");
313 : }
314 287 : fprintf (outfile, "}");
315 287 : }
316 :
317 : DEBUG_FUNCTION void
318 0 : debug_vn_reference_ops (const vec<vn_reference_op_s> ops)
319 : {
320 0 : print_vn_reference_ops (stderr, ops);
321 0 : fputc ('\n', stderr);
322 0 : }
323 :
324 : /* The set of VN hashtables. */
325 :
326 : typedef struct vn_tables_s
327 : {
328 : vn_nary_op_table_type *nary;
329 : vn_phi_table_type *phis;
330 : vn_reference_table_type *references;
331 : } *vn_tables_t;
332 :
333 :
334 : /* vn_constant hashtable helpers. */
335 :
336 : struct vn_constant_hasher : free_ptr_hash <vn_constant_s>
337 : {
338 : static inline hashval_t hash (const vn_constant_s *);
339 : static inline bool equal (const vn_constant_s *, const vn_constant_s *);
340 : };
341 :
342 : /* Hash table hash function for vn_constant_t. */
343 :
344 : inline hashval_t
345 12507071 : vn_constant_hasher::hash (const vn_constant_s *vc1)
346 : {
347 12507071 : return vc1->hashcode;
348 : }
349 :
350 : /* Hash table equality function for vn_constant_t. */
351 :
352 : inline bool
353 15069824 : vn_constant_hasher::equal (const vn_constant_s *vc1, const vn_constant_s *vc2)
354 : {
355 15069824 : if (vc1->hashcode != vc2->hashcode)
356 : return false;
357 :
358 2274529 : return vn_constant_eq_with_type (vc1->constant, vc2->constant);
359 : }
360 :
361 : static hash_table<vn_constant_hasher> *constant_to_value_id;
362 :
363 :
364 : /* Obstack we allocate the vn-tables elements from. */
365 : static obstack vn_tables_obstack;
366 : /* Special obstack we never unwind. */
367 : static obstack vn_tables_insert_obstack;
368 :
369 : static vn_reference_t last_inserted_ref;
370 : static vn_phi_t last_inserted_phi;
371 : static vn_nary_op_t last_inserted_nary;
372 : static vn_ssa_aux_t last_pushed_avail;
373 :
374 : /* Valid hashtables storing information we have proven to be
375 : correct. */
376 : static vn_tables_t valid_info;
377 :
378 : /* Global RPO state for access from hooks. */
379 : static class eliminate_dom_walker *rpo_avail;
380 : basic_block vn_context_bb;
381 : int *vn_bb_to_rpo;
382 :
383 :
384 : /* Valueization hook for simplify_replace_tree. Valueize NAME if it is
385 : an SSA name, otherwise just return it. */
386 : tree (*vn_valueize) (tree);
387 : static tree
388 82385 : vn_valueize_for_srt (tree t, void* context ATTRIBUTE_UNUSED)
389 : {
390 82385 : basic_block saved_vn_context_bb = vn_context_bb;
391 : /* Look for sth available at the definition block of the argument.
392 : This avoids inconsistencies between availability there which
393 : decides if the stmt can be removed and availability at the
394 : use site. The SSA property ensures that things available
395 : at the definition are also available at uses. */
396 82385 : if (!SSA_NAME_IS_DEFAULT_DEF (t))
397 78502 : vn_context_bb = gimple_bb (SSA_NAME_DEF_STMT (t));
398 82385 : tree res = vn_valueize (t);
399 82385 : vn_context_bb = saved_vn_context_bb;
400 82385 : return res;
401 : }
402 :
403 :
404 : /* This represents the top of the VN lattice, which is the universal
405 : value. */
406 :
407 : tree VN_TOP;
408 :
409 : /* Unique counter for our value ids. */
410 :
411 : static unsigned int next_value_id;
412 : static int next_constant_value_id;
413 :
414 :
415 : /* Table of vn_ssa_aux_t's, one per ssa_name. The vn_ssa_aux_t objects
416 : are allocated on an obstack for locality reasons, and to free them
417 : without looping over the vec. */
418 :
419 : struct vn_ssa_aux_hasher : typed_noop_remove <vn_ssa_aux_t>
420 : {
421 : typedef vn_ssa_aux_t value_type;
422 : typedef tree compare_type;
423 : static inline hashval_t hash (const value_type &);
424 : static inline bool equal (const value_type &, const compare_type &);
425 : static inline void mark_deleted (value_type &) {}
426 : static const bool empty_zero_p = true;
427 0 : static inline void mark_empty (value_type &e) { e = NULL; }
428 : static inline bool is_deleted (value_type &) { return false; }
429 >14124*10^7 : static inline bool is_empty (value_type &e) { return e == NULL; }
430 : };
431 :
432 : hashval_t
433 46387465776 : vn_ssa_aux_hasher::hash (const value_type &entry)
434 : {
435 46387465776 : return SSA_NAME_VERSION (entry->name);
436 : }
437 :
438 : bool
439 53094880389 : vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name)
440 : {
441 53094880389 : return name == entry->name;
442 : }
443 :
444 : static hash_table<vn_ssa_aux_hasher> *vn_ssa_aux_hash;
445 : typedef hash_table<vn_ssa_aux_hasher>::iterator vn_ssa_aux_iterator_type;
446 : static struct obstack vn_ssa_aux_obstack;
447 :
448 : static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree);
449 : static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t,
450 : vn_nary_op_table_type *);
451 : static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
452 : enum tree_code, tree, tree *);
453 : static tree vn_lookup_simplify_result (gimple_match_op *);
454 : static vn_reference_t vn_reference_lookup_or_insert_for_pieces
455 : (tree, alias_set_type, alias_set_type, poly_int64, poly_int64, tree,
456 : vec<vn_reference_op_s, va_heap>, tree);
457 :
458 : /* Return whether there is value numbering information for a given SSA name. */
459 :
460 : bool
461 5336883 : has_VN_INFO (tree name)
462 : {
463 5336883 : return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name));
464 : }
465 :
466 : vn_ssa_aux_t
467 4134771072 : VN_INFO (tree name)
468 : {
469 4134771072 : vn_ssa_aux_t *res
470 4134771072 : = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name),
471 : INSERT);
472 4134771072 : if (*res != NULL)
473 : return *res;
474 :
475 178707266 : vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
476 178707266 : memset (newinfo, 0, sizeof (struct vn_ssa_aux));
477 178707266 : newinfo->name = name;
478 178707266 : newinfo->valnum = VN_TOP;
479 : /* We are using the visited flag to handle uses with defs not within the
480 : region being value-numbered. */
481 178707266 : newinfo->visited = false;
482 :
483 : /* Given we create the VN_INFOs on-demand now we have to do initialization
484 : different than VN_TOP here. */
485 178707266 : if (SSA_NAME_IS_DEFAULT_DEF (name))
486 9604709 : switch (TREE_CODE (SSA_NAME_VAR (name)))
487 : {
488 1710811 : case VAR_DECL:
489 : /* All undefined vars are VARYING. */
490 1710811 : newinfo->valnum = name;
491 1710811 : newinfo->visited = true;
492 1710811 : break;
493 :
494 7830978 : case PARM_DECL:
495 : /* Parameters are VARYING but we can record a condition
496 : if we know it is a non-NULL pointer. */
497 7830978 : newinfo->visited = true;
498 7830978 : newinfo->valnum = name;
499 12044559 : if (POINTER_TYPE_P (TREE_TYPE (name))
500 9023288 : && nonnull_arg_p (SSA_NAME_VAR (name)))
501 : {
502 2454397 : tree ops[2];
503 2454397 : ops[0] = name;
504 2454397 : ops[1] = build_int_cst (TREE_TYPE (name), 0);
505 2454397 : vn_nary_op_t nary;
506 : /* Allocate from non-unwinding stack. */
507 2454397 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
508 2454397 : init_vn_nary_op_from_pieces (nary, 2, NE_EXPR,
509 : boolean_type_node, ops);
510 2454397 : nary->predicated_values = 0;
511 2454397 : nary->u.result = boolean_true_node;
512 2454397 : vn_nary_op_insert_into (nary, valid_info->nary);
513 2454397 : gcc_assert (nary->unwind_to == NULL);
514 : /* Also do not link it into the undo chain. */
515 2454397 : last_inserted_nary = nary->next;
516 2454397 : nary->next = (vn_nary_op_t)(void *)-1;
517 2454397 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
518 2454397 : init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR,
519 : boolean_type_node, ops);
520 2454397 : nary->predicated_values = 0;
521 2454397 : nary->u.result = boolean_false_node;
522 2454397 : vn_nary_op_insert_into (nary, valid_info->nary);
523 2454397 : gcc_assert (nary->unwind_to == NULL);
524 2454397 : last_inserted_nary = nary->next;
525 2454397 : nary->next = (vn_nary_op_t)(void *)-1;
526 2454397 : if (dump_file && (dump_flags & TDF_DETAILS))
527 : {
528 38 : fprintf (dump_file, "Recording ");
529 38 : print_generic_expr (dump_file, name, TDF_SLIM);
530 38 : fprintf (dump_file, " != 0\n");
531 : }
532 : }
533 : break;
534 :
535 62920 : case RESULT_DECL:
536 : /* If the result is passed by invisible reference the default
537 : def is initialized, otherwise it's uninitialized. Still
538 : undefined is varying. */
539 62920 : newinfo->visited = true;
540 62920 : newinfo->valnum = name;
541 62920 : break;
542 :
543 0 : default:
544 0 : gcc_unreachable ();
545 : }
546 : return newinfo;
547 : }
548 :
549 : /* Return the SSA value of X. */
550 :
551 : inline tree
552 3529828705 : SSA_VAL (tree x, bool *visited = NULL)
553 : {
554 3529828705 : vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
555 3529828705 : if (visited)
556 1436609681 : *visited = tem && tem->visited;
557 3529828705 : return tem && tem->visited ? tem->valnum : x;
558 : }
559 :
560 : /* Return the SSA value of the VUSE x, supporting released VDEFs
561 : during elimination which will value-number the VDEF to the
562 : associated VUSE (but not substitute in the whole lattice). */
563 :
564 : static inline tree
565 1299199663 : vuse_ssa_val (tree x)
566 : {
567 1299199663 : if (!x)
568 : return NULL_TREE;
569 :
570 1295662974 : do
571 : {
572 1295662974 : x = SSA_VAL (x);
573 1295662974 : gcc_assert (x != VN_TOP);
574 : }
575 1295662974 : while (SSA_NAME_IN_FREE_LIST (x));
576 :
577 : return x;
578 : }
579 :
580 : /* Similar to the above but used as callback for walk_non_aliased_vuses
581 : and thus should stop at unvisited VUSE to not walk across region
582 : boundaries. */
583 :
584 : static tree
585 1096643419 : vuse_valueize (tree vuse)
586 : {
587 1096643419 : do
588 : {
589 1096643419 : bool visited;
590 1096643419 : vuse = SSA_VAL (vuse, &visited);
591 1096643419 : if (!visited)
592 16567814 : return NULL_TREE;
593 1080075605 : gcc_assert (vuse != VN_TOP);
594 : }
595 1080075605 : while (SSA_NAME_IN_FREE_LIST (vuse));
596 : return vuse;
597 : }
598 :
599 :
600 : /* Return the vn_kind the expression computed by the stmt should be
601 : associated with. */
602 :
603 : enum vn_kind
604 105624224 : vn_get_stmt_kind (gimple *stmt)
605 : {
606 105624224 : switch (gimple_code (stmt))
607 : {
608 : case GIMPLE_CALL:
609 : return VN_REFERENCE;
610 : case GIMPLE_PHI:
611 : return VN_PHI;
612 105624224 : case GIMPLE_ASSIGN:
613 105624224 : {
614 105624224 : enum tree_code code = gimple_assign_rhs_code (stmt);
615 105624224 : tree rhs1 = gimple_assign_rhs1 (stmt);
616 105624224 : switch (get_gimple_rhs_class (code))
617 : {
618 : case GIMPLE_UNARY_RHS:
619 : case GIMPLE_BINARY_RHS:
620 : case GIMPLE_TERNARY_RHS:
621 : return VN_NARY;
622 49807316 : case GIMPLE_SINGLE_RHS:
623 49807316 : switch (TREE_CODE_CLASS (code))
624 : {
625 37581921 : case tcc_reference:
626 : /* VOP-less references can go through unary case. */
627 37581921 : if ((code == REALPART_EXPR
628 : || code == IMAGPART_EXPR
629 37581921 : || code == VIEW_CONVERT_EXPR
630 37581921 : || code == BIT_FIELD_REF)
631 37581921 : && (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
632 678413 : || is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
633 : return VN_NARY;
634 :
635 : /* Fallthrough. */
636 : case tcc_declaration:
637 : return VN_REFERENCE;
638 :
639 : case tcc_constant:
640 : return VN_CONSTANT;
641 :
642 6172204 : default:
643 6172204 : if (code == ADDR_EXPR)
644 3357899 : return (is_gimple_min_invariant (rhs1)
645 3357899 : ? VN_CONSTANT : VN_REFERENCE);
646 2814305 : else if (code == CONSTRUCTOR)
647 : return VN_NARY;
648 : return VN_NONE;
649 : }
650 : default:
651 : return VN_NONE;
652 : }
653 : }
654 : default:
655 : return VN_NONE;
656 : }
657 : }
658 :
659 : /* Lookup a value id for CONSTANT and return it. If it does not
660 : exist returns 0. */
661 :
662 : unsigned int
663 0 : get_constant_value_id (tree constant)
664 : {
665 0 : vn_constant_s **slot;
666 0 : struct vn_constant_s vc;
667 :
668 0 : vc.hashcode = vn_hash_constant_with_type (constant);
669 0 : vc.constant = constant;
670 0 : slot = constant_to_value_id->find_slot (&vc, NO_INSERT);
671 0 : if (slot)
672 0 : return (*slot)->value_id;
673 : return 0;
674 : }
675 :
676 : /* Lookup a value id for CONSTANT, and if it does not exist, create a
677 : new one and return it. If it does exist, return it. */
678 :
679 : unsigned int
680 29502947 : get_or_alloc_constant_value_id (tree constant)
681 : {
682 29502947 : vn_constant_s **slot;
683 29502947 : struct vn_constant_s vc;
684 29502947 : vn_constant_t vcp;
685 :
686 : /* If the hashtable isn't initialized we're not running from PRE and thus
687 : do not need value-ids. */
688 29502947 : if (!constant_to_value_id)
689 : return 0;
690 :
691 4859918 : vc.hashcode = vn_hash_constant_with_type (constant);
692 4859918 : vc.constant = constant;
693 4859918 : slot = constant_to_value_id->find_slot (&vc, INSERT);
694 4859918 : if (*slot)
695 2256971 : return (*slot)->value_id;
696 :
697 2602947 : vcp = XNEW (struct vn_constant_s);
698 2602947 : vcp->hashcode = vc.hashcode;
699 2602947 : vcp->constant = constant;
700 2602947 : vcp->value_id = get_next_constant_value_id ();
701 2602947 : *slot = vcp;
702 2602947 : return vcp->value_id;
703 : }
704 :
705 : /* Compute the hash for a reference operand VRO1. */
706 :
707 : static void
708 140748255 : vn_reference_op_compute_hash (const vn_reference_op_t vro1, inchash::hash &hstate)
709 : {
710 140748255 : hstate.add_int (vro1->opcode);
711 140748255 : if (vro1->opcode == CALL_EXPR && !vro1->op0)
712 556418 : hstate.add_int (vro1->clique);
713 140748255 : if (vro1->op0)
714 134171628 : inchash::add_expr (vro1->op0, hstate);
715 140748255 : if (vro1->op1)
716 12043707 : inchash::add_expr (vro1->op1, hstate);
717 140748255 : if (vro1->op2)
718 13854649 : inchash::add_expr (vro1->op2, hstate);
719 140748255 : }
720 :
721 : /* Compute a hash for the reference operation VR1 and return it. */
722 :
723 : hashval_t
724 209461031 : vn_reference_compute_hash (const vn_reference_t vr1)
725 : {
726 209461031 : inchash::hash hstate;
727 209461031 : hashval_t result;
728 209461031 : int i;
729 209461031 : vn_reference_op_t vro;
730 209461031 : poly_offset_int off = -1;
731 209461031 : bool deref = false;
732 :
733 853048798 : FOR_EACH_VEC_ELT (vr1->operands, i, vro)
734 : {
735 643587767 : if (vro->opcode == MEM_REF)
736 : deref = true;
737 445090926 : else if (vro->opcode != ADDR_EXPR)
738 312811084 : deref = false;
739 643587767 : if (maybe_ne (vro->off, -1))
740 : {
741 379008468 : if (known_eq (off, -1))
742 200890620 : off = 0;
743 643587767 : off += vro->off;
744 : }
745 : else
746 : {
747 264579299 : if (maybe_ne (off, -1)
748 264579299 : && maybe_ne (off, 0))
749 107009776 : hstate.add_poly_hwi (off.force_shwi ());
750 264579299 : off = -1;
751 264579299 : if (deref
752 124043764 : && vro->opcode == ADDR_EXPR)
753 : {
754 123831044 : if (vro->op0)
755 : {
756 123831044 : tree op = TREE_OPERAND (vro->op0, 0);
757 123831044 : hstate.add_int (TREE_CODE (op));
758 123831044 : inchash::add_expr (op, hstate);
759 : }
760 : }
761 : else
762 140748255 : vn_reference_op_compute_hash (vro, hstate);
763 : }
764 : }
765 : /* Do not hash vr1->offset or vr1->max_size, we want to get collisions
766 : to be able to identify compatible results. */
767 209461031 : result = hstate.end ();
768 : /* ??? We would ICE later if we hash instead of adding that in. */
769 209461031 : if (vr1->vuse)
770 204339190 : result += SSA_NAME_VERSION (vr1->vuse);
771 :
772 209461031 : return result;
773 : }
774 :
775 : /* Return true if reference operations VR1 and VR2 are equivalent. This
776 : means they have the same set of operands and vuses. If LEXICAL
777 : is true then the full access path has to be the same. */
778 :
779 : bool
780 4504916266 : vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2,
781 : bool lexical)
782 : {
783 4504916266 : unsigned i, j;
784 :
785 : /* Early out if this is not a hash collision. */
786 4504916266 : if (vr1->hashcode != vr2->hashcode)
787 : return false;
788 :
789 : /* The VOP needs to be the same. */
790 18396442 : if (vr1->vuse != vr2->vuse)
791 : return false;
792 :
793 : /* The offset/max_size used for the ao_ref during lookup has to be
794 : the same. */
795 18395996 : if (maybe_ne (vr1->offset, vr2->offset)
796 18395996 : || maybe_ne (vr1->max_size, vr2->max_size))
797 : {
798 : /* But nothing known in the prevailing entry is OK to be used. */
799 7148234 : if (maybe_ne (vr1->offset, 0) || known_size_p (vr1->max_size))
800 : return false;
801 : }
802 :
803 : /* If the operands are the same we are done. */
804 36681490 : if (vr1->operands == vr2->operands)
805 : return true;
806 :
807 18340745 : if (!vr1->type || !vr2->type)
808 : {
809 593754 : if (vr1->type != vr2->type)
810 : return false;
811 : }
812 17746991 : else if (vr1->type == vr2->type)
813 : ;
814 2268460 : else if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
815 2268460 : || (COMPLETE_TYPE_P (vr1->type)
816 2268460 : && !expressions_equal_p (TYPE_SIZE (vr1->type),
817 2268460 : TYPE_SIZE (vr2->type))))
818 : return false;
819 1521379 : else if (vr1->operands[0].opcode == CALL_EXPR
820 1521379 : && !types_compatible_p (vr1->type, vr2->type))
821 : return false;
822 1521379 : else if (INTEGRAL_TYPE_P (vr1->type)
823 603318 : && INTEGRAL_TYPE_P (vr2->type))
824 : {
825 563221 : if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
826 : return false;
827 : }
828 958158 : else if (INTEGRAL_TYPE_P (vr1->type)
829 958158 : && (TYPE_PRECISION (vr1->type)
830 40097 : != TREE_INT_CST_LOW (TYPE_SIZE (vr1->type))))
831 : return false;
832 958112 : else if (INTEGRAL_TYPE_P (vr2->type)
833 958112 : && (TYPE_PRECISION (vr2->type)
834 9076 : != TREE_INT_CST_LOW (TYPE_SIZE (vr2->type))))
835 : return false;
836 19992 : else if (VECTOR_BOOLEAN_TYPE_P (vr1->type)
837 957517 : && VECTOR_BOOLEAN_TYPE_P (vr2->type))
838 : {
839 : /* Vector boolean types can have padding, verify we are dealing with
840 : the same number of elements, aka the precision of the types.
841 : For example, In most architecture the precision_size of vbool*_t
842 : types are calculated like below:
843 : precision_size = type_size * 8
844 :
845 : Unfortunately, the RISC-V will adjust the precision_size for the
846 : vbool*_t in order to align the ISA as below:
847 : type_size = [1, 1, 1, 1, 2, 4, 8]
848 : precision_size = [1, 2, 4, 8, 16, 32, 64]
849 :
850 : Then the precision_size of RISC-V vbool*_t will not be the multiple
851 : of the type_size. We take care of this case consolidated here. */
852 0 : if (maybe_ne (TYPE_VECTOR_SUBPARTS (vr1->type),
853 0 : TYPE_VECTOR_SUBPARTS (vr2->type)))
854 : return false;
855 : }
856 957517 : else if (TYPE_MODE (vr1->type) != TYPE_MODE (vr2->type)
857 957517 : && (!mode_can_transfer_bits (TYPE_MODE (vr1->type))
858 45247 : || !mode_can_transfer_bits (TYPE_MODE (vr2->type))))
859 : return false;
860 :
861 17476233 : i = 0;
862 17476233 : j = 0;
863 22548001 : do
864 : {
865 22548001 : poly_offset_int off1 = 0, off2 = 0;
866 22548001 : vn_reference_op_t vro1, vro2;
867 22548001 : vn_reference_op_s tem1, tem2;
868 22548001 : bool deref1 = false, deref2 = false;
869 22548001 : bool reverse1 = false, reverse2 = false;
870 73574360 : for (; vr1->operands.iterate (i, &vro1); i++)
871 : {
872 51026359 : if (vro1->opcode == MEM_REF)
873 : deref1 = true;
874 : /* Do not look through a storage order barrier. */
875 34948861 : else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
876 77001 : return false;
877 51026359 : reverse1 |= vro1->reverse;
878 51026359 : if (lexical || known_eq (vro1->off, -1))
879 : break;
880 28478358 : off1 += vro1->off;
881 : }
882 51223322 : for (; vr2->operands.iterate (j, &vro2); j++)
883 : {
884 51223322 : if (vro2->opcode == MEM_REF)
885 : deref2 = true;
886 : /* Do not look through a storage order barrier. */
887 35120796 : else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
888 : return false;
889 51223322 : reverse2 |= vro2->reverse;
890 51223322 : if (lexical || known_eq (vro2->off, -1))
891 : break;
892 28675321 : off2 += vro2->off;
893 : }
894 22548001 : if (maybe_ne (off1, off2) || reverse1 != reverse2)
895 : return false;
896 22547882 : if (deref1 && vro1->opcode == ADDR_EXPR)
897 : {
898 8477779 : memset (&tem1, 0, sizeof (tem1));
899 8477779 : tem1.op0 = TREE_OPERAND (vro1->op0, 0);
900 8477779 : tem1.type = TREE_TYPE (tem1.op0);
901 8477779 : tem1.opcode = TREE_CODE (tem1.op0);
902 8477779 : vro1 = &tem1;
903 8477779 : deref1 = false;
904 : }
905 22547882 : if (deref2 && vro2->opcode == ADDR_EXPR)
906 : {
907 8477785 : memset (&tem2, 0, sizeof (tem2));
908 8477785 : tem2.op0 = TREE_OPERAND (vro2->op0, 0);
909 8477785 : tem2.type = TREE_TYPE (tem2.op0);
910 8477785 : tem2.opcode = TREE_CODE (tem2.op0);
911 8477785 : vro2 = &tem2;
912 8477785 : deref2 = false;
913 : }
914 22547882 : if (deref1 != deref2)
915 : return false;
916 22486774 : if (!vn_reference_op_eq (vro1, vro2))
917 : return false;
918 : /* Both alignment and alias set are not relevant for the produced
919 : value but need to be included when doing lexical comparison.
920 : We also need to make sure that the access path ends in an
921 : access of the same size as otherwise we might assume an access
922 : may not trap while in fact it might. */
923 22474272 : if (lexical
924 2286420 : && (vro1->opcode == MEM_REF
925 2286420 : || vro1->opcode == TARGET_MEM_REF)
926 23221209 : && (TYPE_ALIGN (vro1->type) != TYPE_ALIGN (vro2->type)
927 746730 : || (TYPE_SIZE (vro1->type) != TYPE_SIZE (vro2->type)
928 6 : && (! TYPE_SIZE (vro1->type)
929 6 : || ! TYPE_SIZE (vro2->type)
930 6 : || ! operand_equal_p (TYPE_SIZE (vro1->type),
931 6 : TYPE_SIZE (vro2->type))))
932 2240172 : || (get_deref_alias_set (vro1->opcode == MEM_REF
933 746724 : ? TREE_TYPE (vro1->op0)
934 0 : : TREE_TYPE (vro1->op2))
935 1493448 : != get_deref_alias_set (vro2->opcode == MEM_REF
936 746724 : ? TREE_TYPE (vro2->op0)
937 0 : : TREE_TYPE (vro2->op2)))))
938 : return false;
939 22471000 : ++j;
940 22471000 : ++i;
941 : }
942 44942000 : while (vr1->operands.length () != i
943 67413000 : || vr2->operands.length () != j);
944 :
945 : return true;
946 : }
947 :
948 : /* Copy the operations present in load/store REF into RESULT, a vector of
949 : vn_reference_op_s's. */
950 :
951 : void
952 228697957 : copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
953 : {
954 : /* For non-calls, store the information that makes up the address. */
955 228697957 : tree orig = ref;
956 795715477 : while (ref)
957 : {
958 567017520 : vn_reference_op_s temp;
959 :
960 567017520 : memset (&temp, 0, sizeof (temp));
961 567017520 : temp.type = TREE_TYPE (ref);
962 567017520 : temp.opcode = TREE_CODE (ref);
963 567017520 : temp.off = -1;
964 :
965 567017520 : switch (temp.opcode)
966 : {
967 15330568 : case MODIFY_EXPR:
968 15330568 : temp.op0 = TREE_OPERAND (ref, 1);
969 15330568 : break;
970 137 : case WITH_SIZE_EXPR:
971 137 : temp.op0 = TREE_OPERAND (ref, 1);
972 137 : temp.off = 0;
973 137 : break;
974 121272214 : case MEM_REF:
975 : /* The base address gets its own vn_reference_op_s structure. */
976 121272214 : temp.op0 = TREE_OPERAND (ref, 1);
977 121272214 : if (!mem_ref_offset (ref).to_shwi (&temp.off))
978 0 : temp.off = -1;
979 121272214 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
980 121272214 : temp.base = MR_DEPENDENCE_BASE (ref);
981 121272214 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
982 121272214 : break;
983 2533682 : case TARGET_MEM_REF:
984 : /* The base address gets its own vn_reference_op_s structure. */
985 2533682 : temp.op0 = TMR_INDEX (ref);
986 2533682 : temp.op1 = TMR_STEP (ref);
987 2533682 : temp.op2 = TMR_OFFSET (ref);
988 2533682 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
989 2533682 : temp.base = MR_DEPENDENCE_BASE (ref);
990 2533682 : result->safe_push (temp);
991 2533682 : memset (&temp, 0, sizeof (temp));
992 2533682 : temp.type = NULL_TREE;
993 2533682 : temp.opcode = ERROR_MARK;
994 2533682 : temp.op0 = TMR_INDEX2 (ref);
995 2533682 : temp.off = -1;
996 2533682 : break;
997 804528 : case BIT_FIELD_REF:
998 : /* Record bits, position and storage order. */
999 804528 : temp.op0 = TREE_OPERAND (ref, 1);
1000 804528 : temp.op1 = TREE_OPERAND (ref, 2);
1001 1608346 : if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
1002 710 : temp.off = -1;
1003 804528 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
1004 804528 : break;
1005 152564826 : case COMPONENT_REF:
1006 152564826 : temp.op0 = TREE_OPERAND (ref, 1);
1007 152564826 : temp.op1 = TREE_OPERAND (ref, 2);
1008 305127220 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1009 305126955 : && TYPE_REVERSE_STORAGE_ORDER
1010 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1011 152564826 : {
1012 152564826 : tree this_offset = component_ref_field_offset (ref);
1013 152564826 : if (this_offset
1014 152564826 : && poly_int_tree_p (this_offset))
1015 : {
1016 152562696 : tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1));
1017 152562696 : if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0)
1018 : {
1019 152070704 : poly_offset_int off
1020 152070704 : = (wi::to_poly_offset (this_offset)
1021 152070704 : + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT));
1022 : /* Prohibit value-numbering zero offset components
1023 : of addresses the same before the pass folding
1024 : __builtin_object_size had a chance to run. Likewise
1025 : for components of zero size at arbitrary offset. */
1026 152070704 : if (TREE_CODE (orig) != ADDR_EXPR
1027 5127196 : || (TYPE_SIZE (temp.type)
1028 5113684 : && integer_nonzerop (TYPE_SIZE (temp.type))
1029 155223138 : && maybe_ne (off, 0))
1030 155238816 : || (cfun->curr_properties & PROP_objsz))
1031 150571636 : off.to_shwi (&temp.off);
1032 : }
1033 : }
1034 : }
1035 : break;
1036 39017257 : case ARRAY_RANGE_REF:
1037 39017257 : case ARRAY_REF:
1038 39017257 : {
1039 39017257 : tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
1040 : /* Record index as operand. */
1041 39017257 : temp.op0 = TREE_OPERAND (ref, 1);
1042 : /* Always record lower bounds and element size. */
1043 39017257 : temp.op1 = array_ref_low_bound (ref);
1044 : /* But record element size in units of the type alignment. */
1045 39017257 : temp.op2 = TREE_OPERAND (ref, 3);
1046 39017257 : temp.align = eltype->type_common.align;
1047 39017257 : if (! temp.op2)
1048 38806640 : temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
1049 : size_int (TYPE_ALIGN_UNIT (eltype)));
1050 : /* Prohibit value-numbering addresses of one-after-the-last
1051 : element ARRAY_REFs the same as addresses of other components
1052 : before the pass folding __builtin_object_size had a chance
1053 : to run. */
1054 39017257 : bool avoid_oob = true;
1055 39017257 : if (TREE_CODE (orig) != ADDR_EXPR
1056 480658 : || cfun->curr_properties & PROP_objsz)
1057 : avoid_oob = false;
1058 225917 : else if (poly_int_tree_p (temp.op0))
1059 : {
1060 75945 : tree ub = array_ref_up_bound (ref);
1061 75945 : if (ub
1062 74232 : && poly_int_tree_p (ub)
1063 : /* ??? The C frontend for T[0] uses [0:] and the
1064 : C++ frontend [0:-1U]. See layout_type for how
1065 : awkward this is. */
1066 65380 : && !integer_minus_onep (ub)
1067 150177 : && known_le (wi::to_poly_offset (temp.op0),
1068 : wi::to_poly_offset (ub)))
1069 64543 : avoid_oob = false;
1070 : }
1071 39017257 : if (poly_int_tree_p (temp.op0)
1072 22493267 : && poly_int_tree_p (temp.op1)
1073 22493243 : && TREE_CODE (temp.op2) == INTEGER_CST
1074 61449233 : && !avoid_oob)
1075 : {
1076 44843674 : poly_offset_int off = ((wi::to_poly_offset (temp.op0)
1077 67265511 : - wi::to_poly_offset (temp.op1))
1078 44843674 : * wi::to_offset (temp.op2)
1079 22421837 : * vn_ref_op_align_unit (&temp));
1080 22421837 : off.to_shwi (&temp.off);
1081 : }
1082 39017257 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1083 39017257 : && TYPE_REVERSE_STORAGE_ORDER
1084 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1085 : }
1086 39017257 : break;
1087 83698261 : case VAR_DECL:
1088 83698261 : if (DECL_HARD_REGISTER (ref))
1089 : {
1090 20311 : temp.op0 = ref;
1091 20311 : break;
1092 : }
1093 : /* Fallthru. */
1094 87109804 : case PARM_DECL:
1095 87109804 : case CONST_DECL:
1096 87109804 : case RESULT_DECL:
1097 : /* Canonicalize decls to MEM[&decl] which is what we end up with
1098 : when valueizing MEM[ptr] with ptr = &decl. */
1099 87109804 : temp.opcode = MEM_REF;
1100 87109804 : temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
1101 87109804 : temp.off = 0;
1102 87109804 : result->safe_push (temp);
1103 87109804 : temp.opcode = ADDR_EXPR;
1104 87109804 : temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
1105 87109804 : temp.type = TREE_TYPE (temp.op0);
1106 87109804 : temp.off = -1;
1107 87109804 : break;
1108 99238541 : case STRING_CST:
1109 99238541 : case INTEGER_CST:
1110 99238541 : case POLY_INT_CST:
1111 99238541 : case COMPLEX_CST:
1112 99238541 : case VECTOR_CST:
1113 99238541 : case REAL_CST:
1114 99238541 : case FIXED_CST:
1115 99238541 : case CONSTRUCTOR:
1116 99238541 : case SSA_NAME:
1117 99238541 : temp.op0 = ref;
1118 99238541 : break;
1119 46695394 : case ADDR_EXPR:
1120 46695394 : if (is_gimple_min_invariant (ref))
1121 : {
1122 42329301 : temp.op0 = ref;
1123 42329301 : break;
1124 : }
1125 : break;
1126 : /* These are only interesting for their operands, their
1127 : existence, and their type. They will never be the last
1128 : ref in the chain of references (IE they require an
1129 : operand), so we don't have to put anything
1130 : for op* as it will be handled by the iteration */
1131 494932 : case REALPART_EXPR:
1132 494932 : temp.off = 0;
1133 494932 : break;
1134 1434252 : case VIEW_CONVERT_EXPR:
1135 1434252 : temp.off = 0;
1136 1434252 : temp.reverse = storage_order_barrier_p (ref);
1137 1434252 : break;
1138 501074 : case IMAGPART_EXPR:
1139 : /* This is only interesting for its constant offset. */
1140 501074 : temp.off = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (ref)));
1141 501074 : break;
1142 0 : default:
1143 0 : gcc_unreachable ();
1144 : }
1145 567017520 : result->safe_push (temp);
1146 :
1147 567017520 : if (REFERENCE_CLASS_P (ref)
1148 248394755 : || TREE_CODE (ref) == MODIFY_EXPR
1149 233064187 : || TREE_CODE (ref) == WITH_SIZE_EXPR
1150 800081570 : || (TREE_CODE (ref) == ADDR_EXPR
1151 46695394 : && !is_gimple_min_invariant (ref)))
1152 338319563 : ref = TREE_OPERAND (ref, 0);
1153 : else
1154 : ref = NULL_TREE;
1155 : }
1156 228697957 : }
1157 :
1158 : /* Build a alias-oracle reference abstraction in *REF from the vn_reference
1159 : operands in *OPS, the reference alias set SET and the reference type TYPE.
1160 : Return true if something useful was produced. */
1161 :
1162 : bool
1163 14982536 : ao_ref_init_from_vn_reference (ao_ref *ref,
1164 : alias_set_type set, alias_set_type base_set,
1165 : tree type, const vec<vn_reference_op_s> &ops)
1166 : {
1167 14982536 : unsigned i;
1168 14982536 : tree base = NULL_TREE;
1169 14982536 : tree *op0_p = &base;
1170 14982536 : poly_offset_int offset = 0;
1171 14982536 : poly_offset_int max_size;
1172 14982536 : poly_offset_int size = -1;
1173 14982536 : tree size_tree = NULL_TREE;
1174 :
1175 : /* We don't handle calls. */
1176 14982536 : if (!type)
1177 : return false;
1178 :
1179 14982536 : machine_mode mode = TYPE_MODE (type);
1180 14982536 : if (mode == BLKmode)
1181 50831 : size_tree = TYPE_SIZE (type);
1182 : else
1183 29863410 : size = GET_MODE_BITSIZE (mode);
1184 14931705 : if (size_tree != NULL_TREE
1185 50831 : && poly_int_tree_p (size_tree))
1186 50831 : size = wi::to_poly_offset (size_tree);
1187 :
1188 : /* Lower the final access size from the outermost expression. */
1189 14982536 : const_vn_reference_op_t cst_op = &ops[0];
1190 : /* Cast away constness for the sake of the const-unsafe
1191 : FOR_EACH_VEC_ELT(). */
1192 14982536 : vn_reference_op_t op = const_cast<vn_reference_op_t>(cst_op);
1193 14982536 : size_tree = NULL_TREE;
1194 14982536 : if (op->opcode == COMPONENT_REF)
1195 5214588 : size_tree = DECL_SIZE (op->op0);
1196 9767948 : else if (op->opcode == BIT_FIELD_REF)
1197 74770 : size_tree = op->op0;
1198 5289358 : if (size_tree != NULL_TREE
1199 5289358 : && poly_int_tree_p (size_tree)
1200 10578716 : && (!known_size_p (size)
1201 14982536 : || known_lt (wi::to_poly_offset (size_tree), size)))
1202 47294 : size = wi::to_poly_offset (size_tree);
1203 :
1204 : /* Initially, maxsize is the same as the accessed element size.
1205 : In the following it will only grow (or become -1). */
1206 14982536 : max_size = size;
1207 :
1208 : /* Compute cumulative bit-offset for nested component-refs and array-refs,
1209 : and find the ultimate containing object. */
1210 57523712 : FOR_EACH_VEC_ELT (ops, i, op)
1211 : {
1212 42697105 : switch (op->opcode)
1213 : {
1214 : case CALL_EXPR:
1215 : return false;
1216 :
1217 : /* Record the base objects. */
1218 14529698 : case MEM_REF:
1219 14529698 : *op0_p = build2 (MEM_REF, op->type,
1220 : NULL_TREE, op->op0);
1221 14529698 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1222 14529698 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1223 14529698 : op0_p = &TREE_OPERAND (*op0_p, 0);
1224 14529698 : break;
1225 :
1226 296381 : case TARGET_MEM_REF:
1227 889143 : *op0_p = build5 (TARGET_MEM_REF, op->type,
1228 : NULL_TREE, op->op2, op->op0,
1229 296381 : op->op1, ops[i+1].op0);
1230 296381 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1231 296381 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1232 296381 : op0_p = &TREE_OPERAND (*op0_p, 0);
1233 296381 : ++i;
1234 296381 : break;
1235 :
1236 : /* Unwrap some of the wrapped decls. */
1237 6710071 : case ADDR_EXPR:
1238 : /* Apart from ADDR_EXPR arguments to MEM_REF. */
1239 6710071 : if (base != NULL_TREE
1240 6710070 : && TREE_CODE (base) == MEM_REF
1241 6678379 : && op->op0
1242 13388450 : && DECL_P (TREE_OPERAND (op->op0, 0)))
1243 : {
1244 6670985 : const_vn_reference_op_t pop = &ops[i-1];
1245 6670985 : base = TREE_OPERAND (op->op0, 0);
1246 6670985 : if (known_eq (pop->off, -1))
1247 : {
1248 25 : max_size = -1;
1249 25 : offset = 0;
1250 : }
1251 : else
1252 20012880 : offset += poly_offset_int (pop->off) * BITS_PER_UNIT;
1253 : op0_p = NULL;
1254 : break;
1255 : }
1256 : /* Fallthru. */
1257 8155622 : case PARM_DECL:
1258 8155622 : case CONST_DECL:
1259 8155622 : case RESULT_DECL:
1260 : /* ??? We shouldn't see these, but un-canonicalize what
1261 : copy_reference_ops_from_ref does when visiting MEM_REF. */
1262 8155622 : case VAR_DECL:
1263 : /* ??? And for this only have DECL_HARD_REGISTER. */
1264 8155622 : case STRING_CST:
1265 : /* This can show up in ARRAY_REF bases. */
1266 8155622 : case INTEGER_CST:
1267 8155622 : case SSA_NAME:
1268 8155622 : *op0_p = op->op0;
1269 8155622 : op0_p = NULL;
1270 8155622 : break;
1271 :
1272 : /* And now the usual component-reference style ops. */
1273 74770 : case BIT_FIELD_REF:
1274 74770 : offset += wi::to_poly_offset (op->op1);
1275 74770 : break;
1276 :
1277 8488955 : case COMPONENT_REF:
1278 8488955 : {
1279 8488955 : tree field = op->op0;
1280 : /* We do not have a complete COMPONENT_REF tree here so we
1281 : cannot use component_ref_field_offset. Do the interesting
1282 : parts manually. */
1283 8488955 : tree this_offset = DECL_FIELD_OFFSET (field);
1284 :
1285 8488955 : if (op->op1 || !poly_int_tree_p (this_offset))
1286 233 : max_size = -1;
1287 : else
1288 : {
1289 8488722 : poly_offset_int woffset = (wi::to_poly_offset (this_offset)
1290 8488722 : << LOG2_BITS_PER_UNIT);
1291 8488722 : woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
1292 8488722 : offset += woffset;
1293 : }
1294 : break;
1295 : }
1296 :
1297 3131423 : case ARRAY_RANGE_REF:
1298 3131423 : case ARRAY_REF:
1299 : /* Use the recorded constant offset. */
1300 3131423 : if (maybe_eq (op->off, -1))
1301 1216329 : max_size = -1;
1302 : else
1303 5745282 : offset += poly_offset_int (op->off) * BITS_PER_UNIT;
1304 : break;
1305 :
1306 : case REALPART_EXPR:
1307 : break;
1308 :
1309 : case IMAGPART_EXPR:
1310 42541176 : offset += size;
1311 : break;
1312 :
1313 : case VIEW_CONVERT_EXPR:
1314 : break;
1315 :
1316 : case POLY_INT_CST:
1317 : case COMPLEX_CST:
1318 : case VECTOR_CST:
1319 : case REAL_CST:
1320 : case FIXED_CST:
1321 : case CONSTRUCTOR:
1322 : return false;
1323 :
1324 : default:
1325 : return false;
1326 : }
1327 : }
1328 :
1329 14826607 : if (base == NULL_TREE)
1330 : return false;
1331 :
1332 14826607 : ref->ref = NULL_TREE;
1333 14826607 : ref->base = base;
1334 14826607 : ref->ref_alias_set = set;
1335 14826607 : ref->base_alias_set = base_set;
1336 : /* We discount volatiles from value-numbering elsewhere. */
1337 14826607 : ref->volatile_p = false;
1338 :
1339 14826607 : if (!size.to_shwi (&ref->size) || maybe_lt (ref->size, 0))
1340 : {
1341 0 : ref->offset = 0;
1342 0 : ref->size = -1;
1343 0 : ref->max_size = -1;
1344 0 : return true;
1345 : }
1346 :
1347 14826607 : if (!offset.to_shwi (&ref->offset))
1348 : {
1349 26 : ref->offset = 0;
1350 26 : ref->max_size = -1;
1351 26 : return true;
1352 : }
1353 :
1354 14826581 : if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0))
1355 1065958 : ref->max_size = -1;
1356 :
1357 : return true;
1358 : }
1359 :
1360 : /* Copy the operations present in load/store/call REF into RESULT, a vector of
1361 : vn_reference_op_s's. */
1362 :
1363 : static void
1364 9514776 : copy_reference_ops_from_call (gcall *call,
1365 : vec<vn_reference_op_s> *result)
1366 : {
1367 9514776 : vn_reference_op_s temp;
1368 9514776 : unsigned i;
1369 9514776 : tree lhs = gimple_call_lhs (call);
1370 9514776 : int lr;
1371 :
1372 : /* If 2 calls have a different non-ssa lhs, vdef value numbers should be
1373 : different. By adding the lhs here in the vector, we ensure that the
1374 : hashcode is different, guaranteeing a different value number. */
1375 9514776 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
1376 : {
1377 456768 : memset (&temp, 0, sizeof (temp));
1378 456768 : temp.opcode = MODIFY_EXPR;
1379 456768 : temp.type = TREE_TYPE (lhs);
1380 456768 : temp.op0 = lhs;
1381 456768 : temp.off = -1;
1382 456768 : result->safe_push (temp);
1383 : }
1384 :
1385 : /* Copy the type, opcode, function, static chain and EH region, if any. */
1386 9514776 : memset (&temp, 0, sizeof (temp));
1387 9514776 : temp.type = gimple_call_fntype (call);
1388 9514776 : temp.opcode = CALL_EXPR;
1389 9514776 : temp.op0 = gimple_call_fn (call);
1390 9514776 : if (gimple_call_internal_p (call))
1391 541376 : temp.clique = gimple_call_internal_fn (call);
1392 9514776 : temp.op1 = gimple_call_chain (call);
1393 9514776 : if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0)
1394 661666 : temp.op2 = size_int (lr);
1395 9514776 : temp.off = -1;
1396 9514776 : result->safe_push (temp);
1397 :
1398 : /* Copy the call arguments. As they can be references as well,
1399 : just chain them together. */
1400 37602368 : for (i = 0; i < gimple_call_num_args (call); ++i)
1401 : {
1402 18572816 : tree callarg = gimple_call_arg (call, i);
1403 18572816 : copy_reference_ops_from_ref (callarg, result);
1404 : }
1405 9514776 : }
1406 :
1407 : /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates
1408 : *I_P to point to the last element of the replacement. */
1409 : static bool
1410 130061318 : vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
1411 : unsigned int *i_p)
1412 : {
1413 130061318 : unsigned int i = *i_p;
1414 130061318 : vn_reference_op_t op = &(*ops)[i];
1415 130061318 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1416 130061318 : tree addr_base;
1417 130061318 : poly_int64 addr_offset = 0;
1418 :
1419 : /* The only thing we have to do is from &OBJ.foo.bar add the offset
1420 : from .foo.bar to the preceding MEM_REF offset and replace the
1421 : address with &OBJ. */
1422 130061318 : addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (op->op0, 0),
1423 : &addr_offset, vn_valueize);
1424 130061318 : gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
1425 130061318 : if (addr_base != TREE_OPERAND (op->op0, 0))
1426 : {
1427 697994 : poly_offset_int off
1428 697994 : = (poly_offset_int::from (wi::to_poly_wide (mem_op->op0),
1429 : SIGNED)
1430 697994 : + addr_offset);
1431 697994 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1432 697994 : op->op0 = build_fold_addr_expr (addr_base);
1433 697994 : if (tree_fits_shwi_p (mem_op->op0))
1434 697927 : mem_op->off = tree_to_shwi (mem_op->op0);
1435 : else
1436 : mem_op->off = -1;
1437 697994 : return true;
1438 : }
1439 : return false;
1440 : }
1441 :
1442 : /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates
1443 : *I_P to point to the last element of the replacement. */
1444 : static bool
1445 88343870 : vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
1446 : unsigned int *i_p)
1447 : {
1448 88343870 : bool changed = false;
1449 95929794 : vn_reference_op_t op;
1450 :
1451 95929794 : do
1452 : {
1453 95929794 : unsigned int i = *i_p;
1454 95929794 : op = &(*ops)[i];
1455 95929794 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1456 95929794 : gimple *def_stmt;
1457 95929794 : enum tree_code code;
1458 95929794 : poly_offset_int off;
1459 :
1460 95929794 : def_stmt = SSA_NAME_DEF_STMT (op->op0);
1461 95929794 : if (!is_gimple_assign (def_stmt))
1462 88341919 : return changed;
1463 :
1464 38989826 : code = gimple_assign_rhs_code (def_stmt);
1465 38989826 : if (code != ADDR_EXPR
1466 38989826 : && code != POINTER_PLUS_EXPR)
1467 : return changed;
1468 :
1469 20624542 : off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);
1470 :
1471 : /* The only thing we have to do is from &OBJ.foo.bar add the offset
1472 : from .foo.bar to the preceding MEM_REF offset and replace the
1473 : address with &OBJ. */
1474 20624542 : if (code == ADDR_EXPR)
1475 : {
1476 958215 : tree addr, addr_base;
1477 958215 : poly_int64 addr_offset;
1478 :
1479 958215 : addr = gimple_assign_rhs1 (def_stmt);
1480 958215 : addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (addr, 0),
1481 : &addr_offset,
1482 : vn_valueize);
1483 : /* If that didn't work because the address isn't invariant propagate
1484 : the reference tree from the address operation in case the current
1485 : dereference isn't offsetted. */
1486 958215 : if (!addr_base
1487 288106 : && *i_p == ops->length () - 1
1488 144053 : && known_eq (off, 0)
1489 : /* This makes us disable this transform for PRE where the
1490 : reference ops might be also used for code insertion which
1491 : is invalid. */
1492 1044348 : && default_vn_walk_kind == VN_WALKREWRITE)
1493 : {
1494 86043 : auto_vec<vn_reference_op_s, 32> tem;
1495 86043 : copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
1496 : /* Make sure to preserve TBAA info. The only objects not
1497 : wrapped in MEM_REFs that can have their address taken are
1498 : STRING_CSTs. */
1499 86043 : if (tem.length () >= 2
1500 86043 : && tem[tem.length () - 2].opcode == MEM_REF)
1501 : {
1502 86028 : vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
1503 86028 : new_mem_op->op0
1504 86028 : = wide_int_to_tree (TREE_TYPE (mem_op->op0),
1505 172056 : wi::to_poly_wide (new_mem_op->op0));
1506 : }
1507 : /* Do not forward addresses of TARGET_MEM_REF. */
1508 15 : else if (tem[0].opcode == TARGET_MEM_REF)
1509 : return changed;
1510 : else
1511 15 : gcc_assert (tem.last ().opcode == STRING_CST);
1512 86043 : ops->pop ();
1513 86043 : ops->pop ();
1514 86043 : ops->safe_splice (tem);
1515 86043 : --*i_p;
1516 86043 : return true;
1517 86043 : }
1518 872172 : if (!addr_base
1519 814162 : || TREE_CODE (addr_base) != MEM_REF
1520 1684498 : || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
1521 810465 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
1522 : 0))))
1523 : return changed;
1524 :
1525 812326 : off += addr_offset;
1526 812326 : off += mem_ref_offset (addr_base);
1527 812326 : op->op0 = TREE_OPERAND (addr_base, 0);
1528 : }
1529 : else
1530 : {
1531 19666327 : tree ptr, ptroff;
1532 19666327 : ptr = gimple_assign_rhs1 (def_stmt);
1533 19666327 : ptroff = gimple_assign_rhs2 (def_stmt);
1534 19666327 : if (TREE_CODE (ptr) != SSA_NAME
1535 17927360 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
1536 : /* Make sure to not endlessly recurse.
1537 : See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily
1538 : happen when we value-number a PHI to its backedge value. */
1539 17925975 : || SSA_VAL (ptr) == op->op0
1540 37592302 : || !poly_int_tree_p (ptroff))
1541 : return changed;
1542 :
1543 6775549 : off += wi::to_poly_offset (ptroff);
1544 6775549 : op->op0 = ptr;
1545 : }
1546 :
1547 7587875 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1548 7587875 : if (tree_fits_shwi_p (mem_op->op0))
1549 7303239 : mem_op->off = tree_to_shwi (mem_op->op0);
1550 : else
1551 : mem_op->off = -1;
1552 : /* ??? Can end up with endless recursion here!?
1553 : gcc.c-torture/execute/strcmp-1.c */
1554 7587875 : if (TREE_CODE (op->op0) == SSA_NAME)
1555 7586014 : op->op0 = SSA_VAL (op->op0);
1556 7587875 : if (TREE_CODE (op->op0) != SSA_NAME)
1557 1951 : op->opcode = TREE_CODE (op->op0);
1558 :
1559 7587875 : changed = true;
1560 : }
1561 : /* Tail-recurse. */
1562 7587875 : while (TREE_CODE (op->op0) == SSA_NAME);
1563 :
1564 : /* Fold a remaining *&. */
1565 1951 : if (TREE_CODE (op->op0) == ADDR_EXPR)
1566 261 : vn_reference_fold_indirect (ops, i_p);
1567 :
1568 : return changed;
1569 : }
1570 :
1571 : /* Optimize the reference REF to a constant if possible or return
1572 : NULL_TREE if not. */
1573 :
1574 : tree
1575 112961156 : fully_constant_vn_reference_p (vn_reference_t ref)
1576 : {
1577 112961156 : vec<vn_reference_op_s> operands = ref->operands;
1578 112961156 : vn_reference_op_t op;
1579 :
1580 : /* Try to simplify the translated expression if it is
1581 : a call to a builtin function with at most two arguments. */
1582 112961156 : op = &operands[0];
1583 112961156 : if (op->opcode == CALL_EXPR
1584 93752 : && (!op->op0
1585 86205 : || (TREE_CODE (op->op0) == ADDR_EXPR
1586 86205 : && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
1587 86205 : && fndecl_built_in_p (TREE_OPERAND (op->op0, 0),
1588 : BUILT_IN_NORMAL)))
1589 75536 : && operands.length () >= 2
1590 113036660 : && operands.length () <= 3)
1591 : {
1592 36544 : vn_reference_op_t arg0, arg1 = NULL;
1593 36544 : bool anyconst = false;
1594 36544 : arg0 = &operands[1];
1595 36544 : if (operands.length () > 2)
1596 5650 : arg1 = &operands[2];
1597 36544 : if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
1598 36544 : || (arg0->opcode == ADDR_EXPR
1599 13838 : && is_gimple_min_invariant (arg0->op0)))
1600 : anyconst = true;
1601 36544 : if (arg1
1602 36544 : && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
1603 4159 : || (arg1->opcode == ADDR_EXPR
1604 587 : && is_gimple_min_invariant (arg1->op0))))
1605 : anyconst = true;
1606 34466 : if (anyconst)
1607 : {
1608 24669 : combined_fn fn;
1609 24669 : if (op->op0)
1610 23714 : fn = as_combined_fn (DECL_FUNCTION_CODE
1611 23714 : (TREE_OPERAND (op->op0, 0)));
1612 : else
1613 955 : fn = as_combined_fn ((internal_fn) op->clique);
1614 24669 : tree folded;
1615 24669 : if (arg1)
1616 2722 : folded = fold_const_call (fn, ref->type, arg0->op0, arg1->op0);
1617 : else
1618 21947 : folded = fold_const_call (fn, ref->type, arg0->op0);
1619 24669 : if (folded
1620 24669 : && is_gimple_min_invariant (folded))
1621 1060 : return folded;
1622 : }
1623 : }
1624 :
1625 : /* Simplify reads from constants or constant initializers. */
1626 112924612 : else if (BITS_PER_UNIT == 8
1627 112924612 : && ref->type
1628 112924612 : && COMPLETE_TYPE_P (ref->type)
1629 225849182 : && is_gimple_reg_type (ref->type))
1630 : {
1631 108496878 : poly_int64 off = 0;
1632 108496878 : HOST_WIDE_INT size;
1633 108496878 : if (INTEGRAL_TYPE_P (ref->type))
1634 55058227 : size = TYPE_PRECISION (ref->type);
1635 53438651 : else if (tree_fits_shwi_p (TYPE_SIZE (ref->type)))
1636 53438651 : size = tree_to_shwi (TYPE_SIZE (ref->type));
1637 : else
1638 : return NULL_TREE;
1639 108496878 : if (size % BITS_PER_UNIT != 0
1640 106633648 : || size > MAX_BITSIZE_MODE_ANY_MODE)
1641 : return NULL_TREE;
1642 106632321 : size /= BITS_PER_UNIT;
1643 106632321 : unsigned i;
1644 197847836 : for (i = 0; i < operands.length (); ++i)
1645 : {
1646 197847836 : if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant)
1647 : {
1648 307 : ++i;
1649 307 : break;
1650 : }
1651 197847529 : if (operands[i].reverse)
1652 : return NULL_TREE;
1653 197839047 : if (known_eq (operands[i].off, -1))
1654 : return NULL_TREE;
1655 183833313 : off += operands[i].off;
1656 183833313 : if (operands[i].opcode == MEM_REF)
1657 : {
1658 92617798 : ++i;
1659 92617798 : break;
1660 : }
1661 : }
1662 92618105 : vn_reference_op_t base = &operands[--i];
1663 92618105 : tree ctor = error_mark_node;
1664 92618105 : tree decl = NULL_TREE;
1665 92618105 : if (TREE_CODE_CLASS (base->opcode) == tcc_constant)
1666 307 : ctor = base->op0;
1667 92617798 : else if (base->opcode == MEM_REF
1668 92617798 : && base[1].opcode == ADDR_EXPR
1669 151941346 : && (VAR_P (TREE_OPERAND (base[1].op0, 0))
1670 3586919 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL
1671 3586859 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST))
1672 : {
1673 55742810 : decl = TREE_OPERAND (base[1].op0, 0);
1674 55742810 : if (TREE_CODE (decl) == STRING_CST)
1675 : ctor = decl;
1676 : else
1677 55736689 : ctor = ctor_for_folding (decl);
1678 : }
1679 92611984 : if (ctor == NULL_TREE)
1680 386 : return build_zero_cst (ref->type);
1681 92617719 : else if (ctor != error_mark_node)
1682 : {
1683 106360 : HOST_WIDE_INT const_off;
1684 106360 : if (decl)
1685 : {
1686 212106 : tree res = fold_ctor_reference (ref->type, ctor,
1687 106053 : off * BITS_PER_UNIT,
1688 106053 : size * BITS_PER_UNIT, decl);
1689 106053 : if (res)
1690 : {
1691 60173 : STRIP_USELESS_TYPE_CONVERSION (res);
1692 60173 : if (is_gimple_min_invariant (res))
1693 60041 : return res;
1694 : }
1695 : }
1696 307 : else if (off.is_constant (&const_off))
1697 : {
1698 307 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
1699 307 : int len = native_encode_expr (ctor, buf, size, const_off);
1700 307 : if (len > 0)
1701 137 : return native_interpret_expr (ref->type, buf, len);
1702 : }
1703 : }
1704 : }
1705 :
1706 : return NULL_TREE;
1707 : }
1708 :
1709 : /* Return true if OPS contain a storage order barrier. */
1710 :
1711 : static bool
1712 61065006 : contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
1713 : {
1714 61065006 : vn_reference_op_t op;
1715 61065006 : unsigned i;
1716 :
1717 239643851 : FOR_EACH_VEC_ELT (ops, i, op)
1718 178578845 : if (op->opcode == VIEW_CONVERT_EXPR && op->reverse)
1719 : return true;
1720 :
1721 : return false;
1722 : }
1723 :
1724 : /* Return true if OPS represent an access with reverse storage order. */
1725 :
1726 : static bool
1727 63131963 : reverse_storage_order_for_component_p (const vec<vn_reference_op_s> &ops)
1728 : {
1729 63131963 : unsigned i = 0;
1730 63131963 : if (ops[i].opcode == REALPART_EXPR || ops[i].opcode == IMAGPART_EXPR)
1731 : ++i;
1732 63131963 : switch (ops[i].opcode)
1733 : {
1734 60457143 : case ARRAY_REF:
1735 60457143 : case COMPONENT_REF:
1736 60457143 : case BIT_FIELD_REF:
1737 60457143 : case MEM_REF:
1738 60457143 : return ops[i].reverse;
1739 : default:
1740 : return false;
1741 : }
1742 : }
1743 :
1744 : /* Transform any SSA_NAME's in a vector of vn_reference_op_s
1745 : structures into their value numbers. This is done in-place, and
1746 : the vector passed in is returned. *VALUEIZED_ANYTHING will specify
1747 : whether any operands were valueized. */
1748 :
1749 : static void
1750 225713062 : valueize_refs_1 (vec<vn_reference_op_s> *orig, bool *valueized_anything,
1751 : bool with_avail = false)
1752 : {
1753 225713062 : *valueized_anything = false;
1754 :
1755 911994712 : for (unsigned i = 0; i < orig->length (); ++i)
1756 : {
1757 686281650 : re_valueize:
1758 690358815 : vn_reference_op_t vro = &(*orig)[i];
1759 690358815 : if (vro->opcode == SSA_NAME
1760 589732795 : || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
1761 : {
1762 125272567 : tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0);
1763 125272567 : if (tem != vro->op0)
1764 : {
1765 18668066 : *valueized_anything = true;
1766 18668066 : vro->op0 = tem;
1767 : }
1768 : /* If it transforms from an SSA_NAME to a constant, update
1769 : the opcode. */
1770 125272567 : if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
1771 2195926 : vro->opcode = TREE_CODE (vro->op0);
1772 : }
1773 690358815 : if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
1774 : {
1775 26273 : tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1);
1776 26273 : if (tem != vro->op1)
1777 : {
1778 585 : *valueized_anything = true;
1779 585 : vro->op1 = tem;
1780 : }
1781 : }
1782 690358815 : if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
1783 : {
1784 205059 : tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2);
1785 205059 : if (tem != vro->op2)
1786 : {
1787 119944 : *valueized_anything = true;
1788 119944 : vro->op2 = tem;
1789 : }
1790 : }
1791 : /* If it transforms from an SSA_NAME to an address, fold with
1792 : a preceding indirect reference. */
1793 690358815 : if (i > 0
1794 464566172 : && vro->op0
1795 461049574 : && TREE_CODE (vro->op0) == ADDR_EXPR
1796 826446739 : && (*orig)[i - 1].opcode == MEM_REF)
1797 : {
1798 130061057 : if (vn_reference_fold_indirect (orig, &i))
1799 697994 : *valueized_anything = true;
1800 : }
1801 560297758 : else if (i > 0
1802 334505115 : && vro->opcode == SSA_NAME
1803 658727852 : && (*orig)[i - 1].opcode == MEM_REF)
1804 : {
1805 88343870 : if (vn_reference_maybe_forwprop_address (orig, &i))
1806 : {
1807 4077165 : *valueized_anything = true;
1808 : /* Re-valueize the current operand. */
1809 4077165 : goto re_valueize;
1810 : }
1811 : }
1812 : /* If it transforms a non-constant ARRAY_REF into a constant
1813 : one, adjust the constant offset. */
1814 471953888 : else if ((vro->opcode == ARRAY_REF
1815 471953888 : || vro->opcode == ARRAY_RANGE_REF)
1816 40140175 : && known_eq (vro->off, -1)
1817 17331078 : && poly_int_tree_p (vro->op0)
1818 5016920 : && poly_int_tree_p (vro->op1)
1819 476970808 : && TREE_CODE (vro->op2) == INTEGER_CST)
1820 : {
1821 : /* Prohibit value-numbering addresses of one-after-the-last
1822 : element ARRAY_REFs the same as addresses of other components
1823 : before the pass folding __builtin_object_size had a chance
1824 : to run. */
1825 4882522 : if (!(cfun->curr_properties & PROP_objsz)
1826 6127878 : && (*orig)[0].opcode == ADDR_EXPR)
1827 : {
1828 36078 : tree dom = TYPE_DOMAIN ((*orig)[i + 1].type);
1829 55011 : if (!dom
1830 35928 : || !TYPE_MAX_VALUE (dom)
1831 25793 : || !poly_int_tree_p (TYPE_MAX_VALUE (dom))
1832 53299 : || integer_minus_onep (TYPE_MAX_VALUE (dom)))
1833 19740 : continue;
1834 17145 : if (!known_le (wi::to_poly_offset (vro->op0),
1835 : wi::to_poly_offset (TYPE_MAX_VALUE (dom))))
1836 807 : continue;
1837 : }
1838 :
1839 9725564 : poly_offset_int off = ((wi::to_poly_offset (vro->op0)
1840 14588346 : - wi::to_poly_offset (vro->op1))
1841 9725564 : * wi::to_offset (vro->op2)
1842 4862782 : * vn_ref_op_align_unit (vro));
1843 4862782 : off.to_shwi (&vro->off);
1844 : }
1845 : }
1846 225713062 : }
1847 :
1848 : static void
1849 13094746 : valueize_refs (vec<vn_reference_op_s> *orig)
1850 : {
1851 13094746 : bool tem;
1852 0 : valueize_refs_1 (orig, &tem);
1853 0 : }
1854 :
1855 : static vec<vn_reference_op_s> shared_lookup_references;
1856 :
1857 : /* Create a vector of vn_reference_op_s structures from REF, a
1858 : REFERENCE_CLASS_P tree. The vector is shared among all callers of
1859 : this function. *VALUEIZED_ANYTHING will specify whether any
1860 : operands were valueized. */
1861 :
1862 : static vec<vn_reference_op_s>
1863 186070153 : valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
1864 : {
1865 186070153 : if (!ref)
1866 0 : return vNULL;
1867 186070153 : shared_lookup_references.truncate (0);
1868 186070153 : copy_reference_ops_from_ref (ref, &shared_lookup_references);
1869 186070153 : valueize_refs_1 (&shared_lookup_references, valueized_anything);
1870 186070153 : return shared_lookup_references;
1871 : }
1872 :
1873 : /* Create a vector of vn_reference_op_s structures from CALL, a
1874 : call statement. The vector is shared among all callers of
1875 : this function. */
1876 :
1877 : static vec<vn_reference_op_s>
1878 9514776 : valueize_shared_reference_ops_from_call (gcall *call)
1879 : {
1880 9514776 : if (!call)
1881 0 : return vNULL;
1882 9514776 : shared_lookup_references.truncate (0);
1883 9514776 : copy_reference_ops_from_call (call, &shared_lookup_references);
1884 9514776 : valueize_refs (&shared_lookup_references);
1885 9514776 : return shared_lookup_references;
1886 : }
1887 :
1888 : /* Lookup a SCCVN reference operation VR in the current hash table.
1889 : Returns the resulting value number if it exists in the hash table,
1890 : NULL_TREE otherwise. VNRESULT will be filled in with the actual
1891 : vn_reference_t stored in the hashtable if something is found. */
1892 :
1893 : static tree
1894 67341894 : vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
1895 : {
1896 67341894 : vn_reference_s **slot;
1897 67341894 : hashval_t hash;
1898 :
1899 67341894 : hash = vr->hashcode;
1900 67341894 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
1901 67341894 : if (slot)
1902 : {
1903 8466627 : if (vnresult)
1904 8466627 : *vnresult = (vn_reference_t)*slot;
1905 8466627 : return ((vn_reference_t)*slot)->result;
1906 : }
1907 :
1908 : return NULL_TREE;
1909 : }
1910 :
1911 :
1912 : /* Partial definition tracking support. */
1913 :
1914 : struct pd_range
1915 : {
1916 : HOST_WIDE_INT offset;
1917 : HOST_WIDE_INT size;
1918 : pd_range *m_children[2];
1919 : };
1920 :
1921 : struct pd_data
1922 : {
1923 : tree rhs;
1924 : HOST_WIDE_INT rhs_off;
1925 : HOST_WIDE_INT offset;
1926 : HOST_WIDE_INT size;
1927 : };
1928 :
1929 : /* Context for alias walking. */
1930 :
1931 : struct vn_walk_cb_data
1932 : {
1933 63122001 : vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
1934 : vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_,
1935 : bool redundant_store_removal_p_)
1936 63122001 : : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
1937 63122001 : mask (mask_), masked_result (NULL_TREE), same_val (NULL_TREE),
1938 63122001 : vn_walk_kind (vn_walk_kind_),
1939 63122001 : tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_),
1940 126244002 : saved_operands (vNULL), first_range (), first_set (-2),
1941 126244002 : first_base_set (-2)
1942 : {
1943 63122001 : if (!last_vuse_ptr)
1944 29195513 : last_vuse_ptr = &last_vuse;
1945 63122001 : ao_ref_init (&orig_ref, orig_ref_);
1946 63122001 : if (mask)
1947 : {
1948 318386 : wide_int w = wi::to_wide (mask);
1949 318386 : unsigned int pos = 0, prec = w.get_precision ();
1950 318386 : pd_data pd;
1951 318386 : pd.rhs = build_constructor (NULL_TREE, NULL);
1952 318386 : pd.rhs_off = 0;
1953 : /* When bitwise and with a constant is done on a memory load,
1954 : we don't really need all the bits to be defined or defined
1955 : to constants, we don't really care what is in the position
1956 : corresponding to 0 bits in the mask.
1957 : So, push the ranges of those 0 bits in the mask as artificial
1958 : zero stores and let the partial def handling code do the
1959 : rest. */
1960 682118 : while (pos < prec)
1961 : {
1962 660725 : int tz = wi::ctz (w);
1963 660725 : if (pos + tz > prec)
1964 296993 : tz = prec - pos;
1965 660725 : if (tz)
1966 : {
1967 505080 : if (BYTES_BIG_ENDIAN)
1968 : pd.offset = prec - pos - tz;
1969 : else
1970 505080 : pd.offset = pos;
1971 505080 : pd.size = tz;
1972 505080 : void *r = push_partial_def (pd, 0, 0, 0, prec);
1973 505080 : gcc_assert (r == NULL_TREE);
1974 : }
1975 660725 : pos += tz;
1976 660725 : if (pos == prec)
1977 : break;
1978 363732 : w = wi::lrshift (w, tz);
1979 363732 : tz = wi::ctz (wi::bit_not (w));
1980 363732 : if (pos + tz > prec)
1981 0 : tz = prec - pos;
1982 363732 : pos += tz;
1983 363732 : w = wi::lrshift (w, tz);
1984 : }
1985 318386 : }
1986 63122001 : }
1987 : ~vn_walk_cb_data ();
1988 : void *finish (alias_set_type, alias_set_type, tree);
1989 : void *push_partial_def (pd_data pd,
1990 : alias_set_type, alias_set_type, HOST_WIDE_INT,
1991 : HOST_WIDE_INT);
1992 :
1993 : vn_reference_t vr;
1994 : ao_ref orig_ref;
1995 : tree *last_vuse_ptr;
1996 : tree last_vuse;
1997 : tree mask;
1998 : tree masked_result;
1999 : tree same_val;
2000 : vn_lookup_kind vn_walk_kind;
2001 : bool tbaa_p;
2002 : bool redundant_store_removal_p;
2003 : vec<vn_reference_op_s> saved_operands;
2004 :
2005 : /* The VDEFs of partial defs we come along. */
2006 : auto_vec<pd_data, 2> partial_defs;
2007 : /* The first defs range to avoid splay tree setup in most cases. */
2008 : pd_range first_range;
2009 : alias_set_type first_set;
2010 : alias_set_type first_base_set;
2011 : default_splay_tree<pd_range *> known_ranges;
2012 : obstack ranges_obstack;
2013 : static constexpr HOST_WIDE_INT bufsize = 64;
2014 : };
2015 :
2016 63122001 : vn_walk_cb_data::~vn_walk_cb_data ()
2017 : {
2018 63122001 : if (known_ranges)
2019 181417 : obstack_free (&ranges_obstack, NULL);
2020 63122001 : saved_operands.release ();
2021 63122001 : }
2022 :
2023 : void *
2024 1644591 : vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
2025 : {
2026 1644591 : if (first_set != -2)
2027 : {
2028 494308 : set = first_set;
2029 494308 : base_set = first_base_set;
2030 : }
2031 1644591 : if (mask)
2032 : {
2033 457 : masked_result = val;
2034 457 : return (void *) -1;
2035 : }
2036 1644134 : if (same_val && !operand_equal_p (val, same_val))
2037 : return (void *) -1;
2038 1640010 : vec<vn_reference_op_s> &operands
2039 1640010 : = saved_operands.exists () ? saved_operands : vr->operands;
2040 1640010 : return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
2041 : vr->offset, vr->max_size,
2042 1640010 : vr->type, operands, val);
2043 : }
2044 :
2045 : /* Push PD to the vector of partial definitions returning a
2046 : value when we are ready to combine things with VUSE, SET and MAXSIZEI,
2047 : NULL when we want to continue looking for partial defs or -1
2048 : on failure. */
2049 :
2050 : void *
2051 590899 : vn_walk_cb_data::push_partial_def (pd_data pd,
2052 : alias_set_type set, alias_set_type base_set,
2053 : HOST_WIDE_INT offseti,
2054 : HOST_WIDE_INT maxsizei)
2055 : {
2056 : /* We're using a fixed buffer for encoding so fail early if the object
2057 : we want to interpret is bigger. */
2058 590899 : if (maxsizei > bufsize * BITS_PER_UNIT
2059 : || CHAR_BIT != 8
2060 : || BITS_PER_UNIT != 8
2061 : /* Not prepared to handle PDP endian. */
2062 : || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2063 : return (void *)-1;
2064 :
2065 : /* Turn too large constant stores into non-constant stores. */
2066 590824 : if (CONSTANT_CLASS_P (pd.rhs) && pd.size > bufsize * BITS_PER_UNIT)
2067 0 : pd.rhs = error_mark_node;
2068 :
2069 : /* And for non-constant or CONSTRUCTOR stores shrink them to only keep at
2070 : most a partial byte before and/or after the region. */
2071 590824 : if (!CONSTANT_CLASS_P (pd.rhs))
2072 : {
2073 548984 : if (pd.offset < offseti)
2074 : {
2075 8468 : HOST_WIDE_INT o = ROUND_DOWN (offseti - pd.offset, BITS_PER_UNIT);
2076 8468 : gcc_assert (pd.size > o);
2077 8468 : pd.size -= o;
2078 8468 : pd.offset += o;
2079 : }
2080 548984 : if (pd.size + pd.offset > offseti + maxsizei)
2081 7703 : pd.size = maxsizei + ((pd.size + pd.offset - (offseti + maxsizei))
2082 7703 : % BITS_PER_UNIT);
2083 : }
2084 :
2085 590824 : pd.offset -= offseti;
2086 :
2087 1181648 : bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
2088 590824 : || CONSTANT_CLASS_P (pd.rhs));
2089 590824 : pd_range *r;
2090 590824 : if (partial_defs.is_empty ())
2091 : {
2092 : /* If we get a clobber upfront, fail. */
2093 376588 : if (TREE_CLOBBER_P (pd.rhs))
2094 : return (void *)-1;
2095 376228 : if (!pd_constant_p)
2096 : return (void *)-1;
2097 343401 : partial_defs.safe_push (pd);
2098 343401 : first_range.offset = pd.offset;
2099 343401 : first_range.size = pd.size;
2100 343401 : first_set = set;
2101 343401 : first_base_set = base_set;
2102 343401 : last_vuse_ptr = NULL;
2103 343401 : r = &first_range;
2104 : /* Go check if the first partial definition was a full one in case
2105 : the caller didn't optimize for this. */
2106 : }
2107 : else
2108 : {
2109 214236 : if (!known_ranges)
2110 : {
2111 : /* ??? Optimize the case where the 2nd partial def completes
2112 : things. */
2113 181417 : gcc_obstack_init (&ranges_obstack);
2114 181417 : known_ranges.insert_max_node (&first_range);
2115 : }
2116 : /* Lookup the offset and see if we need to merge. */
2117 214236 : int comparison = known_ranges.lookup_le
2118 432778 : ([&] (pd_range *r) { return pd.offset < r->offset; },
2119 193043 : [&] (pd_range *r) { return pd.offset > r->offset; });
2120 214236 : r = known_ranges.root ();
2121 214236 : if (comparison >= 0
2122 214236 : && ranges_known_overlap_p (r->offset, r->size + 1,
2123 : pd.offset, pd.size))
2124 : {
2125 : /* Ignore partial defs already covered. Here we also drop shadowed
2126 : clobbers arriving here at the floor. */
2127 5929 : if (known_subrange_p (pd.offset, pd.size, r->offset, r->size))
2128 : return NULL;
2129 5012 : r->size = MAX (r->offset + r->size, pd.offset + pd.size) - r->offset;
2130 : }
2131 : else
2132 : {
2133 : /* pd.offset wasn't covered yet, insert the range. */
2134 208307 : void *addr = XOBNEW (&ranges_obstack, pd_range);
2135 208307 : r = new (addr) pd_range { pd.offset, pd.size, {} };
2136 208307 : known_ranges.insert_relative (comparison, r);
2137 : }
2138 : /* Merge r which now contains pd's range and is a member of the splay
2139 : tree with adjacent overlapping ranges. */
2140 213319 : if (known_ranges.splay_next_node ())
2141 23308 : do
2142 : {
2143 23308 : pd_range *rafter = known_ranges.root ();
2144 23308 : if (!ranges_known_overlap_p (r->offset, r->size + 1,
2145 23308 : rafter->offset, rafter->size))
2146 : break;
2147 23036 : r->size = MAX (r->offset + r->size,
2148 23036 : rafter->offset + rafter->size) - r->offset;
2149 : }
2150 23036 : while (known_ranges.remove_root_and_splay_next ());
2151 : /* If we get a clobber, fail. */
2152 213319 : if (TREE_CLOBBER_P (pd.rhs))
2153 : return (void *)-1;
2154 : /* Non-constants are OK as long as they are shadowed by a constant. */
2155 211237 : if (!pd_constant_p)
2156 : return (void *)-1;
2157 204759 : partial_defs.safe_push (pd);
2158 : }
2159 :
2160 : /* Now we have merged pd's range into the range tree. When we have covered
2161 : [offseti, sizei] then the tree will contain exactly one node which has
2162 : the desired properties and it will be 'r'. */
2163 548160 : if (!known_subrange_p (0, maxsizei, r->offset, r->size))
2164 : /* Continue looking for partial defs. */
2165 : return NULL;
2166 :
2167 : /* Now simply native encode all partial defs in reverse order. */
2168 9251 : unsigned ndefs = partial_defs.length ();
2169 : /* We support up to 512-bit values (for V8DFmode). */
2170 9251 : unsigned char buffer[bufsize + 1];
2171 9251 : unsigned char this_buffer[bufsize + 1];
2172 9251 : int len;
2173 :
2174 9251 : memset (buffer, 0, bufsize + 1);
2175 9251 : unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
2176 36086 : while (!partial_defs.is_empty ())
2177 : {
2178 26835 : pd_data pd = partial_defs.pop ();
2179 26835 : unsigned int amnt;
2180 26835 : if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
2181 : {
2182 : /* Empty CONSTRUCTOR. */
2183 2296 : if (pd.size >= needed_len * BITS_PER_UNIT)
2184 2296 : len = needed_len;
2185 : else
2186 1843 : len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
2187 2296 : memset (this_buffer, 0, len);
2188 : }
2189 24539 : else if (pd.rhs_off >= 0)
2190 : {
2191 49078 : len = native_encode_expr (pd.rhs, this_buffer, bufsize,
2192 24539 : (MAX (0, -pd.offset)
2193 24539 : + pd.rhs_off) / BITS_PER_UNIT);
2194 24539 : if (len <= 0
2195 24539 : || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
2196 24539 : - MAX (0, -pd.offset) / BITS_PER_UNIT))
2197 : {
2198 0 : if (dump_file && (dump_flags & TDF_DETAILS))
2199 0 : fprintf (dump_file, "Failed to encode %u "
2200 : "partial definitions\n", ndefs);
2201 590899 : return (void *)-1;
2202 : }
2203 : }
2204 : else /* negative pd.rhs_off indicates we want to chop off first bits */
2205 : {
2206 0 : if (-pd.rhs_off >= bufsize)
2207 : return (void *)-1;
2208 0 : len = native_encode_expr (pd.rhs,
2209 0 : this_buffer + -pd.rhs_off / BITS_PER_UNIT,
2210 0 : bufsize - -pd.rhs_off / BITS_PER_UNIT,
2211 0 : MAX (0, -pd.offset) / BITS_PER_UNIT);
2212 0 : if (len <= 0
2213 0 : || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
2214 0 : - MAX (0, -pd.offset) / BITS_PER_UNIT))
2215 : {
2216 0 : if (dump_file && (dump_flags & TDF_DETAILS))
2217 0 : fprintf (dump_file, "Failed to encode %u "
2218 : "partial definitions\n", ndefs);
2219 : return (void *)-1;
2220 : }
2221 : }
2222 :
2223 26835 : unsigned char *p = buffer;
2224 26835 : HOST_WIDE_INT size = pd.size;
2225 26835 : if (pd.offset < 0)
2226 354 : size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
2227 26835 : this_buffer[len] = 0;
2228 26835 : if (BYTES_BIG_ENDIAN)
2229 : {
2230 : /* LSB of this_buffer[len - 1] byte should be at
2231 : pd.offset + pd.size - 1 bits in buffer. */
2232 : amnt = ((unsigned HOST_WIDE_INT) pd.offset
2233 : + pd.size) % BITS_PER_UNIT;
2234 : if (amnt)
2235 : shift_bytes_in_array_right (this_buffer, len + 1, amnt);
2236 : unsigned char *q = this_buffer;
2237 : unsigned int off = 0;
2238 : if (pd.offset >= 0)
2239 : {
2240 : unsigned int msk;
2241 : off = pd.offset / BITS_PER_UNIT;
2242 : gcc_assert (off < needed_len);
2243 : p = buffer + off;
2244 : if (size <= amnt)
2245 : {
2246 : msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
2247 : *p = (*p & ~msk) | (this_buffer[len] & msk);
2248 : size = 0;
2249 : }
2250 : else
2251 : {
2252 : if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2253 : q = (this_buffer + len
2254 : - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2255 : / BITS_PER_UNIT));
2256 : if (pd.offset % BITS_PER_UNIT)
2257 : {
2258 : msk = -1U << (BITS_PER_UNIT
2259 : - (pd.offset % BITS_PER_UNIT));
2260 : *p = (*p & msk) | (*q & ~msk);
2261 : p++;
2262 : q++;
2263 : off++;
2264 : size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
2265 : gcc_assert (size >= 0);
2266 : }
2267 : }
2268 : }
2269 : else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2270 : {
2271 : q = (this_buffer + len
2272 : - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2273 : / BITS_PER_UNIT));
2274 : if (pd.offset % BITS_PER_UNIT)
2275 : {
2276 : q++;
2277 : size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
2278 : % BITS_PER_UNIT);
2279 : gcc_assert (size >= 0);
2280 : }
2281 : }
2282 : if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
2283 : > needed_len)
2284 : size = (needed_len - off) * BITS_PER_UNIT;
2285 : memcpy (p, q, size / BITS_PER_UNIT);
2286 : if (size % BITS_PER_UNIT)
2287 : {
2288 : unsigned int msk
2289 : = -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
2290 : p += size / BITS_PER_UNIT;
2291 : q += size / BITS_PER_UNIT;
2292 : *p = (*q & msk) | (*p & ~msk);
2293 : }
2294 : }
2295 : else
2296 : {
2297 26835 : if (pd.offset >= 0)
2298 : {
2299 : /* LSB of this_buffer[0] byte should be at pd.offset bits
2300 : in buffer. */
2301 26481 : unsigned int msk;
2302 26481 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2303 26481 : amnt = pd.offset % BITS_PER_UNIT;
2304 26481 : if (amnt)
2305 1529 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2306 26481 : unsigned int off = pd.offset / BITS_PER_UNIT;
2307 26481 : gcc_assert (off < needed_len);
2308 26481 : size = MIN (size,
2309 : (HOST_WIDE_INT) (needed_len - off) * BITS_PER_UNIT);
2310 26481 : p = buffer + off;
2311 26481 : if (amnt + size < BITS_PER_UNIT)
2312 : {
2313 : /* Low amnt bits come from *p, then size bits
2314 : from this_buffer[0] and the remaining again from
2315 : *p. */
2316 1169 : msk = ((1 << size) - 1) << amnt;
2317 1169 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2318 1169 : size = 0;
2319 : }
2320 25312 : else if (amnt)
2321 : {
2322 1153 : msk = -1U << amnt;
2323 1153 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2324 1153 : p++;
2325 1153 : size -= (BITS_PER_UNIT - amnt);
2326 : }
2327 : }
2328 : else
2329 : {
2330 354 : amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
2331 354 : if (amnt)
2332 45 : size -= BITS_PER_UNIT - amnt;
2333 354 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2334 354 : if (amnt)
2335 45 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2336 : }
2337 26835 : memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
2338 26835 : p += size / BITS_PER_UNIT;
2339 26835 : if (size % BITS_PER_UNIT)
2340 : {
2341 648 : unsigned int msk = -1U << (size % BITS_PER_UNIT);
2342 648 : *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
2343 648 : & ~msk) | (*p & msk);
2344 : }
2345 : }
2346 : }
2347 :
2348 9251 : tree type = vr->type;
2349 : /* Make sure to interpret in a type that has a range covering the whole
2350 : access size. */
2351 9251 : if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
2352 : {
2353 0 : if (BITINT_TYPE_P (vr->type)
2354 26 : && maxsizei > MAX_FIXED_MODE_SIZE)
2355 13 : type = build_bitint_type (maxsizei, TYPE_UNSIGNED (type));
2356 : else
2357 0 : type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
2358 : }
2359 9251 : tree val;
2360 9251 : if (BYTES_BIG_ENDIAN)
2361 : {
2362 : unsigned sz = needed_len;
2363 : if (maxsizei % BITS_PER_UNIT)
2364 : shift_bytes_in_array_right (buffer, needed_len,
2365 : BITS_PER_UNIT
2366 : - (maxsizei % BITS_PER_UNIT));
2367 : if (INTEGRAL_TYPE_P (type))
2368 : {
2369 : if (TYPE_MODE (type) != BLKmode)
2370 : sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
2371 : else
2372 : sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
2373 : }
2374 : if (sz > needed_len)
2375 : {
2376 : memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
2377 : val = native_interpret_expr (type, this_buffer, sz);
2378 : }
2379 : else
2380 : val = native_interpret_expr (type, buffer, needed_len);
2381 : }
2382 : else
2383 9251 : val = native_interpret_expr (type, buffer, bufsize);
2384 : /* If we chop off bits because the types precision doesn't match the memory
2385 : access size this is ok when optimizing reads but not when called from
2386 : the DSE code during elimination. */
2387 9251 : if (val && type != vr->type)
2388 : {
2389 13 : if (! int_fits_type_p (val, vr->type))
2390 : val = NULL_TREE;
2391 : else
2392 13 : val = fold_convert (vr->type, val);
2393 : }
2394 :
2395 9247 : if (val)
2396 : {
2397 9247 : if (dump_file && (dump_flags & TDF_DETAILS))
2398 0 : fprintf (dump_file,
2399 : "Successfully combined %u partial definitions\n", ndefs);
2400 : /* We are using the alias-set of the first store we encounter which
2401 : should be appropriate here. */
2402 9247 : return finish (first_set, first_base_set, val);
2403 : }
2404 : else
2405 : {
2406 4 : if (dump_file && (dump_flags & TDF_DETAILS))
2407 0 : fprintf (dump_file,
2408 : "Failed to interpret %u encoded partial definitions\n", ndefs);
2409 : return (void *)-1;
2410 : }
2411 : }
2412 :
2413 : /* Callback for walk_non_aliased_vuses. Adjusts the vn_reference_t VR_
2414 : with the current VUSE and performs the expression lookup. */
2415 :
2416 : static void *
2417 1104818843 : vn_reference_lookup_2 (ao_ref *op, tree vuse, void *data_)
2418 : {
2419 1104818843 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2420 1104818843 : vn_reference_t vr = data->vr;
2421 1104818843 : vn_reference_s **slot;
2422 1104818843 : hashval_t hash;
2423 :
2424 : /* If we have partial definitions recorded we have to go through
2425 : vn_reference_lookup_3. */
2426 1104818843 : if (!data->partial_defs.is_empty ())
2427 : return NULL;
2428 :
2429 1103991179 : if (data->last_vuse_ptr)
2430 : {
2431 1079680016 : *data->last_vuse_ptr = vuse;
2432 1079680016 : data->last_vuse = vuse;
2433 : }
2434 :
2435 : /* Fixup vuse and hash. */
2436 1103991179 : if (vr->vuse)
2437 1103991179 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2438 1103991179 : vr->vuse = vuse_ssa_val (vuse);
2439 1103991179 : if (vr->vuse)
2440 1103991179 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2441 :
2442 1103991179 : hash = vr->hashcode;
2443 1103991179 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
2444 1103991179 : if (slot)
2445 : {
2446 8174244 : if ((*slot)->result && data->saved_operands.exists ())
2447 478567 : return data->finish (vr->set, vr->base_set, (*slot)->result);
2448 : return *slot;
2449 : }
2450 :
2451 1095816935 : if (SSA_NAME_IS_DEFAULT_DEF (vuse))
2452 : {
2453 18622850 : HOST_WIDE_INT op_offset, op_size;
2454 18622850 : tree v = NULL_TREE;
2455 18622850 : tree base = ao_ref_base (op);
2456 :
2457 18622850 : if (base
2458 18622850 : && op->offset.is_constant (&op_offset)
2459 18622850 : && op->size.is_constant (&op_size)
2460 18622850 : && op->max_size_known_p ()
2461 36773582 : && known_eq (op->size, op->max_size))
2462 : {
2463 17834113 : if (TREE_CODE (base) == PARM_DECL)
2464 672702 : v = ipcp_get_aggregate_const (cfun, base, false, op_offset,
2465 : op_size);
2466 17161411 : else if (TREE_CODE (base) == MEM_REF
2467 7172712 : && integer_zerop (TREE_OPERAND (base, 1))
2468 5767997 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
2469 5762790 : && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0))
2470 21001995 : && (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (base, 0)))
2471 : == PARM_DECL))
2472 3785806 : v = ipcp_get_aggregate_const (cfun,
2473 3785806 : SSA_NAME_VAR (TREE_OPERAND (base, 0)),
2474 : true, op_offset, op_size);
2475 : }
2476 4458508 : if (v)
2477 1180 : return data->finish (vr->set, vr->base_set, v);
2478 : }
2479 :
2480 : return NULL;
2481 : }
2482 :
2483 : /* Lookup an existing or insert a new vn_reference entry into the
2484 : value table for the VUSE, SET, TYPE, OPERANDS reference which
2485 : has the value VALUE which is either a constant or an SSA name. */
2486 :
2487 : static vn_reference_t
2488 1640010 : vn_reference_lookup_or_insert_for_pieces (tree vuse,
2489 : alias_set_type set,
2490 : alias_set_type base_set,
2491 : poly_int64 offset,
2492 : poly_int64 max_size,
2493 : tree type,
2494 : vec<vn_reference_op_s,
2495 : va_heap> operands,
2496 : tree value)
2497 : {
2498 1640010 : vn_reference_s vr1;
2499 1640010 : vn_reference_t result;
2500 1640010 : unsigned value_id;
2501 1640010 : vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
2502 1640010 : vr1.operands = operands;
2503 1640010 : vr1.type = type;
2504 1640010 : vr1.set = set;
2505 1640010 : vr1.base_set = base_set;
2506 1640010 : vr1.offset = offset;
2507 1640010 : vr1.max_size = max_size;
2508 1640010 : vr1.hashcode = vn_reference_compute_hash (&vr1);
2509 1640010 : if (vn_reference_lookup_1 (&vr1, &result))
2510 14780 : return result;
2511 :
2512 1625230 : if (TREE_CODE (value) == SSA_NAME)
2513 390769 : value_id = VN_INFO (value)->value_id;
2514 : else
2515 1234461 : value_id = get_or_alloc_constant_value_id (value);
2516 1625230 : return vn_reference_insert_pieces (vuse, set, base_set, offset, max_size,
2517 1625230 : type, operands.copy (), value, value_id);
2518 : }
2519 :
2520 : /* Return a value-number for RCODE OPS... either by looking up an existing
2521 : value-number for the possibly simplified result or by inserting the
2522 : operation if INSERT is true. If SIMPLIFY is false, return a value
2523 : number for the unsimplified expression. */
2524 :
2525 : static tree
2526 19036990 : vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
2527 : bool simplify)
2528 : {
2529 19036990 : tree result = NULL_TREE;
2530 : /* We will be creating a value number for
2531 : RCODE (OPS...).
2532 : So first simplify and lookup this expression to see if it
2533 : is already available. */
2534 : /* For simplification valueize. */
2535 19036990 : unsigned i = 0;
2536 19036990 : if (simplify)
2537 44171883 : for (i = 0; i < res_op->num_ops; ++i)
2538 25142278 : if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
2539 : {
2540 16114565 : tree tem = vn_valueize (res_op->ops[i]);
2541 16114565 : if (!tem)
2542 : break;
2543 16114565 : res_op->ops[i] = tem;
2544 : }
2545 : /* If valueization of an operand fails (it is not available), skip
2546 : simplification. */
2547 19036990 : bool res = false;
2548 19036990 : if (i == res_op->num_ops)
2549 : {
2550 : /* Do not leak not available operands into the simplified expression
2551 : when called from PRE context. */
2552 19029605 : if (rpo_avail)
2553 11403976 : mprts_hook = vn_lookup_simplify_result;
2554 19029605 : res = res_op->resimplify (NULL, vn_valueize);
2555 19029605 : mprts_hook = NULL;
2556 : }
2557 32793910 : gimple *new_stmt = NULL;
2558 19029605 : if (res
2559 19029605 : && gimple_simplified_result_is_gimple_val (res_op))
2560 : {
2561 : /* The expression is already available. */
2562 5272685 : result = res_op->ops[0];
2563 : /* Valueize it, simplification returns sth in AVAIL only. */
2564 5272685 : if (TREE_CODE (result) == SSA_NAME)
2565 295743 : result = SSA_VAL (result);
2566 : }
2567 : else
2568 : {
2569 13764305 : tree val = vn_lookup_simplify_result (res_op);
2570 : /* ??? In weird cases we can end up with internal-fn calls,
2571 : but this isn't expected so throw the result away. See
2572 : PR123040 for an example. Likewise we can end up with
2573 : &MEM[ptr_1 + CST] which would be a vn_reference (PR127000). */
2574 13764305 : if (!val
2575 13764305 : && insert
2576 149178 : && res_op->code.is_tree_code ()
2577 13913483 : && (tree_code) res_op->code != ADDR_EXPR)
2578 : {
2579 149178 : gimple_seq stmts = NULL;
2580 149178 : result = maybe_push_res_to_seq (res_op, &stmts);
2581 149178 : if (result)
2582 : {
2583 149172 : gcc_assert (gimple_seq_singleton_p (stmts));
2584 149172 : new_stmt = gimple_seq_first_stmt (stmts);
2585 : }
2586 : }
2587 : else
2588 : /* The expression is already available. */
2589 : result = val;
2590 : }
2591 295749 : if (new_stmt)
2592 : {
2593 : /* The expression is not yet available, value-number lhs to
2594 : the new SSA_NAME we created. */
2595 : /* Initialize value-number information properly. */
2596 149172 : vn_ssa_aux_t result_info = VN_INFO (result);
2597 149172 : result_info->valnum = result;
2598 149172 : result_info->value_id = get_next_value_id ();
2599 149172 : result_info->visited = 1;
2600 149172 : gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
2601 : new_stmt);
2602 149172 : result_info->needs_insertion = true;
2603 : /* ??? PRE phi-translation inserts NARYs without corresponding
2604 : SSA name result. Re-use those but set their result according
2605 : to the stmt we just built. */
2606 149172 : vn_nary_op_t nary = NULL;
2607 149172 : vn_nary_op_lookup_stmt (new_stmt, &nary);
2608 149172 : if (nary)
2609 : {
2610 0 : gcc_assert (! nary->predicated_values && nary->u.result == NULL_TREE);
2611 0 : nary->u.result = gimple_assign_lhs (new_stmt);
2612 : }
2613 : /* As all "inserted" statements are singleton SCCs, insert
2614 : to the valid table. This is strictly needed to
2615 : avoid re-generating new value SSA_NAMEs for the same
2616 : expression during SCC iteration over and over (the
2617 : optimistic table gets cleared after each iteration).
2618 : We do not need to insert into the optimistic table, as
2619 : lookups there will fall back to the valid table. */
2620 : else
2621 : {
2622 149172 : unsigned int length = vn_nary_length_from_stmt (new_stmt);
2623 149172 : vn_nary_op_t vno1
2624 149172 : = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack);
2625 149172 : vno1->value_id = result_info->value_id;
2626 149172 : vno1->length = length;
2627 149172 : vno1->predicated_values = 0;
2628 149172 : vno1->u.result = result;
2629 149172 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (new_stmt));
2630 149172 : vn_nary_op_insert_into (vno1, valid_info->nary);
2631 : /* Also do not link it into the undo chain. */
2632 149172 : last_inserted_nary = vno1->next;
2633 149172 : vno1->next = (vn_nary_op_t)(void *)-1;
2634 : }
2635 149172 : if (dump_file && (dump_flags & TDF_DETAILS))
2636 : {
2637 595 : fprintf (dump_file, "Inserting name ");
2638 595 : print_generic_expr (dump_file, result);
2639 595 : fprintf (dump_file, " for expression ");
2640 595 : print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
2641 595 : fprintf (dump_file, "\n");
2642 : }
2643 : }
2644 19036990 : return result;
2645 : }
2646 :
2647 : /* Return a value-number for RCODE OPS... either by looking up an existing
2648 : value-number for the simplified result or by inserting the operation. */
2649 :
2650 : static tree
2651 195203 : vn_nary_build_or_lookup (gimple_match_op *res_op)
2652 : {
2653 0 : return vn_nary_build_or_lookup_1 (res_op, true, true);
2654 : }
2655 :
2656 : /* Try to simplify the expression RCODE OPS... of type TYPE and return
2657 : its value if present. Update NARY with a simplified expression if
2658 : it fits. */
2659 :
2660 : tree
2661 7622371 : vn_nary_simplify (vn_nary_op_t nary)
2662 : {
2663 7622371 : if (nary->length > gimple_match_op::MAX_NUM_OPS
2664 : /* For CONSTRUCTOR the vn_nary_op_t and gimple_match_op representation
2665 : does not match. */
2666 7621825 : || nary->opcode == CONSTRUCTOR)
2667 : return NULL_TREE;
2668 7619332 : gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
2669 7619332 : nary->type, nary->length);
2670 7619332 : memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
2671 7619332 : tree res = vn_nary_build_or_lookup_1 (&op, false, true);
2672 : /* Do not update *NARY with a simplified result that contains abnormals.
2673 : This matches what maybe_push_res_to_seq does when requesting insertion. */
2674 27605896 : for (unsigned i = 0; i < op.num_ops; ++i)
2675 12367314 : if (TREE_CODE (op.ops[i]) == SSA_NAME
2676 12367314 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op.ops[i]))
2677 : return res;
2678 7619250 : if (op.code.is_tree_code ()
2679 7619250 : && op.num_ops <= nary->length
2680 15237669 : && (tree_code) op.code != CONSTRUCTOR)
2681 : {
2682 7618418 : nary->opcode = (tree_code) op.code;
2683 7618418 : nary->length = op.num_ops;
2684 19983944 : for (unsigned i = 0; i < op.num_ops; ++i)
2685 12365526 : nary->op[i] = op.ops[i];
2686 : }
2687 : return res;
2688 : }
2689 :
2690 : /* Elimination engine. */
2691 :
2692 : class eliminate_dom_walker : public dom_walker
2693 : {
2694 : public:
2695 : eliminate_dom_walker (cdi_direction, bitmap);
2696 : virtual ~eliminate_dom_walker ();
2697 :
2698 : edge before_dom_children (basic_block) final override;
2699 : void after_dom_children (basic_block) final override;
2700 :
2701 : virtual tree eliminate_avail (basic_block, tree op);
2702 : virtual void eliminate_push_avail (basic_block, tree op);
2703 : tree eliminate_insert (basic_block, gimple_stmt_iterator *gsi, tree val);
2704 :
2705 : void eliminate_stmt (basic_block, gimple_stmt_iterator *);
2706 :
2707 : unsigned eliminate_cleanup (bool region_p = false);
2708 :
2709 : bool do_pre;
2710 : unsigned int el_todo;
2711 : unsigned int eliminations;
2712 : unsigned int insertions;
2713 :
2714 : /* SSA names that had their defs inserted by PRE if do_pre. */
2715 : bitmap inserted_exprs;
2716 :
2717 : /* Blocks with statements that have had their EH properties changed. */
2718 : bitmap need_eh_cleanup;
2719 :
2720 : /* Blocks with statements that have had their AB properties changed. */
2721 : bitmap need_ab_cleanup;
2722 :
2723 : /* Local state for the eliminate domwalk. */
2724 : auto_vec<gimple *> to_remove;
2725 : auto_vec<gimple *> to_fixup;
2726 : auto_vec<tree> avail;
2727 : auto_vec<tree> avail_stack;
2728 : };
2729 :
2730 : /* Adaptor to the elimination engine using RPO availability. */
2731 :
2732 : class rpo_elim : public eliminate_dom_walker
2733 : {
2734 : public:
2735 6366283 : rpo_elim(basic_block entry_)
2736 6366283 : : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
2737 12732566 : m_avail_freelist (NULL) {}
2738 :
2739 : tree eliminate_avail (basic_block, tree op) final override;
2740 :
2741 : void eliminate_push_avail (basic_block, tree) final override;
2742 :
2743 : basic_block entry;
2744 : /* Freelist of avail entries which are allocated from the vn_ssa_aux
2745 : obstack. */
2746 : vn_avail *m_avail_freelist;
2747 : };
2748 :
2749 : /* Return true if BASE1 and BASE2 can be adjusted so they have the
2750 : same address and adjust *OFFSET1 and *OFFSET2 accordingly.
2751 : Otherwise return false. */
2752 :
2753 : static bool
2754 7099041 : adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
2755 : tree base2, poly_int64 *offset2)
2756 : {
2757 7099041 : poly_int64 soff;
2758 7099041 : if (TREE_CODE (base1) == MEM_REF
2759 3245713 : && TREE_CODE (base2) == MEM_REF)
2760 : {
2761 2608319 : if (mem_ref_offset (base1).to_shwi (&soff))
2762 : {
2763 2608319 : base1 = TREE_OPERAND (base1, 0);
2764 2608319 : *offset1 += soff * BITS_PER_UNIT;
2765 : }
2766 2608319 : if (mem_ref_offset (base2).to_shwi (&soff))
2767 : {
2768 2608319 : base2 = TREE_OPERAND (base2, 0);
2769 2608319 : *offset2 += soff * BITS_PER_UNIT;
2770 : }
2771 2608319 : return operand_equal_p (base1, base2, 0);
2772 : }
2773 4490722 : return operand_equal_p (base1, base2, OEP_ADDRESS_OF);
2774 : }
2775 :
2776 : /* Callback for walk_non_aliased_vuses. Tries to perform a lookup
2777 : from the statement defining VUSE and if not successful tries to
2778 : translate *REFP and VR_ through an aggregate copy at the definition
2779 : of VUSE. If *DISAMBIGUATE_ONLY is true then do not perform translation
2780 : of *REF and *VR. If only disambiguation was performed then
2781 : *DISAMBIGUATE_ONLY is set to true. */
2782 :
2783 : static void *
2784 43876064 : vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
2785 : translate_flags *disambiguate_only)
2786 : {
2787 43876064 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2788 43876064 : vn_reference_t vr = data->vr;
2789 43876064 : gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
2790 43876064 : tree base = ao_ref_base (ref);
2791 43876064 : HOST_WIDE_INT offseti = 0, maxsizei, sizei = 0;
2792 43876064 : static vec<vn_reference_op_s> lhs_ops;
2793 43876064 : ao_ref lhs_ref;
2794 43876064 : bool lhs_ref_ok = false;
2795 43876064 : poly_int64 copy_size;
2796 :
2797 : /* First try to disambiguate after value-replacing in the definitions LHS. */
2798 43876064 : if (is_gimple_assign (def_stmt))
2799 : {
2800 20917109 : tree lhs = gimple_assign_lhs (def_stmt);
2801 20917109 : bool valueized_anything = false;
2802 : /* Avoid re-allocation overhead. */
2803 20917109 : lhs_ops.truncate (0);
2804 20917109 : basic_block saved_rpo_bb = vn_context_bb;
2805 20917109 : vn_context_bb = gimple_bb (def_stmt);
2806 20917109 : if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE)
2807 : {
2808 13627653 : copy_reference_ops_from_ref (lhs, &lhs_ops);
2809 13627653 : valueize_refs_1 (&lhs_ops, &valueized_anything, true);
2810 : }
2811 20917109 : vn_context_bb = saved_rpo_bb;
2812 20917109 : ao_ref_init (&lhs_ref, lhs);
2813 20917109 : lhs_ref_ok = true;
2814 20917109 : if (valueized_anything
2815 2125727 : && ao_ref_init_from_vn_reference
2816 2125727 : (&lhs_ref, ao_ref_alias_set (&lhs_ref),
2817 2125727 : ao_ref_base_alias_set (&lhs_ref), TREE_TYPE (lhs), lhs_ops)
2818 23042836 : && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
2819 : {
2820 1842842 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2821 6807462 : return NULL;
2822 : }
2823 :
2824 : /* When the def is a CLOBBER we can optimistically disambiguate
2825 : against it since any overlap it would be undefined behavior.
2826 : Avoid this for obvious must aliases to save compile-time though.
2827 : We also may not do this when the query is used for redundant
2828 : store removal. */
2829 19074267 : if (!data->redundant_store_removal_p
2830 10618511 : && gimple_clobber_p (def_stmt)
2831 19610653 : && !operand_equal_p (ao_ref_base (&lhs_ref), base, OEP_ADDRESS_OF))
2832 : {
2833 507935 : *disambiguate_only = TR_DISAMBIGUATE;
2834 507935 : return NULL;
2835 : }
2836 :
2837 : /* Besides valueizing the LHS we can also use access-path based
2838 : disambiguation on the original non-valueized ref. */
2839 18566332 : if (!ref->ref
2840 : && lhs_ref_ok
2841 2775960 : && data->orig_ref.ref)
2842 : {
2843 : /* We want to use the non-valueized LHS for this, but avoid redundant
2844 : work. */
2845 1912070 : ao_ref *lref = &lhs_ref;
2846 1912070 : ao_ref lref_alt;
2847 1912070 : if (valueized_anything)
2848 : {
2849 112981 : ao_ref_init (&lref_alt, lhs);
2850 112981 : lref = &lref_alt;
2851 : }
2852 1912070 : if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
2853 : {
2854 323016 : *disambiguate_only = (valueized_anything
2855 161508 : ? TR_VALUEIZE_AND_DISAMBIGUATE
2856 : : TR_DISAMBIGUATE);
2857 161508 : return NULL;
2858 : }
2859 : }
2860 :
2861 : /* If we reach a clobbering statement try to skip it and see if
2862 : we find a VN result with exactly the same value as the
2863 : possible clobber. In this case we can ignore the clobber
2864 : and return the found value. */
2865 18404824 : if (!gimple_has_volatile_ops (def_stmt)
2866 16973176 : && ((is_gimple_reg_type (TREE_TYPE (lhs))
2867 12816451 : && types_compatible_p (TREE_TYPE (lhs), vr->type)
2868 9959829 : && !storage_order_barrier_p (lhs)
2869 9959829 : && !reverse_storage_order_for_component_p (lhs))
2870 7013351 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == CONSTRUCTOR)
2871 11048464 : && (ref->ref || data->orig_ref.ref)
2872 10561186 : && !data->mask
2873 10540737 : && data->partial_defs.is_empty ()
2874 10538346 : && multiple_p (get_object_alignment
2875 : (ref->ref ? ref->ref : data->orig_ref.ref),
2876 : ref->size)
2877 41218419 : && multiple_p (get_object_alignment (lhs), ref->size))
2878 : {
2879 10135596 : HOST_WIDE_INT offset2i, size2i;
2880 10135596 : poly_int64 offset = ref->offset;
2881 10135596 : poly_int64 maxsize = ref->max_size;
2882 :
2883 10135596 : gcc_assert (lhs_ref_ok);
2884 10135596 : tree base2 = ao_ref_base (&lhs_ref);
2885 10135596 : poly_int64 offset2 = lhs_ref.offset;
2886 10135596 : poly_int64 size2 = lhs_ref.size;
2887 10135596 : poly_int64 maxsize2 = lhs_ref.max_size;
2888 :
2889 10135596 : tree rhs = gimple_assign_rhs1 (def_stmt);
2890 10135596 : if (TREE_CODE (rhs) == CONSTRUCTOR)
2891 1054888 : rhs = integer_zero_node;
2892 : /* ??? We may not compare to ahead values which might be from
2893 : a different loop iteration but only to loop invariants. Use
2894 : CONSTANT_CLASS_P (unvalueized!) as conservative approximation.
2895 : The one-hop lookup below doesn't have this issue since there's
2896 : a virtual PHI before we ever reach a backedge to cross.
2897 : We can skip multiple defs as long as they are from the same
2898 : value though. */
2899 10135596 : if (data->same_val
2900 10135596 : && !operand_equal_p (data->same_val, rhs))
2901 : ;
2902 : /* When this is a (partial) must-def, leave it to handling
2903 : below in case we are interested in the value. */
2904 9857638 : else if (!(*disambiguate_only > TR_TRANSLATE)
2905 3416851 : && base2
2906 3416851 : && known_eq (maxsize2, size2)
2907 2421480 : && adjust_offsets_for_equal_base_address (base, &offset,
2908 : base2, &offset2)
2909 1180375 : && offset2.is_constant (&offset2i)
2910 1180375 : && size2.is_constant (&size2i)
2911 1180375 : && maxsize.is_constant (&maxsizei)
2912 1180375 : && offset.is_constant (&offseti)
2913 11038013 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
2914 : size2i))
2915 : ;
2916 8773631 : else if (CONSTANT_CLASS_P (rhs))
2917 : {
2918 4226611 : if (dump_file && (dump_flags & TDF_DETAILS))
2919 : {
2920 2330 : fprintf (dump_file,
2921 : "Skipping possible redundant definition ");
2922 2330 : print_gimple_stmt (dump_file, def_stmt, 0);
2923 : }
2924 : /* Delay the actual compare of the values to the end of the walk
2925 : but do not update last_vuse from here. */
2926 4226611 : data->last_vuse_ptr = NULL;
2927 4226611 : data->same_val = rhs;
2928 4295177 : return NULL;
2929 : }
2930 : else
2931 : {
2932 4547020 : tree saved_vuse = vr->vuse;
2933 4547020 : hashval_t saved_hashcode = vr->hashcode;
2934 4547020 : if (vr->vuse)
2935 4547020 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2936 9094040 : vr->vuse = vuse_ssa_val (gimple_vuse (def_stmt));
2937 4547020 : if (vr->vuse)
2938 4547020 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2939 4547020 : vn_reference_t vnresult = NULL;
2940 : /* Do not use vn_reference_lookup_2 since that might perform
2941 : expression hashtable insertion but this lookup crosses
2942 : a possible may-alias making such insertion conditionally
2943 : invalid. */
2944 4547020 : vn_reference_lookup_1 (vr, &vnresult);
2945 : /* Need to restore vr->vuse and vr->hashcode. */
2946 4547020 : vr->vuse = saved_vuse;
2947 4547020 : vr->hashcode = saved_hashcode;
2948 4547020 : if (vnresult)
2949 : {
2950 255543 : if (TREE_CODE (rhs) == SSA_NAME)
2951 254244 : rhs = SSA_VAL (rhs);
2952 255543 : if (vnresult->result
2953 255543 : && operand_equal_p (vnresult->result, rhs, 0))
2954 68566 : return vnresult;
2955 : }
2956 : }
2957 : }
2958 : }
2959 22958955 : else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE
2960 20573384 : && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
2961 25088261 : && gimple_call_num_args (def_stmt) <= 4)
2962 : {
2963 : /* For builtin calls valueize its arguments and call the
2964 : alias oracle again. Valueization may improve points-to
2965 : info of pointers and constify size and position arguments.
2966 : Originally this was motivated by PR61034 which has
2967 : conditional calls to free falsely clobbering ref because
2968 : of imprecise points-to info of the argument. */
2969 : tree oldargs[4];
2970 : bool valueized_anything = false;
2971 5026329 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2972 : {
2973 3461078 : oldargs[i] = gimple_call_arg (def_stmt, i);
2974 3461078 : tree val = vn_valueize (oldargs[i]);
2975 3461078 : if (val != oldargs[i])
2976 : {
2977 134374 : gimple_call_set_arg (def_stmt, i, val);
2978 134374 : valueized_anything = true;
2979 : }
2980 : }
2981 1565251 : if (valueized_anything)
2982 : {
2983 104982 : bool res = call_may_clobber_ref_p_1 (as_a <gcall *> (def_stmt),
2984 : ref, data->tbaa_p);
2985 484523 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2986 274559 : gimple_call_set_arg (def_stmt, i, oldargs[i]);
2987 104982 : if (!res)
2988 : {
2989 31590 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2990 31590 : return NULL;
2991 : }
2992 : }
2993 : }
2994 :
2995 37037012 : if (*disambiguate_only > TR_TRANSLATE)
2996 : return (void *)-1;
2997 :
2998 : /* If we cannot constrain the size of the reference we cannot
2999 : test if anything kills it. */
3000 24667827 : if (!ref->max_size_known_p ())
3001 : return (void *)-1;
3002 :
3003 24228725 : poly_int64 offset = ref->offset;
3004 24228725 : poly_int64 maxsize = ref->max_size;
3005 :
3006 : /* def_stmt may-defs *ref. See if we can derive a value for *ref
3007 : from that definition.
3008 : 1) Memset. */
3009 24228725 : if (is_gimple_reg_type (vr->type)
3010 24219339 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
3011 24127916 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
3012 91957 : && (integer_zerop (gimple_call_arg (def_stmt, 1))
3013 33685 : || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
3014 8906 : || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
3015 : && CHAR_BIT == 8
3016 : && BITS_PER_UNIT == 8
3017 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
3018 32394 : && offset.is_constant (&offseti)
3019 32394 : && ref->size.is_constant (&sizei)
3020 32394 : && (offseti % BITS_PER_UNIT == 0
3021 183 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST)))
3022 90666 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
3023 37097 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3024 37097 : && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
3025 24282869 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3026 30574 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
3027 : {
3028 54103 : tree base2;
3029 54103 : poly_int64 offset2, size2, maxsize2;
3030 54103 : bool reverse;
3031 54103 : tree ref2 = gimple_call_arg (def_stmt, 0);
3032 54103 : if (TREE_CODE (ref2) == SSA_NAME)
3033 : {
3034 30533 : ref2 = SSA_VAL (ref2);
3035 30533 : if (TREE_CODE (ref2) == SSA_NAME
3036 30533 : && (TREE_CODE (base) != MEM_REF
3037 19158 : || TREE_OPERAND (base, 0) != ref2))
3038 : {
3039 24187 : gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
3040 24187 : if (gimple_assign_single_p (def_stmt)
3041 24187 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3042 829 : ref2 = gimple_assign_rhs1 (def_stmt);
3043 : }
3044 : }
3045 54103 : if (TREE_CODE (ref2) == ADDR_EXPR)
3046 : {
3047 27324 : ref2 = TREE_OPERAND (ref2, 0);
3048 27324 : base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
3049 : &reverse);
3050 27324 : if (!known_size_p (maxsize2)
3051 27284 : || !known_eq (maxsize2, size2)
3052 54540 : || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
3053 53739 : return (void *)-1;
3054 : }
3055 26779 : else if (TREE_CODE (ref2) == SSA_NAME)
3056 : {
3057 26779 : poly_int64 soff;
3058 26779 : if (TREE_CODE (base) != MEM_REF
3059 45324 : || !(mem_ref_offset (base)
3060 45324 : << LOG2_BITS_PER_UNIT).to_shwi (&soff))
3061 22771 : return (void *)-1;
3062 18545 : offset += soff;
3063 18545 : offset2 = 0;
3064 18545 : if (TREE_OPERAND (base, 0) != ref2)
3065 : {
3066 15124 : gimple *def = SSA_NAME_DEF_STMT (ref2);
3067 15124 : if (is_gimple_assign (def)
3068 13608 : && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
3069 11757 : && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
3070 15741 : && poly_int_tree_p (gimple_assign_rhs2 (def)))
3071 : {
3072 587 : tree rhs2 = gimple_assign_rhs2 (def);
3073 587 : if (!(poly_offset_int::from (wi::to_poly_wide (rhs2),
3074 : SIGNED)
3075 587 : << LOG2_BITS_PER_UNIT).to_shwi (&offset2))
3076 : return (void *)-1;
3077 587 : ref2 = gimple_assign_rhs1 (def);
3078 587 : if (TREE_CODE (ref2) == SSA_NAME)
3079 587 : ref2 = SSA_VAL (ref2);
3080 : }
3081 : else
3082 : return (void *)-1;
3083 : }
3084 : }
3085 : else
3086 : return (void *)-1;
3087 27331 : tree len = gimple_call_arg (def_stmt, 2);
3088 27331 : HOST_WIDE_INT leni, offset2i;
3089 27331 : if (TREE_CODE (len) == SSA_NAME)
3090 263 : len = SSA_VAL (len);
3091 : /* Sometimes the above trickery is smarter than alias analysis. Take
3092 : advantage of that. */
3093 27331 : if (!ranges_maybe_overlap_p (offset, maxsize, offset2,
3094 54662 : (wi::to_poly_offset (len)
3095 27331 : << LOG2_BITS_PER_UNIT)))
3096 : return NULL;
3097 54604 : if (data->partial_defs.is_empty ()
3098 27273 : && known_subrange_p (offset, maxsize, offset2,
3099 27273 : wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
3100 : {
3101 26756 : tree val;
3102 26756 : if (integer_zerop (gimple_call_arg (def_stmt, 1)))
3103 21721 : val = build_zero_cst (vr->type);
3104 5035 : else if (INTEGRAL_TYPE_P (vr->type)
3105 3991 : && known_eq (ref->size, 8)
3106 8021 : && offseti % BITS_PER_UNIT == 0)
3107 : {
3108 2986 : gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
3109 2986 : vr->type, gimple_call_arg (def_stmt, 1));
3110 2986 : val = vn_nary_build_or_lookup (&res_op);
3111 2986 : if (!val
3112 2986 : || (TREE_CODE (val) == SSA_NAME
3113 616 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
3114 0 : return (void *)-1;
3115 : }
3116 : else
3117 : {
3118 2049 : unsigned buflen
3119 2049 : = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)) + 1;
3120 2049 : if (INTEGRAL_TYPE_P (vr->type)
3121 2049 : && TYPE_MODE (vr->type) != BLKmode)
3122 2008 : buflen = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (vr->type)) + 1;
3123 2049 : unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
3124 2049 : memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
3125 : buflen);
3126 2049 : if (BYTES_BIG_ENDIAN)
3127 : {
3128 : unsigned int amnt
3129 : = (((unsigned HOST_WIDE_INT) offseti + sizei)
3130 : % BITS_PER_UNIT);
3131 : if (amnt)
3132 : {
3133 : shift_bytes_in_array_right (buf, buflen,
3134 : BITS_PER_UNIT - amnt);
3135 : buf++;
3136 : buflen--;
3137 : }
3138 : }
3139 2049 : else if (offseti % BITS_PER_UNIT != 0)
3140 : {
3141 121 : unsigned int amnt
3142 : = BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) offseti
3143 121 : % BITS_PER_UNIT);
3144 121 : shift_bytes_in_array_left (buf, buflen, amnt);
3145 121 : buf++;
3146 121 : buflen--;
3147 : }
3148 2049 : val = native_interpret_expr (vr->type, buf, buflen);
3149 2049 : if (!val)
3150 : return (void *)-1;
3151 : }
3152 26756 : return data->finish (0, 0, val);
3153 : }
3154 : /* For now handle clearing memory with partial defs. */
3155 575 : else if (known_eq (ref->size, maxsize)
3156 498 : && integer_zerop (gimple_call_arg (def_stmt, 1))
3157 215 : && tree_fits_poly_int64_p (len)
3158 211 : && tree_to_poly_int64 (len).is_constant (&leni)
3159 211 : && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
3160 211 : && offset.is_constant (&offseti)
3161 211 : && offset2.is_constant (&offset2i)
3162 211 : && maxsize.is_constant (&maxsizei)
3163 575 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
3164 575 : leni << LOG2_BITS_PER_UNIT))
3165 : {
3166 211 : pd_data pd;
3167 211 : pd.rhs = build_constructor (NULL_TREE, NULL);
3168 211 : pd.rhs_off = 0;
3169 211 : pd.offset = offset2i;
3170 211 : pd.size = leni << LOG2_BITS_PER_UNIT;
3171 211 : return data->push_partial_def (pd, 0, 0, offseti, maxsizei);
3172 : }
3173 : }
3174 :
3175 : /* 2) Assignment from an empty CONSTRUCTOR. */
3176 24174622 : else if (is_gimple_reg_type (vr->type)
3177 24165236 : && gimple_assign_single_p (def_stmt)
3178 7993752 : && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
3179 2030089 : && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0
3180 26204711 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)))
3181 : {
3182 2030057 : tree base2;
3183 2030057 : poly_int64 offset2, size2, maxsize2;
3184 2030057 : HOST_WIDE_INT offset2i, size2i;
3185 2030057 : gcc_assert (lhs_ref_ok);
3186 2030057 : base2 = ao_ref_base (&lhs_ref);
3187 2030057 : offset2 = lhs_ref.offset;
3188 2030057 : size2 = lhs_ref.size;
3189 2030057 : maxsize2 = lhs_ref.max_size;
3190 2030057 : if (known_size_p (maxsize2)
3191 2030011 : && known_eq (maxsize2, size2)
3192 4060022 : && adjust_offsets_for_equal_base_address (base, &offset,
3193 : base2, &offset2))
3194 : {
3195 1998768 : if (data->partial_defs.is_empty ()
3196 1995216 : && known_subrange_p (offset, maxsize, offset2, size2))
3197 : {
3198 : /* While technically undefined behavior do not optimize
3199 : a full read from a clobber. */
3200 1994425 : if (gimple_clobber_p (def_stmt))
3201 1998718 : return (void *)-1;
3202 1014688 : tree val = build_zero_cst (vr->type);
3203 1014688 : return data->finish (ao_ref_alias_set (&lhs_ref),
3204 1014688 : ao_ref_base_alias_set (&lhs_ref), val);
3205 : }
3206 4343 : else if (known_eq (ref->size, maxsize)
3207 4293 : && maxsize.is_constant (&maxsizei)
3208 4293 : && offset.is_constant (&offseti)
3209 4293 : && offset2.is_constant (&offset2i)
3210 4293 : && size2.is_constant (&size2i)
3211 4343 : && ranges_known_overlap_p (offseti, maxsizei,
3212 : offset2i, size2i))
3213 : {
3214 : /* Let clobbers be consumed by the partial-def tracker
3215 : which can choose to ignore them if they are shadowed
3216 : by a later def. */
3217 4293 : pd_data pd;
3218 4293 : pd.rhs = gimple_assign_rhs1 (def_stmt);
3219 4293 : pd.rhs_off = 0;
3220 4293 : pd.offset = offset2i;
3221 4293 : pd.size = size2i;
3222 4293 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3223 : ao_ref_base_alias_set (&lhs_ref),
3224 : offseti, maxsizei);
3225 : }
3226 : }
3227 : }
3228 :
3229 : /* 3) Assignment from a constant. We can use folds native encode/interpret
3230 : routines to extract the assigned bits. */
3231 22144565 : else if (known_eq (ref->size, maxsize)
3232 21614486 : && is_gimple_reg_type (vr->type)
3233 21605100 : && !reverse_storage_order_for_component_p (vr->operands)
3234 21602286 : && !contains_storage_order_barrier_p (vr->operands)
3235 21602286 : && gimple_assign_single_p (def_stmt)
3236 5637418 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
3237 : && CHAR_BIT == 8
3238 : && BITS_PER_UNIT == 8
3239 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
3240 : /* native_encode and native_decode operate on arrays of bytes
3241 : and so fundamentally need a compile-time size and offset. */
3242 5634485 : && maxsize.is_constant (&maxsizei)
3243 5634485 : && offset.is_constant (&offseti)
3244 27779050 : && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
3245 4737388 : || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
3246 1930772 : && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
3247 : {
3248 913983 : tree lhs = gimple_assign_lhs (def_stmt);
3249 913983 : tree base2;
3250 913983 : poly_int64 offset2, size2, maxsize2;
3251 913983 : HOST_WIDE_INT offset2i, size2i;
3252 913983 : bool reverse;
3253 913983 : gcc_assert (lhs_ref_ok);
3254 913983 : base2 = ao_ref_base (&lhs_ref);
3255 913983 : offset2 = lhs_ref.offset;
3256 913983 : size2 = lhs_ref.size;
3257 913983 : maxsize2 = lhs_ref.max_size;
3258 913983 : reverse = reverse_storage_order_for_component_p (lhs);
3259 913983 : if (base2
3260 913983 : && !reverse
3261 913155 : && !storage_order_barrier_p (lhs)
3262 913155 : && known_eq (maxsize2, size2)
3263 879588 : && adjust_offsets_for_equal_base_address (base, &offset,
3264 : base2, &offset2)
3265 86943 : && offset.is_constant (&offseti)
3266 86943 : && offset2.is_constant (&offset2i)
3267 913983 : && size2.is_constant (&size2i))
3268 : {
3269 86943 : if (data->partial_defs.is_empty ()
3270 69500 : && known_subrange_p (offseti, maxsizei, offset2, size2))
3271 : {
3272 : /* We support up to 512-bit values (for V8DFmode). */
3273 44996 : unsigned char buffer[65];
3274 44996 : int len;
3275 :
3276 44996 : tree rhs = gimple_assign_rhs1 (def_stmt);
3277 44996 : if (TREE_CODE (rhs) == SSA_NAME)
3278 1781 : rhs = SSA_VAL (rhs);
3279 89992 : len = native_encode_expr (rhs,
3280 : buffer, sizeof (buffer) - 1,
3281 44996 : (offseti - offset2i) / BITS_PER_UNIT);
3282 44996 : if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
3283 : {
3284 41974 : tree type = vr->type;
3285 41974 : unsigned char *buf = buffer;
3286 41974 : unsigned int amnt = 0;
3287 : /* Make sure to interpret in a type that has a range
3288 : covering the whole access size. */
3289 41974 : if (INTEGRAL_TYPE_P (vr->type)
3290 41974 : && maxsizei != TYPE_PRECISION (vr->type))
3291 : {
3292 1040 : bool uns = TYPE_UNSIGNED (type);
3293 1039 : if (BITINT_TYPE_P (vr->type)
3294 1041 : && maxsizei > MAX_FIXED_MODE_SIZE)
3295 1 : type = build_bitint_type (maxsizei, uns);
3296 : else
3297 1039 : type = build_nonstandard_integer_type (maxsizei, uns);
3298 : }
3299 41974 : if (BYTES_BIG_ENDIAN)
3300 : {
3301 : /* For big-endian native_encode_expr stored the rhs
3302 : such that the LSB of it is the LSB of buffer[len - 1].
3303 : That bit is stored into memory at position
3304 : offset2 + size2 - 1, i.e. in byte
3305 : base + (offset2 + size2 - 1) / BITS_PER_UNIT.
3306 : E.g. for offset2 1 and size2 14, rhs -1 and memory
3307 : previously cleared that is:
3308 : 0 1
3309 : 01111111|11111110
3310 : Now, if we want to extract offset 2 and size 12 from
3311 : it using native_interpret_expr (which actually works
3312 : for integral bitfield types in terms of byte size of
3313 : the mode), the native_encode_expr stored the value
3314 : into buffer as
3315 : XX111111|11111111
3316 : and returned len 2 (the X bits are outside of
3317 : precision).
3318 : Let sz be maxsize / BITS_PER_UNIT if not extracting
3319 : a bitfield, and GET_MODE_SIZE otherwise.
3320 : We need to align the LSB of the value we want to
3321 : extract as the LSB of buf[sz - 1].
3322 : The LSB from memory we need to read is at position
3323 : offset + maxsize - 1. */
3324 : HOST_WIDE_INT sz = maxsizei / BITS_PER_UNIT;
3325 : if (INTEGRAL_TYPE_P (type))
3326 : {
3327 : if (TYPE_MODE (type) != BLKmode)
3328 : sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
3329 : else
3330 : sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
3331 : }
3332 : amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
3333 : - offseti - maxsizei) % BITS_PER_UNIT;
3334 : if (amnt)
3335 : shift_bytes_in_array_right (buffer, len, amnt);
3336 : amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
3337 : - offseti - maxsizei - amnt) / BITS_PER_UNIT;
3338 : if ((unsigned HOST_WIDE_INT) sz + amnt > (unsigned) len)
3339 : len = 0;
3340 : else
3341 : {
3342 : buf = buffer + len - sz - amnt;
3343 : len -= (buf - buffer);
3344 : }
3345 : }
3346 : else
3347 : {
3348 41974 : amnt = ((unsigned HOST_WIDE_INT) offset2i
3349 41974 : - offseti) % BITS_PER_UNIT;
3350 41974 : if (amnt)
3351 : {
3352 344 : buffer[len] = 0;
3353 344 : shift_bytes_in_array_left (buffer, len + 1, amnt);
3354 344 : buf = buffer + 1;
3355 : }
3356 : }
3357 41974 : tree val = native_interpret_expr (type, buf, len);
3358 : /* If we chop off bits because the types precision doesn't
3359 : match the memory access size this is ok when optimizing
3360 : reads but not when called from the DSE code during
3361 : elimination. */
3362 41974 : if (val
3363 41972 : && type != vr->type)
3364 : {
3365 1040 : if (! int_fits_type_p (val, vr->type))
3366 : val = NULL_TREE;
3367 : else
3368 1040 : val = fold_convert (vr->type, val);
3369 : }
3370 :
3371 41972 : if (val)
3372 41972 : return data->finish (ao_ref_alias_set (&lhs_ref),
3373 41972 : ao_ref_base_alias_set (&lhs_ref), val);
3374 : }
3375 : }
3376 41947 : else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
3377 : size2i))
3378 : {
3379 41947 : pd_data pd;
3380 41947 : tree rhs = gimple_assign_rhs1 (def_stmt);
3381 41947 : if (TREE_CODE (rhs) == SSA_NAME)
3382 2286 : rhs = SSA_VAL (rhs);
3383 41947 : pd.rhs = rhs;
3384 41947 : pd.rhs_off = 0;
3385 41947 : pd.offset = offset2i;
3386 41947 : pd.size = size2i;
3387 41947 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3388 : ao_ref_base_alias_set (&lhs_ref),
3389 : offseti, maxsizei);
3390 : }
3391 : }
3392 : }
3393 :
3394 : /* 4) Assignment from an SSA name which definition we may be able
3395 : to access pieces from or we can combine to a larger entity. */
3396 21230582 : else if (known_eq (ref->size, maxsize)
3397 20700503 : && is_gimple_reg_type (vr->type)
3398 20691117 : && !reverse_storage_order_for_component_p (vr->operands)
3399 20688303 : && !contains_storage_order_barrier_p (vr->operands)
3400 20688303 : && gimple_assign_single_p (def_stmt)
3401 4723435 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
3402 25951084 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
3403 : {
3404 1913886 : tree lhs = gimple_assign_lhs (def_stmt);
3405 1913886 : tree base2;
3406 1913886 : poly_int64 offset2, size2, maxsize2;
3407 1913886 : HOST_WIDE_INT offset2i, size2i, offseti;
3408 1913886 : bool reverse;
3409 1913886 : gcc_assert (lhs_ref_ok);
3410 1913886 : base2 = ao_ref_base (&lhs_ref);
3411 1913886 : offset2 = lhs_ref.offset;
3412 1913886 : size2 = lhs_ref.size;
3413 1913886 : maxsize2 = lhs_ref.max_size;
3414 1913886 : reverse = reverse_storage_order_for_component_p (lhs);
3415 1913886 : tree def_rhs = gimple_assign_rhs1 (def_stmt);
3416 1913886 : if (!reverse
3417 1913674 : && !storage_order_barrier_p (lhs)
3418 1913674 : && known_size_p (maxsize2)
3419 1887342 : && known_eq (maxsize2, size2)
3420 3681880 : && adjust_offsets_for_equal_base_address (base, &offset,
3421 : base2, &offset2))
3422 : {
3423 86079 : if (data->partial_defs.is_empty ()
3424 79588 : && known_subrange_p (offset, maxsize, offset2, size2)
3425 : /* ??? We can't handle bitfield precision extracts without
3426 : either using an alternate type for the BIT_FIELD_REF and
3427 : then doing a conversion or possibly adjusting the offset
3428 : according to endianness. */
3429 55308 : && (! INTEGRAL_TYPE_P (vr->type)
3430 41266 : || known_eq (ref->size, TYPE_PRECISION (vr->type)))
3431 96878 : && multiple_p (ref->size, BITS_PER_UNIT))
3432 : {
3433 46730 : tree val = NULL_TREE;
3434 93454 : if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs))
3435 51534 : || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
3436 : {
3437 91028 : gimple_match_op op (gimple_match_cond::UNCOND,
3438 45514 : BIT_FIELD_REF, vr->type,
3439 : SSA_VAL (def_rhs),
3440 : bitsize_int (ref->size),
3441 45514 : bitsize_int (offset - offset2));
3442 45514 : val = vn_nary_build_or_lookup (&op);
3443 : }
3444 1216 : else if (known_eq (ref->size, size2))
3445 : {
3446 1142 : gimple_match_op op (gimple_match_cond::UNCOND,
3447 1142 : VIEW_CONVERT_EXPR, vr->type,
3448 1142 : SSA_VAL (def_rhs));
3449 1142 : val = vn_nary_build_or_lookup (&op);
3450 : }
3451 46656 : if (val
3452 46656 : && (TREE_CODE (val) != SSA_NAME
3453 45858 : || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
3454 46637 : return data->finish (ao_ref_alias_set (&lhs_ref),
3455 85986 : ao_ref_base_alias_set (&lhs_ref), val);
3456 : }
3457 39349 : else if (maxsize.is_constant (&maxsizei)
3458 39349 : && offset.is_constant (&offseti)
3459 39349 : && offset2.is_constant (&offset2i)
3460 39349 : && size2.is_constant (&size2i)
3461 39349 : && ranges_known_overlap_p (offset, maxsize, offset2, size2))
3462 : {
3463 39349 : pd_data pd;
3464 39349 : pd.rhs = SSA_VAL (def_rhs);
3465 39349 : pd.rhs_off = 0;
3466 39349 : pd.offset = offset2i;
3467 39349 : pd.size = size2i;
3468 39349 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3469 : ao_ref_base_alias_set (&lhs_ref),
3470 : offseti, maxsizei);
3471 : }
3472 : }
3473 : }
3474 :
3475 : /* 4b) Assignment done via one of the vectorizer internal store
3476 : functions where we may be able to access pieces from or we can
3477 : combine to a larger entity. */
3478 19316696 : else if (known_eq (ref->size, maxsize)
3479 18786617 : && is_gimple_reg_type (vr->type)
3480 18777231 : && !reverse_storage_order_for_component_p (vr->operands)
3481 18774417 : && !contains_storage_order_barrier_p (vr->operands)
3482 18774417 : && is_gimple_call (def_stmt)
3483 15140193 : && gimple_call_internal_p (def_stmt)
3484 19628686 : && internal_store_fn_p (gimple_call_internal_fn (def_stmt)))
3485 : {
3486 36 : gcall *call = as_a <gcall *> (def_stmt);
3487 36 : internal_fn fn = gimple_call_internal_fn (call);
3488 :
3489 36 : tree mask = NULL_TREE, len = NULL_TREE, bias = NULL_TREE;
3490 36 : switch (fn)
3491 : {
3492 36 : case IFN_MASK_STORE:
3493 36 : mask = gimple_call_arg (call, internal_fn_mask_index (fn));
3494 36 : mask = vn_valueize (mask);
3495 36 : if (TREE_CODE (mask) != VECTOR_CST)
3496 28 : return (void *)-1;
3497 : break;
3498 0 : case IFN_LEN_STORE:
3499 0 : {
3500 0 : int len_index = internal_fn_len_index (fn);
3501 0 : len = gimple_call_arg (call, len_index);
3502 0 : bias = gimple_call_arg (call, len_index + 1);
3503 0 : if (!tree_fits_uhwi_p (len) || !tree_fits_shwi_p (bias))
3504 : return (void *) -1;
3505 : break;
3506 : }
3507 : default:
3508 : return (void *)-1;
3509 : }
3510 14 : tree def_rhs = gimple_call_arg (call,
3511 14 : internal_fn_stored_value_index (fn));
3512 14 : def_rhs = vn_valueize (def_rhs);
3513 14 : if (TREE_CODE (def_rhs) != VECTOR_CST)
3514 : return (void *)-1;
3515 :
3516 14 : ao_ref_init_from_ptr_and_size (&lhs_ref,
3517 : vn_valueize (gimple_call_arg (call, 0)),
3518 14 : TYPE_SIZE_UNIT (TREE_TYPE (def_rhs)));
3519 14 : tree base2;
3520 14 : poly_int64 offset2, size2, maxsize2;
3521 14 : HOST_WIDE_INT offset2i, size2i, offseti;
3522 14 : base2 = ao_ref_base (&lhs_ref);
3523 14 : offset2 = lhs_ref.offset;
3524 14 : size2 = lhs_ref.size;
3525 14 : maxsize2 = lhs_ref.max_size;
3526 14 : if (known_size_p (maxsize2)
3527 14 : && known_eq (maxsize2, size2)
3528 14 : && adjust_offsets_for_equal_base_address (base, &offset,
3529 : base2, &offset2)
3530 6 : && maxsize.is_constant (&maxsizei)
3531 6 : && offset.is_constant (&offseti)
3532 6 : && offset2.is_constant (&offset2i)
3533 14 : && size2.is_constant (&size2i))
3534 : {
3535 6 : if (!ranges_maybe_overlap_p (offset, maxsize, offset2, size2))
3536 : /* Poor-mans disambiguation. */
3537 : return NULL;
3538 6 : else if (ranges_known_overlap_p (offset, maxsize, offset2, size2))
3539 : {
3540 6 : pd_data pd;
3541 6 : pd.rhs = def_rhs;
3542 6 : tree aa = gimple_call_arg (call, 1);
3543 6 : alias_set_type set = get_deref_alias_set (TREE_TYPE (aa));
3544 6 : tree vectype = TREE_TYPE (def_rhs);
3545 6 : unsigned HOST_WIDE_INT elsz
3546 6 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype)));
3547 6 : if (mask)
3548 : {
3549 : HOST_WIDE_INT start = 0, length = 0;
3550 : unsigned mask_idx = 0;
3551 48 : do
3552 : {
3553 48 : if (integer_zerop (VECTOR_CST_ELT (mask, mask_idx)))
3554 : {
3555 24 : if (length != 0)
3556 : {
3557 18 : pd.rhs_off = start;
3558 18 : pd.offset = offset2i + start;
3559 18 : pd.size = length;
3560 18 : if (ranges_known_overlap_p
3561 18 : (offset, maxsize, pd.offset, pd.size))
3562 : {
3563 0 : void *res = data->push_partial_def
3564 0 : (pd, set, set, offseti, maxsizei);
3565 0 : if (res != NULL)
3566 6 : return res;
3567 : }
3568 : }
3569 24 : start = (mask_idx + 1) * elsz;
3570 24 : length = 0;
3571 : }
3572 : else
3573 24 : length += elsz;
3574 48 : mask_idx++;
3575 : }
3576 48 : while (known_lt (mask_idx, TYPE_VECTOR_SUBPARTS (vectype)));
3577 6 : if (length != 0)
3578 : {
3579 6 : pd.rhs_off = start;
3580 6 : pd.offset = offset2i + start;
3581 6 : pd.size = length;
3582 6 : if (ranges_known_overlap_p (offset, maxsize,
3583 : pd.offset, pd.size))
3584 2 : return data->push_partial_def (pd, set, set,
3585 2 : offseti, maxsizei);
3586 : }
3587 : }
3588 0 : else if (fn == IFN_LEN_STORE)
3589 : {
3590 0 : pd.offset = offset2i;
3591 0 : pd.size = (tree_to_uhwi (len)
3592 0 : + -tree_to_shwi (bias)) * BITS_PER_UNIT;
3593 0 : if (BYTES_BIG_ENDIAN)
3594 : pd.rhs_off = pd.size - tree_to_uhwi (TYPE_SIZE (vectype));
3595 : else
3596 0 : pd.rhs_off = 0;
3597 0 : if (ranges_known_overlap_p (offset, maxsize,
3598 : pd.offset, pd.size))
3599 0 : return data->push_partial_def (pd, set, set,
3600 0 : offseti, maxsizei);
3601 : }
3602 : else
3603 0 : gcc_unreachable ();
3604 : return NULL;
3605 : }
3606 : }
3607 : }
3608 :
3609 : /* 5) For aggregate copies translate the reference through them if
3610 : the copy kills ref. */
3611 19316660 : else if (data->vn_walk_kind == VN_WALKREWRITE
3612 15585497 : && gimple_assign_single_p (def_stmt)
3613 2602746 : && !gimple_has_volatile_ops (def_stmt)
3614 21917128 : && (DECL_P (gimple_assign_rhs1 (def_stmt))
3615 1992174 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
3616 1571045 : || handled_component_p (gimple_assign_rhs1 (def_stmt))))
3617 : {
3618 2385947 : tree base2;
3619 2385947 : int i, j, k;
3620 2385947 : auto_vec<vn_reference_op_s> rhs;
3621 2385947 : vn_reference_op_t vro;
3622 2385947 : ao_ref r;
3623 :
3624 2385947 : gcc_assert (lhs_ref_ok);
3625 :
3626 : /* See if the assignment kills REF. */
3627 2385947 : base2 = ao_ref_base (&lhs_ref);
3628 2385947 : if (!lhs_ref.max_size_known_p ()
3629 2385347 : || (base != base2
3630 91521 : && (TREE_CODE (base) != MEM_REF
3631 75884 : || TREE_CODE (base2) != MEM_REF
3632 57106 : || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
3633 19540 : || !tree_int_cst_equal (TREE_OPERAND (base, 1),
3634 19540 : TREE_OPERAND (base2, 1))))
3635 4697415 : || !stmt_kills_ref_p (def_stmt, ref))
3636 : return (void *)-1;
3637 :
3638 : /* Find the common base of ref and the lhs. lhs_ops already
3639 : contains valueized operands for the lhs. */
3640 1986150 : poly_int64 extra_off = 0;
3641 1986150 : i = vr->operands.length () - 1;
3642 1986150 : j = lhs_ops.length () - 1;
3643 :
3644 : /* The base should be always equal due to the above check. */
3645 1986150 : if (! vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3646 : return (void *)-1;
3647 1985885 : i--, j--;
3648 :
3649 : /* The 2nd component should always exist and be a MEM_REF. */
3650 1985885 : if (!(i >= 0 && j >= 0))
3651 : ;
3652 1985885 : else if (vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3653 946731 : i--, j--;
3654 1039154 : else if (vr->operands[i].opcode == MEM_REF
3655 1037742 : && lhs_ops[j].opcode == MEM_REF
3656 1037742 : && known_ne (lhs_ops[j].off, -1)
3657 2076896 : && known_ne (vr->operands[i].off, -1))
3658 : {
3659 1037742 : bool found = false;
3660 : /* When we ge a mismatch at a MEM_REF that is not the sole component
3661 : try finding a match in one of the outer components and continue
3662 : stripping there. This happens when addresses of components get
3663 : forwarded into dereferences. */
3664 1037742 : if (i > 0)
3665 : {
3666 114256 : int temi = i - 1;
3667 114256 : poly_int64 tem_extra_off = extra_off + vr->operands[i].off;
3668 114256 : while (temi >= 0
3669 255093 : && known_ne (vr->operands[temi].off, -1))
3670 : {
3671 142361 : if (vr->operands[temi].type
3672 142361 : && lhs_ops[j].type
3673 284722 : && (TYPE_MAIN_VARIANT (vr->operands[temi].type)
3674 142361 : == TYPE_MAIN_VARIANT (lhs_ops[j].type)))
3675 : {
3676 1524 : i = temi;
3677 : /* Strip the component that was type matched to
3678 : the MEM_REF. */
3679 1524 : extra_off = (tem_extra_off
3680 1524 : + vr->operands[i].off - lhs_ops[j].off);
3681 1524 : i--, j--;
3682 : /* Strip further equal components. */
3683 1524 : found = true;
3684 1524 : break;
3685 : }
3686 140837 : tem_extra_off += vr->operands[temi].off;
3687 140837 : temi--;
3688 : }
3689 : }
3690 1037742 : if (!found && j > 0)
3691 : {
3692 33932 : int temj = j - 1;
3693 33932 : poly_int64 tem_extra_off = extra_off - lhs_ops[j].off;
3694 33932 : while (temj >= 0
3695 64726 : && known_ne (lhs_ops[temj].off, -1))
3696 : {
3697 36292 : if (vr->operands[i].type
3698 36292 : && lhs_ops[temj].type
3699 72584 : && (TYPE_MAIN_VARIANT (vr->operands[i].type)
3700 36292 : == TYPE_MAIN_VARIANT (lhs_ops[temj].type)))
3701 : {
3702 5498 : j = temj;
3703 : /* Strip the component that was type matched to
3704 : the MEM_REF. */
3705 5498 : extra_off = (tem_extra_off
3706 5498 : + vr->operands[i].off - lhs_ops[j].off);
3707 5498 : i--, j--;
3708 : /* Strip further equal components. */
3709 5498 : found = true;
3710 5498 : break;
3711 : }
3712 30794 : tem_extra_off += -lhs_ops[temj].off;
3713 30794 : temj--;
3714 : }
3715 : }
3716 : /* When we cannot find a common base to reconstruct the full
3717 : reference instead try to reduce the lookup to the new
3718 : base plus a constant offset. */
3719 1037742 : if (!found)
3720 : {
3721 : while (j >= 0
3722 2091780 : && known_ne (lhs_ops[j].off, -1))
3723 : {
3724 1061060 : extra_off += -lhs_ops[j].off;
3725 1061060 : j--;
3726 : }
3727 1030720 : if (j != -1)
3728 : return (void *)-1;
3729 : while (i >= 0
3730 2194481 : && known_ne (vr->operands[i].off, -1))
3731 : {
3732 : /* Punt if the additional ops contain a storage order
3733 : barrier. */
3734 1163761 : if (vr->operands[i].opcode == VIEW_CONVERT_EXPR
3735 1163761 : && vr->operands[i].reverse)
3736 : break;
3737 1163761 : extra_off += vr->operands[i].off;
3738 1163761 : i--;
3739 : }
3740 1030720 : if (i != -1)
3741 : return (void *)-1;
3742 : found = true;
3743 : }
3744 : /* If we did find a match we'd eventually append a MEM_REF
3745 : as component. Don't. */
3746 : if (!found)
3747 : return (void *)-1;
3748 : }
3749 : else
3750 : return (void *)-1;
3751 :
3752 : /* Strip further common components, attempting to consume lhs_ops
3753 : in full. */
3754 1984045 : while (j >= 0 && i >= 0
3755 1984045 : && vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3756 : {
3757 26131 : i--;
3758 26131 : j--;
3759 : }
3760 :
3761 : /* i now points to the first additional op.
3762 : ??? LHS may not be completely contained in VR, one or more
3763 : VIEW_CONVERT_EXPRs could be in its way. We could at least
3764 : try handling outermost VIEW_CONVERT_EXPRs. */
3765 1957914 : if (j != -1)
3766 : return (void *)-1;
3767 :
3768 : /* Punt if the additional ops contain a storage order barrier. */
3769 3070987 : for (k = i; k >= 0; k--)
3770 : {
3771 1116138 : vro = &vr->operands[k];
3772 1116138 : if (vro->opcode == VIEW_CONVERT_EXPR && vro->reverse)
3773 : return (void *)-1;
3774 : }
3775 :
3776 : /* Now re-write REF to be based on the rhs of the assignment. */
3777 1954849 : tree rhs1 = gimple_assign_rhs1 (def_stmt);
3778 1954849 : copy_reference_ops_from_ref (rhs1, &rhs);
3779 :
3780 : /* When none of the original operands survives the storage order of
3781 : the translated reference is the one of the RHS of the copy. The
3782 : operands we folded into a constant offset above may well have
3783 : specified a reverse storage order, which is a property of the
3784 : component and not of its position, so it is not recoverable from
3785 : that offset. Punt unless both accesses are in natural order. */
3786 1954849 : if (i < 0
3787 1954849 : && (reverse_storage_order_for_component_p (vr->operands)
3788 1029212 : || reverse_storage_order_for_component_p (rhs)))
3789 : return (void *)-1;
3790 :
3791 : /* Apply an extra offset to the inner MEM_REF of the RHS. */
3792 1954758 : bool force_no_tbaa = false;
3793 1954758 : if (maybe_ne (extra_off, 0))
3794 : {
3795 743525 : if (rhs.length () < 2)
3796 : return (void *)-1;
3797 743525 : int ix = rhs.length () - 2;
3798 743525 : if (rhs[ix].opcode != MEM_REF
3799 743525 : || known_eq (rhs[ix].off, -1))
3800 : return (void *)-1;
3801 743507 : rhs[ix].off += extra_off;
3802 743507 : rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
3803 743507 : build_int_cst (TREE_TYPE (rhs[ix].op0),
3804 : extra_off));
3805 : /* When we have offsetted the RHS, reading only parts of it,
3806 : we can no longer use the original TBAA type, force alias-set
3807 : zero. */
3808 743507 : force_no_tbaa = true;
3809 : }
3810 :
3811 : /* Save the operands since we need to use the original ones for
3812 : the hash entry we use. */
3813 1954740 : if (!data->saved_operands.exists ())
3814 1828665 : data->saved_operands = vr->operands.copy ();
3815 :
3816 : /* We need to pre-pend vr->operands[0..i] to rhs. */
3817 1954740 : vec<vn_reference_op_s> old = vr->operands;
3818 5864220 : if (i + 1 + rhs.length () > vr->operands.length ())
3819 1144230 : vr->operands.safe_grow (i + 1 + rhs.length (), true);
3820 : else
3821 810510 : vr->operands.truncate (i + 1 + rhs.length ());
3822 7054090 : FOR_EACH_VEC_ELT (rhs, j, vro)
3823 5099350 : vr->operands[i + 1 + j] = *vro;
3824 1954740 : valueize_refs (&vr->operands);
3825 3909480 : if (old == shared_lookup_references)
3826 1954740 : shared_lookup_references = vr->operands;
3827 1954740 : vr->hashcode = vn_reference_compute_hash (vr);
3828 :
3829 : /* Try folding the new reference to a constant. */
3830 1954740 : tree val = fully_constant_vn_reference_p (vr);
3831 1954740 : if (val)
3832 : {
3833 22330 : if (data->partial_defs.is_empty ())
3834 22313 : return data->finish (ao_ref_alias_set (&lhs_ref),
3835 22313 : ao_ref_base_alias_set (&lhs_ref), val);
3836 : /* This is the only interesting case for partial-def handling
3837 : coming from targets that like to gimplify init-ctors as
3838 : aggregate copies from constant data like aarch64 for
3839 : PR83518. */
3840 17 : if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
3841 : {
3842 17 : pd_data pd;
3843 17 : pd.rhs = val;
3844 17 : pd.rhs_off = 0;
3845 17 : pd.offset = 0;
3846 17 : pd.size = maxsizei;
3847 17 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3848 : ao_ref_base_alias_set (&lhs_ref),
3849 : 0, maxsizei);
3850 : }
3851 : }
3852 :
3853 : /* Continuing with partial defs isn't easily possible here, we
3854 : have to find a full def from further lookups from here. Probably
3855 : not worth the special-casing everywhere. */
3856 4318357 : if (!data->partial_defs.is_empty ())
3857 : return (void *)-1;
3858 :
3859 : /* Adjust *ref from the new operands. */
3860 1925895 : ao_ref rhs1_ref;
3861 1925895 : ao_ref_init (&rhs1_ref, rhs1);
3862 3122990 : if (!ao_ref_init_from_vn_reference (&r,
3863 : force_no_tbaa ? 0
3864 1197095 : : ao_ref_alias_set (&rhs1_ref),
3865 : force_no_tbaa ? 0
3866 1197095 : : ao_ref_base_alias_set (&rhs1_ref),
3867 : vr->type, vr->operands))
3868 : return (void *)-1;
3869 : /* This can happen with bitfields. */
3870 1925895 : if (maybe_ne (ref->size, r.size))
3871 : {
3872 : /* If the access lacks some subsetting simply apply that by
3873 : shortening it. That in the end can only be successful
3874 : if we can pun the lookup result which in turn requires
3875 : exact offsets. */
3876 1581 : if (known_eq (r.size, r.max_size)
3877 1581 : && known_lt (ref->size, r.size))
3878 1581 : r.size = r.max_size = ref->size;
3879 : else
3880 : return (void *)-1;
3881 : }
3882 1925895 : *ref = r;
3883 1925895 : vr->offset = r.offset;
3884 1925895 : vr->max_size = r.max_size;
3885 :
3886 : /* Do not update last seen VUSE after translating. */
3887 1925895 : data->last_vuse_ptr = NULL;
3888 : /* Invalidate the original access path since it now contains
3889 : the wrong base. */
3890 1925895 : data->orig_ref.ref = NULL_TREE;
3891 : /* Use the alias-set of this LHS for recording an eventual result. */
3892 1925895 : if (data->first_set == -2)
3893 : {
3894 1801476 : data->first_set = ao_ref_alias_set (&lhs_ref);
3895 1801476 : data->first_base_set = ao_ref_base_alias_set (&lhs_ref);
3896 : }
3897 :
3898 : /* Keep looking for the adjusted *REF / VR pair. */
3899 : return NULL;
3900 2385947 : }
3901 :
3902 : /* 6) For memcpy copies translate the reference through them if the copy
3903 : kills ref. But we cannot (easily) do this translation if the memcpy is
3904 : a storage order barrier, i.e. is equivalent to a VIEW_CONVERT_EXPR that
3905 : can modify the storage order of objects (see storage_order_barrier_p). */
3906 16930713 : else if (data->vn_walk_kind == VN_WALKREWRITE
3907 13199550 : && is_gimple_reg_type (vr->type)
3908 : /* ??? Handle BCOPY as well. */
3909 13190164 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
3910 13119686 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
3911 13119263 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
3912 13118087 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
3913 13117845 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
3914 13091847 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
3915 98645 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3916 86773 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
3917 98609 : && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
3918 69947 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
3919 98594 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), ©_size)
3920 56786 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3921 56786 : && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)),
3922 : ©_size)))
3923 : /* Handling this is more complicated, give up for now. */
3924 16975134 : && data->partial_defs.is_empty ())
3925 : {
3926 43727 : tree lhs, rhs;
3927 43727 : ao_ref r;
3928 43727 : poly_int64 rhs_offset, lhs_offset;
3929 43727 : vn_reference_op_s op;
3930 43727 : poly_uint64 mem_offset;
3931 43727 : poly_int64 at, byte_maxsize;
3932 :
3933 : /* Only handle non-variable, addressable refs. */
3934 43727 : if (maybe_ne (ref->size, maxsize)
3935 43205 : || !multiple_p (offset, BITS_PER_UNIT, &at)
3936 86996 : || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize))
3937 : return (void *)-1;
3938 :
3939 : /* Extract a pointer base and an offset for the destination. */
3940 43205 : lhs = gimple_call_arg (def_stmt, 0);
3941 43205 : lhs_offset = 0;
3942 43205 : if (TREE_CODE (lhs) == SSA_NAME)
3943 : {
3944 33060 : lhs = vn_valueize (lhs);
3945 33060 : if (TREE_CODE (lhs) == SSA_NAME)
3946 : {
3947 32731 : gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
3948 32731 : if (gimple_assign_single_p (def_stmt)
3949 32731 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3950 2524 : lhs = gimple_assign_rhs1 (def_stmt);
3951 : }
3952 : }
3953 43205 : if (TREE_CODE (lhs) == ADDR_EXPR)
3954 : {
3955 18172 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
3956 17875 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (lhs))))
3957 : return (void *)-1;
3958 12858 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0),
3959 : &lhs_offset);
3960 12858 : if (!tem)
3961 : return (void *)-1;
3962 12112 : if (TREE_CODE (tem) == MEM_REF
3963 12112 : && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3964 : {
3965 1778 : lhs = TREE_OPERAND (tem, 0);
3966 1778 : if (TREE_CODE (lhs) == SSA_NAME)
3967 1778 : lhs = vn_valueize (lhs);
3968 1778 : lhs_offset += mem_offset;
3969 : }
3970 10334 : else if (DECL_P (tem))
3971 10334 : lhs = build_fold_addr_expr (tem);
3972 : else
3973 : return (void *)-1;
3974 : }
3975 42319 : if (TREE_CODE (lhs) != SSA_NAME
3976 10335 : && TREE_CODE (lhs) != ADDR_EXPR)
3977 : return (void *)-1;
3978 :
3979 : /* Extract a pointer base and an offset for the source. */
3980 42319 : rhs = gimple_call_arg (def_stmt, 1);
3981 42319 : rhs_offset = 0;
3982 42319 : if (TREE_CODE (rhs) == SSA_NAME)
3983 19751 : rhs = vn_valueize (rhs);
3984 42319 : if (TREE_CODE (rhs) == ADDR_EXPR)
3985 : {
3986 35345 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (rhs)))
3987 24816 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (rhs))))
3988 : return (void *)-1;
3989 24188 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0),
3990 : &rhs_offset);
3991 24188 : if (!tem)
3992 : return (void *)-1;
3993 24188 : if (TREE_CODE (tem) == MEM_REF
3994 24188 : && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3995 : {
3996 0 : rhs = TREE_OPERAND (tem, 0);
3997 0 : rhs_offset += mem_offset;
3998 : }
3999 24188 : else if (DECL_P (tem)
4000 17694 : || TREE_CODE (tem) == STRING_CST)
4001 24188 : rhs = build_fold_addr_expr (tem);
4002 : else
4003 : return (void *)-1;
4004 : }
4005 42319 : if (TREE_CODE (rhs) == SSA_NAME)
4006 18131 : rhs = SSA_VAL (rhs);
4007 24188 : else if (TREE_CODE (rhs) != ADDR_EXPR)
4008 : return (void *)-1;
4009 :
4010 : /* The bases of the destination and the references have to agree. */
4011 42319 : if (TREE_CODE (base) == MEM_REF)
4012 : {
4013 16009 : if (TREE_OPERAND (base, 0) != lhs
4014 16009 : || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset))
4015 : return (void *) -1;
4016 12863 : at += mem_offset;
4017 : }
4018 26310 : else if (!DECL_P (base)
4019 25305 : || TREE_CODE (lhs) != ADDR_EXPR
4020 35463 : || TREE_OPERAND (lhs, 0) != base)
4021 : return (void *)-1;
4022 :
4023 : /* If the access is completely outside of the memcpy destination
4024 : area there is no aliasing. */
4025 12863 : if (!ranges_maybe_overlap_p (lhs_offset, copy_size, at, byte_maxsize))
4026 : return NULL;
4027 : /* And the access has to be contained within the memcpy destination. */
4028 12830 : if (!known_subrange_p (at, byte_maxsize, lhs_offset, copy_size))
4029 : return (void *)-1;
4030 :
4031 : /* Save the operands since we need to use the original ones for
4032 : the hash entry we use. */
4033 12213 : if (!data->saved_operands.exists ())
4034 11774 : data->saved_operands = vr->operands.copy ();
4035 :
4036 : /* Make room for 2 operands in the new reference. */
4037 12213 : if (vr->operands.length () < 2)
4038 : {
4039 0 : vec<vn_reference_op_s> old = vr->operands;
4040 0 : vr->operands.safe_grow_cleared (2, true);
4041 0 : if (old == shared_lookup_references)
4042 0 : shared_lookup_references = vr->operands;
4043 : }
4044 : else
4045 12213 : vr->operands.truncate (2);
4046 :
4047 : /* The looked-through reference is a simple MEM_REF. */
4048 12213 : memset (&op, 0, sizeof (op));
4049 12213 : op.type = vr->type;
4050 12213 : op.opcode = MEM_REF;
4051 12213 : op.op0 = build_int_cst (ptr_type_node, at - lhs_offset + rhs_offset);
4052 12213 : op.off = at - lhs_offset + rhs_offset;
4053 12213 : vr->operands[0] = op;
4054 12213 : op.type = TREE_TYPE (rhs);
4055 12213 : op.opcode = TREE_CODE (rhs);
4056 12213 : op.op0 = rhs;
4057 12213 : op.off = -1;
4058 12213 : vr->operands[1] = op;
4059 12213 : vr->hashcode = vn_reference_compute_hash (vr);
4060 :
4061 : /* Try folding the new reference to a constant. */
4062 12213 : tree val = fully_constant_vn_reference_p (vr);
4063 12213 : if (val)
4064 3231 : return data->finish (0, 0, val);
4065 :
4066 : /* Adjust *ref from the new operands. */
4067 8982 : if (!ao_ref_init_from_vn_reference (&r, 0, 0, vr->type, vr->operands))
4068 : return (void *)-1;
4069 : /* This can happen with bitfields. */
4070 8982 : if (maybe_ne (ref->size, r.size))
4071 : return (void *)-1;
4072 8982 : *ref = r;
4073 8982 : vr->offset = r.offset;
4074 8982 : vr->max_size = r.max_size;
4075 :
4076 : /* Do not update last seen VUSE after translating. */
4077 8982 : data->last_vuse_ptr = NULL;
4078 : /* Invalidate the original access path since it now contains
4079 : the wrong base. */
4080 8982 : data->orig_ref.ref = NULL_TREE;
4081 : /* Use the alias-set of this stmt for recording an eventual result. */
4082 8982 : if (data->first_set == -2)
4083 : {
4084 8594 : data->first_set = 0;
4085 8594 : data->first_base_set = 0;
4086 : }
4087 :
4088 : /* Keep looking for the adjusted *REF / VR pair. */
4089 : return NULL;
4090 : }
4091 :
4092 : /* Bail out and stop walking. */
4093 : return (void *)-1;
4094 : }
4095 :
4096 : /* Return true if E is a backedge with respect to our CFG walk order. */
4097 :
4098 : static bool
4099 214087903 : vn_is_backedge (edge e, void *)
4100 : {
4101 : /* During PRE elimination we no longer have access to this info. */
4102 214087903 : return (!vn_bb_to_rpo
4103 214087903 : || vn_bb_to_rpo[e->dest->index] <= vn_bb_to_rpo[e->src->index]);
4104 : }
4105 :
4106 : /* Return a reference op vector from OP that can be used for
4107 : vn_reference_lookup_pieces. The caller is responsible for releasing
4108 : the vector. */
4109 :
4110 : vec<vn_reference_op_s>
4111 4927416 : vn_reference_operands_for_lookup (tree op)
4112 : {
4113 4927416 : bool valueized;
4114 4927416 : return valueize_shared_reference_ops_from_ref (op, &valueized).copy ();
4115 : }
4116 :
4117 : /* Lookup a reference operation by it's parts, in the current hash table.
4118 : Returns the resulting value number if it exists in the hash table,
4119 : NULL_TREE otherwise. VNRESULT will be filled in with the actual
4120 : vn_reference_t stored in the hashtable if something is found. */
4121 :
4122 : tree
4123 8053278 : vn_reference_lookup_pieces (tree vuse, alias_set_type set,
4124 : alias_set_type base_set, tree type,
4125 : vec<vn_reference_op_s> operands,
4126 : vn_reference_t *vnresult, vn_lookup_kind kind)
4127 : {
4128 8053278 : struct vn_reference_s vr1;
4129 8053278 : vn_reference_t tmp;
4130 8053278 : tree cst;
4131 :
4132 8053278 : if (!vnresult)
4133 0 : vnresult = &tmp;
4134 8053278 : *vnresult = NULL;
4135 :
4136 8053278 : vr1.vuse = vuse_ssa_val (vuse);
4137 8053278 : shared_lookup_references.truncate (0);
4138 16106556 : shared_lookup_references.safe_grow (operands.length (), true);
4139 8053278 : memcpy (shared_lookup_references.address (),
4140 8053278 : operands.address (),
4141 : sizeof (vn_reference_op_s)
4142 8053278 : * operands.length ());
4143 8053278 : bool valueized_p;
4144 8053278 : valueize_refs_1 (&shared_lookup_references, &valueized_p);
4145 8053278 : vr1.operands = shared_lookup_references;
4146 8053278 : vr1.type = type;
4147 8053278 : vr1.set = set;
4148 8053278 : vr1.base_set = base_set;
4149 : /* We can pretend there's no extra info fed in since the ao_refs offset
4150 : and max_size are computed only from the VN reference ops. */
4151 8053278 : vr1.offset = 0;
4152 8053278 : vr1.max_size = -1;
4153 8053278 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4154 8053278 : if ((cst = fully_constant_vn_reference_p (&vr1)))
4155 : return cst;
4156 :
4157 8033305 : vn_reference_lookup_1 (&vr1, vnresult);
4158 8033305 : if (!*vnresult
4159 3091619 : && kind != VN_NOWALK
4160 3091619 : && vr1.vuse)
4161 : {
4162 3061374 : ao_ref r;
4163 3061374 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4164 3061374 : vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE,
4165 3061374 : false);
4166 3061374 : vec<vn_reference_op_s> ops_for_ref;
4167 3061374 : if (!valueized_p)
4168 2966120 : ops_for_ref = vr1.operands;
4169 : else
4170 : {
4171 : /* For ao_ref_from_mem we have to ensure only available SSA names
4172 : end up in base and the only convenient way to make this work
4173 : for PRE is to re-valueize with that in mind. */
4174 190508 : ops_for_ref.create (operands.length ());
4175 190508 : ops_for_ref.quick_grow (operands.length ());
4176 95254 : memcpy (ops_for_ref.address (),
4177 95254 : operands.address (),
4178 : sizeof (vn_reference_op_s)
4179 95254 : * operands.length ());
4180 95254 : valueize_refs_1 (&ops_for_ref, &valueized_p, true);
4181 : }
4182 3061374 : if (ao_ref_init_from_vn_reference (&r, set, base_set, type,
4183 : ops_for_ref))
4184 2987689 : *vnresult
4185 2987689 : = ((vn_reference_t)
4186 2987689 : walk_non_aliased_vuses (&r, vr1.vuse, true, vn_reference_lookup_2,
4187 : vn_reference_lookup_3, vn_is_backedge,
4188 : vuse_valueize, limit, &data));
4189 6122748 : if (ops_for_ref != shared_lookup_references)
4190 95254 : ops_for_ref.release ();
4191 6122748 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4192 3061374 : if (*vnresult
4193 433827 : && data.same_val
4194 3061374 : && (!(*vnresult)->result
4195 0 : || !operand_equal_p ((*vnresult)->result, data.same_val)))
4196 : {
4197 0 : *vnresult = NULL;
4198 0 : return NULL_TREE;
4199 : }
4200 3061374 : }
4201 :
4202 8033305 : if (*vnresult)
4203 5375513 : return (*vnresult)->result;
4204 :
4205 : return NULL_TREE;
4206 : }
4207 :
4208 : /* When OPERANDS is an ADDR_EXPR that can be possibly expressed as a
4209 : POINTER_PLUS_EXPR return true and fill in its operands in OPS. */
4210 :
4211 : bool
4212 2315772 : vn_pp_nary_for_addr (const vec<vn_reference_op_s>& operands, tree ops[2])
4213 : {
4214 4631544 : gcc_assert (operands[0].opcode == ADDR_EXPR
4215 : && operands.last ().opcode == SSA_NAME);
4216 : poly_int64 off = 0;
4217 : vn_reference_op_t vro;
4218 : unsigned i;
4219 7519434 : for (i = 1; operands.iterate (i, &vro); ++i)
4220 : {
4221 7519434 : if (vro->opcode == SSA_NAME)
4222 : break;
4223 5254696 : else if (known_eq (vro->off, -1))
4224 : break;
4225 5203662 : off += vro->off;
4226 : }
4227 2315772 : if (i == operands.length () - 1
4228 2264738 : && maybe_ne (off, 0)
4229 : /* Make sure we the offset we accumulated in a 64bit int
4230 : fits the address computation carried out in target
4231 : offset precision. */
4232 3821044 : && (off.coeffs[0]
4233 1505272 : == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
4234 : {
4235 1504732 : gcc_assert (operands[i-1].opcode == MEM_REF);
4236 1504732 : ops[0] = operands[i].op0;
4237 1504732 : ops[1] = wide_int_to_tree (sizetype, off);
4238 1504732 : return true;
4239 : }
4240 : return false;
4241 : }
4242 :
4243 : /* Lookup OP in the current hash table, and return the resulting value
4244 : number if it exists in the hash table. Return NULL_TREE if it does
4245 : not exist in the hash table or if the result field of the structure
4246 : was NULL.. VNRESULT will be filled in with the vn_reference_t
4247 : stored in the hashtable if one exists. When TBAA_P is false assume
4248 : we are looking up a store and treat it as having alias-set zero.
4249 : *LAST_VUSE_PTR will be updated with the VUSE the value lookup succeeded.
4250 : MASK is either NULL_TREE, or can be an INTEGER_CST if the result of the
4251 : load is bitwise anded with MASK and so we are only interested in a subset
4252 : of the bits and can ignore if the other bits are uninitialized or
4253 : not initialized with constants. When doing redundant store removal
4254 : the caller has to set REDUNDANT_STORE_REMOVAL_P. */
4255 :
4256 : tree
4257 103991618 : vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
4258 : vn_reference_t *vnresult, bool tbaa_p,
4259 : tree *last_vuse_ptr, tree mask,
4260 : bool redundant_store_removal_p)
4261 : {
4262 103991618 : vec<vn_reference_op_s> operands;
4263 103991618 : struct vn_reference_s vr1;
4264 103991618 : bool valueized_anything;
4265 :
4266 103991618 : if (vnresult)
4267 103602204 : *vnresult = NULL;
4268 :
4269 103991618 : vr1.vuse = vuse_ssa_val (vuse);
4270 207983236 : vr1.operands = operands
4271 103991618 : = valueize_shared_reference_ops_from_ref (op, &valueized_anything);
4272 :
4273 : /* Handle &MEM[ptr + 5].b[1].c as POINTER_PLUS_EXPR. Avoid doing
4274 : this before the pass folding __builtin_object_size had a chance to run. */
4275 103991618 : if ((cfun->curr_properties & PROP_objsz)
4276 75466185 : && operands[0].opcode == ADDR_EXPR
4277 105151565 : && operands.last ().opcode == SSA_NAME)
4278 : {
4279 1125247 : tree ops[2];
4280 1125247 : if (vn_pp_nary_for_addr (operands, ops))
4281 : {
4282 732307 : tree res = vn_nary_op_lookup_pieces (2, POINTER_PLUS_EXPR,
4283 732307 : TREE_TYPE (op), ops, NULL);
4284 732307 : if (res)
4285 732307 : return res;
4286 732307 : return NULL_TREE;
4287 : }
4288 : }
4289 :
4290 103259311 : vr1.type = TREE_TYPE (op);
4291 103259311 : ao_ref op_ref;
4292 103259311 : ao_ref_init (&op_ref, op);
4293 103259311 : vr1.set = ao_ref_alias_set (&op_ref);
4294 103259311 : vr1.base_set = ao_ref_base_alias_set (&op_ref);
4295 103259311 : vr1.offset = 0;
4296 103259311 : vr1.max_size = -1;
4297 103259311 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4298 103259311 : if (mask == NULL_TREE)
4299 102940925 : if (tree cst = fully_constant_vn_reference_p (&vr1))
4300 : return cst;
4301 :
4302 103243221 : if (kind != VN_NOWALK && vr1.vuse)
4303 : {
4304 60060627 : vn_reference_t wvnresult;
4305 60060627 : ao_ref r;
4306 60060627 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4307 60060627 : auto_vec<vn_reference_op_s> ops_for_ref;
4308 60060627 : if (valueized_anything)
4309 : {
4310 4771978 : copy_reference_ops_from_ref (op, &ops_for_ref);
4311 4771978 : bool tem;
4312 4771978 : valueize_refs_1 (&ops_for_ref, &tem, true);
4313 : }
4314 : /* Make sure to use a valueized reference if we valueized anything.
4315 : Otherwise preserve the full reference for advanced TBAA. */
4316 60060627 : if (!valueized_anything
4317 60060627 : || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
4318 : vr1.type, ops_for_ref))
4319 : {
4320 55288649 : ao_ref_init (&r, op);
4321 : /* Record the extra info we're getting from the full ref. */
4322 55288649 : ao_ref_base (&r);
4323 55288649 : vr1.offset = r.offset;
4324 55288649 : vr1.max_size = r.max_size;
4325 : }
4326 60060627 : vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
4327 : last_vuse_ptr, kind, tbaa_p, mask,
4328 115349276 : redundant_store_removal_p);
4329 :
4330 60060627 : wvnresult
4331 : = ((vn_reference_t)
4332 60060627 : walk_non_aliased_vuses (&r, vr1.vuse, tbaa_p, vn_reference_lookup_2,
4333 : vn_reference_lookup_3, vn_is_backedge,
4334 : vuse_valueize, limit, &data));
4335 120121254 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4336 60060627 : if (wvnresult)
4337 : {
4338 8965061 : gcc_assert (mask == NULL_TREE);
4339 8965061 : if (data.same_val
4340 8965061 : && (!wvnresult->result
4341 69341 : || !operand_equal_p (wvnresult->result, data.same_val)))
4342 : return NULL_TREE;
4343 8915970 : if (vnresult)
4344 8914145 : *vnresult = wvnresult;
4345 8915970 : return wvnresult->result;
4346 : }
4347 51095566 : else if (mask)
4348 318386 : return data.masked_result;
4349 :
4350 : return NULL_TREE;
4351 60060627 : }
4352 :
4353 43182594 : if (last_vuse_ptr)
4354 1508592 : *last_vuse_ptr = vr1.vuse;
4355 43182594 : if (mask)
4356 : return NULL_TREE;
4357 43182594 : return vn_reference_lookup_1 (&vr1, vnresult);
4358 : }
4359 :
4360 : /* Lookup CALL in the current hash table and return the entry in
4361 : *VNRESULT if found. Populates *VR for the hashtable lookup. */
4362 :
4363 : void
4364 9514776 : vn_reference_lookup_call (gcall *call, vn_reference_t *vnresult,
4365 : vn_reference_t vr)
4366 : {
4367 9514776 : if (vnresult)
4368 9514776 : *vnresult = NULL;
4369 :
4370 9514776 : tree vuse = gimple_vuse (call);
4371 :
4372 9514776 : vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
4373 9514776 : vr->operands = valueize_shared_reference_ops_from_call (call);
4374 9514776 : tree lhs = gimple_call_lhs (call);
4375 : /* For non-SSA return values the reference ops contain the LHS. */
4376 5141247 : vr->type = ((lhs && TREE_CODE (lhs) == SSA_NAME)
4377 14199255 : ? TREE_TYPE (lhs) : NULL_TREE);
4378 9514776 : vr->punned = false;
4379 9514776 : vr->set = 0;
4380 9514776 : vr->base_set = 0;
4381 9514776 : vr->offset = 0;
4382 9514776 : vr->max_size = -1;
4383 9514776 : vr->hashcode = vn_reference_compute_hash (vr);
4384 9514776 : vn_reference_lookup_1 (vr, vnresult);
4385 9514776 : }
4386 :
4387 : /* Insert OP into the current hash table with a value number of RESULT. */
4388 :
4389 : static void
4390 77151119 : vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
4391 : {
4392 77151119 : vn_reference_s **slot;
4393 77151119 : vn_reference_t vr1;
4394 77151119 : bool tem;
4395 :
4396 77151119 : vec<vn_reference_op_s> operands
4397 77151119 : = valueize_shared_reference_ops_from_ref (op, &tem);
4398 : /* Handle &MEM[ptr + 5].b[1].c as POINTER_PLUS_EXPR. Avoid doing this
4399 : before the pass folding __builtin_object_size had a chance to run. */
4400 77151119 : if ((cfun->curr_properties & PROP_objsz)
4401 57915088 : && operands[0].opcode == ADDR_EXPR
4402 78103734 : && operands.last ().opcode == SSA_NAME)
4403 : {
4404 920383 : tree ops[2];
4405 920383 : if (vn_pp_nary_for_addr (operands, ops))
4406 : {
4407 590762 : vn_nary_op_insert_pieces (2, POINTER_PLUS_EXPR,
4408 590762 : TREE_TYPE (op), ops, result,
4409 590762 : VN_INFO (result)->value_id);
4410 590762 : return;
4411 : }
4412 : }
4413 :
4414 76560357 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4415 76560357 : if (TREE_CODE (result) == SSA_NAME)
4416 52987684 : vr1->value_id = VN_INFO (result)->value_id;
4417 : else
4418 23572673 : vr1->value_id = get_or_alloc_constant_value_id (result);
4419 76560357 : vr1->vuse = vuse_ssa_val (vuse);
4420 76560357 : vr1->operands = operands.copy ();
4421 76560357 : vr1->type = TREE_TYPE (op);
4422 76560357 : vr1->punned = false;
4423 76560357 : ao_ref op_ref;
4424 76560357 : ao_ref_init (&op_ref, op);
4425 76560357 : vr1->set = ao_ref_alias_set (&op_ref);
4426 76560357 : vr1->base_set = ao_ref_base_alias_set (&op_ref);
4427 : /* Specifically use an unknown extent here, we're not doing any lookup
4428 : and assume the caller didn't either (or it went VARYING). */
4429 76560357 : vr1->offset = 0;
4430 76560357 : vr1->max_size = -1;
4431 76560357 : vr1->hashcode = vn_reference_compute_hash (vr1);
4432 76560357 : vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
4433 76560357 : vr1->result_vdef = vdef;
4434 :
4435 76560357 : slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
4436 : INSERT);
4437 :
4438 : /* Because IL walking on reference lookup can end up visiting
4439 : a def that is only to be visited later in iteration order
4440 : when we are about to make an irreducible region reducible
4441 : the def can be effectively processed and its ref being inserted
4442 : by vn_reference_lookup_3 already. So we cannot assert (!*slot)
4443 : but save a lookup if we deal with already inserted refs here. */
4444 76560357 : if (*slot)
4445 : {
4446 : /* We cannot assert that we have the same value either because
4447 : when disentangling an irreducible region we may end up visiting
4448 : a use before the corresponding def. That's a missed optimization
4449 : only though. See gcc.dg/tree-ssa/pr87126.c for example. */
4450 0 : if (dump_file && (dump_flags & TDF_DETAILS)
4451 0 : && !operand_equal_p ((*slot)->result, vr1->result, 0))
4452 : {
4453 0 : fprintf (dump_file, "Keeping old value ");
4454 0 : print_generic_expr (dump_file, (*slot)->result);
4455 0 : fprintf (dump_file, " because of collision\n");
4456 : }
4457 0 : free_reference (vr1);
4458 0 : obstack_free (&vn_tables_obstack, vr1);
4459 : return;
4460 : }
4461 :
4462 76560357 : *slot = vr1;
4463 76560357 : vr1->next = last_inserted_ref;
4464 76560357 : last_inserted_ref = vr1;
4465 : }
4466 :
4467 : /* Insert a reference by it's pieces into the current hash table with
4468 : a value number of RESULT. Return the resulting reference
4469 : structure we created. */
4470 :
4471 : vn_reference_t
4472 1625230 : vn_reference_insert_pieces (tree vuse, alias_set_type set,
4473 : alias_set_type base_set,
4474 : poly_int64 offset, poly_int64 max_size, tree type,
4475 : vec<vn_reference_op_s> operands,
4476 : tree result, unsigned int value_id)
4477 :
4478 : {
4479 1625230 : vn_reference_s **slot;
4480 1625230 : vn_reference_t vr1;
4481 :
4482 1625230 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4483 1625230 : vr1->value_id = value_id;
4484 1625230 : vr1->vuse = vuse_ssa_val (vuse);
4485 1625230 : vr1->operands = operands;
4486 1625230 : valueize_refs (&vr1->operands);
4487 1625230 : vr1->type = type;
4488 1625230 : vr1->punned = false;
4489 1625230 : vr1->set = set;
4490 1625230 : vr1->base_set = base_set;
4491 1625230 : vr1->offset = offset;
4492 1625230 : vr1->max_size = max_size;
4493 1625230 : vr1->hashcode = vn_reference_compute_hash (vr1);
4494 1625230 : if (result && TREE_CODE (result) == SSA_NAME)
4495 390769 : result = SSA_VAL (result);
4496 1625230 : vr1->result = result;
4497 1625230 : vr1->result_vdef = NULL_TREE;
4498 :
4499 1625230 : slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
4500 : INSERT);
4501 :
4502 : /* At this point we should have all the things inserted that we have
4503 : seen before, and we should never try inserting something that
4504 : already exists. */
4505 1625230 : gcc_assert (!*slot);
4506 :
4507 1625230 : *slot = vr1;
4508 1625230 : vr1->next = last_inserted_ref;
4509 1625230 : last_inserted_ref = vr1;
4510 1625230 : return vr1;
4511 : }
4512 :
4513 : /* Compute and return the hash value for nary operation VBO1. */
4514 :
4515 : hashval_t
4516 311757123 : vn_nary_op_compute_hash (const vn_nary_op_t vno1)
4517 : {
4518 311757123 : inchash::hash hstate;
4519 311757123 : unsigned i;
4520 :
4521 311757123 : if (((vno1->length == 2
4522 262404605 : && commutative_tree_code (vno1->opcode))
4523 142577057 : || (vno1->length == 3
4524 1657921 : && commutative_ternary_tree_code (vno1->opcode)))
4525 480939452 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4526 2508582 : std::swap (vno1->op[0], vno1->op[1]);
4527 309248541 : else if (TREE_CODE_CLASS (vno1->opcode) == tcc_comparison
4528 309248541 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4529 : {
4530 475677 : std::swap (vno1->op[0], vno1->op[1]);
4531 475677 : vno1->opcode = swap_tree_comparison (vno1->opcode);
4532 : }
4533 :
4534 311757123 : hstate.add_int (vno1->opcode);
4535 890047110 : for (i = 0; i < vno1->length; ++i)
4536 578289987 : inchash::add_expr (vno1->op[i], hstate);
4537 :
4538 311757123 : return hstate.end ();
4539 : }
4540 :
4541 : /* Compare nary operations VNO1 and VNO2 and return true if they are
4542 : equivalent. */
4543 :
4544 : bool
4545 978766642 : vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
4546 : {
4547 978766642 : unsigned i;
4548 :
4549 978766642 : if (vno1->hashcode != vno2->hashcode)
4550 : return false;
4551 :
4552 51807230 : if (vno1->length != vno2->length)
4553 : return false;
4554 :
4555 51807230 : if (vno1->opcode != vno2->opcode
4556 51807230 : || !types_compatible_p (vno1->type, vno2->type))
4557 : return false;
4558 :
4559 146311160 : for (i = 0; i < vno1->length; ++i)
4560 95792125 : if (!expressions_equal_p (vno1->op[i], vno2->op[i]))
4561 : return false;
4562 :
4563 : /* BIT_INSERT_EXPR has an implicit operand as the type precision
4564 : of op1. Need to check to make sure they are the same. */
4565 50519035 : if (vno1->opcode == BIT_INSERT_EXPR
4566 581 : && TREE_CODE (vno1->op[1]) == INTEGER_CST
4567 50519163 : && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
4568 128 : != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
4569 0 : return false;
4570 :
4571 : return true;
4572 : }
4573 :
4574 : /* Initialize VNO from the pieces provided. */
4575 :
4576 : static void
4577 193452785 : init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
4578 : enum tree_code code, tree type, tree *ops)
4579 : {
4580 193452785 : vno->opcode = code;
4581 193452785 : vno->length = length;
4582 193452785 : vno->type = type;
4583 4908794 : memcpy (&vno->op[0], ops, sizeof (tree) * length);
4584 0 : }
4585 :
4586 : /* Return the number of operands for a vn_nary ops structure from STMT. */
4587 :
4588 : unsigned int
4589 112125042 : vn_nary_length_from_stmt (gimple *stmt)
4590 : {
4591 112125042 : switch (gimple_assign_rhs_code (stmt))
4592 : {
4593 : case REALPART_EXPR:
4594 : case IMAGPART_EXPR:
4595 : case VIEW_CONVERT_EXPR:
4596 : return 1;
4597 :
4598 640342 : case BIT_FIELD_REF:
4599 640342 : return 3;
4600 :
4601 552743 : case CONSTRUCTOR:
4602 552743 : return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4603 :
4604 107226989 : default:
4605 107226989 : return gimple_num_ops (stmt) - 1;
4606 : }
4607 : }
4608 :
4609 : /* Initialize VNO from STMT. */
4610 :
4611 : void
4612 112125042 : init_vn_nary_op_from_stmt (vn_nary_op_t vno, gassign *stmt)
4613 : {
4614 112125042 : unsigned i;
4615 :
4616 112125042 : vno->opcode = gimple_assign_rhs_code (stmt);
4617 112125042 : vno->type = TREE_TYPE (gimple_assign_lhs (stmt));
4618 112125042 : switch (vno->opcode)
4619 : {
4620 3704968 : case REALPART_EXPR:
4621 3704968 : case IMAGPART_EXPR:
4622 3704968 : case VIEW_CONVERT_EXPR:
4623 3704968 : vno->length = 1;
4624 3704968 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4625 3704968 : break;
4626 :
4627 640342 : case BIT_FIELD_REF:
4628 640342 : vno->length = 3;
4629 640342 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4630 640342 : vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
4631 640342 : vno->op[2] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
4632 640342 : break;
4633 :
4634 552743 : case CONSTRUCTOR:
4635 552743 : vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4636 2197012 : for (i = 0; i < vno->length; ++i)
4637 1644269 : vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
4638 : break;
4639 :
4640 107226989 : default:
4641 107226989 : gcc_checking_assert (!gimple_assign_single_p (stmt));
4642 107226989 : vno->length = gimple_num_ops (stmt) - 1;
4643 293802461 : for (i = 0; i < vno->length; ++i)
4644 186575472 : vno->op[i] = gimple_op (stmt, i + 1);
4645 : }
4646 112125042 : }
4647 :
4648 : /* Compute the hashcode for VNO and look for it in the hash table;
4649 : return the resulting value number if it exists in the hash table.
4650 : Return NULL_TREE if it does not exist in the hash table or if the
4651 : result field of the operation is NULL. VNRESULT will contain the
4652 : vn_nary_op_t from the hashtable if it exists. */
4653 :
4654 : static tree
4655 135401827 : vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
4656 : {
4657 135401827 : vn_nary_op_s **slot;
4658 :
4659 135401827 : if (vnresult)
4660 127398029 : *vnresult = NULL;
4661 :
4662 376551798 : for (unsigned i = 0; i < vno->length; ++i)
4663 241149971 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4664 170467702 : vno->op[i] = SSA_VAL (vno->op[i]);
4665 :
4666 135401827 : vno->hashcode = vn_nary_op_compute_hash (vno);
4667 135401827 : slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
4668 135401827 : if (!slot)
4669 : return NULL_TREE;
4670 18243039 : if (vnresult)
4671 17777095 : *vnresult = *slot;
4672 18243039 : return (*slot)->predicated_values ? NULL_TREE : (*slot)->u.result;
4673 : }
4674 :
4675 : /* Lookup a n-ary operation by its pieces and return the resulting value
4676 : number if it exists in the hash table. Return NULL_TREE if it does
4677 : not exist in the hash table or if the result field of the operation
4678 : is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
4679 : if it exists. */
4680 :
4681 : tree
4682 77345148 : vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
4683 : tree type, tree *ops, vn_nary_op_t *vnresult)
4684 : {
4685 77345148 : vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
4686 : sizeof_vn_nary_op (length));
4687 77345148 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4688 77345148 : return vn_nary_op_lookup_1 (vno1, vnresult);
4689 : }
4690 :
4691 : /* Lookup the rhs of STMT in the current hash table, and return the resulting
4692 : value number if it exists in the hash table. Return NULL_TREE if
4693 : it does not exist in the hash table. VNRESULT will contain the
4694 : vn_nary_op_t from the hashtable if it exists. */
4695 :
4696 : tree
4697 58056679 : vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
4698 : {
4699 58056679 : vn_nary_op_t vno1
4700 58056679 : = XALLOCAVAR (struct vn_nary_op_s,
4701 : sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
4702 58056679 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
4703 58056679 : return vn_nary_op_lookup_1 (vno1, vnresult);
4704 : }
4705 :
4706 : /* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
4707 :
4708 : vn_nary_op_t
4709 175368085 : alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
4710 : {
4711 175368085 : return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
4712 : }
4713 :
4714 : /* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's
4715 : obstack. */
4716 :
4717 : static vn_nary_op_t
4718 157512071 : alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
4719 : {
4720 0 : vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack);
4721 :
4722 157512071 : vno1->value_id = value_id;
4723 157512071 : vno1->length = length;
4724 157512071 : vno1->predicated_values = 0;
4725 157512071 : vno1->u.result = result;
4726 :
4727 157512071 : return vno1;
4728 : }
4729 :
4730 : /* Insert VNO into TABLE. */
4731 :
4732 : static vn_nary_op_t
4733 162570037 : vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table)
4734 : {
4735 162570037 : vn_nary_op_s **slot;
4736 :
4737 162570037 : gcc_assert (! vno->predicated_values
4738 : || (! vno->u.values->next
4739 : && vno->u.values->n == 1));
4740 :
4741 475705666 : for (unsigned i = 0; i < vno->length; ++i)
4742 313135629 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4743 203826267 : vno->op[i] = SSA_VAL (vno->op[i]);
4744 :
4745 162570037 : vno->hashcode = vn_nary_op_compute_hash (vno);
4746 162570037 : slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT);
4747 162570037 : vno->unwind_to = *slot;
4748 162570037 : if (*slot)
4749 : {
4750 : /* Prefer non-predicated values.
4751 : ??? Only if those are constant, otherwise, with constant predicated
4752 : value, turn them into predicated values with entry-block validity
4753 : (??? but we always find the first valid result currently). */
4754 31288785 : if ((*slot)->predicated_values
4755 30546864 : && ! vno->predicated_values)
4756 : {
4757 : /* ??? We cannot remove *slot from the unwind stack list.
4758 : For the moment we deal with this by skipping not found
4759 : entries but this isn't ideal ... */
4760 73558 : *slot = vno;
4761 : /* ??? Maintain a stack of states we can unwind in
4762 : vn_nary_op_s? But how far do we unwind? In reality
4763 : we need to push change records somewhere... Or not
4764 : unwind vn_nary_op_s and linking them but instead
4765 : unwind the results "list", linking that, which also
4766 : doesn't move on hashtable resize. */
4767 : /* We can also have a ->unwind_to recording *slot there.
4768 : That way we can make u.values a fixed size array with
4769 : recording the number of entries but of course we then
4770 : have always N copies for each unwind_to-state. Or we
4771 : make sure to only ever append and each unwinding will
4772 : pop off one entry (but how to deal with predicated
4773 : replaced with non-predicated here?) */
4774 73558 : vno->next = last_inserted_nary;
4775 73558 : last_inserted_nary = vno;
4776 73558 : return vno;
4777 : }
4778 31215227 : else if (vno->predicated_values
4779 31214875 : && ! (*slot)->predicated_values)
4780 : return *slot;
4781 30473658 : else if (vno->predicated_values
4782 30473306 : && (*slot)->predicated_values)
4783 : {
4784 : /* ??? Factor this all into a insert_single_predicated_value
4785 : routine. */
4786 30473306 : gcc_assert (!vno->u.values->next && vno->u.values->n == 1);
4787 30473306 : basic_block vno_bb
4788 30473306 : = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]);
4789 30473306 : vn_pval *nval = vno->u.values;
4790 30473306 : vn_pval **next = &vno->u.values;
4791 30473306 : vn_pval *ins = NULL;
4792 30473306 : vn_pval *ins_at = NULL;
4793 : /* Find an existing value to append to. */
4794 57207436 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4795 : {
4796 31520767 : if (expressions_equal_p (val->result, nval->result))
4797 : {
4798 : /* Limit the number of places we register a predicate
4799 : as valid. */
4800 4786637 : if (val->n > 8)
4801 136026 : return *slot;
4802 11791256 : for (unsigned i = 0; i < val->n; ++i)
4803 : {
4804 7401446 : basic_block val_bb
4805 7401446 : = BASIC_BLOCK_FOR_FN (cfun,
4806 : val->valid_dominated_by_p[i]);
4807 7401446 : if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb))
4808 : /* Value registered with more generic predicate. */
4809 260801 : return *slot;
4810 7140645 : else if (flag_checking)
4811 : /* Shouldn't happen, we insert in RPO order. */
4812 7140645 : gcc_assert (!dominated_by_p (CDI_DOMINATORS,
4813 : val_bb, vno_bb));
4814 : }
4815 : /* Append the location. */
4816 4389810 : ins_at = val;
4817 4389810 : ins = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4818 : sizeof (vn_pval)
4819 : + val->n * sizeof (int));
4820 4389810 : ins->next = NULL;
4821 4389810 : ins->result = val->result;
4822 4389810 : ins->n = val->n + 1;
4823 4389810 : memcpy (ins->valid_dominated_by_p,
4824 4389810 : val->valid_dominated_by_p,
4825 4389810 : val->n * sizeof (int));
4826 4389810 : ins->valid_dominated_by_p[val->n] = vno_bb->index;
4827 4389810 : if (dump_file && (dump_flags & TDF_DETAILS))
4828 4 : fprintf (dump_file, "Appending predicate to value.\n");
4829 : break;
4830 : }
4831 : }
4832 : /* Copy the rest of the value chain. */
4833 62120638 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4834 : {
4835 32044159 : if (val == ins_at)
4836 : /* Replace the node we appended to. */
4837 4389810 : *next = ins;
4838 : else
4839 : {
4840 : /* Copy other predicated values. */
4841 27654349 : *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4842 : sizeof (vn_pval)
4843 : + ((val->n-1)
4844 : * sizeof (int)));
4845 27654349 : memcpy (*next, val,
4846 27654349 : sizeof (vn_pval) + (val->n-1) * sizeof (int));
4847 27654349 : (*next)->next = NULL;
4848 : }
4849 32044159 : next = &(*next)->next;
4850 : }
4851 : /* Append the value if we didn't find it. */
4852 30076479 : if (!ins_at)
4853 25686669 : *next = nval;
4854 30076479 : *slot = vno;
4855 30076479 : vno->next = last_inserted_nary;
4856 30076479 : last_inserted_nary = vno;
4857 30076479 : return vno;
4858 : }
4859 :
4860 : /* While we do not want to insert things twice it's awkward to
4861 : avoid it in the case where visit_nary_op pattern-matches stuff
4862 : and ends up simplifying the replacement to itself. We then
4863 : get two inserts, one from visit_nary_op and one from
4864 : vn_nary_build_or_lookup.
4865 : So allow inserts with the same value number. */
4866 352 : if ((*slot)->u.result == vno->u.result)
4867 : return *slot;
4868 : }
4869 :
4870 : /* ??? There's also optimistic vs. previous committed state merging
4871 : that is problematic for the case of unwinding. */
4872 :
4873 : /* ??? We should return NULL if we do not use 'vno' and have the
4874 : caller release it. */
4875 131281252 : gcc_assert (!*slot);
4876 :
4877 131281252 : *slot = vno;
4878 131281252 : vno->next = last_inserted_nary;
4879 131281252 : last_inserted_nary = vno;
4880 131281252 : return vno;
4881 : }
4882 :
4883 : /* Insert a n-ary operation into the current hash table using it's
4884 : pieces. Return the vn_nary_op_t structure we created and put in
4885 : the hashtable. */
4886 :
4887 : vn_nary_op_t
4888 590762 : vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
4889 : tree type, tree *ops,
4890 : tree result, unsigned int value_id)
4891 : {
4892 590762 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
4893 590762 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4894 590762 : return vn_nary_op_insert_into (vno1, valid_info->nary);
4895 : }
4896 :
4897 : /* Return whether we can track a predicate valid when PRED_E is executed. */
4898 :
4899 : static bool
4900 156275367 : can_track_predicate_on_edge (edge pred_e)
4901 : {
4902 : /* ??? As we are currently recording the destination basic-block index in
4903 : vn_pval.valid_dominated_by_p and using dominance for the
4904 : validity check we cannot track predicates on all edges. */
4905 156275367 : if (single_pred_p (pred_e->dest))
4906 : return true;
4907 : /* Never record for backedges. */
4908 12453674 : if (pred_e->flags & EDGE_DFS_BACK)
4909 : return false;
4910 : /* When there's more than one predecessor we cannot track
4911 : predicate validity based on the destination block. The
4912 : exception is when all other incoming edges sources are
4913 : dominated by the destination block. */
4914 11751398 : edge_iterator ei;
4915 11751398 : edge e;
4916 20068192 : FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
4917 18169527 : if (e != pred_e && ! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
4918 : return false;
4919 : return true;
4920 : }
4921 :
4922 : static vn_nary_op_t
4923 110608081 : vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
4924 : tree type, tree *ops,
4925 : tree result, unsigned int value_id,
4926 : edge pred_e)
4927 : {
4928 110608081 : if (flag_checking)
4929 110607261 : gcc_assert (can_track_predicate_on_edge (pred_e));
4930 :
4931 77132 : if (dump_file && (dump_flags & TDF_DETAILS)
4932 : /* ??? Fix dumping, but currently we only get comparisons. */
4933 110681033 : && TREE_CODE_CLASS (code) == tcc_comparison)
4934 : {
4935 72952 : fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index,
4936 72952 : pred_e->dest->index);
4937 72952 : print_generic_expr (dump_file, ops[0], TDF_SLIM);
4938 72952 : fprintf (dump_file, " %s ", get_tree_code_name (code));
4939 72952 : print_generic_expr (dump_file, ops[1], TDF_SLIM);
4940 109057 : fprintf (dump_file, " == %s\n",
4941 72952 : integer_zerop (result) ? "false" : "true");
4942 : }
4943 110608081 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id);
4944 110608081 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4945 110608081 : vno1->predicated_values = 1;
4946 110608081 : vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4947 : sizeof (vn_pval));
4948 110608081 : vno1->u.values->next = NULL;
4949 110608081 : vno1->u.values->result = result;
4950 110608081 : vno1->u.values->n = 1;
4951 110608081 : vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index;
4952 110608081 : return vn_nary_op_insert_into (vno1, valid_info->nary);
4953 : }
4954 :
4955 : static bool
4956 : dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool);
4957 :
4958 : static tree
4959 1815861 : vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb,
4960 : edge e = NULL)
4961 : {
4962 1815861 : if (! vno->predicated_values)
4963 0 : return vno->u.result;
4964 3795892 : for (vn_pval *val = vno->u.values; val; val = val->next)
4965 5790778 : for (unsigned i = 0; i < val->n; ++i)
4966 : {
4967 3810747 : basic_block cand
4968 3810747 : = BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]);
4969 : /* Do not handle backedge executability optimistically since
4970 : when figuring out whether to iterate we do not consider
4971 : changed predication.
4972 : When asking for predicated values on an edge avoid looking
4973 : at edge executability for edges forward in our iteration
4974 : as well. */
4975 3810747 : if (e && (e->flags & EDGE_DFS_BACK))
4976 : {
4977 23150 : if (dominated_by_p (CDI_DOMINATORS, bb, cand))
4978 7171 : return val->result;
4979 : }
4980 3787597 : else if (dominated_by_p_w_unex (bb, cand, false))
4981 554123 : return val->result;
4982 : }
4983 : return NULL_TREE;
4984 : }
4985 :
4986 : static tree
4987 205533 : vn_nary_op_get_predicated_value (vn_nary_op_t vno, edge e)
4988 : {
4989 0 : return vn_nary_op_get_predicated_value (vno, e->src, e);
4990 : }
4991 :
4992 : /* Insert the rhs of STMT into the current hash table with a value number of
4993 : RESULT. */
4994 :
4995 : static vn_nary_op_t
4996 46313228 : vn_nary_op_insert_stmt (gimple *stmt, tree result)
4997 : {
4998 46313228 : vn_nary_op_t vno1
4999 46313228 : = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
5000 46313228 : result, VN_INFO (result)->value_id);
5001 46313228 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
5002 46313228 : return vn_nary_op_insert_into (vno1, valid_info->nary);
5003 : }
5004 :
5005 : /* Compute a hashcode for PHI operation VP1 and return it. */
5006 :
5007 : static inline hashval_t
5008 51183040 : vn_phi_compute_hash (vn_phi_t vp1)
5009 : {
5010 51183040 : inchash::hash hstate;
5011 51183040 : tree phi1op;
5012 51183040 : tree type;
5013 51183040 : edge e;
5014 51183040 : edge_iterator ei;
5015 :
5016 102366080 : hstate.add_int (EDGE_COUNT (vp1->block->preds));
5017 51183040 : switch (EDGE_COUNT (vp1->block->preds))
5018 : {
5019 : case 1:
5020 : break;
5021 43983469 : case 2:
5022 : /* When this is a PHI node subject to CSE for different blocks
5023 : avoid hashing the block index. */
5024 43983469 : if (vp1->cclhs)
5025 : break;
5026 : /* Fallthru. */
5027 34499259 : default:
5028 34499259 : hstate.add_int (vp1->block->index);
5029 : }
5030 :
5031 : /* If all PHI arguments are constants we need to distinguish
5032 : the PHI node via its type. */
5033 51183040 : type = vp1->type;
5034 51183040 : hstate.merge_hash (vn_hash_type (type));
5035 :
5036 178676757 : FOR_EACH_EDGE (e, ei, vp1->block->preds)
5037 : {
5038 : /* Don't hash backedge values they need to be handled as VN_TOP
5039 : for optimistic value-numbering. */
5040 127493717 : if (e->flags & EDGE_DFS_BACK)
5041 28099936 : continue;
5042 :
5043 99393781 : phi1op = vp1->phiargs[e->dest_idx];
5044 99393781 : if (phi1op == VN_TOP)
5045 246720 : continue;
5046 99147061 : inchash::add_expr (phi1op, hstate);
5047 : }
5048 :
5049 51183040 : return hstate.end ();
5050 : }
5051 :
5052 :
5053 : /* Return true if COND1 and COND2 represent the same condition, set
5054 : *INVERTED_P if one needs to be inverted to make it the same as
5055 : the other. */
5056 :
5057 : static bool
5058 3542914 : cond_stmts_equal_p (gcond *cond1, tree lhs1, tree rhs1,
5059 : gcond *cond2, tree lhs2, tree rhs2, bool *inverted_p)
5060 : {
5061 3542914 : enum tree_code code1 = gimple_cond_code (cond1);
5062 3542914 : enum tree_code code2 = gimple_cond_code (cond2);
5063 :
5064 3542914 : *inverted_p = false;
5065 3542914 : if (code1 == code2)
5066 : ;
5067 286790 : else if (code1 == swap_tree_comparison (code2))
5068 : std::swap (lhs2, rhs2);
5069 249807 : else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
5070 115260 : *inverted_p = true;
5071 134547 : else if (code1 == invert_tree_comparison
5072 134547 : (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
5073 : {
5074 10280 : std::swap (lhs2, rhs2);
5075 10280 : *inverted_p = true;
5076 : }
5077 : else
5078 : return false;
5079 :
5080 3418647 : return ((expressions_equal_p (lhs1, lhs2)
5081 108315 : && expressions_equal_p (rhs1, rhs2))
5082 3445072 : || (commutative_tree_code (code1)
5083 1763501 : && expressions_equal_p (lhs1, rhs2)
5084 2979 : && expressions_equal_p (rhs1, lhs2)));
5085 : }
5086 :
5087 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
5088 :
5089 : static int
5090 40804718 : vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
5091 : {
5092 40804718 : if (vp1->hashcode != vp2->hashcode)
5093 : return false;
5094 :
5095 12563793 : if (vp1->block != vp2->block)
5096 : {
5097 10651815 : if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds))
5098 : return false;
5099 :
5100 3550605 : switch (EDGE_COUNT (vp1->block->preds))
5101 : {
5102 : case 1:
5103 : /* Single-arg PHIs are just copies. */
5104 : break;
5105 :
5106 3550605 : case 2:
5107 3550605 : {
5108 : /* Make sure both PHIs are classified as CSEable. */
5109 3550605 : if (! vp1->cclhs || ! vp2->cclhs)
5110 : return false;
5111 :
5112 : /* Rule out backedges into the PHI. */
5113 3550605 : gcc_checking_assert
5114 : (vp1->block->loop_father->header != vp1->block
5115 : && vp2->block->loop_father->header != vp2->block);
5116 :
5117 : /* If the PHI nodes do not have compatible types
5118 : they are not the same. */
5119 3550605 : if (!types_compatible_p (vp1->type, vp2->type))
5120 : return false;
5121 :
5122 : /* If the immediate dominator end in switch stmts multiple
5123 : values may end up in the same PHI arg via intermediate
5124 : CFG merges. */
5125 3542914 : basic_block idom1
5126 3542914 : = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5127 3542914 : basic_block idom2
5128 3542914 : = get_immediate_dominator (CDI_DOMINATORS, vp2->block);
5129 3542914 : gcc_checking_assert (EDGE_COUNT (idom1->succs) == 2
5130 : && EDGE_COUNT (idom2->succs) == 2);
5131 :
5132 : /* Verify the controlling stmt is the same. */
5133 7085828 : gcond *last1 = as_a <gcond *> (*gsi_last_bb (idom1));
5134 7085828 : gcond *last2 = as_a <gcond *> (*gsi_last_bb (idom2));
5135 3542914 : bool inverted_p;
5136 3542914 : if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
5137 3542914 : last2, vp2->cclhs, vp2->ccrhs,
5138 : &inverted_p))
5139 : return false;
5140 :
5141 : /* Get at true/false controlled edges into the PHI. */
5142 82068 : edge te1, te2, fe1, fe2;
5143 82068 : if (! extract_true_false_controlled_edges (idom1, vp1->block,
5144 : &te1, &fe1)
5145 82068 : || ! extract_true_false_controlled_edges (idom2, vp2->block,
5146 : &te2, &fe2))
5147 : return false;
5148 :
5149 : /* Swap edges if the second condition is the inverted of the
5150 : first. */
5151 46971 : if (inverted_p)
5152 1867 : std::swap (te2, fe2);
5153 :
5154 : /* Since we do not know which edge will be executed we have
5155 : to be careful when matching VN_TOP. Be conservative and
5156 : only match VN_TOP == VN_TOP for now, we could allow
5157 : VN_TOP on the not prevailing PHI though. See for example
5158 : PR102920. */
5159 46971 : if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
5160 46971 : vp2->phiargs[te2->dest_idx], false)
5161 92202 : || ! expressions_equal_p (vp1->phiargs[fe1->dest_idx],
5162 45231 : vp2->phiargs[fe2->dest_idx], false))
5163 1740 : return false;
5164 :
5165 : return true;
5166 : }
5167 :
5168 : default:
5169 : return false;
5170 : }
5171 : }
5172 :
5173 : /* If the PHI nodes do not have compatible types
5174 : they are not the same. */
5175 9013188 : if (!types_compatible_p (vp1->type, vp2->type))
5176 : return false;
5177 :
5178 : /* Any phi in the same block will have it's arguments in the
5179 : same edge order, because of how we store phi nodes. */
5180 9012060 : unsigned nargs = EDGE_COUNT (vp1->block->preds);
5181 20789557 : for (unsigned i = 0; i < nargs; ++i)
5182 : {
5183 16646522 : tree phi1op = vp1->phiargs[i];
5184 16646522 : tree phi2op = vp2->phiargs[i];
5185 16646522 : if (phi1op == phi2op)
5186 11680339 : continue;
5187 4966183 : if (!expressions_equal_p (phi1op, phi2op, false))
5188 : return false;
5189 : }
5190 :
5191 : return true;
5192 : }
5193 :
5194 : /* Lookup PHI in the current hash table, and return the resulting
5195 : value number if it exists in the hash table. Return NULL_TREE if
5196 : it does not exist in the hash table. */
5197 :
5198 : static tree
5199 28003315 : vn_phi_lookup (gimple *phi, bool backedges_varying_p)
5200 : {
5201 28003315 : vn_phi_s **slot;
5202 28003315 : struct vn_phi_s *vp1;
5203 28003315 : edge e;
5204 28003315 : edge_iterator ei;
5205 :
5206 28003315 : vp1 = XALLOCAVAR (struct vn_phi_s,
5207 : sizeof (struct vn_phi_s)
5208 : + (gimple_phi_num_args (phi) - 1) * sizeof (tree));
5209 :
5210 : /* Canonicalize the SSA_NAME's to their value number. */
5211 97019145 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5212 : {
5213 69015830 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5214 69015830 : if (TREE_CODE (def) == SSA_NAME
5215 57541819 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5216 : {
5217 54939672 : if (!virtual_operand_p (def)
5218 54939672 : && ssa_undefined_value_p (def, false))
5219 136969 : def = VN_TOP;
5220 : else
5221 54802703 : def = SSA_VAL (def);
5222 : }
5223 69015830 : vp1->phiargs[e->dest_idx] = def;
5224 : }
5225 28003315 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5226 28003315 : vp1->block = gimple_bb (phi);
5227 : /* Extract values of the controlling condition. */
5228 28003315 : vp1->cclhs = NULL_TREE;
5229 28003315 : vp1->ccrhs = NULL_TREE;
5230 28003315 : if (EDGE_COUNT (vp1->block->preds) == 2
5231 28003315 : && vp1->block->loop_father->header != vp1->block)
5232 : {
5233 8834172 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5234 8834172 : if (EDGE_COUNT (idom1->succs) == 2)
5235 17566798 : if (gcond *last1 = safe_dyn_cast <gcond *> (*gsi_last_bb (idom1)))
5236 : {
5237 : /* ??? We want to use SSA_VAL here. But possibly not
5238 : allow VN_TOP. */
5239 8529098 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5240 8529098 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5241 : }
5242 : }
5243 28003315 : vp1->hashcode = vn_phi_compute_hash (vp1);
5244 28003315 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
5245 28003315 : if (!slot)
5246 : return NULL_TREE;
5247 4188266 : return (*slot)->result;
5248 : }
5249 :
5250 : /* Insert PHI into the current hash table with a value number of
5251 : RESULT. */
5252 :
5253 : static vn_phi_t
5254 23179725 : vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
5255 : {
5256 23179725 : vn_phi_s **slot;
5257 23179725 : vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack,
5258 : sizeof (vn_phi_s)
5259 : + ((gimple_phi_num_args (phi) - 1)
5260 : * sizeof (tree)));
5261 23179725 : edge e;
5262 23179725 : edge_iterator ei;
5263 :
5264 : /* Canonicalize the SSA_NAME's to their value number. */
5265 81657612 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5266 : {
5267 58477887 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5268 58477887 : if (TREE_CODE (def) == SSA_NAME
5269 48073520 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5270 : {
5271 45471871 : if (!virtual_operand_p (def)
5272 45471871 : && ssa_undefined_value_p (def, false))
5273 109987 : def = VN_TOP;
5274 : else
5275 45361884 : def = SSA_VAL (def);
5276 : }
5277 58477887 : vp1->phiargs[e->dest_idx] = def;
5278 : }
5279 23179725 : vp1->value_id = VN_INFO (result)->value_id;
5280 23179725 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5281 23179725 : vp1->block = gimple_bb (phi);
5282 : /* Extract values of the controlling condition. */
5283 23179725 : vp1->cclhs = NULL_TREE;
5284 23179725 : vp1->ccrhs = NULL_TREE;
5285 23179725 : if (EDGE_COUNT (vp1->block->preds) == 2
5286 23179725 : && vp1->block->loop_father->header != vp1->block)
5287 : {
5288 8454615 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5289 8454615 : if (EDGE_COUNT (idom1->succs) == 2)
5290 16811994 : if (gcond *last1 = safe_dyn_cast <gcond *> (*gsi_last_bb (idom1)))
5291 : {
5292 : /* ??? We want to use SSA_VAL here. But possibly not
5293 : allow VN_TOP. */
5294 8154683 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5295 8154683 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5296 : }
5297 : }
5298 23179725 : vp1->result = result;
5299 23179725 : vp1->hashcode = vn_phi_compute_hash (vp1);
5300 :
5301 23179725 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
5302 23179725 : gcc_assert (!*slot);
5303 :
5304 23179725 : *slot = vp1;
5305 23179725 : vp1->next = last_inserted_phi;
5306 23179725 : last_inserted_phi = vp1;
5307 23179725 : return vp1;
5308 : }
5309 :
5310 :
5311 : /* Return true if BB1 is dominated by BB2 taking into account edges
5312 : that are not executable. When ALLOW_BACK is false consider not
5313 : executable backedges as executable. */
5314 :
5315 : static bool
5316 78105990 : dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
5317 : {
5318 78105990 : edge_iterator ei;
5319 78105990 : edge e;
5320 :
5321 78105990 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5322 : return true;
5323 :
5324 : /* Before iterating we'd like to know if there exists a
5325 : (executable) path from bb2 to bb1 at all, if not we can
5326 : directly return false. For now simply iterate once. */
5327 :
5328 : /* Iterate to the single executable bb1 predecessor. */
5329 22090096 : if (EDGE_COUNT (bb1->preds) > 1)
5330 : {
5331 3022446 : edge prede = NULL;
5332 6597172 : FOR_EACH_EDGE (e, ei, bb1->preds)
5333 6172313 : if ((e->flags & EDGE_EXECUTABLE)
5334 635708 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5335 : {
5336 5620033 : if (prede)
5337 : {
5338 : prede = NULL;
5339 : break;
5340 : }
5341 : prede = e;
5342 : }
5343 3022446 : if (prede)
5344 : {
5345 424859 : bb1 = prede->src;
5346 :
5347 : /* Re-do the dominance check with changed bb1. */
5348 424859 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5349 : return true;
5350 : }
5351 : }
5352 :
5353 : /* Iterate to the single executable bb2 successor. */
5354 21845185 : if (EDGE_COUNT (bb2->succs) > 1)
5355 : {
5356 6860337 : edge succe = NULL;
5357 13894844 : FOR_EACH_EDGE (e, ei, bb2->succs)
5358 13720911 : if ((e->flags & EDGE_EXECUTABLE)
5359 215894 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5360 : {
5361 13505063 : if (succe)
5362 : {
5363 : succe = NULL;
5364 : break;
5365 : }
5366 : succe = e;
5367 : }
5368 6860337 : if (succe
5369 : /* Limit the number of edges we check, we should bring in
5370 : context from the iteration and compute the single
5371 : executable incoming edge when visiting a block. */
5372 6860337 : && EDGE_COUNT (succe->dest->preds) < 8)
5373 : {
5374 : /* Verify the reached block is only reached through succe.
5375 : If there is only one edge we can spare us the dominator
5376 : check and iterate directly. */
5377 131383 : if (EDGE_COUNT (succe->dest->preds) > 1)
5378 : {
5379 60205 : FOR_EACH_EDGE (e, ei, succe->dest->preds)
5380 47293 : if (e != succe
5381 30725 : && ((e->flags & EDGE_EXECUTABLE)
5382 19158 : || (!allow_back && (e->flags & EDGE_DFS_BACK))))
5383 : {
5384 : succe = NULL;
5385 : break;
5386 : }
5387 : }
5388 131383 : if (succe)
5389 : {
5390 119807 : bb2 = succe->dest;
5391 :
5392 : /* Re-do the dominance check with changed bb2. */
5393 119807 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5394 : return true;
5395 : }
5396 : }
5397 : }
5398 : /* Iterate to the single successor of bb2 with only a single executable
5399 : incoming edge. */
5400 14984848 : else if (EDGE_COUNT (bb2->succs) == 1
5401 14448087 : && EDGE_COUNT (single_succ (bb2)->preds) > 1
5402 : /* Limit the number of edges we check, we should bring in
5403 : context from the iteration and compute the single
5404 : executable incoming edge when visiting a block. */
5405 29171875 : && EDGE_COUNT (single_succ (bb2)->preds) < 8)
5406 : {
5407 5263311 : edge prede = NULL;
5408 11853787 : FOR_EACH_EDGE (e, ei, single_succ (bb2)->preds)
5409 11298872 : if ((e->flags & EDGE_EXECUTABLE)
5410 1380228 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5411 : {
5412 9923340 : if (prede)
5413 : {
5414 : prede = NULL;
5415 : break;
5416 : }
5417 : prede = e;
5418 : }
5419 : /* We might actually get to a query with BB2 not visited yet when
5420 : we're querying for a predicated value. */
5421 5263311 : if (prede && prede->src == bb2)
5422 : {
5423 490751 : bb2 = prede->dest;
5424 :
5425 : /* Re-do the dominance check with changed bb2. */
5426 490751 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5427 : return true;
5428 : }
5429 : }
5430 :
5431 : /* We could now iterate updating bb1 / bb2. */
5432 : return false;
5433 : }
5434 :
5435 : /* Set the value number of FROM to TO, return true if it has changed
5436 : as a result. */
5437 :
5438 : static inline bool
5439 211661900 : set_ssa_val_to (tree from, tree to)
5440 : {
5441 211661900 : vn_ssa_aux_t from_info = VN_INFO (from);
5442 211661900 : tree currval = from_info->valnum; // SSA_VAL (from)
5443 211661900 : poly_int64 toff, coff;
5444 211661900 : bool curr_undefined = false;
5445 211661900 : bool curr_invariant = false;
5446 :
5447 : /* The only thing we allow as value numbers are ssa_names
5448 : and invariants. So assert that here. We don't allow VN_TOP
5449 : as visiting a stmt should produce a value-number other than
5450 : that.
5451 : ??? Still VN_TOP can happen for unreachable code, so force
5452 : it to varying in that case. Not all code is prepared to
5453 : get VN_TOP on valueization. */
5454 211661900 : if (to == VN_TOP)
5455 : {
5456 : /* ??? When iterating and visiting PHI <undef, backedge-value>
5457 : for the first time we rightfully get VN_TOP and we need to
5458 : preserve that to optimize for example gcc.dg/tree-ssa/ssa-sccvn-2.c.
5459 : With SCCVN we were simply lucky we iterated the other PHI
5460 : cycles first and thus visited the backedge-value DEF. */
5461 0 : if (currval == VN_TOP)
5462 0 : goto set_and_exit;
5463 0 : if (dump_file && (dump_flags & TDF_DETAILS))
5464 0 : fprintf (dump_file, "Forcing value number to varying on "
5465 : "receiving VN_TOP\n");
5466 : to = from;
5467 : }
5468 :
5469 211661900 : gcc_checking_assert (to != NULL_TREE
5470 : && ((TREE_CODE (to) == SSA_NAME
5471 : && (to == from || SSA_VAL (to) == to))
5472 : || is_gimple_min_invariant (to)));
5473 :
5474 211661900 : if (from != to)
5475 : {
5476 33827028 : if (currval == from)
5477 : {
5478 14508 : if (dump_file && (dump_flags & TDF_DETAILS))
5479 : {
5480 0 : fprintf (dump_file, "Not changing value number of ");
5481 0 : print_generic_expr (dump_file, from);
5482 0 : fprintf (dump_file, " from VARYING to ");
5483 0 : print_generic_expr (dump_file, to);
5484 0 : fprintf (dump_file, "\n");
5485 : }
5486 : return false;
5487 : }
5488 33812520 : curr_invariant = is_gimple_min_invariant (currval);
5489 67625040 : curr_undefined = (TREE_CODE (currval) == SSA_NAME
5490 3961038 : && !virtual_operand_p (currval)
5491 37537821 : && ssa_undefined_value_p (currval, false));
5492 33812520 : if (currval != VN_TOP
5493 : && !curr_invariant
5494 5523402 : && !curr_undefined
5495 37760168 : && is_gimple_min_invariant (to))
5496 : {
5497 214 : if (dump_file && (dump_flags & TDF_DETAILS))
5498 : {
5499 0 : fprintf (dump_file, "Forcing VARYING instead of changing "
5500 : "value number of ");
5501 0 : print_generic_expr (dump_file, from);
5502 0 : fprintf (dump_file, " from ");
5503 0 : print_generic_expr (dump_file, currval);
5504 0 : fprintf (dump_file, " (non-constant) to ");
5505 0 : print_generic_expr (dump_file, to);
5506 0 : fprintf (dump_file, " (constant)\n");
5507 : }
5508 : to = from;
5509 : }
5510 33812306 : else if (currval != VN_TOP
5511 5523188 : && !curr_undefined
5512 5509798 : && TREE_CODE (to) == SSA_NAME
5513 4638843 : && !virtual_operand_p (to)
5514 38215412 : && ssa_undefined_value_p (to, false))
5515 : {
5516 6 : if (dump_file && (dump_flags & TDF_DETAILS))
5517 : {
5518 0 : fprintf (dump_file, "Forcing VARYING instead of changing "
5519 : "value number of ");
5520 0 : print_generic_expr (dump_file, from);
5521 0 : fprintf (dump_file, " from ");
5522 0 : print_generic_expr (dump_file, currval);
5523 0 : fprintf (dump_file, " (non-undefined) to ");
5524 0 : print_generic_expr (dump_file, to);
5525 0 : fprintf (dump_file, " (undefined)\n");
5526 : }
5527 : to = from;
5528 : }
5529 33812300 : else if (TREE_CODE (to) == SSA_NAME
5530 33812300 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to))
5531 : to = from;
5532 : }
5533 :
5534 177834872 : set_and_exit:
5535 211647392 : if (dump_file && (dump_flags & TDF_DETAILS))
5536 : {
5537 408087 : fprintf (dump_file, "Setting value number of ");
5538 408087 : print_generic_expr (dump_file, from);
5539 408087 : fprintf (dump_file, " to ");
5540 408087 : print_generic_expr (dump_file, to);
5541 : }
5542 :
5543 211647392 : if (currval != to
5544 173214004 : && !operand_equal_p (currval, to, 0)
5545 : /* Different undefined SSA names are not actually different. See
5546 : PR82320 for a testcase were we'd otherwise not terminate iteration. */
5547 173144191 : && !(curr_undefined
5548 3458 : && TREE_CODE (to) == SSA_NAME
5549 609 : && !virtual_operand_p (to)
5550 609 : && ssa_undefined_value_p (to, false))
5551 : /* ??? For addresses involving volatile objects or types operand_equal_p
5552 : does not reliably detect ADDR_EXPRs as equal. We know we are only
5553 : getting invariant gimple addresses here, so can use
5554 : get_addr_base_and_unit_offset to do this comparison. */
5555 384790942 : && !(TREE_CODE (currval) == ADDR_EXPR
5556 471076 : && TREE_CODE (to) == ADDR_EXPR
5557 12 : && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff)
5558 6 : == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
5559 6 : && known_eq (coff, toff)))
5560 : {
5561 173143544 : if (to != from
5562 29324593 : && currval != VN_TOP
5563 1039079 : && !curr_undefined
5564 : /* We do not want to allow lattice transitions from one value
5565 : to another since that may lead to not terminating iteration
5566 : (see PR95049). Since there's no convenient way to check
5567 : for the allowed transition of VAL -> PHI (loop entry value,
5568 : same on two PHIs, to same PHI result) we restrict the check
5569 : to invariants. */
5570 1039079 : && curr_invariant
5571 173834947 : && is_gimple_min_invariant (to))
5572 : {
5573 0 : if (dump_file && (dump_flags & TDF_DETAILS))
5574 0 : fprintf (dump_file, " forced VARYING");
5575 : to = from;
5576 : }
5577 173143544 : if (dump_file && (dump_flags & TDF_DETAILS))
5578 407771 : fprintf (dump_file, " (changed)\n");
5579 173143544 : from_info->valnum = to;
5580 173143544 : return true;
5581 : }
5582 38503848 : if (dump_file && (dump_flags & TDF_DETAILS))
5583 316 : fprintf (dump_file, "\n");
5584 : return false;
5585 : }
5586 :
5587 : /* Set all definitions in STMT to value number to themselves.
5588 : Return true if a value number changed. */
5589 :
5590 : static bool
5591 317289826 : defs_to_varying (gimple *stmt)
5592 : {
5593 317289826 : bool changed = false;
5594 317289826 : ssa_op_iter iter;
5595 317289826 : def_operand_p defp;
5596 :
5597 348371508 : FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
5598 : {
5599 31081682 : tree def = DEF_FROM_PTR (defp);
5600 31081682 : changed |= set_ssa_val_to (def, def);
5601 : }
5602 317289826 : return changed;
5603 : }
5604 :
5605 : /* Visit a copy between LHS and RHS, return true if the value number
5606 : changed. */
5607 :
5608 : static bool
5609 8238639 : visit_copy (tree lhs, tree rhs)
5610 : {
5611 : /* Valueize. */
5612 8238639 : rhs = SSA_VAL (rhs);
5613 :
5614 8238639 : return set_ssa_val_to (lhs, rhs);
5615 : }
5616 :
5617 : /* Lookup a value for OP in type WIDE_TYPE where the value in type of OP
5618 : is the same. */
5619 :
5620 : static tree
5621 2513291 : valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
5622 : {
5623 2513291 : if (TREE_CODE (op) == SSA_NAME)
5624 2205522 : op = vn_valueize (op);
5625 :
5626 : /* Either we have the op widened available. */
5627 2513291 : tree ops[3] = {};
5628 2513291 : ops[0] = op;
5629 2513291 : tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR,
5630 : wide_type, ops, NULL);
5631 2513291 : if (tem)
5632 : return tem;
5633 :
5634 : /* Or the op is truncated from some existing value. */
5635 2218931 : if (allow_truncate && TREE_CODE (op) == SSA_NAME)
5636 : {
5637 571835 : gimple *def = SSA_NAME_DEF_STMT (op);
5638 571835 : if (is_gimple_assign (def)
5639 571835 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5640 : {
5641 312225 : tem = gimple_assign_rhs1 (def);
5642 312225 : if (useless_type_conversion_p (wide_type, TREE_TYPE (tem)))
5643 : {
5644 213613 : if (TREE_CODE (tem) == SSA_NAME)
5645 213613 : tem = vn_valueize (tem);
5646 : return tem;
5647 : }
5648 : }
5649 : }
5650 :
5651 : /* For constants simply extend it. */
5652 2005318 : if (TREE_CODE (op) == INTEGER_CST)
5653 341294 : return wide_int_to_tree (wide_type, wi::to_widest (op));
5654 :
5655 : return NULL_TREE;
5656 : }
5657 :
5658 : /* Return true if RESULT, the result of a value-number lookup, may be
5659 : used at the statement being visited. A result of wrapping type can
5660 : be inserted for code hoisting without introducing undefined
5661 : overflow; anything else has to be available. See PR86554. */
5662 :
5663 : static bool
5664 22654 : vn_nary_result_avail_or_insertable_p (tree result)
5665 : {
5666 22654 : return (TYPE_OVERFLOW_WRAPS (TREE_TYPE (result))
5667 14324 : || (rpo_avail && vn_context_bb
5668 14324 : && rpo_avail->eliminate_avail (vn_context_bb, result)));
5669 : }
5670 :
5671 : /* If OP is an SSA name defined by a conversion from an integral type,
5672 : return the valueized source of the conversion, otherwise return
5673 : NULL_TREE. */
5674 :
5675 : static tree
5676 14330867 : ssa_integral_conversion_op (tree op)
5677 : {
5678 14330867 : if (TREE_CODE (op) != SSA_NAME)
5679 : return NULL_TREE;
5680 14016077 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
5681 11780840 : if (!def || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5682 : return NULL_TREE;
5683 1548181 : const tree src = gimple_assign_rhs1 (def);
5684 1548181 : if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
5685 : return NULL_TREE;
5686 1291310 : return vn_valueize (src);
5687 : }
5688 :
5689 : /* Visit a nary operator RHS, value number it, and return true if the
5690 : value number of LHS has changed as a result. */
5691 :
5692 : static bool
5693 50188870 : visit_nary_op (tree lhs, gassign *stmt)
5694 : {
5695 50188870 : vn_nary_op_t vnresult;
5696 50188870 : tree result = vn_nary_op_lookup_stmt (stmt, &vnresult);
5697 50188870 : if (! result && vnresult)
5698 143462 : result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt));
5699 46385168 : if (result)
5700 3873606 : return set_ssa_val_to (lhs, result);
5701 :
5702 : /* Do some special pattern matching for redundancies of operations
5703 : in different types. */
5704 46315264 : enum tree_code code = gimple_assign_rhs_code (stmt);
5705 46315264 : tree type = TREE_TYPE (lhs);
5706 46315264 : tree rhs1 = gimple_assign_rhs1 (stmt);
5707 46315264 : switch (code)
5708 : {
5709 10288794 : CASE_CONVERT:
5710 : /* Match arithmetic done in a different type where we can easily
5711 : substitute the result from some earlier sign-changed or widened
5712 : operation. */
5713 10288794 : if (INTEGRAL_TYPE_P (type)
5714 9224891 : && TREE_CODE (rhs1) == SSA_NAME
5715 : /* We only handle sign-changes, zero-extension -> & mask or
5716 : sign-extension if we know the inner operation doesn't
5717 : overflow. */
5718 19272142 : && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
5719 5410143 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5720 5409349 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5721 8254679 : && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
5722 6096580 : || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
5723 : {
5724 7845760 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5725 5710969 : if (def
5726 5710969 : && (gimple_assign_rhs_code (def) == PLUS_EXPR
5727 4446757 : || gimple_assign_rhs_code (def) == MINUS_EXPR
5728 4284066 : || gimple_assign_rhs_code (def) == MULT_EXPR))
5729 : {
5730 2017232 : tree ops[3] = {};
5731 : /* When requiring a sign-extension we cannot model a
5732 : previous truncation with a single op so don't bother. */
5733 2017232 : bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
5734 : /* Either we have the op widened available. */
5735 2017232 : ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
5736 : allow_truncate);
5737 2017232 : if (ops[0])
5738 992118 : ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
5739 : allow_truncate);
5740 2017232 : if (ops[0] && ops[1])
5741 : {
5742 353208 : ops[0] = vn_nary_op_lookup_pieces
5743 353208 : (2, gimple_assign_rhs_code (def), type, ops, NULL);
5744 : /* We have wider operation available. */
5745 353208 : if (ops[0] && vn_nary_result_avail_or_insertable_p (ops[0]))
5746 : {
5747 8259 : unsigned lhs_prec = TYPE_PRECISION (type);
5748 8259 : unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
5749 8259 : if (lhs_prec == rhs_prec
5750 8259 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5751 811 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5752 : {
5753 7620 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5754 7620 : NOP_EXPR, type, ops[0]);
5755 7620 : result = vn_nary_build_or_lookup (&match_op);
5756 7620 : if (result)
5757 : {
5758 7620 : bool changed = set_ssa_val_to (lhs, result);
5759 7620 : if (TREE_CODE (result) == SSA_NAME)
5760 7620 : vn_nary_op_insert_stmt (stmt, result);
5761 7620 : return changed;
5762 : }
5763 : }
5764 : else
5765 : {
5766 639 : tree mask = wide_int_to_tree
5767 639 : (type, wi::mask (rhs_prec, false, lhs_prec));
5768 639 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5769 639 : BIT_AND_EXPR,
5770 639 : TREE_TYPE (lhs),
5771 639 : ops[0], mask);
5772 639 : result = vn_nary_build_or_lookup (&match_op);
5773 639 : if (result)
5774 : {
5775 639 : bool changed = set_ssa_val_to (lhs, result);
5776 639 : if (TREE_CODE (result) == SSA_NAME)
5777 639 : vn_nary_op_insert_stmt (stmt, result);
5778 639 : return changed;
5779 : }
5780 : }
5781 : }
5782 : }
5783 : }
5784 : }
5785 : break;
5786 13954686 : case PLUS_EXPR:
5787 13954686 : case MINUS_EXPR:
5788 13954686 : {
5789 : /* Match (T)A +- B against an existing (T)(A +- B'), the inverse
5790 : of the conversion case above, so the redundancy is detected
5791 : regardless of the order the two forms appear in the IL.
5792 : See PR124545. The narrow operation is only ever looked up,
5793 : never created: assuming no overflow is only valid for
5794 : operations the program actually executes, so the narrow
5795 : leader has to be available. Creating the narrow operation
5796 : instead is wrong-code, see PR126415. */
5797 13954686 : const tree narrow1 = ssa_integral_conversion_op (vn_valueize (rhs1));
5798 13954686 : if (!INTEGRAL_TYPE_P (type) || !narrow1)
5799 : break;
5800 1115212 : const tree ntype = TREE_TYPE (narrow1);
5801 : /* A sign-change keeps the value bit-identical; a widening is
5802 : only handled when the narrow operation cannot wrap. */
5803 1115212 : const bool sign_change_p
5804 1115212 : = TYPE_PRECISION (ntype) == TYPE_PRECISION (type);
5805 1115212 : const bool nowrap_widening_p
5806 1115212 : = (TYPE_PRECISION (ntype) < TYPE_PRECISION (type)
5807 1115212 : && TYPE_OVERFLOW_UNDEFINED (ntype));
5808 1115212 : if (!sign_change_p && !nowrap_widening_p)
5809 : break;
5810 : /* Determine the narrow variant of the second operand: a
5811 : constant that narrows and extends back unchanged, or a
5812 : conversion from the same narrow type. */
5813 851718 : const tree rhs2 = gimple_assign_rhs2 (stmt);
5814 851718 : tree narrow2 = NULL_TREE;
5815 851718 : if (TREE_CODE (rhs2) == INTEGER_CST)
5816 : {
5817 475537 : const widest_int cst = wi::to_widest (rhs2);
5818 475537 : const widest_int narrowed
5819 475537 : = wi::ext (cst, TYPE_PRECISION (ntype), TYPE_SIGN (ntype));
5820 475537 : const widest_int extended
5821 475537 : = wi::ext (narrowed, TYPE_PRECISION (type), TYPE_SIGN (type));
5822 475537 : if (cst == extended)
5823 472693 : narrow2 = fold_convert (ntype, rhs2);
5824 475543 : }
5825 376181 : else if (TREE_CODE (rhs2) == SSA_NAME)
5826 : {
5827 376181 : const tree op = ssa_integral_conversion_op (vn_valueize (rhs2));
5828 376181 : if (op && types_compatible_p (TREE_TYPE (op), ntype))
5829 : narrow2 = op;
5830 : }
5831 640576 : if (!narrow2)
5832 : break;
5833 637732 : tree ops[3] = { narrow1, narrow2 };
5834 637732 : const tree narrow_val
5835 637732 : = vn_nary_op_lookup_pieces (2, code, ntype, ops, NULL);
5836 : /* We have a narrower or sign-changed operation available. */
5837 637732 : if (narrow_val && vn_nary_result_avail_or_insertable_p (narrow_val))
5838 : {
5839 11789 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5840 11789 : NOP_EXPR, type, narrow_val);
5841 11789 : result = vn_nary_build_or_lookup (&match_op);
5842 11789 : if (result)
5843 : {
5844 11789 : const bool changed = set_ssa_val_to (lhs, result);
5845 11789 : if (TREE_CODE (result) == SSA_NAME)
5846 11789 : vn_nary_op_insert_stmt (stmt, result);
5847 11789 : return changed;
5848 : }
5849 : }
5850 : }
5851 625943 : break;
5852 1560027 : case BIT_AND_EXPR:
5853 1560027 : if (INTEGRAL_TYPE_P (type)
5854 1516195 : && TREE_CODE (rhs1) == SSA_NAME
5855 1516195 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
5856 927024 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)
5857 926904 : && default_vn_walk_kind != VN_NOWALK
5858 : && CHAR_BIT == 8
5859 : && BITS_PER_UNIT == 8
5860 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
5861 926695 : && TYPE_PRECISION (type) <= vn_walk_cb_data::bufsize * BITS_PER_UNIT
5862 926693 : && !integer_all_onesp (gimple_assign_rhs2 (stmt))
5863 2486720 : && !integer_zerop (gimple_assign_rhs2 (stmt)))
5864 : {
5865 926693 : gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5866 680192 : if (ass
5867 680192 : && !gimple_has_volatile_ops (ass)
5868 678606 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5869 : {
5870 318386 : tree last_vuse = gimple_vuse (ass);
5871 318386 : tree op = gimple_assign_rhs1 (ass);
5872 955158 : tree result = vn_reference_lookup (op, gimple_vuse (ass),
5873 : default_vn_walk_kind,
5874 : NULL, true, &last_vuse,
5875 : gimple_assign_rhs2 (stmt));
5876 318386 : if (result
5877 318843 : && useless_type_conversion_p (TREE_TYPE (result),
5878 457 : TREE_TYPE (op)))
5879 457 : return set_ssa_val_to (lhs, result);
5880 : }
5881 : }
5882 : break;
5883 256051 : case BIT_FIELD_REF:
5884 256051 : if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
5885 : {
5886 256023 : tree op0 = vn_valueize (TREE_OPERAND (rhs1, 0));
5887 256023 : gassign *ass;
5888 256023 : if (TREE_CODE (op0) == SSA_NAME
5889 256023 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)))
5890 211567 : && !gimple_has_volatile_ops (ass)
5891 467507 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5892 : {
5893 77873 : tree last_vuse = gimple_vuse (ass);
5894 77873 : tree op = gimple_assign_rhs1 (ass);
5895 : /* Avoid building invalid and unexpected refs. */
5896 77873 : if (TREE_CODE (op) != TARGET_MEM_REF
5897 : && TREE_CODE (op) != BIT_FIELD_REF
5898 : && TREE_CODE (op) != REALPART_EXPR
5899 : && TREE_CODE (op) != IMAGPART_EXPR)
5900 : {
5901 71028 : tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1),
5902 : gimple_assign_rhs1 (ass),
5903 71028 : TREE_OPERAND (rhs1, 1),
5904 71028 : TREE_OPERAND (rhs1, 2));
5905 142056 : tree result = vn_reference_lookup (op, gimple_vuse (ass),
5906 : default_vn_walk_kind,
5907 : NULL, true, &last_vuse);
5908 71028 : if (result
5909 71028 : && useless_type_conversion_p (type, TREE_TYPE (result)))
5910 1825 : return set_ssa_val_to (lhs, result);
5911 69462 : else if (result
5912 259 : && TYPE_SIZE (type)
5913 259 : && TYPE_SIZE (TREE_TYPE (result))
5914 69721 : && operand_equal_p (TYPE_SIZE (type),
5915 259 : TYPE_SIZE (TREE_TYPE (result))))
5916 : {
5917 259 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5918 259 : VIEW_CONVERT_EXPR,
5919 259 : type, result);
5920 259 : result = vn_nary_build_or_lookup (&match_op);
5921 259 : if (result)
5922 : {
5923 259 : bool changed = set_ssa_val_to (lhs, result);
5924 259 : if (TREE_CODE (result) == SSA_NAME)
5925 247 : vn_nary_op_insert_stmt (stmt, result);
5926 259 : return changed;
5927 : }
5928 : }
5929 : }
5930 : }
5931 : }
5932 : break;
5933 349443 : case TRUNC_DIV_EXPR:
5934 349443 : if (TYPE_UNSIGNED (type))
5935 : break;
5936 : /* Fallthru. */
5937 5609189 : case RDIV_EXPR:
5938 5609189 : case MULT_EXPR:
5939 : /* Match up ([-]a){/,*}([-])b with v=a{/,*}b, replacing it with -v. */
5940 5609189 : if (! HONOR_SIGN_DEPENDENT_ROUNDING (type))
5941 : {
5942 5608275 : tree rhs[2];
5943 5608275 : rhs[0] = rhs1;
5944 5608275 : rhs[1] = gimple_assign_rhs2 (stmt);
5945 16815960 : for (unsigned i = 0; i <= 1; ++i)
5946 : {
5947 11215070 : unsigned j = i == 0 ? 1 : 0;
5948 11215070 : tree ops[2];
5949 11215070 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5950 11215070 : NEGATE_EXPR, type, rhs[i]);
5951 11215070 : ops[i] = vn_nary_build_or_lookup_1 (&match_op, false, true);
5952 11215070 : ops[j] = rhs[j];
5953 11215070 : if (ops[i]
5954 11215070 : && (ops[0] = vn_nary_op_lookup_pieces (2, code,
5955 : type, ops, NULL)))
5956 : {
5957 7385 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5958 7385 : NEGATE_EXPR, type, ops[0]);
5959 7385 : result = vn_nary_build_or_lookup_1 (&match_op, true, false);
5960 7385 : if (result)
5961 : {
5962 7385 : bool changed = set_ssa_val_to (lhs, result);
5963 7385 : if (TREE_CODE (result) == SSA_NAME)
5964 7385 : vn_nary_op_insert_stmt (stmt, result);
5965 7385 : return changed;
5966 : }
5967 : }
5968 : }
5969 : }
5970 : break;
5971 371647 : case LSHIFT_EXPR:
5972 : /* For X << C, use the value number of X * (1 << C). */
5973 371647 : if (INTEGRAL_TYPE_P (type)
5974 355583 : && TYPE_OVERFLOW_WRAPS (type)
5975 561759 : && !TYPE_SATURATING (type))
5976 : {
5977 190112 : tree rhs2 = gimple_assign_rhs2 (stmt);
5978 190112 : if (TREE_CODE (rhs2) == INTEGER_CST
5979 110569 : && tree_fits_uhwi_p (rhs2)
5980 300681 : && tree_to_uhwi (rhs2) < TYPE_PRECISION (type))
5981 : {
5982 221138 : wide_int w = wi::set_bit_in_zero (tree_to_uhwi (rhs2),
5983 110569 : TYPE_PRECISION (type));
5984 221138 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5985 110569 : MULT_EXPR, type, rhs1,
5986 110569 : wide_int_to_tree (type, w));
5987 110569 : result = vn_nary_build_or_lookup (&match_op);
5988 110569 : if (result)
5989 : {
5990 110569 : bool changed = set_ssa_val_to (lhs, result);
5991 110569 : if (TREE_CODE (result) == SSA_NAME)
5992 110568 : vn_nary_op_insert_stmt (stmt, result);
5993 110569 : return changed;
5994 : }
5995 110569 : }
5996 : }
5997 : break;
5998 : default:
5999 : break;
6000 : }
6001 :
6002 46174980 : bool changed = set_ssa_val_to (lhs, lhs);
6003 46174980 : vn_nary_op_insert_stmt (stmt, lhs);
6004 46174980 : return changed;
6005 : }
6006 :
6007 : /* Visit a call STMT storing into LHS. Return true if the value number
6008 : of the LHS has changed as a result. */
6009 :
6010 : static bool
6011 8945061 : visit_reference_op_call (tree lhs, gcall *stmt)
6012 : {
6013 8945061 : bool changed = false;
6014 8945061 : struct vn_reference_s vr1;
6015 8945061 : vn_reference_t vnresult = NULL;
6016 8945061 : tree vdef = gimple_vdef (stmt);
6017 8945061 : modref_summary *summary;
6018 :
6019 : /* Non-ssa lhs is handled in copy_reference_ops_from_call. */
6020 8945061 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
6021 4799331 : lhs = NULL_TREE;
6022 :
6023 8945061 : vn_reference_lookup_call (stmt, &vnresult, &vr1);
6024 :
6025 : /* If the lookup did not succeed for pure functions try to use
6026 : modref info to find a candidate to CSE to. */
6027 8945061 : const unsigned accesses_limit = 8;
6028 8945061 : if (!vnresult
6029 8235563 : && !vdef
6030 8235563 : && lhs
6031 2863254 : && gimple_vuse (stmt)
6032 10555967 : && (((summary = get_modref_function_summary (stmt, NULL))
6033 233880 : && !summary->global_memory_read
6034 95840 : && summary->load_accesses < accesses_limit)
6035 1515425 : || gimple_call_flags (stmt) & ECF_CONST))
6036 : {
6037 : /* First search if we can do something useful and build a
6038 : vector of all loads we have to check. */
6039 96231 : bool unknown_memory_access = false;
6040 96231 : auto_vec<ao_ref, accesses_limit> accesses;
6041 96231 : unsigned load_accesses = summary ? summary->load_accesses : 0;
6042 96231 : if (!unknown_memory_access)
6043 : /* Add loads done as part of setting up the call arguments.
6044 : That's also necessary for CONST functions which will
6045 : not have a modref summary. */
6046 284909 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
6047 : {
6048 188686 : tree arg = gimple_call_arg (stmt, i);
6049 188686 : if (TREE_CODE (arg) != SSA_NAME
6050 188686 : && !is_gimple_min_invariant (arg))
6051 : {
6052 64706 : if (accesses.length () >= accesses_limit - load_accesses)
6053 : {
6054 : unknown_memory_access = true;
6055 : break;
6056 : }
6057 32345 : accesses.quick_grow (accesses.length () + 1);
6058 32345 : ao_ref_init (&accesses.last (), arg);
6059 : }
6060 : }
6061 96231 : if (summary && !unknown_memory_access)
6062 : {
6063 : /* Add loads as analyzed by IPA modref. */
6064 330532 : for (auto base_node : summary->loads->bases)
6065 83054 : if (unknown_memory_access)
6066 : break;
6067 338614 : else for (auto ref_node : base_node->refs)
6068 90403 : if (unknown_memory_access)
6069 : break;
6070 379846 : else for (auto access_node : ref_node->accesses)
6071 : {
6072 253106 : accesses.quick_grow (accesses.length () + 1);
6073 126553 : ao_ref *r = &accesses.last ();
6074 126553 : if (!access_node.get_ao_ref (stmt, r))
6075 : {
6076 : /* Initialize a ref based on the argument and
6077 : unknown offset if possible. */
6078 17880 : tree arg = access_node.get_call_arg (stmt);
6079 17880 : if (arg && TREE_CODE (arg) == SSA_NAME)
6080 4413 : arg = SSA_VAL (arg);
6081 4413 : if (arg
6082 17870 : && TREE_CODE (arg) == ADDR_EXPR
6083 13463 : && (arg = get_base_address (arg))
6084 17876 : && DECL_P (arg))
6085 : {
6086 0 : ao_ref_init (r, arg);
6087 0 : r->ref = NULL_TREE;
6088 0 : r->base = arg;
6089 : }
6090 : else
6091 : {
6092 : unknown_memory_access = true;
6093 : break;
6094 : }
6095 : }
6096 108673 : r->base_alias_set = base_node->base;
6097 108673 : r->ref_alias_set = ref_node->ref;
6098 : }
6099 : }
6100 :
6101 : /* Walk the VUSE->VDEF chain optimistically trying to find an entry
6102 : for the call in the hashtable. */
6103 96231 : unsigned limit = (unknown_memory_access
6104 96231 : ? 0
6105 78343 : : (param_sccvn_max_alias_queries_per_access
6106 78343 : / (accesses.length () + 1)));
6107 96231 : tree saved_vuse = vr1.vuse;
6108 96231 : hashval_t saved_hashcode = vr1.hashcode;
6109 520420 : while (limit > 0 && !vnresult && !SSA_NAME_IS_DEFAULT_DEF (vr1.vuse))
6110 : {
6111 453278 : vr1.hashcode = vr1.hashcode - SSA_NAME_VERSION (vr1.vuse);
6112 453278 : gimple *def = SSA_NAME_DEF_STMT (vr1.vuse);
6113 : /* ??? We could use fancy stuff like in walk_non_aliased_vuses, but
6114 : do not bother for now. */
6115 453278 : if (is_a <gphi *> (def))
6116 : break;
6117 848378 : vr1.vuse = vuse_ssa_val (gimple_vuse (def));
6118 424189 : vr1.hashcode = vr1.hashcode + SSA_NAME_VERSION (vr1.vuse);
6119 424189 : vn_reference_lookup_1 (&vr1, &vnresult);
6120 424189 : limit--;
6121 : }
6122 :
6123 : /* If we found a candidate to CSE to verify it is valid. */
6124 96231 : if (vnresult && !accesses.is_empty ())
6125 : {
6126 1980 : tree vuse = vuse_ssa_val (gimple_vuse (stmt));
6127 7440 : while (vnresult && vuse != vr1.vuse)
6128 : {
6129 3480 : gimple *def = SSA_NAME_DEF_STMT (vuse);
6130 18718 : for (auto &ref : accesses)
6131 : {
6132 : /* ??? stmt_may_clobber_ref_p_1 does per stmt constant
6133 : analysis overhead that we might be able to cache. */
6134 10038 : if (stmt_may_clobber_ref_p_1 (def, &ref, true))
6135 : {
6136 1760 : vnresult = NULL;
6137 1760 : break;
6138 : }
6139 : }
6140 6960 : vuse = vuse_ssa_val (gimple_vuse (def));
6141 : }
6142 : }
6143 96231 : vr1.vuse = saved_vuse;
6144 96231 : vr1.hashcode = saved_hashcode;
6145 96231 : }
6146 :
6147 8945061 : if (vnresult)
6148 : {
6149 709746 : if (vdef)
6150 : {
6151 177164 : if (vnresult->result_vdef)
6152 177164 : changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
6153 0 : else if (!lhs && gimple_call_lhs (stmt))
6154 : /* If stmt has non-SSA_NAME lhs, value number the vdef to itself,
6155 : as the call still acts as a lhs store. */
6156 0 : changed |= set_ssa_val_to (vdef, vdef);
6157 : else
6158 : /* If the call was discovered to be pure or const reflect
6159 : that as far as possible. */
6160 0 : changed |= set_ssa_val_to (vdef,
6161 : vuse_ssa_val (gimple_vuse (stmt)));
6162 : }
6163 :
6164 709746 : if (!vnresult->result && lhs)
6165 0 : vnresult->result = lhs;
6166 :
6167 709746 : if (vnresult->result && lhs)
6168 126101 : changed |= set_ssa_val_to (lhs, vnresult->result);
6169 : }
6170 : else
6171 : {
6172 8235315 : vn_reference_t vr2;
6173 8235315 : vn_reference_s **slot;
6174 8235315 : tree vdef_val = vdef;
6175 8235315 : if (vdef)
6176 : {
6177 : /* If we value numbered an indirect functions function to
6178 : one not clobbering memory value number its VDEF to its
6179 : VUSE. */
6180 5036363 : tree fn = gimple_call_fn (stmt);
6181 5036363 : if (fn && TREE_CODE (fn) == SSA_NAME)
6182 : {
6183 130405 : fn = SSA_VAL (fn);
6184 130405 : if (TREE_CODE (fn) == ADDR_EXPR
6185 2000 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
6186 2000 : && (flags_from_decl_or_type (TREE_OPERAND (fn, 0))
6187 2000 : & (ECF_CONST | ECF_PURE))
6188 : /* If stmt has non-SSA_NAME lhs, value number the
6189 : vdef to itself, as the call still acts as a lhs
6190 : store. */
6191 131808 : && (lhs || gimple_call_lhs (stmt) == NULL_TREE))
6192 2664 : vdef_val = vuse_ssa_val (gimple_vuse (stmt));
6193 : }
6194 5036363 : changed |= set_ssa_val_to (vdef, vdef_val);
6195 : }
6196 8235315 : if (lhs)
6197 4019629 : changed |= set_ssa_val_to (lhs, lhs);
6198 8235315 : vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s);
6199 8235315 : vr2->vuse = vr1.vuse;
6200 : /* As we are not walking the virtual operand chain we know the
6201 : shared_lookup_references are still original so we can re-use
6202 : them here. */
6203 8235315 : vr2->operands = vr1.operands.copy ();
6204 8235315 : vr2->type = vr1.type;
6205 8235315 : vr2->punned = vr1.punned;
6206 8235315 : vr2->set = vr1.set;
6207 8235315 : vr2->offset = vr1.offset;
6208 8235315 : vr2->max_size = vr1.max_size;
6209 8235315 : vr2->base_set = vr1.base_set;
6210 8235315 : vr2->hashcode = vr1.hashcode;
6211 8235315 : vr2->result = lhs;
6212 8235315 : vr2->result_vdef = vdef_val;
6213 8235315 : vr2->value_id = 0;
6214 8235315 : slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
6215 : INSERT);
6216 8235315 : gcc_assert (!*slot);
6217 8235315 : *slot = vr2;
6218 8235315 : vr2->next = last_inserted_ref;
6219 8235315 : last_inserted_ref = vr2;
6220 : }
6221 :
6222 8945061 : return changed;
6223 : }
6224 :
6225 : /* Visit a load from a reference operator RHS, part of STMT, value number it,
6226 : and return true if the value number of the LHS has changed as a result. */
6227 :
6228 : static bool
6229 35793738 : visit_reference_op_load (tree lhs, tree op, gimple *stmt)
6230 : {
6231 35793738 : bool changed = false;
6232 35793738 : tree result;
6233 35793738 : vn_reference_t res;
6234 :
6235 35793738 : tree vuse = gimple_vuse (stmt);
6236 35793738 : tree last_vuse = vuse;
6237 35793738 : result = vn_reference_lookup (op, vuse, default_vn_walk_kind, &res, true, &last_vuse);
6238 :
6239 : /* We handle type-punning through unions by value-numbering based
6240 : on offset and size of the access. Be prepared to handle a
6241 : type-mismatch here via creating a VIEW_CONVERT_EXPR. */
6242 35793738 : if (result
6243 35793738 : && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
6244 : {
6245 18955 : if (CONSTANT_CLASS_P (result))
6246 4270 : result = const_unop (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
6247 : else
6248 : {
6249 : /* We will be setting the value number of lhs to the value number
6250 : of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
6251 : So first simplify and lookup this expression to see if it
6252 : is already available. */
6253 14685 : gimple_match_op res_op (gimple_match_cond::UNCOND,
6254 14685 : VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
6255 14685 : result = vn_nary_build_or_lookup (&res_op);
6256 14685 : if (result
6257 14679 : && TREE_CODE (result) == SSA_NAME
6258 27705 : && VN_INFO (result)->needs_insertion)
6259 : /* Track whether this is the canonical expression for different
6260 : typed loads. We use that as a stopgap measure for code
6261 : hoisting when dealing with floating point loads. */
6262 11367 : res->punned = true;
6263 : }
6264 :
6265 : /* When building the conversion fails avoid inserting the reference
6266 : again. */
6267 18955 : if (!result)
6268 6 : return set_ssa_val_to (lhs, lhs);
6269 : }
6270 :
6271 35774783 : if (result)
6272 5828574 : changed = set_ssa_val_to (lhs, result);
6273 : else
6274 : {
6275 29965158 : changed = set_ssa_val_to (lhs, lhs);
6276 29965158 : vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
6277 29965158 : if (vuse && SSA_VAL (last_vuse) != SSA_VAL (vuse))
6278 : {
6279 9293753 : if (dump_file && (dump_flags & TDF_DETAILS))
6280 : {
6281 23478 : fprintf (dump_file, "Using extra use virtual operand ");
6282 23478 : print_generic_expr (dump_file, last_vuse);
6283 23478 : fprintf (dump_file, "\n");
6284 : }
6285 9293753 : vn_reference_insert (op, lhs, vuse, NULL_TREE);
6286 : }
6287 : }
6288 :
6289 : return changed;
6290 : }
6291 :
6292 :
6293 : /* Visit a store to a reference operator LHS, part of STMT, value number it,
6294 : and return true if the value number of the LHS has changed as a result. */
6295 :
6296 : static bool
6297 33987756 : visit_reference_op_store (tree lhs, tree op, gimple *stmt)
6298 : {
6299 33987756 : bool changed = false;
6300 33987756 : vn_reference_t vnresult = NULL;
6301 33987756 : tree assign;
6302 33987756 : bool resultsame = false;
6303 33987756 : tree vuse = gimple_vuse (stmt);
6304 33987756 : tree vdef = gimple_vdef (stmt);
6305 :
6306 33987756 : if (TREE_CODE (op) == SSA_NAME)
6307 15470648 : op = SSA_VAL (op);
6308 :
6309 : /* First we want to lookup using the *vuses* from the store and see
6310 : if there the last store to this location with the same address
6311 : had the same value.
6312 :
6313 : The vuses represent the memory state before the store. If the
6314 : memory state, address, and value of the store is the same as the
6315 : last store to this location, then this store will produce the
6316 : same memory state as that store.
6317 :
6318 : In this case the vdef versions for this store are value numbered to those
6319 : vuse versions, since they represent the same memory state after
6320 : this store.
6321 :
6322 : Otherwise, the vdefs for the store are used when inserting into
6323 : the table, since the store generates a new memory state. */
6324 :
6325 33987756 : vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
6326 33987756 : if (vnresult
6327 1710607 : && vnresult->result)
6328 : {
6329 1710607 : tree result = vnresult->result;
6330 1710607 : gcc_checking_assert (TREE_CODE (result) != SSA_NAME
6331 : || result == SSA_VAL (result));
6332 1710607 : resultsame = expressions_equal_p (result, op);
6333 1710607 : if (resultsame)
6334 : {
6335 : /* If the TBAA state isn't compatible for downstream reads
6336 : we cannot value-number the VDEFs the same. */
6337 54195 : ao_ref lhs_ref;
6338 54195 : ao_ref_init (&lhs_ref, lhs);
6339 54195 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
6340 54195 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
6341 54195 : if ((vnresult->set != set
6342 913 : && ! alias_set_subset_of (set, vnresult->set))
6343 54791 : || (vnresult->base_set != base_set
6344 8270 : && ! alias_set_subset_of (base_set, vnresult->base_set)))
6345 2724 : resultsame = false;
6346 : }
6347 : }
6348 :
6349 2724 : if (!resultsame)
6350 : {
6351 33936285 : if (dump_file && (dump_flags & TDF_DETAILS))
6352 : {
6353 20794 : fprintf (dump_file, "No store match\n");
6354 20794 : fprintf (dump_file, "Value numbering store ");
6355 20794 : print_generic_expr (dump_file, lhs);
6356 20794 : fprintf (dump_file, " to ");
6357 20794 : print_generic_expr (dump_file, op);
6358 20794 : fprintf (dump_file, "\n");
6359 : }
6360 : /* Have to set value numbers before insert, since insert is
6361 : going to valueize the references in-place. */
6362 33936285 : if (vdef)
6363 33936285 : changed |= set_ssa_val_to (vdef, vdef);
6364 :
6365 : /* Do not insert structure copies into the tables. */
6366 33936285 : if (is_gimple_min_invariant (op)
6367 33936285 : || is_gimple_reg (op))
6368 30248059 : vn_reference_insert (lhs, op, vdef, NULL);
6369 :
6370 : /* Only perform the following when being called from PRE
6371 : which embeds tail merging. */
6372 33936285 : if (default_vn_walk_kind == VN_WALK)
6373 : {
6374 7686419 : assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
6375 7686419 : vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
6376 7686419 : if (!vnresult)
6377 7644149 : vn_reference_insert (assign, lhs, vuse, vdef);
6378 : }
6379 : }
6380 : else
6381 : {
6382 : /* We had a match, so value number the vdef to have the value
6383 : number of the vuse it came from. */
6384 :
6385 51471 : if (dump_file && (dump_flags & TDF_DETAILS))
6386 9 : fprintf (dump_file, "Store matched earlier value, "
6387 : "value numbering store vdefs to matching vuses.\n");
6388 :
6389 51471 : changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
6390 : }
6391 :
6392 33987756 : return changed;
6393 : }
6394 :
6395 : /* Visit and value number PHI, return true if the value number
6396 : changed. When BACKEDGES_VARYING_P is true then assume all
6397 : backedge values are varying. When INSERTED is not NULL then
6398 : this is just a ahead query for a possible iteration, set INSERTED
6399 : to true if we'd insert into the hashtable. */
6400 :
6401 : static bool
6402 35103261 : visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
6403 : {
6404 35103261 : tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
6405 35103261 : bool seen_undef_visited = false;
6406 35103261 : tree backedge_val = NULL_TREE;
6407 35103261 : bool seen_non_backedge = false;
6408 35103261 : tree sameval_base = NULL_TREE;
6409 35103261 : poly_int64 soff, doff;
6410 35103261 : unsigned n_executable = 0;
6411 35103261 : edge sameval_e = NULL;
6412 :
6413 : /* TODO: We could check for this in initialization, and replace this
6414 : with a gcc_assert. */
6415 35103261 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
6416 30889 : return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
6417 :
6418 : /* We track whether a PHI was CSEd to avoid excessive iterations
6419 : that would be necessary only because the PHI changed arguments
6420 : but not value. */
6421 35072372 : if (!inserted)
6422 27439836 : gimple_set_plf (phi, GF_PLF_1, false);
6423 :
6424 35072372 : basic_block bb = gimple_bb (phi);
6425 :
6426 : /* For the equivalence handling below make sure to first process an
6427 : edge with a non-constant. */
6428 35072372 : auto_vec<edge, 2> preds;
6429 70144744 : preds.reserve_exact (EDGE_COUNT (bb->preds));
6430 35072372 : bool seen_nonconstant = false;
6431 151266241 : for (unsigned i = 0; i < EDGE_COUNT (bb->preds); ++i)
6432 : {
6433 81121497 : edge e = EDGE_PRED (bb, i);
6434 81121497 : preds.quick_push (e);
6435 81121497 : if (!seen_nonconstant)
6436 : {
6437 42900767 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6438 42900767 : if (TREE_CODE (def) == SSA_NAME)
6439 : {
6440 33304482 : seen_nonconstant = true;
6441 33304482 : if (i != 0)
6442 5813839 : std::swap (preds[0], preds[i]);
6443 : }
6444 : }
6445 : }
6446 :
6447 : /* See if all non-TOP arguments have the same value. TOP is
6448 : equivalent to everything, so we can ignore it. */
6449 147643156 : for (edge e : preds)
6450 69652595 : if (e->flags & EDGE_EXECUTABLE)
6451 : {
6452 64548213 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6453 :
6454 64548213 : if (def == PHI_RESULT (phi))
6455 340650 : continue;
6456 64233389 : ++n_executable;
6457 64233389 : bool visited = true;
6458 64233389 : if (TREE_CODE (def) == SSA_NAME)
6459 : {
6460 51886184 : tree val = SSA_VAL (def, &visited);
6461 51886184 : if (SSA_NAME_IS_DEFAULT_DEF (def))
6462 2743879 : visited = true;
6463 51886184 : if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
6464 49291301 : def = val;
6465 51886184 : if (e->flags & EDGE_DFS_BACK)
6466 15609075 : backedge_val = def;
6467 : }
6468 64233389 : if (!(e->flags & EDGE_DFS_BACK))
6469 48481313 : seen_non_backedge = true;
6470 64233389 : if (def == VN_TOP)
6471 : ;
6472 : /* Ignore undefined defs for sameval but record one. */
6473 64233389 : else if (TREE_CODE (def) == SSA_NAME
6474 48421635 : && ! virtual_operand_p (def)
6475 88754267 : && ssa_undefined_value_p (def, false))
6476 : {
6477 234764 : if (!seen_undef
6478 : /* Avoid having not visited undefined defs if we also have
6479 : a visited one. */
6480 35832 : || (!seen_undef_visited && visited))
6481 : {
6482 198936 : seen_undef = def;
6483 198936 : seen_undef_visited = visited;
6484 : }
6485 : }
6486 63998625 : else if (sameval == VN_TOP)
6487 : {
6488 : sameval = def;
6489 : sameval_e = e;
6490 : }
6491 28973560 : else if (expressions_equal_p (def, sameval))
6492 : sameval_e = NULL;
6493 45574225 : else if (virtual_operand_p (def))
6494 : {
6495 : sameval = NULL_TREE;
6496 27226555 : break;
6497 : }
6498 : else
6499 : {
6500 : /* We know we're arriving only with invariant addresses here,
6501 : try harder comparing them. We can do some caching here
6502 : which we cannot do in expressions_equal_p. */
6503 16945189 : if (TREE_CODE (def) == ADDR_EXPR
6504 399699 : && TREE_CODE (sameval) == ADDR_EXPR
6505 109132 : && sameval_base != (void *)-1)
6506 : {
6507 109132 : if (!sameval_base)
6508 109130 : sameval_base = get_addr_base_and_unit_offset
6509 109130 : (TREE_OPERAND (sameval, 0), &soff);
6510 109130 : if (!sameval_base)
6511 : sameval_base = (tree)(void *)-1;
6512 109137 : else if ((get_addr_base_and_unit_offset
6513 109132 : (TREE_OPERAND (def, 0), &doff) == sameval_base)
6514 109132 : && known_eq (soff, doff))
6515 5 : continue;
6516 : }
6517 : /* There's also the possibility to use equivalences. */
6518 32795914 : if (!FLOAT_TYPE_P (TREE_TYPE (def))
6519 : /* But only do this if we didn't force any of sameval or
6520 : val to VARYING because of backedge processing rules. */
6521 15744876 : && (TREE_CODE (sameval) != SSA_NAME
6522 12401379 : || SSA_VAL (sameval) == sameval)
6523 32689999 : && (TREE_CODE (def) != SSA_NAME || SSA_VAL (def) == def))
6524 : {
6525 15744803 : vn_nary_op_t vnresult;
6526 15744803 : tree ops[2];
6527 15744803 : ops[0] = def;
6528 15744803 : ops[1] = sameval;
6529 : /* Canonicalize the operands order for eq below. */
6530 15744803 : if (tree_swap_operands_p (ops[0], ops[1]))
6531 9422808 : std::swap (ops[0], ops[1]);
6532 15744803 : tree val = vn_nary_op_lookup_pieces (2, EQ_EXPR,
6533 : boolean_type_node,
6534 : ops, &vnresult);
6535 15744803 : if (! val && vnresult && vnresult->predicated_values)
6536 : {
6537 205533 : val = vn_nary_op_get_predicated_value (vnresult, e);
6538 111676 : if (val && integer_truep (val)
6539 231476 : && !(sameval_e && (sameval_e->flags & EDGE_DFS_BACK)))
6540 : {
6541 25821 : if (dump_file && (dump_flags & TDF_DETAILS))
6542 : {
6543 2 : fprintf (dump_file, "Predication says ");
6544 2 : print_generic_expr (dump_file, def, TDF_NONE);
6545 2 : fprintf (dump_file, " and ");
6546 2 : print_generic_expr (dump_file, sameval, TDF_NONE);
6547 2 : fprintf (dump_file, " are equal on edge %d -> %d\n",
6548 2 : e->src->index, e->dest->index);
6549 : }
6550 25821 : continue;
6551 : }
6552 : }
6553 : }
6554 : sameval = NULL_TREE;
6555 : break;
6556 : }
6557 : }
6558 :
6559 : /* If the value we want to use is flowing over the backedge and we
6560 : should take it as VARYING but it has a non-VARYING value drop to
6561 : VARYING.
6562 : If we value-number a virtual operand never value-number to the
6563 : value from the backedge as that confuses the alias-walking code.
6564 : See gcc.dg/torture/pr87176.c. If the value is the same on a
6565 : non-backedge everything is OK though. */
6566 35072372 : bool visited_p;
6567 35072372 : if ((backedge_val
6568 35072372 : && !seen_non_backedge
6569 2164 : && TREE_CODE (backedge_val) == SSA_NAME
6570 1897 : && sameval == backedge_val
6571 313 : && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
6572 40 : || SSA_VAL (backedge_val) != backedge_val))
6573 : /* Do not value-number a virtual operand to sth not visited though
6574 : given that allows us to escape a region in alias walking. */
6575 35074263 : || (sameval
6576 7845544 : && TREE_CODE (sameval) == SSA_NAME
6577 4662250 : && !SSA_NAME_IS_DEFAULT_DEF (sameval)
6578 3936051 : && SSA_NAME_IS_VIRTUAL_OPERAND (sameval)
6579 1988986 : && (SSA_VAL (sameval, &visited_p), !visited_p)))
6580 : /* Note this just drops to VARYING without inserting the PHI into
6581 : the hashes. */
6582 303969 : result = PHI_RESULT (phi);
6583 : /* If none of the edges was executable keep the value-number at VN_TOP,
6584 : if only a single edge is executable use its value. */
6585 34768403 : else if (n_executable <= 1)
6586 6759458 : result = seen_undef ? seen_undef : sameval;
6587 : /* If we saw only undefined values and VN_TOP use one of the
6588 : undefined values. */
6589 28008945 : else if (sameval == VN_TOP)
6590 5630 : result = (seen_undef && seen_undef_visited) ? seen_undef : sameval;
6591 : /* First see if it is equivalent to a phi node in this block. We prefer
6592 : this as it allows IV elimination - see PRs 66502 and 67167. */
6593 28003315 : else if ((result = vn_phi_lookup (phi, backedges_varying_p)))
6594 : {
6595 4188266 : if (!inserted
6596 70565 : && TREE_CODE (result) == SSA_NAME
6597 4258831 : && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI)
6598 : {
6599 70565 : gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true);
6600 70565 : if (dump_file && (dump_flags & TDF_DETAILS))
6601 : {
6602 6 : fprintf (dump_file, "Marking CSEd to PHI node ");
6603 6 : print_gimple_expr (dump_file, SSA_NAME_DEF_STMT (result),
6604 : 0, TDF_SLIM);
6605 6 : fprintf (dump_file, "\n");
6606 : }
6607 : }
6608 : }
6609 : /* If all values are the same use that, unless we've seen undefined
6610 : values as well and the value isn't constant.
6611 : CCP/copyprop have the same restriction to not remove uninit warnings. */
6612 23815049 : else if (sameval
6613 23815049 : && (! seen_undef || is_gimple_min_invariant (sameval)))
6614 : result = sameval;
6615 : else
6616 : {
6617 23179725 : result = PHI_RESULT (phi);
6618 : /* Only insert PHIs that are varying, for constant value numbers
6619 : we mess up equivalences otherwise as we are only comparing
6620 : the immediate controlling predicates. */
6621 23179725 : vn_phi_insert (phi, result, backedges_varying_p);
6622 23179725 : if (inserted)
6623 3355491 : *inserted = true;
6624 : }
6625 :
6626 35072372 : return set_ssa_val_to (PHI_RESULT (phi), result);
6627 35072372 : }
6628 :
6629 : /* Try to simplify RHS using equivalences and constant folding. */
6630 :
6631 : static tree
6632 130980339 : try_to_simplify (gassign *stmt)
6633 : {
6634 130980339 : enum tree_code code = gimple_assign_rhs_code (stmt);
6635 130980339 : tree tem;
6636 :
6637 : /* For stores we can end up simplifying a SSA_NAME rhs. Just return
6638 : in this case, there is no point in doing extra work. */
6639 130980339 : if (code == SSA_NAME)
6640 : return NULL_TREE;
6641 :
6642 : /* First try constant folding based on our current lattice. */
6643 115509363 : mprts_hook = vn_lookup_simplify_result;
6644 115509363 : tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
6645 115509363 : mprts_hook = NULL;
6646 115509363 : if (tem
6647 115509363 : && (TREE_CODE (tem) == SSA_NAME
6648 25720530 : || is_gimple_min_invariant (tem)))
6649 25731292 : return tem;
6650 :
6651 : return NULL_TREE;
6652 : }
6653 :
6654 : /* Visit and value number STMT, return true if the value number
6655 : changed. */
6656 :
6657 : static bool
6658 489812811 : visit_stmt (gimple *stmt, bool backedges_varying_p = false)
6659 : {
6660 489812811 : bool changed = false;
6661 :
6662 489812811 : if (dump_file && (dump_flags & TDF_DETAILS))
6663 : {
6664 420892 : fprintf (dump_file, "Value numbering stmt = ");
6665 420892 : print_gimple_stmt (dump_file, stmt, 0);
6666 : }
6667 :
6668 489812811 : if (gimple_code (stmt) == GIMPLE_PHI)
6669 27460975 : changed = visit_phi (stmt, NULL, backedges_varying_p);
6670 639645626 : else if (gimple_has_volatile_ops (stmt))
6671 9449356 : changed = defs_to_varying (stmt);
6672 452902480 : else if (gassign *ass = dyn_cast <gassign *> (stmt))
6673 : {
6674 136168314 : enum tree_code code = gimple_assign_rhs_code (ass);
6675 136168314 : tree lhs = gimple_assign_lhs (ass);
6676 136168314 : tree rhs1 = gimple_assign_rhs1 (ass);
6677 136168314 : tree simplified;
6678 :
6679 : /* Shortcut for copies. Simplifying copies is pointless,
6680 : since we copy the expression and value they represent. */
6681 136168314 : if (code == SSA_NAME
6682 20658951 : && TREE_CODE (lhs) == SSA_NAME)
6683 : {
6684 5187975 : changed = visit_copy (lhs, rhs1);
6685 5187975 : goto done;
6686 : }
6687 130980339 : simplified = try_to_simplify (ass);
6688 130980339 : if (simplified)
6689 : {
6690 25731292 : if (dump_file && (dump_flags & TDF_DETAILS))
6691 : {
6692 14973 : fprintf (dump_file, "RHS ");
6693 14973 : print_gimple_expr (dump_file, ass, 0);
6694 14973 : fprintf (dump_file, " simplified to ");
6695 14973 : print_generic_expr (dump_file, simplified);
6696 14973 : fprintf (dump_file, "\n");
6697 : }
6698 : }
6699 : /* Setting value numbers to constants will occasionally
6700 : screw up phi congruence because constants are not
6701 : uniquely associated with a single ssa name that can be
6702 : looked up. */
6703 25731292 : if (simplified
6704 25731292 : && is_gimple_min_invariant (simplified)
6705 22680937 : && TREE_CODE (lhs) == SSA_NAME)
6706 : {
6707 7846184 : changed = set_ssa_val_to (lhs, simplified);
6708 7846184 : goto done;
6709 : }
6710 123134155 : else if (simplified
6711 17885108 : && TREE_CODE (simplified) == SSA_NAME
6712 3050355 : && TREE_CODE (lhs) == SSA_NAME)
6713 : {
6714 3050355 : changed = visit_copy (lhs, simplified);
6715 3050355 : goto done;
6716 : }
6717 :
6718 120083800 : if ((TREE_CODE (lhs) == SSA_NAME
6719 : /* We can substitute SSA_NAMEs that are live over
6720 : abnormal edges with their constant value. */
6721 86095742 : && !(gimple_assign_copy_p (ass)
6722 26 : && is_gimple_min_invariant (rhs1))
6723 86095716 : && !(simplified
6724 0 : && is_gimple_min_invariant (simplified))
6725 86095716 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
6726 : /* Stores or copies from SSA_NAMEs that are live over
6727 : abnormal edges are a problem. */
6728 206178203 : || (code == SSA_NAME
6729 15470976 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
6730 1641 : changed = defs_to_varying (ass);
6731 120082159 : else if (REFERENCE_CLASS_P (lhs)
6732 120082159 : || DECL_P (lhs))
6733 33987756 : changed = visit_reference_op_store (lhs, rhs1, ass);
6734 86094403 : else if (TREE_CODE (lhs) == SSA_NAME)
6735 : {
6736 86094403 : if ((gimple_assign_copy_p (ass)
6737 26 : && is_gimple_min_invariant (rhs1))
6738 86094429 : || (simplified
6739 0 : && is_gimple_min_invariant (simplified)))
6740 : {
6741 0 : if (simplified)
6742 0 : changed = set_ssa_val_to (lhs, simplified);
6743 : else
6744 0 : changed = set_ssa_val_to (lhs, rhs1);
6745 : }
6746 : else
6747 : {
6748 : /* Visit the original statement. */
6749 86094403 : switch (vn_get_stmt_kind (ass))
6750 : {
6751 50188870 : case VN_NARY:
6752 50188870 : changed = visit_nary_op (lhs, ass);
6753 50188870 : break;
6754 35793738 : case VN_REFERENCE:
6755 35793738 : changed = visit_reference_op_load (lhs, rhs1, ass);
6756 35793738 : break;
6757 111795 : default:
6758 111795 : changed = defs_to_varying (ass);
6759 111795 : break;
6760 : }
6761 : }
6762 : }
6763 : else
6764 0 : changed = defs_to_varying (ass);
6765 : }
6766 316734166 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
6767 : {
6768 25814719 : tree lhs = gimple_call_lhs (call_stmt);
6769 25814719 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
6770 : {
6771 : /* Try constant folding based on our current lattice. */
6772 8655480 : tree simplified = gimple_fold_stmt_to_constant_1 (call_stmt,
6773 : vn_valueize);
6774 8655480 : if (simplified)
6775 : {
6776 68292 : if (dump_file && (dump_flags & TDF_DETAILS))
6777 : {
6778 1 : fprintf (dump_file, "call ");
6779 1 : print_gimple_expr (dump_file, call_stmt, 0);
6780 1 : fprintf (dump_file, " simplified to ");
6781 1 : print_generic_expr (dump_file, simplified);
6782 1 : fprintf (dump_file, "\n");
6783 : }
6784 : }
6785 : /* Setting value numbers to constants will occasionally
6786 : screw up phi congruence because constants are not
6787 : uniquely associated with a single ssa name that can be
6788 : looked up. */
6789 68292 : if (simplified
6790 68292 : && is_gimple_min_invariant (simplified))
6791 : {
6792 61762 : changed = set_ssa_val_to (lhs, simplified);
6793 123524 : if (gimple_vdef (call_stmt))
6794 751 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6795 : SSA_VAL (gimple_vuse (call_stmt)));
6796 61762 : goto done;
6797 : }
6798 8593718 : else if (simplified
6799 6530 : && TREE_CODE (simplified) == SSA_NAME)
6800 : {
6801 309 : changed = visit_copy (lhs, simplified);
6802 618 : if (gimple_vdef (call_stmt))
6803 0 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6804 : SSA_VAL (gimple_vuse (call_stmt)));
6805 309 : goto done;
6806 : }
6807 8593409 : else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
6808 : {
6809 414 : changed = defs_to_varying (call_stmt);
6810 414 : goto done;
6811 : }
6812 : }
6813 :
6814 : /* Pick up flags from a devirtualization target. */
6815 25752234 : tree fn = gimple_call_fn (stmt);
6816 25752234 : int extra_fnflags = 0;
6817 25752234 : if (fn && TREE_CODE (fn) == SSA_NAME)
6818 : {
6819 541259 : fn = SSA_VAL (fn);
6820 541259 : if (TREE_CODE (fn) == ADDR_EXPR
6821 541259 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
6822 5363 : extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
6823 : }
6824 25752234 : if ((/* Calls to the same function with the same vuse
6825 : and the same operands do not necessarily return the same
6826 : value, unless they're pure or const. */
6827 25752234 : ((gimple_call_flags (call_stmt) | extra_fnflags)
6828 25752234 : & (ECF_PURE | ECF_CONST))
6829 : /* If calls have a vdef, subsequent calls won't have
6830 : the same incoming vuse. So, if 2 calls with vdef have the
6831 : same vuse, we know they're not subsequent.
6832 : We can value number 2 calls to the same function with the
6833 : same vuse and the same operands which are not subsequent
6834 : the same, because there is no code in the program that can
6835 : compare the 2 values... */
6836 21679050 : || (gimple_vdef (call_stmt)
6837 : /* ... unless the call returns a pointer which does
6838 : not alias with anything else. In which case the
6839 : information that the values are distinct are encoded
6840 : in the IL. */
6841 21644237 : && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
6842 : /* Only perform the following when being called from PRE
6843 : which embeds tail merging. */
6844 21058013 : && default_vn_walk_kind == VN_WALK))
6845 : /* Do not process .DEFERRED_INIT since that confuses uninit
6846 : analysis. */
6847 30898149 : && !gimple_call_internal_p (call_stmt, IFN_DEFERRED_INIT))
6848 8945061 : changed = visit_reference_op_call (lhs, call_stmt);
6849 : else
6850 16807173 : changed = defs_to_varying (call_stmt);
6851 : }
6852 : else
6853 290919447 : changed = defs_to_varying (stmt);
6854 489812811 : done:
6855 489812811 : return changed;
6856 : }
6857 :
6858 :
6859 : /* Allocate a value number table. */
6860 :
6861 : static void
6862 6366283 : allocate_vn_table (vn_tables_t table, unsigned size)
6863 : {
6864 6366283 : table->phis = new vn_phi_table_type (size);
6865 6366283 : table->nary = new vn_nary_op_table_type (size);
6866 6366283 : table->references = new vn_reference_table_type (size);
6867 6366283 : }
6868 :
6869 : /* Free a value number table. */
6870 :
6871 : static void
6872 6366283 : free_vn_table (vn_tables_t table)
6873 : {
6874 : /* Walk over elements and release vectors. */
6875 6366283 : vn_reference_iterator_type hir;
6876 6366283 : vn_reference_t vr;
6877 79120622 : FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir)
6878 72754339 : vr->operands.release ();
6879 6366283 : delete table->phis;
6880 6366283 : table->phis = NULL;
6881 6366283 : delete table->nary;
6882 6366283 : table->nary = NULL;
6883 6366283 : delete table->references;
6884 6366283 : table->references = NULL;
6885 6366283 : }
6886 :
6887 : /* Set *ID according to RESULT. */
6888 :
6889 : static void
6890 35602638 : set_value_id_for_result (tree result, unsigned int *id)
6891 : {
6892 35602638 : if (result && TREE_CODE (result) == SSA_NAME)
6893 22165305 : *id = VN_INFO (result)->value_id;
6894 10028469 : else if (result && is_gimple_min_invariant (result))
6895 3794899 : *id = get_or_alloc_constant_value_id (result);
6896 : else
6897 9642434 : *id = get_next_value_id ();
6898 35602638 : }
6899 :
6900 : /* Set the value ids in the valid hash tables. */
6901 :
6902 : static void
6903 988750 : set_hashtable_value_ids (void)
6904 : {
6905 988750 : vn_nary_op_iterator_type hin;
6906 988750 : vn_phi_iterator_type hip;
6907 988750 : vn_reference_iterator_type hir;
6908 988750 : vn_nary_op_t vno;
6909 988750 : vn_reference_t vr;
6910 988750 : vn_phi_t vp;
6911 :
6912 : /* Now set the value ids of the things we had put in the hash
6913 : table. */
6914 :
6915 25470208 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin)
6916 24481458 : if (! vno->predicated_values)
6917 7993912 : set_value_id_for_result (vno->u.result, &vno->value_id);
6918 :
6919 5122478 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip)
6920 4133728 : set_value_id_for_result (vp->result, &vp->value_id);
6921 :
6922 24463748 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t,
6923 : hir)
6924 23474998 : set_value_id_for_result (vr->result, &vr->value_id);
6925 988750 : }
6926 :
6927 : /* Return the maximum value id we have ever seen. */
6928 :
6929 : unsigned int
6930 1977500 : get_max_value_id (void)
6931 : {
6932 1977500 : return next_value_id;
6933 : }
6934 :
6935 : /* Return the maximum constant value id we have ever seen. */
6936 :
6937 : unsigned int
6938 1977500 : get_max_constant_value_id (void)
6939 : {
6940 1977500 : return -next_constant_value_id;
6941 : }
6942 :
6943 : /* Return the next unique value id. */
6944 :
6945 : unsigned int
6946 50661631 : get_next_value_id (void)
6947 : {
6948 50661631 : gcc_checking_assert ((int)next_value_id > 0);
6949 50661631 : return next_value_id++;
6950 : }
6951 :
6952 : /* Return the next unique value id for constants. */
6953 :
6954 : unsigned int
6955 2602947 : get_next_constant_value_id (void)
6956 : {
6957 2602947 : gcc_checking_assert (next_constant_value_id < 0);
6958 2602947 : return next_constant_value_id--;
6959 : }
6960 :
6961 :
6962 : /* Compare two expressions E1 and E2 and return true if they are equal.
6963 : If match_vn_top_optimistically is true then VN_TOP is equal to anything,
6964 : otherwise VN_TOP only matches VN_TOP. */
6965 :
6966 : bool
6967 254026850 : expressions_equal_p (tree e1, tree e2, bool match_vn_top_optimistically)
6968 : {
6969 : /* The obvious case. */
6970 254026850 : if (e1 == e2)
6971 : return true;
6972 :
6973 : /* If either one is VN_TOP consider them equal. */
6974 72046996 : if (match_vn_top_optimistically
6975 67077238 : && (e1 == VN_TOP || e2 == VN_TOP))
6976 : return true;
6977 :
6978 : /* If only one of them is null, they cannot be equal. While in general
6979 : this should not happen for operations like TARGET_MEM_REF some
6980 : operands are optional and an identity value we could substitute
6981 : has differing semantics. */
6982 72046996 : if (!e1 || !e2)
6983 : return false;
6984 :
6985 : /* SSA_NAME compare pointer equal. */
6986 72046996 : if (TREE_CODE (e1) == SSA_NAME || TREE_CODE (e2) == SSA_NAME)
6987 : return false;
6988 :
6989 : /* Now perform the actual comparison. */
6990 36210014 : if (TREE_CODE (e1) == TREE_CODE (e2)
6991 36210014 : && operand_equal_p (e1, e2, OEP_PURE_SAME))
6992 : return true;
6993 :
6994 : return false;
6995 : }
6996 :
6997 :
6998 : /* Return true if the nary operation NARY may trap. This is a copy
6999 : of stmt_could_throw_1_p adjusted to the SCCVN IL. */
7000 :
7001 : bool
7002 5731524 : vn_nary_may_trap (vn_nary_op_t nary)
7003 : {
7004 5731524 : tree type;
7005 5731524 : tree rhs2 = NULL_TREE;
7006 5731524 : bool honor_nans = false;
7007 5731524 : bool honor_snans = false;
7008 5731524 : bool fp_operation = false;
7009 5731524 : bool honor_trapv = false;
7010 5731524 : bool handled, ret;
7011 5731524 : unsigned i;
7012 :
7013 5731524 : if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
7014 : || TREE_CODE_CLASS (nary->opcode) == tcc_unary
7015 5731524 : || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
7016 : {
7017 5611127 : type = nary->type;
7018 5611127 : fp_operation = FLOAT_TYPE_P (type);
7019 5488441 : if (fp_operation)
7020 : {
7021 122686 : honor_nans = flag_trapping_math && !flag_finite_math_only;
7022 122686 : honor_snans = flag_signaling_nans != 0;
7023 : }
7024 5488441 : else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
7025 : honor_trapv = true;
7026 : }
7027 5731524 : if (nary->length >= 2)
7028 2310910 : rhs2 = nary->op[1];
7029 5731524 : ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
7030 : honor_trapv, honor_nans, honor_snans,
7031 : rhs2, &handled);
7032 5731524 : if (handled && ret)
7033 : return true;
7034 :
7035 13460662 : for (i = 0; i < nary->length; ++i)
7036 7851208 : if (tree_could_trap_p (nary->op[i]))
7037 : return true;
7038 :
7039 : return false;
7040 : }
7041 :
7042 : /* Return true if the reference operation REF may trap. */
7043 :
7044 : bool
7045 945579 : vn_reference_may_trap (vn_reference_t ref)
7046 : {
7047 945579 : switch (ref->operands[0].opcode)
7048 : {
7049 : case MODIFY_EXPR:
7050 : case CALL_EXPR:
7051 : /* We do not handle calls. */
7052 : return true;
7053 : case ADDR_EXPR:
7054 : /* And toplevel address computations never trap. */
7055 : return false;
7056 : default:;
7057 : }
7058 :
7059 : vn_reference_op_t op;
7060 : unsigned i;
7061 2596053 : FOR_EACH_VEC_ELT (ref->operands, i, op)
7062 : {
7063 2595797 : switch (op->opcode)
7064 : {
7065 : case WITH_SIZE_EXPR:
7066 : case TARGET_MEM_REF:
7067 : /* Always variable. */
7068 : return true;
7069 720905 : case COMPONENT_REF:
7070 720905 : if (op->op1 && TREE_CODE (op->op1) == SSA_NAME)
7071 : return true;
7072 : break;
7073 0 : case ARRAY_RANGE_REF:
7074 0 : if (TREE_CODE (op->op0) == SSA_NAME)
7075 : return true;
7076 : break;
7077 206429 : case ARRAY_REF:
7078 206429 : {
7079 206429 : if (TREE_CODE (op->op0) != INTEGER_CST)
7080 : return true;
7081 :
7082 : /* !in_array_bounds */
7083 185690 : tree domain_type = TYPE_DOMAIN (ref->operands[i+1].type);
7084 185690 : if (!domain_type)
7085 : return true;
7086 :
7087 185644 : tree min = op->op1;
7088 185644 : tree max = TYPE_MAX_VALUE (domain_type);
7089 185644 : if (!min
7090 185644 : || !max
7091 172494 : || TREE_CODE (min) != INTEGER_CST
7092 172494 : || TREE_CODE (max) != INTEGER_CST)
7093 : return true;
7094 :
7095 169794 : if (tree_int_cst_lt (op->op0, min)
7096 169794 : || tree_int_cst_lt (max, op->op0))
7097 : return true;
7098 :
7099 : break;
7100 : }
7101 : case MEM_REF:
7102 : /* Nothing interesting in itself, the base is separate. */
7103 : break;
7104 : /* The following are the address bases. */
7105 : case SSA_NAME:
7106 : return true;
7107 533227 : case ADDR_EXPR:
7108 533227 : if (op->op0)
7109 533227 : return tree_could_trap_p (TREE_OPERAND (op->op0, 0));
7110 : return false;
7111 1737381 : default:;
7112 : }
7113 : }
7114 : return false;
7115 : }
7116 :
7117 10804246 : eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction,
7118 : bitmap inserted_exprs_)
7119 10804246 : : dom_walker (direction), do_pre (inserted_exprs_ != NULL),
7120 10804246 : el_todo (0), eliminations (0), insertions (0),
7121 10804246 : inserted_exprs (inserted_exprs_)
7122 : {
7123 10804246 : need_eh_cleanup = BITMAP_ALLOC (NULL);
7124 10804246 : need_ab_cleanup = BITMAP_ALLOC (NULL);
7125 10804246 : }
7126 :
7127 10804246 : eliminate_dom_walker::~eliminate_dom_walker ()
7128 : {
7129 10804246 : BITMAP_FREE (need_eh_cleanup);
7130 10804246 : BITMAP_FREE (need_ab_cleanup);
7131 10804246 : }
7132 :
7133 : /* Return a leader for OP that is available at the current point of the
7134 : eliminate domwalk. */
7135 :
7136 : tree
7137 188962128 : eliminate_dom_walker::eliminate_avail (basic_block, tree op)
7138 : {
7139 188962128 : tree valnum = VN_INFO (op)->valnum;
7140 188962128 : if (TREE_CODE (valnum) == SSA_NAME)
7141 : {
7142 183709028 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
7143 : return valnum;
7144 319584115 : if (avail.length () > SSA_NAME_VERSION (valnum))
7145 : {
7146 144046742 : tree av = avail[SSA_NAME_VERSION (valnum)];
7147 : /* When PRE discovers a new redundancy there's no way to unite
7148 : the value classes so it instead inserts a copy old-val = new-val.
7149 : Look through such copies here, providing one more level of
7150 : simplification at elimination time. */
7151 144046742 : gassign *ass;
7152 253420437 : if (av && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (av))))
7153 77757234 : if (gimple_assign_rhs_class (ass) == GIMPLE_SINGLE_RHS)
7154 : {
7155 41352947 : tree rhs1 = gimple_assign_rhs1 (ass);
7156 41352947 : if (CONSTANT_CLASS_P (rhs1)
7157 41352947 : || (TREE_CODE (rhs1) == SSA_NAME
7158 35259 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
7159 : av = rhs1;
7160 : }
7161 : return av;
7162 : }
7163 : }
7164 5253100 : else if (is_gimple_min_invariant (valnum))
7165 5253100 : return valnum;
7166 : return NULL_TREE;
7167 : }
7168 :
7169 : /* At the current point of the eliminate domwalk make OP available. */
7170 :
7171 : void
7172 51789581 : eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
7173 : {
7174 51789581 : tree valnum = VN_INFO (op)->valnum;
7175 51789581 : if (TREE_CODE (valnum) == SSA_NAME)
7176 : {
7177 100078431 : if (avail.length () <= SSA_NAME_VERSION (valnum))
7178 17501923 : avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1, true);
7179 51789581 : tree pushop = op;
7180 51789581 : if (avail[SSA_NAME_VERSION (valnum)])
7181 46023 : pushop = avail[SSA_NAME_VERSION (valnum)];
7182 51789581 : avail_stack.safe_push (pushop);
7183 51789581 : avail[SSA_NAME_VERSION (valnum)] = op;
7184 : }
7185 51789581 : }
7186 :
7187 : /* Insert the expression recorded by SCCVN for VAL at *GSI. Returns
7188 : the leader for the expression if insertion was successful. */
7189 :
7190 : tree
7191 139681 : eliminate_dom_walker::eliminate_insert (basic_block bb,
7192 : gimple_stmt_iterator *gsi, tree val)
7193 : {
7194 : /* We can insert a sequence with a single assignment only. */
7195 139681 : gimple_seq stmts = VN_INFO (val)->expr;
7196 139681 : if (!gimple_seq_singleton_p (stmts))
7197 : return NULL_TREE;
7198 139681 : gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts));
7199 139681 : if (!stmt
7200 139681 : || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
7201 : && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
7202 : && gimple_assign_rhs_code (stmt) != NEGATE_EXPR
7203 : && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF
7204 : && (gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
7205 109 : || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)))
7206 : return NULL_TREE;
7207 :
7208 46245 : tree op = gimple_assign_rhs1 (stmt);
7209 46245 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
7210 46245 : || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7211 20262 : op = TREE_OPERAND (op, 0);
7212 46245 : tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op;
7213 46199 : if (!leader)
7214 : return NULL_TREE;
7215 :
7216 36049 : tree res;
7217 36049 : stmts = NULL;
7218 55321 : if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7219 34150 : res = gimple_build (&stmts, BIT_FIELD_REF,
7220 17075 : TREE_TYPE (val), leader,
7221 17075 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
7222 17075 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
7223 18974 : else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
7224 210 : res = gimple_build (&stmts, BIT_AND_EXPR,
7225 105 : TREE_TYPE (val), leader, gimple_assign_rhs2 (stmt));
7226 : else
7227 18869 : res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
7228 18869 : TREE_TYPE (val), leader);
7229 36049 : if (TREE_CODE (res) != SSA_NAME
7230 36048 : || SSA_NAME_IS_DEFAULT_DEF (res)
7231 72097 : || gimple_bb (SSA_NAME_DEF_STMT (res)))
7232 : {
7233 4 : gimple_seq_discard (stmts);
7234 :
7235 : /* During propagation we have to treat SSA info conservatively
7236 : and thus we can end up simplifying the inserted expression
7237 : at elimination time to sth not defined in stmts. */
7238 : /* But then this is a redundancy we failed to detect. Which means
7239 : res now has two values. That doesn't play well with how
7240 : we track availability here, so give up. */
7241 4 : if (dump_file && (dump_flags & TDF_DETAILS))
7242 : {
7243 0 : if (TREE_CODE (res) == SSA_NAME)
7244 0 : res = eliminate_avail (bb, res);
7245 0 : if (res)
7246 : {
7247 0 : fprintf (dump_file, "Failed to insert expression for value ");
7248 0 : print_generic_expr (dump_file, val);
7249 0 : fprintf (dump_file, " which is really fully redundant to ");
7250 0 : print_generic_expr (dump_file, res);
7251 0 : fprintf (dump_file, "\n");
7252 : }
7253 : }
7254 :
7255 : return NULL_TREE;
7256 : }
7257 : else
7258 : {
7259 36045 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
7260 36045 : vn_ssa_aux_t vn_info = VN_INFO (res);
7261 36045 : vn_info->valnum = val;
7262 36045 : vn_info->visited = true;
7263 : }
7264 :
7265 36045 : insertions++;
7266 36045 : if (dump_file && (dump_flags & TDF_DETAILS))
7267 : {
7268 501 : fprintf (dump_file, "Inserted ");
7269 501 : print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0);
7270 : }
7271 :
7272 : return res;
7273 : }
7274 :
7275 : void
7276 381187064 : eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
7277 : {
7278 381187064 : tree sprime = NULL_TREE;
7279 381187064 : gimple *stmt = gsi_stmt (*gsi);
7280 381187064 : tree lhs = gimple_get_lhs (stmt);
7281 124781228 : if (lhs && TREE_CODE (lhs) == SSA_NAME
7282 172311748 : && !gimple_has_volatile_ops (stmt)
7283 : /* See PR43491. Do not replace a global register variable when
7284 : it is a the RHS of an assignment. Do replace local register
7285 : variables since gcc does not guarantee a local variable will
7286 : be allocated in register.
7287 : ??? The fix isn't effective here. This should instead
7288 : be ensured by not value-numbering them the same but treating
7289 : them like volatiles? */
7290 466273702 : && !(gimple_assign_single_p (stmt)
7291 36838991 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
7292 2506878 : && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
7293 4183 : && is_global_var (gimple_assign_rhs1 (stmt)))))
7294 : {
7295 85086390 : sprime = eliminate_avail (b, lhs);
7296 85086390 : if (!sprime)
7297 : {
7298 : /* If there is no existing usable leader but SCCVN thinks
7299 : it has an expression it wants to use as replacement,
7300 : insert that. */
7301 71526626 : tree val = VN_INFO (lhs)->valnum;
7302 71526626 : vn_ssa_aux_t vn_info;
7303 71526626 : if (val != VN_TOP
7304 71526626 : && TREE_CODE (val) == SSA_NAME
7305 71526626 : && (vn_info = VN_INFO (val), true)
7306 71526626 : && vn_info->needs_insertion
7307 341907 : && vn_info->expr != NULL
7308 71666307 : && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE)
7309 36045 : eliminate_push_avail (b, sprime);
7310 : }
7311 :
7312 : /* If this now constitutes a copy duplicate points-to
7313 : and range info appropriately. This is especially
7314 : important for inserted code. */
7315 71526626 : if (sprime
7316 13595809 : && TREE_CODE (sprime) == SSA_NAME)
7317 9337411 : maybe_duplicate_ssa_info_at_copy (lhs, sprime);
7318 :
7319 : /* Inhibit the use of an inserted PHI on a loop header when
7320 : the address of the memory reference is a simple induction
7321 : variable. In other cases the vectorizer won't do anything
7322 : anyway (either it's loop invariant or a complicated
7323 : expression). */
7324 9337411 : if (sprime
7325 13595809 : && TREE_CODE (sprime) == SSA_NAME
7326 9337411 : && do_pre
7327 947642 : && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1)
7328 929097 : && loop_outer (b->loop_father)
7329 401921 : && has_zero_uses (sprime)
7330 199553 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
7331 199345 : && gimple_assign_load_p (stmt))
7332 : {
7333 108680 : gimple *def_stmt = SSA_NAME_DEF_STMT (sprime);
7334 108680 : basic_block def_bb = gimple_bb (def_stmt);
7335 108680 : if (gimple_code (def_stmt) == GIMPLE_PHI
7336 108680 : && def_bb->loop_father->header == def_bb)
7337 : {
7338 68225 : loop_p loop = def_bb->loop_father;
7339 68225 : ssa_op_iter iter;
7340 68225 : tree op;
7341 68225 : bool found = false;
7342 86792 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
7343 : {
7344 64546 : affine_iv iv;
7345 64546 : def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
7346 64546 : if (def_bb
7347 58254 : && flow_bb_inside_loop_p (loop, def_bb)
7348 117505 : && simple_iv (loop, loop, op, &iv, true))
7349 : {
7350 45979 : found = true;
7351 45979 : break;
7352 : }
7353 : }
7354 22246 : if (found)
7355 : {
7356 45979 : if (dump_file && (dump_flags & TDF_DETAILS))
7357 : {
7358 3 : fprintf (dump_file, "Not replacing ");
7359 3 : print_gimple_expr (dump_file, stmt, 0);
7360 3 : fprintf (dump_file, " with ");
7361 3 : print_generic_expr (dump_file, sprime);
7362 3 : fprintf (dump_file, " which would add a loop"
7363 : " carried dependence to loop %d\n",
7364 : loop->num);
7365 : }
7366 : /* Don't keep sprime available. */
7367 : sprime = NULL_TREE;
7368 : }
7369 : }
7370 : }
7371 :
7372 85086390 : if (sprime)
7373 : {
7374 : /* If we can propagate the value computed for LHS into
7375 : all uses don't bother doing anything with this stmt. */
7376 13549830 : if (may_propagate_copy (lhs, sprime))
7377 : {
7378 : /* Mark it for removal. */
7379 13547889 : to_remove.safe_push (stmt);
7380 :
7381 : /* ??? Don't count copy/constant propagations. */
7382 13547889 : if (gimple_assign_single_p (stmt)
7383 13547889 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7384 4763843 : || gimple_assign_rhs1 (stmt) == sprime))
7385 14424439 : return;
7386 :
7387 8265863 : if (dump_file && (dump_flags & TDF_DETAILS))
7388 : {
7389 19223 : fprintf (dump_file, "Replaced ");
7390 19223 : print_gimple_expr (dump_file, stmt, 0);
7391 19223 : fprintf (dump_file, " with ");
7392 19223 : print_generic_expr (dump_file, sprime);
7393 19223 : fprintf (dump_file, " in all uses of ");
7394 19223 : print_gimple_stmt (dump_file, stmt, 0);
7395 : }
7396 :
7397 8265863 : eliminations++;
7398 8265863 : return;
7399 : }
7400 :
7401 : /* If this is an assignment from our leader (which
7402 : happens in the case the value-number is a constant)
7403 : then there is nothing to do. Likewise if we run into
7404 : inserted code that needed a conversion because of
7405 : our type-agnostic value-numbering of loads. */
7406 1941 : if ((gimple_assign_single_p (stmt)
7407 1 : || (is_gimple_assign (stmt)
7408 1 : && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
7409 0 : || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)))
7410 1942 : && sprime == gimple_assign_rhs1 (stmt))
7411 : return;
7412 :
7413 : /* Else replace its RHS. */
7414 719 : if (dump_file && (dump_flags & TDF_DETAILS))
7415 : {
7416 0 : fprintf (dump_file, "Replaced ");
7417 0 : print_gimple_expr (dump_file, stmt, 0);
7418 0 : fprintf (dump_file, " with ");
7419 0 : print_generic_expr (dump_file, sprime);
7420 0 : fprintf (dump_file, " in ");
7421 0 : print_gimple_stmt (dump_file, stmt, 0);
7422 : }
7423 719 : eliminations++;
7424 :
7425 719 : bool can_make_abnormal_goto = (is_gimple_call (stmt)
7426 719 : && stmt_can_make_abnormal_goto (stmt));
7427 719 : gimple *orig_stmt = stmt;
7428 719 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
7429 719 : TREE_TYPE (sprime)))
7430 : {
7431 : /* We preserve conversions to but not from function or method
7432 : types. This asymmetry makes it necessary to re-instantiate
7433 : conversions here. */
7434 717 : if (POINTER_TYPE_P (TREE_TYPE (lhs))
7435 717 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (lhs))))
7436 717 : sprime = fold_convert (TREE_TYPE (lhs), sprime);
7437 : else
7438 0 : gcc_unreachable ();
7439 : }
7440 719 : tree vdef = gimple_vdef (stmt);
7441 719 : tree vuse = gimple_vuse (stmt);
7442 719 : propagate_tree_value_into_stmt (gsi, sprime);
7443 719 : stmt = gsi_stmt (*gsi);
7444 719 : update_stmt (stmt);
7445 : /* In case the VDEF on the original stmt was released, value-number
7446 : it to the VUSE. This is to make vuse_ssa_val able to skip
7447 : released virtual operands. */
7448 1438 : if (vdef != gimple_vdef (stmt))
7449 : {
7450 0 : gcc_assert (SSA_NAME_IN_FREE_LIST (vdef));
7451 0 : VN_INFO (vdef)->valnum = vuse;
7452 : }
7453 :
7454 : /* If we removed EH side-effects from the statement, clean
7455 : its EH information. */
7456 719 : if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
7457 : {
7458 0 : bitmap_set_bit (need_eh_cleanup,
7459 0 : gimple_bb (stmt)->index);
7460 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7461 0 : fprintf (dump_file, " Removed EH side-effects.\n");
7462 : }
7463 :
7464 : /* Likewise for AB side-effects. */
7465 719 : if (can_make_abnormal_goto
7466 719 : && !stmt_can_make_abnormal_goto (stmt))
7467 : {
7468 0 : bitmap_set_bit (need_ab_cleanup,
7469 0 : gimple_bb (stmt)->index);
7470 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7471 0 : fprintf (dump_file, " Removed AB side-effects.\n");
7472 : }
7473 :
7474 : return;
7475 : }
7476 : }
7477 :
7478 : /* If the statement is a scalar store, see if the expression
7479 : has the same value number as its rhs. If so, the store is
7480 : dead. */
7481 367637234 : if (gimple_assign_single_p (stmt)
7482 132134024 : && !gimple_has_volatile_ops (stmt)
7483 57302716 : && !is_gimple_reg (gimple_assign_lhs (stmt))
7484 29427185 : && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
7485 2873661 : || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
7486 397060412 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7487 16767551 : || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
7488 : {
7489 26267721 : tree rhs = gimple_assign_rhs1 (stmt);
7490 26267721 : vn_reference_t vnresult;
7491 : /* ??? gcc.dg/torture/pr91445.c shows that we lookup a boolean
7492 : typed load of a byte known to be 0x11 as 1 so a store of
7493 : a boolean 1 is detected as redundant. Because of this we
7494 : have to make sure to lookup with a ref where its size
7495 : matches the precision. */
7496 26267721 : tree lookup_lhs = lhs;
7497 52265381 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
7498 13691631 : && (TREE_CODE (lhs) != COMPONENT_REF
7499 8291916 : || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
7500 39753132 : && !type_has_mode_precision_p (TREE_TYPE (lhs)))
7501 : {
7502 865855 : if (BITINT_TYPE_P (TREE_TYPE (lhs))
7503 449837 : && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE)
7504 : lookup_lhs = NULL_TREE;
7505 431246 : else if (TREE_CODE (lhs) == COMPONENT_REF
7506 431246 : || TREE_CODE (lhs) == MEM_REF)
7507 : {
7508 305130 : tree ltype = build_nonstandard_integer_type
7509 305130 : (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhs))),
7510 305130 : TYPE_UNSIGNED (TREE_TYPE (lhs)));
7511 305130 : if (TREE_CODE (lhs) == COMPONENT_REF)
7512 : {
7513 236026 : tree foff = component_ref_field_offset (lhs);
7514 236026 : tree f = TREE_OPERAND (lhs, 1);
7515 236026 : if (!poly_int_tree_p (foff))
7516 : lookup_lhs = NULL_TREE;
7517 : else
7518 472052 : lookup_lhs = build3 (BIT_FIELD_REF, ltype,
7519 236026 : TREE_OPERAND (lhs, 0),
7520 236026 : TYPE_SIZE (TREE_TYPE (lhs)),
7521 : bit_from_pos
7522 236026 : (foff, DECL_FIELD_BIT_OFFSET (f)));
7523 : }
7524 : else
7525 69104 : lookup_lhs = build2 (MEM_REF, ltype,
7526 69104 : TREE_OPERAND (lhs, 0),
7527 69104 : TREE_OPERAND (lhs, 1));
7528 : }
7529 : else
7530 : lookup_lhs = NULL_TREE;
7531 : }
7532 26134291 : tree val = NULL_TREE, tem;
7533 26134291 : if (lookup_lhs)
7534 52268582 : val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
7535 : VN_WALKREWRITE, &vnresult, false,
7536 : NULL, NULL_TREE, true);
7537 26267721 : if (TREE_CODE (rhs) == SSA_NAME)
7538 12655627 : rhs = VN_INFO (rhs)->valnum;
7539 26267721 : gassign *ass;
7540 26267721 : if (val
7541 26267721 : && (operand_equal_p (val, rhs, 0)
7542 : /* Due to the bitfield lookups above we can get bit
7543 : interpretations of the same RHS as values here. Those
7544 : are redundant as well. */
7545 3231830 : || (TREE_CODE (val) == SSA_NAME
7546 1970902 : && gimple_assign_single_p (SSA_NAME_DEF_STMT (val))
7547 1800629 : && (tem = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val)))
7548 1800629 : && TREE_CODE (tem) == VIEW_CONVERT_EXPR
7549 3650 : && TREE_OPERAND (tem, 0) == rhs)
7550 3231828 : || (TREE_CODE (rhs) == SSA_NAME
7551 26752290 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs)))
7552 1541516 : && gimple_assign_rhs1 (ass) == val
7553 716138 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (ass))
7554 9 : && tree_nop_conversion_p (TREE_TYPE (rhs), TREE_TYPE (val)))))
7555 : {
7556 : /* We can only remove the later store if the former aliases
7557 : at least all accesses the later one does or if the store
7558 : was to readonly memory storing the same value. */
7559 255759 : ao_ref lhs_ref;
7560 255759 : ao_ref_init (&lhs_ref, lhs);
7561 255759 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
7562 255759 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
7563 255759 : if (! vnresult
7564 255759 : || ((vnresult->set == set
7565 56756 : || alias_set_subset_of (set, vnresult->set))
7566 236736 : && (vnresult->base_set == base_set
7567 26408 : || alias_set_subset_of (base_set, vnresult->base_set))))
7568 : {
7569 231569 : if (dump_file && (dump_flags & TDF_DETAILS))
7570 : {
7571 17 : fprintf (dump_file, "Deleted redundant store ");
7572 17 : print_gimple_stmt (dump_file, stmt, 0);
7573 : }
7574 :
7575 : /* Queue stmt for removal. */
7576 231569 : to_remove.safe_push (stmt);
7577 231569 : return;
7578 : }
7579 : }
7580 : }
7581 :
7582 : /* If this is a control statement value numbering left edges
7583 : unexecuted on force the condition in a way consistent with
7584 : that. */
7585 367405665 : if (gcond *cond = dyn_cast <gcond *> (stmt))
7586 : {
7587 19664245 : if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
7588 19664245 : ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
7589 : {
7590 643040 : if (dump_file && (dump_flags & TDF_DETAILS))
7591 : {
7592 15 : fprintf (dump_file, "Removing unexecutable edge from ");
7593 15 : print_gimple_stmt (dump_file, stmt, 0);
7594 : }
7595 643040 : if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
7596 643040 : == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
7597 250562 : gimple_cond_make_true (cond);
7598 : else
7599 392478 : gimple_cond_make_false (cond);
7600 643040 : update_stmt (cond);
7601 643040 : el_todo |= TODO_cleanup_cfg;
7602 643040 : return;
7603 : }
7604 : }
7605 :
7606 366762625 : bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
7607 366762625 : bool was_noreturn = (is_gimple_call (stmt)
7608 366762625 : && gimple_call_noreturn_p (stmt));
7609 366762625 : tree vdef = gimple_vdef (stmt);
7610 366762625 : tree vuse = gimple_vuse (stmt);
7611 :
7612 : /* If we didn't replace the whole stmt (or propagate the result
7613 : into all uses), replace all uses on this stmt with their
7614 : leaders. */
7615 366762625 : bool modified = false;
7616 366762625 : use_operand_p use_p;
7617 366762625 : ssa_op_iter iter;
7618 539077074 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
7619 : {
7620 172314449 : tree use = USE_FROM_PTR (use_p);
7621 : /* ??? The call code above leaves stmt operands un-updated. */
7622 172314449 : if (TREE_CODE (use) != SSA_NAME)
7623 0 : continue;
7624 172314449 : tree sprime;
7625 172314449 : if (SSA_NAME_IS_DEFAULT_DEF (use))
7626 : /* ??? For default defs BB shouldn't matter, but we have to
7627 : solve the inconsistency between rpo eliminate and
7628 : dom eliminate avail valueization first. */
7629 27692184 : sprime = eliminate_avail (b, use);
7630 : else
7631 : /* Look for sth available at the definition block of the argument.
7632 : This avoids inconsistencies between availability there which
7633 : decides if the stmt can be removed and availability at the
7634 : use site. The SSA property ensures that things available
7635 : at the definition are also available at uses. */
7636 144622265 : sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use);
7637 172314449 : if (sprime && sprime != use
7638 13684817 : && may_propagate_copy (use, sprime, true)
7639 : /* We substitute into debug stmts to avoid excessive
7640 : debug temporaries created by removed stmts, but we need
7641 : to avoid doing so for inserted sprimes as we never want
7642 : to create debug temporaries for them. */
7643 185998549 : && (!inserted_exprs
7644 1234167 : || TREE_CODE (sprime) != SSA_NAME
7645 1216171 : || !is_gimple_debug (stmt)
7646 387470 : || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
7647 : {
7648 13332437 : propagate_value (use_p, sprime);
7649 13332437 : modified = true;
7650 : }
7651 : }
7652 :
7653 : /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated
7654 : into which is a requirement for the IPA devirt machinery. */
7655 366762625 : gimple *old_stmt = stmt;
7656 366762625 : if (modified)
7657 : {
7658 : /* If a formerly non-invariant ADDR_EXPR is turned into an
7659 : invariant one it was on a separate stmt. */
7660 12404841 : if (gimple_assign_single_p (stmt)
7661 12404841 : && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
7662 247404 : recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
7663 12404841 : gimple_stmt_iterator prev = *gsi;
7664 12404841 : gsi_prev (&prev);
7665 12404841 : if (fold_stmt (gsi, follow_all_ssa_edges))
7666 : {
7667 : /* fold_stmt may have created new stmts in between
7668 : the previous stmt and the folded stmt. Mark
7669 : all defs created there as varying to not confuse
7670 : the SCCVN machinery as we're using that even during
7671 : elimination. */
7672 1058768 : if (gsi_end_p (prev))
7673 229454 : prev = gsi_start_bb (b);
7674 : else
7675 944041 : gsi_next (&prev);
7676 1058768 : if (gsi_stmt (prev) != gsi_stmt (*gsi))
7677 109343 : do
7678 : {
7679 68912 : tree def;
7680 68912 : ssa_op_iter dit;
7681 133547 : FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),
7682 : dit, SSA_OP_ALL_DEFS)
7683 : /* As existing DEFs may move between stmts
7684 : only process new ones. */
7685 64635 : if (! has_VN_INFO (def))
7686 : {
7687 40329 : vn_ssa_aux_t vn_info = VN_INFO (def);
7688 40329 : vn_info->valnum = def;
7689 40329 : vn_info->visited = true;
7690 : }
7691 68912 : if (gsi_stmt (prev) == gsi_stmt (*gsi))
7692 : break;
7693 40431 : gsi_next (&prev);
7694 40431 : }
7695 : while (1);
7696 : }
7697 12404841 : stmt = gsi_stmt (*gsi);
7698 : /* In case we folded the stmt away schedule the NOP for removal. */
7699 12404841 : if (gimple_nop_p (stmt))
7700 844 : to_remove.safe_push (stmt);
7701 : }
7702 :
7703 : /* Visit indirect calls and turn them into direct calls if
7704 : possible using the devirtualization machinery. Do this before
7705 : checking for required EH/abnormal/noreturn cleanup as devird
7706 : may expose more of those. */
7707 366762625 : if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
7708 : {
7709 23280750 : tree fn = gimple_call_fn (call_stmt);
7710 23280750 : if (fn
7711 22463412 : && flag_devirtualize
7712 44994876 : && virtual_method_call_p (fn))
7713 : {
7714 191625 : tree otr_type = obj_type_ref_class (fn);
7715 191625 : unsigned HOST_WIDE_INT otr_tok
7716 191625 : = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));
7717 191625 : tree instance;
7718 191625 : ipa_polymorphic_call_context context (current_function_decl,
7719 191625 : fn, stmt, &instance);
7720 191625 : context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),
7721 : otr_type, stmt, NULL);
7722 191625 : bool final;
7723 191625 : vec <cgraph_node *> targets
7724 191625 : = possible_polymorphic_call_targets (obj_type_ref_class (fn),
7725 : otr_tok, context, &final);
7726 191625 : if (dump_file)
7727 22 : dump_possible_polymorphic_call_targets (dump_file,
7728 : obj_type_ref_class (fn),
7729 : otr_tok, context);
7730 191920 : if (final && targets.length () <= 1 && dbg_cnt (devirt))
7731 : {
7732 73 : tree fn;
7733 73 : if (targets.length () == 1)
7734 73 : fn = targets[0]->decl;
7735 : else
7736 0 : fn = builtin_decl_unreachable ();
7737 73 : if (dump_enabled_p ())
7738 : {
7739 9 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
7740 : "converting indirect call to "
7741 : "function %s\n",
7742 9 : lang_hooks.decl_printable_name (fn, 2));
7743 : }
7744 73 : gimple_call_set_fndecl (call_stmt, fn);
7745 : /* If changing the call to __builtin_unreachable
7746 : or similar noreturn function, adjust gimple_call_fntype
7747 : too. */
7748 73 : if (gimple_call_noreturn_p (call_stmt)
7749 0 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
7750 0 : && TYPE_ARG_TYPES (TREE_TYPE (fn))
7751 73 : && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn)))
7752 0 : == void_type_node))
7753 0 : gimple_call_set_fntype (call_stmt, TREE_TYPE (fn));
7754 73 : maybe_remove_unused_call_args (cfun, call_stmt);
7755 73 : modified = true;
7756 : }
7757 : }
7758 : }
7759 :
7760 366762625 : if (modified)
7761 : {
7762 : /* When changing a call into a noreturn call, cfg cleanup
7763 : is needed to fix up the noreturn call. */
7764 12404862 : if (!was_noreturn
7765 12404862 : && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
7766 56 : to_fixup.safe_push (stmt);
7767 : /* When changing a condition or switch into one we know what
7768 : edge will be executed, schedule a cfg cleanup. */
7769 12404862 : if ((gimple_code (stmt) == GIMPLE_COND
7770 1575348 : && (gimple_cond_true_p (as_a <gcond *> (stmt))
7771 1569458 : || gimple_cond_false_p (as_a <gcond *> (stmt))))
7772 13971427 : || (gimple_code (stmt) == GIMPLE_SWITCH
7773 8011 : && TREE_CODE (gimple_switch_index
7774 : (as_a <gswitch *> (stmt))) == INTEGER_CST))
7775 10642 : el_todo |= TODO_cleanup_cfg;
7776 : /* If we removed EH side-effects from the statement, clean
7777 : its EH information. */
7778 12404862 : if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
7779 : {
7780 1965 : bitmap_set_bit (need_eh_cleanup,
7781 1965 : gimple_bb (stmt)->index);
7782 1965 : if (dump_file && (dump_flags & TDF_DETAILS))
7783 0 : fprintf (dump_file, " Removed EH side-effects.\n");
7784 : }
7785 : /* Likewise for AB side-effects. */
7786 12404862 : if (can_make_abnormal_goto
7787 12404862 : && !stmt_can_make_abnormal_goto (stmt))
7788 : {
7789 0 : bitmap_set_bit (need_ab_cleanup,
7790 0 : gimple_bb (stmt)->index);
7791 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7792 0 : fprintf (dump_file, " Removed AB side-effects.\n");
7793 : }
7794 12404862 : update_stmt (stmt);
7795 : /* In case the VDEF on the original stmt was released, value-number
7796 : it to the VUSE. This is to make vuse_ssa_val able to skip
7797 : released virtual operands. */
7798 15772743 : if (vdef && SSA_NAME_IN_FREE_LIST (vdef))
7799 2168 : VN_INFO (vdef)->valnum = vuse;
7800 : }
7801 :
7802 : /* Make new values available - for fully redundant LHS we
7803 : continue with the next stmt above and skip this.
7804 : But avoid picking up dead defs. */
7805 366762625 : tree def;
7806 439637585 : FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
7807 72874960 : if (! has_zero_uses (def)
7808 72874960 : || (inserted_exprs
7809 217905 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (def))))
7810 71424454 : eliminate_push_avail (b, def);
7811 : }
7812 :
7813 : /* Perform elimination for the basic-block B during the domwalk. */
7814 :
7815 : edge
7816 42855822 : eliminate_dom_walker::before_dom_children (basic_block b)
7817 : {
7818 : /* Mark new bb. */
7819 42855822 : avail_stack.safe_push (NULL_TREE);
7820 :
7821 : /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */
7822 42855822 : if (!(b->flags & BB_EXECUTABLE))
7823 : return NULL;
7824 :
7825 37840495 : vn_context_bb = b;
7826 :
7827 49643931 : for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
7828 : {
7829 11803436 : gphi *phi = gsi.phi ();
7830 11803436 : tree res = PHI_RESULT (phi);
7831 :
7832 23606872 : if (virtual_operand_p (res))
7833 : {
7834 5470910 : gsi_next (&gsi);
7835 5470910 : continue;
7836 : }
7837 :
7838 6332526 : tree sprime = eliminate_avail (b, res);
7839 6332526 : if (sprime
7840 6332526 : && sprime != res)
7841 : {
7842 443262 : if (dump_file && (dump_flags & TDF_DETAILS))
7843 : {
7844 20 : fprintf (dump_file, "Replaced redundant PHI node defining ");
7845 20 : print_generic_expr (dump_file, res);
7846 20 : fprintf (dump_file, " with ");
7847 20 : print_generic_expr (dump_file, sprime);
7848 20 : fprintf (dump_file, "\n");
7849 : }
7850 :
7851 : /* If we inserted this PHI node ourself, it's not an elimination. */
7852 443262 : if (! inserted_exprs
7853 565280 : || ! bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
7854 414809 : eliminations++;
7855 :
7856 : /* If we will propagate into all uses don't bother to do
7857 : anything. */
7858 443262 : if (may_propagate_copy (res, sprime))
7859 : {
7860 : /* Mark the PHI for removal. */
7861 443262 : to_remove.safe_push (phi);
7862 443262 : gsi_next (&gsi);
7863 443262 : continue;
7864 : }
7865 :
7866 0 : remove_phi_node (&gsi, false);
7867 :
7868 0 : if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
7869 0 : sprime = fold_convert (TREE_TYPE (res), sprime);
7870 0 : gimple *stmt = gimple_build_assign (res, sprime);
7871 0 : gimple_stmt_iterator gsi2 = gsi_after_labels (b);
7872 0 : gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
7873 0 : continue;
7874 0 : }
7875 :
7876 5889264 : eliminate_push_avail (b, res);
7877 5889264 : gsi_next (&gsi);
7878 : }
7879 :
7880 75680990 : for (gimple_stmt_iterator gsi = gsi_start_bb (b);
7881 302882091 : !gsi_end_p (gsi);
7882 265041596 : gsi_next (&gsi))
7883 265041596 : eliminate_stmt (b, &gsi);
7884 :
7885 : /* Replace destination PHI arguments. */
7886 37840495 : edge_iterator ei;
7887 37840495 : edge e;
7888 89348893 : FOR_EACH_EDGE (e, ei, b->succs)
7889 51508398 : if (e->flags & EDGE_EXECUTABLE)
7890 50932966 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
7891 81437633 : !gsi_end_p (gsi);
7892 30504667 : gsi_next (&gsi))
7893 : {
7894 30504667 : gphi *phi = gsi.phi ();
7895 30504667 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
7896 30504667 : tree arg = USE_FROM_PTR (use_p);
7897 50502387 : if (TREE_CODE (arg) != SSA_NAME
7898 30504667 : || virtual_operand_p (arg))
7899 19997720 : continue;
7900 10506947 : tree sprime = eliminate_avail (b, arg);
7901 21013894 : if (sprime && may_propagate_copy (arg, sprime,
7902 10506947 : !(e->flags & EDGE_ABNORMAL)))
7903 10494858 : propagate_value (use_p, sprime);
7904 : }
7905 :
7906 37840495 : vn_context_bb = NULL;
7907 :
7908 37840495 : return NULL;
7909 : }
7910 :
7911 : /* Make no longer available leaders no longer available. */
7912 :
7913 : void
7914 42855822 : eliminate_dom_walker::after_dom_children (basic_block)
7915 : {
7916 42855822 : tree entry;
7917 94645403 : while ((entry = avail_stack.pop ()) != NULL_TREE)
7918 : {
7919 51789581 : tree valnum = VN_INFO (entry)->valnum;
7920 51789581 : tree old = avail[SSA_NAME_VERSION (valnum)];
7921 51789581 : if (old == entry)
7922 : avail[SSA_NAME_VERSION (valnum)] = NULL_TREE;
7923 : else
7924 46023 : avail[SSA_NAME_VERSION (valnum)] = entry;
7925 : }
7926 42855822 : }
7927 :
7928 : /* Remove queued stmts and perform delayed cleanups. */
7929 :
7930 : unsigned
7931 6346680 : eliminate_dom_walker::eliminate_cleanup (bool region_p)
7932 : {
7933 6346680 : statistics_counter_event (cfun, "Eliminated", eliminations);
7934 6346680 : statistics_counter_event (cfun, "Insertions", insertions);
7935 :
7936 : /* We cannot remove stmts during BB walk, especially not release SSA
7937 : names there as this confuses the VN machinery. The stmts ending
7938 : up in to_remove are either stores or simple copies.
7939 : Remove stmts in reverse order to make debug stmt creation possible. */
7940 34607662 : while (!to_remove.is_empty ())
7941 : {
7942 15567566 : bool do_release_defs = true;
7943 15567566 : gimple *stmt = to_remove.pop ();
7944 :
7945 : /* When we are value-numbering a region we do not require exit PHIs to
7946 : be present so we have to make sure to deal with uses outside of the
7947 : region of stmts that we thought are eliminated.
7948 : ??? Note we may be confused by uses in dead regions we didn't run
7949 : elimination on. Rather than checking individual uses we accept
7950 : dead copies to be generated here (gcc.c-torture/execute/20060905-1.c
7951 : contains such example). */
7952 15567566 : if (region_p)
7953 : {
7954 1829701 : if (gphi *phi = dyn_cast <gphi *> (stmt))
7955 : {
7956 1139471 : tree lhs = gimple_phi_result (phi);
7957 1139471 : if (!has_zero_uses (lhs))
7958 : {
7959 24206 : if (dump_file && (dump_flags & TDF_DETAILS))
7960 3 : fprintf (dump_file, "Keeping eliminated stmt live "
7961 : "as copy because of out-of-region uses\n");
7962 24206 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7963 24206 : gimple *copy = gimple_build_assign (lhs, sprime);
7964 24206 : gimple_stmt_iterator gsi
7965 24206 : = gsi_after_labels (gimple_bb (stmt));
7966 24206 : gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
7967 24206 : do_release_defs = false;
7968 : }
7969 : }
7970 690230 : else if (tree lhs = gimple_get_lhs (stmt))
7971 690230 : if (TREE_CODE (lhs) == SSA_NAME
7972 690230 : && !has_zero_uses (lhs))
7973 : {
7974 2106 : if (dump_file && (dump_flags & TDF_DETAILS))
7975 0 : fprintf (dump_file, "Keeping eliminated stmt live "
7976 : "as copy because of out-of-region uses\n");
7977 2106 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7978 2106 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7979 2106 : if (is_gimple_assign (stmt))
7980 : {
7981 2106 : gimple_assign_set_rhs_from_tree (&gsi, sprime);
7982 2106 : stmt = gsi_stmt (gsi);
7983 2106 : update_stmt (stmt);
7984 2106 : if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
7985 0 : bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
7986 2106 : continue;
7987 : }
7988 : else
7989 : {
7990 0 : gimple *copy = gimple_build_assign (lhs, sprime);
7991 0 : gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
7992 0 : do_release_defs = false;
7993 : }
7994 : }
7995 : }
7996 :
7997 15565460 : if (dump_file && (dump_flags & TDF_DETAILS))
7998 : {
7999 21858 : fprintf (dump_file, "Removing dead stmt ");
8000 21858 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
8001 : }
8002 :
8003 15565460 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
8004 15565460 : if (gimple_code (stmt) == GIMPLE_PHI)
8005 1787264 : remove_phi_node (&gsi, do_release_defs);
8006 : else
8007 : {
8008 13778196 : basic_block bb = gimple_bb (stmt);
8009 13778196 : unlink_stmt_vdef (stmt);
8010 13778196 : if (gsi_remove (&gsi, true))
8011 26747 : bitmap_set_bit (need_eh_cleanup, bb->index);
8012 13778196 : if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt))
8013 2 : bitmap_set_bit (need_ab_cleanup, bb->index);
8014 13778196 : if (do_release_defs)
8015 13778196 : release_defs (stmt);
8016 : }
8017 :
8018 : /* Removing a stmt may expose a forwarder block. */
8019 15565460 : el_todo |= TODO_cleanup_cfg;
8020 : }
8021 :
8022 : /* Fixup stmts that became noreturn calls. This may require splitting
8023 : blocks and thus isn't possible during the dominator walk. Do this
8024 : in reverse order so we don't inadvertently remove a stmt we want to
8025 : fixup by visiting a dominating now noreturn call first. */
8026 6346736 : while (!to_fixup.is_empty ())
8027 : {
8028 56 : gimple *stmt = to_fixup.pop ();
8029 :
8030 56 : if (dump_file && (dump_flags & TDF_DETAILS))
8031 : {
8032 0 : fprintf (dump_file, "Fixing up noreturn call ");
8033 0 : print_gimple_stmt (dump_file, stmt, 0);
8034 : }
8035 :
8036 56 : if (fixup_noreturn_call (stmt))
8037 56 : el_todo |= TODO_cleanup_cfg;
8038 : }
8039 :
8040 6346680 : bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
8041 6346680 : bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
8042 :
8043 6346680 : if (do_eh_cleanup)
8044 10811 : gimple_purge_all_dead_eh_edges (need_eh_cleanup);
8045 :
8046 6346680 : if (do_ab_cleanup)
8047 2 : gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
8048 :
8049 6346680 : if (do_eh_cleanup || do_ab_cleanup)
8050 10813 : el_todo |= TODO_cleanup_cfg;
8051 :
8052 6346680 : return el_todo;
8053 : }
8054 :
8055 : /* Eliminate fully redundant computations. */
8056 :
8057 : static unsigned
8058 4437963 : eliminate_with_rpo_vn (bitmap inserted_exprs)
8059 : {
8060 4437963 : eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);
8061 :
8062 4437963 : eliminate_dom_walker *saved_rpo_avail = rpo_avail;
8063 4437963 : rpo_avail = &walker;
8064 4437963 : walker.walk (cfun->cfg->x_entry_block_ptr);
8065 4437963 : rpo_avail = saved_rpo_avail;
8066 :
8067 4437963 : return walker.eliminate_cleanup ();
8068 4437963 : }
8069 :
8070 : /* Give every value a value id, for PRE. */
8071 :
8072 : static void
8073 988750 : assign_value_ids ()
8074 : {
8075 : /* ??? Prune requirement of these. */
8076 988750 : constant_to_value_id = new hash_table<vn_constant_hasher> (23);
8077 :
8078 : /* Initialize the value ids and prune out remaining VN_TOPs
8079 : from dead code. */
8080 988750 : tree name;
8081 988750 : unsigned i;
8082 48799109 : FOR_EACH_SSA_NAME (i, name, cfun)
8083 : {
8084 34703435 : vn_ssa_aux_t info = VN_INFO (name);
8085 34703435 : if (!info->visited
8086 34626848 : || info->valnum == VN_TOP)
8087 76587 : info->valnum = name;
8088 34703435 : if (info->valnum == name)
8089 33521231 : info->value_id = get_next_value_id ();
8090 1182204 : else if (is_gimple_min_invariant (info->valnum))
8091 41485 : info->value_id = get_or_alloc_constant_value_id (info->valnum);
8092 : }
8093 :
8094 : /* Propagate. */
8095 48799109 : FOR_EACH_SSA_NAME (i, name, cfun)
8096 : {
8097 34703435 : vn_ssa_aux_t info = VN_INFO (name);
8098 34703435 : if (TREE_CODE (info->valnum) == SSA_NAME
8099 34661950 : && info->valnum != name
8100 35844154 : && info->value_id != VN_INFO (info->valnum)->value_id)
8101 1140719 : info->value_id = VN_INFO (info->valnum)->value_id;
8102 : }
8103 :
8104 988750 : set_hashtable_value_ids ();
8105 :
8106 988750 : if (dump_file && (dump_flags & TDF_DETAILS))
8107 : {
8108 14 : fprintf (dump_file, "Value numbers:\n");
8109 406 : FOR_EACH_SSA_NAME (i, name, cfun)
8110 : {
8111 307 : if (VN_INFO (name)->visited
8112 307 : && SSA_VAL (name) != name)
8113 : {
8114 33 : print_generic_expr (dump_file, name);
8115 33 : fprintf (dump_file, " = ");
8116 33 : print_generic_expr (dump_file, SSA_VAL (name));
8117 33 : fprintf (dump_file, " (%04d)\n", VN_INFO (name)->value_id);
8118 : }
8119 : }
8120 : }
8121 988750 : }
8122 :
8123 : /* Free VN associated data structures. */
8124 :
8125 : static void
8126 6366283 : free_rpo_vn (void)
8127 : {
8128 6366283 : free_vn_table (valid_info);
8129 6366283 : XDELETE (valid_info);
8130 6366283 : obstack_free (&vn_tables_obstack, NULL);
8131 6366283 : obstack_free (&vn_tables_insert_obstack, NULL);
8132 :
8133 6366283 : vn_ssa_aux_iterator_type it;
8134 6366283 : vn_ssa_aux_t info;
8135 185073549 : FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it)
8136 178707266 : if (info->needs_insertion)
8137 4234496 : release_ssa_name (info->name);
8138 6366283 : obstack_free (&vn_ssa_aux_obstack, NULL);
8139 6366283 : delete vn_ssa_aux_hash;
8140 :
8141 6366283 : delete constant_to_value_id;
8142 6366283 : constant_to_value_id = NULL;
8143 6366283 : }
8144 :
8145 : /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
8146 :
8147 : static tree
8148 23677186 : vn_lookup_simplify_result (gimple_match_op *res_op)
8149 : {
8150 23677186 : if (!res_op->code.is_tree_code ())
8151 : return NULL_TREE;
8152 23673991 : tree *ops = res_op->ops;
8153 23673991 : unsigned int length = res_op->num_ops;
8154 23673991 : if (res_op->code == CONSTRUCTOR
8155 : /* ??? We're arriving here with SCCVNs view, decomposed CONSTRUCTOR
8156 : and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree. */
8157 23673991 : && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR)
8158 : {
8159 1054 : length = CONSTRUCTOR_NELTS (res_op->ops[0]);
8160 1054 : ops = XALLOCAVEC (tree, length);
8161 4742 : for (unsigned i = 0; i < length; ++i)
8162 3688 : ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value;
8163 : }
8164 23673991 : vn_nary_op_t vnresult = NULL;
8165 23673991 : tree res = vn_nary_op_lookup_pieces (length, (tree_code) res_op->code,
8166 : res_op->type, ops, &vnresult);
8167 : /* If this is used from expression simplification make sure to
8168 : return an available expression. */
8169 23673991 : if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail)
8170 2315319 : res = rpo_avail->eliminate_avail (vn_context_bb, res);
8171 : return res;
8172 : }
8173 :
8174 : /* Return a leader for OPs value that is valid at BB. */
8175 :
8176 : tree
8177 286091092 : rpo_elim::eliminate_avail (basic_block bb, tree op)
8178 : {
8179 286091092 : bool visited;
8180 286091092 : tree valnum = SSA_VAL (op, &visited);
8181 : /* If we didn't visit OP then it must be defined outside of the
8182 : region we process and also dominate it. So it is available. */
8183 286091092 : if (!visited)
8184 : return op;
8185 283872912 : if (TREE_CODE (valnum) == SSA_NAME)
8186 : {
8187 269191849 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
8188 : return valnum;
8189 262159746 : vn_ssa_aux_t valnum_info = VN_INFO (valnum);
8190 262159746 : vn_avail *av = valnum_info->avail;
8191 262159746 : if (!av)
8192 : {
8193 : /* See above. But when there's availability info prefer
8194 : what we recorded there for example to preserve LC SSA. */
8195 86164971 : if (!valnum_info->visited)
8196 : return valnum;
8197 85269090 : return NULL_TREE;
8198 : }
8199 175994775 : if (av->location == bb->index)
8200 : /* On tramp3d 90% of the cases are here. */
8201 115984308 : return ssa_name (av->leader);
8202 74318393 : do
8203 : {
8204 74318393 : basic_block abb = BASIC_BLOCK_FOR_FN (cfun, av->location);
8205 : /* ??? During elimination we have to use availability at the
8206 : definition site of a use we try to replace. This
8207 : is required to not run into inconsistencies because
8208 : of dominated_by_p_w_unex behavior and removing a definition
8209 : while not replacing all uses.
8210 : ??? We could try to consistently walk dominators
8211 : ignoring non-executable regions. The nearest common
8212 : dominator of bb and abb is where we can stop walking. We
8213 : may also be able to "pre-compute" (bits of) the next immediate
8214 : (non-)dominator during the RPO walk when marking edges as
8215 : executable. */
8216 74318393 : if (dominated_by_p_w_unex (bb, abb, true))
8217 : {
8218 55888704 : tree leader = ssa_name (av->leader);
8219 : /* Prevent eliminations that break loop-closed SSA. */
8220 55888704 : if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
8221 3802870 : && ! SSA_NAME_IS_DEFAULT_DEF (leader)
8222 59691574 : && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT
8223 3802870 : (leader))->loop_father,
8224 : bb))
8225 : return NULL_TREE;
8226 55809597 : if (dump_file && (dump_flags & TDF_DETAILS))
8227 : {
8228 3951 : print_generic_expr (dump_file, leader);
8229 3951 : fprintf (dump_file, " is available for ");
8230 3951 : print_generic_expr (dump_file, valnum);
8231 3951 : fprintf (dump_file, "\n");
8232 : }
8233 : /* On tramp3d 99% of the _remaining_ cases succeed at
8234 : the first enty. */
8235 : return leader;
8236 : }
8237 : /* ??? Can we somehow skip to the immediate dominator
8238 : RPO index (bb_to_rpo)? Again, maybe not worth, on
8239 : tramp3d the worst number of elements in the vector is 9. */
8240 18429689 : av = av->next;
8241 : }
8242 18429689 : while (av);
8243 : /* While we prefer avail we have to fallback to using the value
8244 : directly if defined outside of the region when none of the
8245 : available defs suit. */
8246 4121763 : if (!valnum_info->visited)
8247 2 : return valnum;
8248 : }
8249 14681063 : else if (valnum != VN_TOP)
8250 : /* valnum is is_gimple_min_invariant. */
8251 14681063 : return valnum;
8252 : return NULL_TREE;
8253 : }
8254 :
8255 : /* Make LEADER a leader for its value at BB. */
8256 :
8257 : void
8258 99937038 : rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
8259 : {
8260 99937038 : tree valnum = VN_INFO (leader)->valnum;
8261 99937038 : if (valnum == VN_TOP
8262 99937038 : || is_gimple_min_invariant (valnum))
8263 : return;
8264 99937038 : if (dump_file && (dump_flags & TDF_DETAILS))
8265 : {
8266 332934 : fprintf (dump_file, "Making available beyond BB%d ", bb->index);
8267 332934 : print_generic_expr (dump_file, leader);
8268 332934 : fprintf (dump_file, " for value ");
8269 332934 : print_generic_expr (dump_file, valnum);
8270 332934 : fprintf (dump_file, "\n");
8271 : }
8272 99937038 : vn_ssa_aux_t value = VN_INFO (valnum);
8273 99937038 : vn_avail *av;
8274 99937038 : if (m_avail_freelist)
8275 : {
8276 18960874 : av = m_avail_freelist;
8277 18960874 : m_avail_freelist = m_avail_freelist->next;
8278 : }
8279 : else
8280 80976164 : av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
8281 99937038 : av->location = bb->index;
8282 99937038 : av->leader = SSA_NAME_VERSION (leader);
8283 99937038 : av->next = value->avail;
8284 99937038 : av->next_undo = last_pushed_avail;
8285 99937038 : last_pushed_avail = value;
8286 99937038 : value->avail = av;
8287 : }
8288 :
8289 : /* Valueization hook for RPO VN plus required state. */
8290 :
8291 : tree
8292 2281927254 : rpo_vn_valueize (tree name)
8293 : {
8294 2281927254 : if (TREE_CODE (name) == SSA_NAME)
8295 : {
8296 2234341132 : vn_ssa_aux_t val = VN_INFO (name);
8297 2234341132 : if (val)
8298 : {
8299 2234341132 : tree tem = val->valnum;
8300 2234341132 : if (tem != VN_TOP && tem != name)
8301 : {
8302 120936673 : if (TREE_CODE (tem) != SSA_NAME)
8303 : return tem;
8304 : /* For all values we only valueize to an available leader
8305 : which means we can use SSA name info without restriction. */
8306 103164867 : tem = rpo_avail->eliminate_avail (vn_context_bb, tem);
8307 103164867 : if (tem)
8308 102975069 : return tem;
8309 : }
8310 : }
8311 : }
8312 : return name;
8313 : }
8314 :
8315 : /* Insert on PRED_E predicates derived from CODE OPS being true besides the
8316 : inverted condition. */
8317 :
8318 : static void
8319 28057465 : insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e)
8320 : {
8321 28057465 : switch (code)
8322 : {
8323 1375576 : case LT_EXPR:
8324 : /* a < b -> a {!,<}= b */
8325 1375576 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8326 : ops, boolean_true_node, 0, pred_e);
8327 1375576 : vn_nary_op_insert_pieces_predicated (2, LE_EXPR, boolean_type_node,
8328 : ops, boolean_true_node, 0, pred_e);
8329 : /* a < b -> ! a {>,=} b */
8330 1375576 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8331 : ops, boolean_false_node, 0, pred_e);
8332 1375576 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8333 : ops, boolean_false_node, 0, pred_e);
8334 1375576 : break;
8335 3574840 : case GT_EXPR:
8336 : /* a > b -> a {!,>}= b */
8337 3574840 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8338 : ops, boolean_true_node, 0, pred_e);
8339 3574840 : vn_nary_op_insert_pieces_predicated (2, GE_EXPR, boolean_type_node,
8340 : ops, boolean_true_node, 0, pred_e);
8341 : /* a > b -> ! a {<,=} b */
8342 3574840 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8343 : ops, boolean_false_node, 0, pred_e);
8344 3574840 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8345 : ops, boolean_false_node, 0, pred_e);
8346 3574840 : break;
8347 9592742 : case EQ_EXPR:
8348 : /* a == b -> ! a {<,>} b */
8349 9592742 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8350 : ops, boolean_false_node, 0, pred_e);
8351 9592742 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8352 : ops, boolean_false_node, 0, pred_e);
8353 9592742 : break;
8354 : case LE_EXPR:
8355 : case GE_EXPR:
8356 : case NE_EXPR:
8357 : /* Nothing besides inverted condition. */
8358 : break;
8359 28057465 : default:;
8360 : }
8361 28057465 : }
8362 :
8363 : /* Insert on the TRUE_E true and FALSE_E false predicates
8364 : derived from LHS CODE RHS. */
8365 :
8366 : static void
8367 24092599 : insert_predicates_for_cond (tree_code code, tree lhs, tree rhs,
8368 : edge true_e, edge false_e)
8369 : {
8370 : /* If both edges are null, then there is nothing to be done. */
8371 24092599 : if (!true_e && !false_e)
8372 1420078 : return;
8373 :
8374 : /* Canonicalize the comparison if needed, putting
8375 : the constant in the rhs. */
8376 22676013 : if (tree_swap_operands_p (lhs, rhs))
8377 : {
8378 0 : std::swap (lhs, rhs);
8379 0 : code = swap_tree_comparison (code);
8380 : }
8381 :
8382 : /* If the lhs is not a ssa name, don't record anything. */
8383 22676013 : if (TREE_CODE (lhs) != SSA_NAME)
8384 : return;
8385 :
8386 22672521 : tree_code icode = invert_tree_comparison (code, HONOR_NANS (lhs));
8387 22672521 : tree ops[2];
8388 22672521 : ops[0] = lhs;
8389 22672521 : ops[1] = rhs;
8390 22672521 : if (true_e)
8391 18516536 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8392 : boolean_true_node, 0, true_e);
8393 22672521 : if (false_e)
8394 17481198 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8395 : boolean_false_node, 0, false_e);
8396 22672521 : if (icode != ERROR_MARK)
8397 : {
8398 22411605 : if (true_e)
8399 18352408 : vn_nary_op_insert_pieces_predicated (2, icode, boolean_type_node, ops,
8400 : boolean_false_node, 0, true_e);
8401 22411605 : if (false_e)
8402 17270791 : vn_nary_op_insert_pieces_predicated (2, icode, boolean_type_node, ops,
8403 : boolean_true_node, 0, false_e);
8404 : }
8405 : /* Relax for non-integers, inverted condition handled
8406 : above. */
8407 22672521 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
8408 : {
8409 17672417 : if (true_e)
8410 14492953 : insert_related_predicates_on_edge (code, ops, true_e);
8411 17672417 : if (false_e)
8412 13564512 : insert_related_predicates_on_edge (icode, ops, false_e);
8413 : }
8414 22672521 : if (integer_zerop (rhs)
8415 22672521 : && (code == NE_EXPR || code == EQ_EXPR))
8416 : {
8417 9411723 : gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
8418 : /* (A CMP B) != 0 is the same as (A CMP B).
8419 : (A CMP B) == 0 is just (A CMP B) with the edges swapped. */
8420 9411723 : if (is_gimple_assign (def_stmt)
8421 9411723 : && TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
8422 : {
8423 426247 : tree_code nc = gimple_assign_rhs_code (def_stmt);
8424 426247 : tree nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
8425 426247 : tree nrhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8426 : // Canonicalize the comparison before the check below,
8427 : // it might be the case where nlhs is a constant now.
8428 426247 : if (tree_swap_operands_p (nlhs, nrhs))
8429 : {
8430 16847 : std::swap (nlhs, nrhs);
8431 16847 : nc = swap_tree_comparison (nc);
8432 : }
8433 426247 : edge nt = true_e;
8434 426247 : edge nf = false_e;
8435 426247 : if (code == EQ_EXPR)
8436 299335 : std::swap (nt, nf);
8437 426247 : if (lhs != nlhs)
8438 426242 : insert_predicates_for_cond (nc, nlhs, nrhs, nt, nf);
8439 : }
8440 : /* (a | b) == 0 ->
8441 : on true edge assert: a == 0 & b == 0. */
8442 : /* (a | b) != 0 ->
8443 : on false edge assert: a == 0 & b == 0. */
8444 9411723 : if (is_gimple_assign (def_stmt)
8445 9411723 : && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
8446 : {
8447 249709 : edge e = code == EQ_EXPR ? true_e : false_e;
8448 249709 : tree nlhs;
8449 :
8450 249709 : nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
8451 : /* A valueization of the `a` might return the old lhs
8452 : which is already handled above. */
8453 249709 : if (nlhs != lhs)
8454 249709 : insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
8455 :
8456 : /* A valueization of the `b` might return the old lhs
8457 : which is already handled above. */
8458 249709 : nlhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8459 249709 : if (nlhs != lhs)
8460 249709 : insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
8461 : }
8462 : }
8463 : }
8464 :
8465 : /* Main stmt worker for RPO VN, process BB. */
8466 :
8467 : static unsigned
8468 63614076 : process_bb (rpo_elim &avail, basic_block bb,
8469 : bool bb_visited, bool iterate_phis, bool iterate, bool eliminate,
8470 : bool do_region, bitmap exit_bbs, bool skip_phis)
8471 : {
8472 63614076 : unsigned todo = 0;
8473 63614076 : edge_iterator ei;
8474 63614076 : edge e;
8475 :
8476 63614076 : vn_context_bb = bb;
8477 :
8478 : /* If we are in loop-closed SSA preserve this state. This is
8479 : relevant when called on regions from outside of FRE/PRE. */
8480 63614076 : bool lc_phi_nodes = false;
8481 63614076 : if (!skip_phis
8482 63614076 : && loops_state_satisfies_p (LOOP_CLOSED_SSA))
8483 3914877 : FOR_EACH_EDGE (e, ei, bb->preds)
8484 2367536 : if (e->src->loop_father != e->dest->loop_father
8485 2367536 : && flow_loop_nested_p (e->dest->loop_father,
8486 : e->src->loop_father))
8487 : {
8488 : lc_phi_nodes = true;
8489 : break;
8490 : }
8491 :
8492 : /* When we visit a loop header substitute into loop info. */
8493 63614076 : if (!iterate && eliminate && bb->loop_father->header == bb)
8494 : {
8495 : /* Keep fields in sync with substitute_in_loop_info. */
8496 958202 : if (bb->loop_father->nb_iterations)
8497 156799 : bb->loop_father->nb_iterations
8498 156799 : = simplify_replace_tree (bb->loop_father->nb_iterations,
8499 : NULL_TREE, NULL_TREE, &vn_valueize_for_srt);
8500 : }
8501 :
8502 : /* Value-number all defs in the basic-block. */
8503 63614076 : if (!skip_phis)
8504 91049249 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8505 27460975 : gsi_next (&gsi))
8506 : {
8507 27460975 : gphi *phi = gsi.phi ();
8508 27460975 : tree res = PHI_RESULT (phi);
8509 27460975 : vn_ssa_aux_t res_info = VN_INFO (res);
8510 27460975 : if (!bb_visited)
8511 : {
8512 19501498 : gcc_assert (!res_info->visited);
8513 19501498 : res_info->valnum = VN_TOP;
8514 19501498 : res_info->visited = true;
8515 : }
8516 :
8517 : /* When not iterating force backedge values to varying. */
8518 27460975 : visit_stmt (phi, !iterate_phis);
8519 54921950 : if (virtual_operand_p (res))
8520 10972767 : continue;
8521 :
8522 : /* Eliminate */
8523 : /* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness
8524 : how we handle backedges and availability.
8525 : And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization. */
8526 16488208 : tree val = res_info->valnum;
8527 16488208 : if (res != val && !iterate && eliminate)
8528 : {
8529 1465835 : if (tree leader = avail.eliminate_avail (bb, res))
8530 : {
8531 1344497 : if (leader != res
8532 : /* Preserve loop-closed SSA form. */
8533 1344497 : && (! lc_phi_nodes
8534 5962 : || is_gimple_min_invariant (leader)))
8535 : {
8536 1344002 : if (dump_file && (dump_flags & TDF_DETAILS))
8537 : {
8538 241 : fprintf (dump_file, "Replaced redundant PHI node "
8539 : "defining ");
8540 241 : print_generic_expr (dump_file, res);
8541 241 : fprintf (dump_file, " with ");
8542 241 : print_generic_expr (dump_file, leader);
8543 241 : fprintf (dump_file, "\n");
8544 : }
8545 1344002 : avail.eliminations++;
8546 :
8547 1344002 : if (may_propagate_copy (res, leader))
8548 : {
8549 : /* Schedule for removal. */
8550 1344002 : avail.to_remove.safe_push (phi);
8551 1344002 : continue;
8552 : }
8553 : /* ??? Else generate a copy stmt. */
8554 : }
8555 : }
8556 : }
8557 : /* Only make defs available that not already are. But make
8558 : sure loop-closed SSA PHI node defs are picked up for
8559 : downstream uses. */
8560 15144206 : if (lc_phi_nodes
8561 15144206 : || res == val
8562 15144206 : || ! avail.eliminate_avail (bb, res))
8563 11577382 : avail.eliminate_push_avail (bb, res);
8564 : }
8565 :
8566 : /* For empty BBs mark outgoing edges executable. For non-empty BBs
8567 : we do this when processing the last stmt as we have to do this
8568 : before elimination which otherwise forces GIMPLE_CONDs to
8569 : if (1 != 0) style when seeing non-executable edges. */
8570 127228152 : if (gsi_end_p (gsi_start_bb (bb)))
8571 : {
8572 14227620 : FOR_EACH_EDGE (e, ei, bb->succs)
8573 : {
8574 7113810 : if (!(e->flags & EDGE_EXECUTABLE))
8575 : {
8576 4880802 : if (dump_file && (dump_flags & TDF_DETAILS))
8577 6405 : fprintf (dump_file,
8578 : "marking outgoing edge %d -> %d executable\n",
8579 6405 : e->src->index, e->dest->index);
8580 4880802 : e->flags |= EDGE_EXECUTABLE;
8581 4880802 : e->dest->flags |= BB_EXECUTABLE;
8582 : }
8583 2233008 : else if (!(e->dest->flags & BB_EXECUTABLE))
8584 : {
8585 0 : if (dump_file && (dump_flags & TDF_DETAILS))
8586 0 : fprintf (dump_file,
8587 : "marking destination block %d reachable\n",
8588 : e->dest->index);
8589 0 : e->dest->flags |= BB_EXECUTABLE;
8590 : }
8591 : }
8592 : }
8593 127228152 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
8594 525965912 : !gsi_end_p (gsi); gsi_next (&gsi))
8595 : {
8596 462351836 : ssa_op_iter i;
8597 462351836 : tree op;
8598 462351836 : if (!bb_visited)
8599 : {
8600 523895945 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
8601 : {
8602 143065932 : vn_ssa_aux_t op_info = VN_INFO (op);
8603 143065932 : gcc_assert (!op_info->visited);
8604 143065932 : op_info->valnum = VN_TOP;
8605 143065932 : op_info->visited = true;
8606 : }
8607 :
8608 : /* We somehow have to deal with uses that are not defined
8609 : in the processed region. Forcing unvisited uses to
8610 : varying here doesn't play well with def-use following during
8611 : expression simplification, so we deal with this by checking
8612 : the visited flag in SSA_VAL. */
8613 : }
8614 :
8615 462351836 : visit_stmt (gsi_stmt (gsi));
8616 :
8617 462351836 : gimple *last = gsi_stmt (gsi);
8618 462351836 : e = NULL;
8619 462351836 : switch (gimple_code (last))
8620 : {
8621 120185 : case GIMPLE_SWITCH:
8622 120185 : e = find_taken_edge (bb, vn_valueize (gimple_switch_index
8623 120185 : (as_a <gswitch *> (last))));
8624 120185 : break;
8625 25462697 : case GIMPLE_COND:
8626 25462697 : {
8627 25462697 : tree lhs = vn_valueize (gimple_cond_lhs (last));
8628 25462697 : tree rhs = vn_valueize (gimple_cond_rhs (last));
8629 25462697 : tree_code cmpcode = gimple_cond_code (last);
8630 : /* Canonicalize the comparison if needed, putting
8631 : the constant in the rhs. */
8632 25462697 : if (tree_swap_operands_p (lhs, rhs))
8633 : {
8634 861429 : std::swap (lhs, rhs);
8635 861429 : cmpcode = swap_tree_comparison (cmpcode);
8636 : }
8637 25462697 : tree val = gimple_simplify (cmpcode,
8638 : boolean_type_node, lhs, rhs,
8639 : NULL, vn_valueize);
8640 : /* If the condition didn't simplify see if we have recorded
8641 : an expression from sofar taken edges. */
8642 25462697 : if (! val || TREE_CODE (val) != INTEGER_CST)
8643 : {
8644 23546679 : vn_nary_op_t vnresult;
8645 23546679 : tree ops[2];
8646 23546679 : ops[0] = lhs;
8647 23546679 : ops[1] = rhs;
8648 23546679 : val = vn_nary_op_lookup_pieces (2, cmpcode,
8649 : boolean_type_node, ops,
8650 : &vnresult);
8651 : /* Got back a ssa name, then try looking up `val != 0`
8652 : as it might have been recorded that way. */
8653 23546679 : if (val && TREE_CODE (val) == SSA_NAME)
8654 : {
8655 164797 : ops[0] = val;
8656 164797 : ops[1] = build_zero_cst (TREE_TYPE (val));
8657 164797 : val = vn_nary_op_lookup_pieces (2, NE_EXPR,
8658 : boolean_type_node, ops,
8659 : &vnresult);
8660 : }
8661 : /* Did we get a predicated value? */
8662 23546653 : if (! val && vnresult && vnresult->predicated_values)
8663 : {
8664 1466866 : val = vn_nary_op_get_predicated_value (vnresult, bb);
8665 1466866 : if (val && dump_file && (dump_flags & TDF_DETAILS))
8666 : {
8667 2 : fprintf (dump_file, "Got predicated value ");
8668 2 : print_generic_expr (dump_file, val, TDF_NONE);
8669 2 : fprintf (dump_file, " for ");
8670 2 : print_gimple_stmt (dump_file, last, TDF_SLIM);
8671 : }
8672 : }
8673 : }
8674 23546679 : if (val)
8675 2295758 : e = find_taken_edge (bb, val);
8676 25462697 : if (! e)
8677 : {
8678 : /* If we didn't manage to compute the taken edge then
8679 : push predicated expressions for the condition itself
8680 : and related conditions to the hashtables. This allows
8681 : simplification of redundant conditions which is
8682 : important as early cleanup. */
8683 23166939 : edge true_e, false_e;
8684 23166939 : extract_true_false_edges_from_block (bb, &true_e, &false_e);
8685 557904 : if ((do_region && bitmap_bit_p (exit_bbs, true_e->dest->index))
8686 23403199 : || !can_track_predicate_on_edge (true_e))
8687 5145334 : true_e = NULL;
8688 557904 : if ((do_region && bitmap_bit_p (exit_bbs, false_e->dest->index))
8689 23380715 : || !can_track_predicate_on_edge (false_e))
8690 6075447 : false_e = NULL;
8691 23166939 : insert_predicates_for_cond (cmpcode, lhs, rhs, true_e, false_e);
8692 : }
8693 : break;
8694 : }
8695 1426 : case GIMPLE_GOTO:
8696 1426 : e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last)));
8697 1426 : break;
8698 : default:
8699 : e = NULL;
8700 : }
8701 462351836 : if (e)
8702 : {
8703 2299575 : todo = TODO_cleanup_cfg;
8704 2299575 : if (!(e->flags & EDGE_EXECUTABLE))
8705 : {
8706 1813994 : if (dump_file && (dump_flags & TDF_DETAILS))
8707 59 : fprintf (dump_file,
8708 : "marking known outgoing %sedge %d -> %d executable\n",
8709 59 : e->flags & EDGE_DFS_BACK ? "back-" : "",
8710 59 : e->src->index, e->dest->index);
8711 1813994 : e->flags |= EDGE_EXECUTABLE;
8712 1813994 : e->dest->flags |= BB_EXECUTABLE;
8713 : }
8714 485581 : else if (!(e->dest->flags & BB_EXECUTABLE))
8715 : {
8716 27622 : if (dump_file && (dump_flags & TDF_DETAILS))
8717 1 : fprintf (dump_file,
8718 : "marking destination block %d reachable\n",
8719 : e->dest->index);
8720 27622 : e->dest->flags |= BB_EXECUTABLE;
8721 : }
8722 : }
8723 460052261 : else if (gsi_one_before_end_p (gsi))
8724 : {
8725 132978598 : FOR_EACH_EDGE (e, ei, bb->succs)
8726 : {
8727 78777907 : if (!(e->flags & EDGE_EXECUTABLE))
8728 : {
8729 57955738 : if (dump_file && (dump_flags & TDF_DETAILS))
8730 18950 : fprintf (dump_file,
8731 : "marking outgoing edge %d -> %d executable\n",
8732 18950 : e->src->index, e->dest->index);
8733 57955738 : e->flags |= EDGE_EXECUTABLE;
8734 57955738 : e->dest->flags |= BB_EXECUTABLE;
8735 : }
8736 20822169 : else if (!(e->dest->flags & BB_EXECUTABLE))
8737 : {
8738 2662607 : if (dump_file && (dump_flags & TDF_DETAILS))
8739 6254 : fprintf (dump_file,
8740 : "marking destination block %d reachable\n",
8741 : e->dest->index);
8742 2662607 : e->dest->flags |= BB_EXECUTABLE;
8743 : }
8744 : }
8745 : }
8746 :
8747 : /* Eliminate. That also pushes to avail. */
8748 462351836 : if (eliminate && ! iterate)
8749 116145468 : avail.eliminate_stmt (bb, &gsi);
8750 : else
8751 : /* If not eliminating, make all not already available defs
8752 : available. But avoid picking up dead defs. */
8753 428747109 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF)
8754 82540741 : if (! has_zero_uses (op)
8755 82540741 : && ! avail.eliminate_avail (bb, op))
8756 62799474 : avail.eliminate_push_avail (bb, op);
8757 : }
8758 :
8759 : /* Eliminate in destination PHI arguments. Always substitute in dest
8760 : PHIs, even for non-executable edges. This handles region
8761 : exits PHIs. */
8762 63614076 : if (!iterate && eliminate)
8763 34193631 : FOR_EACH_EDGE (e, ei, bb->succs)
8764 20371835 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
8765 39491838 : !gsi_end_p (gsi); gsi_next (&gsi))
8766 : {
8767 19120003 : gphi *phi = gsi.phi ();
8768 19120003 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
8769 19120003 : tree arg = USE_FROM_PTR (use_p);
8770 29073873 : if (TREE_CODE (arg) != SSA_NAME
8771 19120003 : || virtual_operand_p (arg))
8772 9953870 : continue;
8773 9166133 : tree sprime;
8774 9166133 : if (SSA_NAME_IS_DEFAULT_DEF (arg))
8775 : {
8776 121421 : sprime = SSA_VAL (arg);
8777 121421 : gcc_assert (TREE_CODE (sprime) != SSA_NAME
8778 : || SSA_NAME_IS_DEFAULT_DEF (sprime));
8779 : }
8780 : else
8781 : /* Look for sth available at the definition block of the argument.
8782 : This avoids inconsistencies between availability there which
8783 : decides if the stmt can be removed and availability at the
8784 : use site. The SSA property ensures that things available
8785 : at the definition are also available at uses. */
8786 9044712 : sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)),
8787 : arg);
8788 9166133 : if (sprime
8789 9166133 : && sprime != arg
8790 9166133 : && may_propagate_copy (arg, sprime, !(e->flags & EDGE_ABNORMAL)))
8791 1578070 : propagate_value (use_p, sprime);
8792 : }
8793 :
8794 63614076 : vn_context_bb = NULL;
8795 63614076 : return todo;
8796 : }
8797 :
8798 : /* Unwind state per basic-block. */
8799 :
8800 : struct unwind_state
8801 : {
8802 : /* Times this block has been visited. */
8803 : unsigned visited;
8804 : /* Whether to handle this as iteration point or whether to treat
8805 : incoming backedge PHI values as varying. */
8806 : bool iterate;
8807 : /* Maximum RPO index this block is reachable from. */
8808 : int max_rpo;
8809 : /* Unwind state. */
8810 : void *ob_top;
8811 : vn_reference_t ref_top;
8812 : vn_phi_t phi_top;
8813 : vn_nary_op_t nary_top;
8814 : vn_avail *avail_top;
8815 : };
8816 :
8817 : /* Record in TO the RPO VN state do_unwind unwinds to. */
8818 :
8819 : static void
8820 4474265 : record_unwind_state (unwind_state *to)
8821 : {
8822 4474265 : to->ob_top = obstack_alloc (&vn_tables_obstack, 0);
8823 4474265 : to->ref_top = last_inserted_ref;
8824 4474265 : to->phi_top = last_inserted_phi;
8825 4474265 : to->nary_top = last_inserted_nary;
8826 4474265 : to->avail_top = last_pushed_avail ? last_pushed_avail->avail : NULL;
8827 4474265 : }
8828 :
8829 : /* Unwind the RPO VN state for iteration. */
8830 :
8831 : static void
8832 1946487 : do_unwind (unwind_state *to, rpo_elim &avail)
8833 : {
8834 1946487 : gcc_assert (to->iterate);
8835 35452484 : for (; last_inserted_nary != to->nary_top;
8836 33505997 : last_inserted_nary = last_inserted_nary->next)
8837 : {
8838 33505997 : vn_nary_op_t *slot;
8839 33505997 : slot = valid_info->nary->find_slot_with_hash
8840 33505997 : (last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT);
8841 : /* Predication causes the need to restore previous state. */
8842 33505997 : if ((*slot)->unwind_to)
8843 6872090 : *slot = (*slot)->unwind_to;
8844 : else
8845 26633907 : valid_info->nary->clear_slot (slot);
8846 : }
8847 7562909 : for (; last_inserted_phi != to->phi_top;
8848 5616422 : last_inserted_phi = last_inserted_phi->next)
8849 : {
8850 5616422 : vn_phi_t *slot;
8851 5616422 : slot = valid_info->phis->find_slot_with_hash
8852 5616422 : (last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT);
8853 5616422 : valid_info->phis->clear_slot (slot);
8854 : }
8855 15613050 : for (; last_inserted_ref != to->ref_top;
8856 13666563 : last_inserted_ref = last_inserted_ref->next)
8857 : {
8858 13666563 : vn_reference_t *slot;
8859 13666563 : slot = valid_info->references->find_slot_with_hash
8860 13666563 : (last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT);
8861 13666563 : (*slot)->operands.release ();
8862 13666563 : valid_info->references->clear_slot (slot);
8863 : }
8864 1946487 : obstack_free (&vn_tables_obstack, to->ob_top);
8865 :
8866 : /* Prune [rpo_idx, ] from avail. */
8867 20907361 : for (; last_pushed_avail && last_pushed_avail->avail != to->avail_top;)
8868 : {
8869 18960874 : vn_ssa_aux_t val = last_pushed_avail;
8870 18960874 : vn_avail *av = val->avail;
8871 18960874 : val->avail = av->next;
8872 18960874 : last_pushed_avail = av->next_undo;
8873 18960874 : av->next = avail.m_avail_freelist;
8874 18960874 : avail.m_avail_freelist = av;
8875 : }
8876 1946487 : }
8877 :
8878 : /* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
8879 : If ITERATE is true then treat backedges optimistically as not
8880 : executed and iterate. If ELIMINATE is true then perform
8881 : elimination, otherwise leave that to the caller. If SKIP_ENTRY_PHIS
8882 : is true then force PHI nodes in ENTRY->dest to VARYING. AVAIL and
8883 : BB_TO_RPO belong to the caller, which can keep them past the walk. */
8884 :
8885 : static unsigned
8886 6366283 : do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
8887 : bool iterate, bool eliminate, bool skip_entry_phis,
8888 : vn_lookup_kind kind, rpo_elim &avail, int *bb_to_rpo)
8889 : {
8890 6366283 : unsigned todo = 0;
8891 6366283 : default_vn_walk_kind = kind;
8892 :
8893 : /* We currently do not support region-based iteration when
8894 : elimination is requested. */
8895 6366283 : gcc_assert (!entry || !iterate || !eliminate);
8896 : /* When iterating we need loop info up-to-date. */
8897 6366283 : gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP));
8898 :
8899 6366283 : bool do_region = entry != NULL;
8900 6366283 : if (!do_region)
8901 : {
8902 5666911 : entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn));
8903 5666911 : exit_bbs = BITMAP_ALLOC (NULL);
8904 5666911 : bitmap_set_bit (exit_bbs, EXIT_BLOCK);
8905 : }
8906 :
8907 : /* Clear EDGE_DFS_BACK on "all" entry edges, RPO order compute will
8908 : re-mark those that are contained in the region. */
8909 6366283 : edge_iterator ei;
8910 6366283 : edge e;
8911 12790293 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8912 6424010 : e->flags &= ~EDGE_DFS_BACK;
8913 :
8914 6366283 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS);
8915 6366283 : auto_vec<std::pair<int, int> > toplevel_scc_extents;
8916 6366283 : int n = rev_post_order_and_mark_dfs_back_seme
8917 8294603 : (fn, entry, exit_bbs, true, rpo, !iterate ? &toplevel_scc_extents : NULL);
8918 :
8919 6366283 : if (!do_region)
8920 5666911 : BITMAP_FREE (exit_bbs);
8921 :
8922 : /* If there are any non-DFS_BACK edges into entry->dest skip
8923 : processing PHI nodes for that block. This supports
8924 : value-numbering loop bodies w/o the actual loop. */
8925 12790292 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8926 6424010 : if (e != entry
8927 57727 : && !(e->flags & EDGE_DFS_BACK))
8928 : break;
8929 6366283 : if (e != NULL && dump_file && (dump_flags & TDF_DETAILS))
8930 0 : fprintf (dump_file, "Region does not contain all edges into "
8931 : "the entry block, skipping its PHIs.\n");
8932 6366283 : skip_entry_phis |= e != NULL;
8933 :
8934 58769994 : for (int i = 0; i < n; ++i)
8935 52403711 : bb_to_rpo[rpo[i]] = i;
8936 6366283 : vn_bb_to_rpo = bb_to_rpo;
8937 :
8938 6366283 : unwind_state *rpo_state = XNEWVEC (unwind_state, n);
8939 :
8940 6366283 : rpo_avail = &avail;
8941 :
8942 : /* Verify we have no extra entries into the region. */
8943 6366283 : if (flag_checking && do_region)
8944 : {
8945 699366 : auto_bb_flag bb_in_region (fn);
8946 2842629 : for (int i = 0; i < n; ++i)
8947 : {
8948 1443897 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8949 1443897 : bb->flags |= bb_in_region;
8950 : }
8951 : /* We can't merge the first two loops because we cannot rely
8952 : on EDGE_DFS_BACK for edges not within the region. But if
8953 : we decide to always have the bb_in_region flag we can
8954 : do the checking during the RPO walk itself (but then it's
8955 : also easy to handle MEME conservatively). */
8956 2143263 : for (int i = 0; i < n; ++i)
8957 : {
8958 1443897 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8959 1443897 : edge e;
8960 1443897 : edge_iterator ei;
8961 3157758 : FOR_EACH_EDGE (e, ei, bb->preds)
8962 1713861 : gcc_assert (e == entry
8963 : || (skip_entry_phis && bb == entry->dest)
8964 : || (e->src->flags & bb_in_region));
8965 : }
8966 2143263 : for (int i = 0; i < n; ++i)
8967 : {
8968 1443897 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8969 1443897 : bb->flags &= ~bb_in_region;
8970 : }
8971 699366 : }
8972 :
8973 : /* Create the VN state. For the initial size of the various hashtables
8974 : use a heuristic based on region size and number of SSA names. */
8975 6366283 : unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names)
8976 6366283 : / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS));
8977 6366283 : VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
8978 6366283 : next_value_id = 1;
8979 6366283 : next_constant_value_id = -1;
8980 :
8981 6366283 : vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2);
8982 6366283 : gcc_obstack_init (&vn_ssa_aux_obstack);
8983 :
8984 6366283 : gcc_obstack_init (&vn_tables_obstack);
8985 6366283 : gcc_obstack_init (&vn_tables_insert_obstack);
8986 6366283 : valid_info = XCNEW (struct vn_tables_s);
8987 6366283 : allocate_vn_table (valid_info, region_size);
8988 6366283 : last_inserted_ref = NULL;
8989 6366283 : last_inserted_phi = NULL;
8990 6366283 : last_inserted_nary = NULL;
8991 6366283 : last_pushed_avail = NULL;
8992 :
8993 6366283 : vn_valueize = rpo_vn_valueize;
8994 :
8995 : /* Initialize the unwind state and edge/BB executable state. */
8996 6366283 : unsigned curr_scc = 0;
8997 58769994 : for (int i = 0; i < n; ++i)
8998 : {
8999 52403711 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
9000 52403711 : rpo_state[i].visited = 0;
9001 52403711 : rpo_state[i].max_rpo = i;
9002 61229371 : if (!iterate && curr_scc < toplevel_scc_extents.length ())
9003 : {
9004 7317526 : if (i >= toplevel_scc_extents[curr_scc].first
9005 7317526 : && i <= toplevel_scc_extents[curr_scc].second)
9006 3989525 : rpo_state[i].max_rpo = toplevel_scc_extents[curr_scc].second;
9007 7317526 : if (i == toplevel_scc_extents[curr_scc].second)
9008 741922 : curr_scc++;
9009 : }
9010 52403711 : bb->flags &= ~BB_EXECUTABLE;
9011 52403711 : bool has_backedges = false;
9012 52403711 : edge e;
9013 52403711 : edge_iterator ei;
9014 124388878 : FOR_EACH_EDGE (e, ei, bb->preds)
9015 : {
9016 71985167 : if (e->flags & EDGE_DFS_BACK)
9017 2901471 : has_backedges = true;
9018 71985167 : e->flags &= ~EDGE_EXECUTABLE;
9019 71985167 : if (iterate || e == entry || (skip_entry_phis && bb == entry->dest))
9020 71985167 : continue;
9021 : }
9022 52403711 : rpo_state[i].iterate = iterate && has_backedges;
9023 : }
9024 6366283 : entry->flags |= EDGE_EXECUTABLE;
9025 6366283 : entry->dest->flags |= BB_EXECUTABLE;
9026 :
9027 : /* As heuristic to improve compile-time we handle only the N innermost
9028 : loops and the outermost one optimistically. */
9029 6366283 : if (iterate)
9030 : {
9031 4437963 : unsigned max_depth = param_rpo_vn_max_loop_depth;
9032 14901034 : for (auto loop : loops_list (cfun, LI_ONLY_INNERMOST))
9033 1589617 : if (loop_depth (loop) > max_depth)
9034 2108 : for (unsigned i = 2;
9035 9160 : i < loop_depth (loop) - max_depth; ++i)
9036 : {
9037 2108 : basic_block header = superloop_at_depth (loop, i)->header;
9038 2108 : bool non_latch_backedge = false;
9039 2108 : edge e;
9040 2108 : edge_iterator ei;
9041 6355 : FOR_EACH_EDGE (e, ei, header->preds)
9042 4247 : if (e->flags & EDGE_DFS_BACK)
9043 : {
9044 : /* There can be a non-latch backedge into the header
9045 : which is part of an outer irreducible region. We
9046 : cannot avoid iterating this block then. */
9047 2139 : if (!dominated_by_p (CDI_DOMINATORS,
9048 2139 : e->src, e->dest))
9049 : {
9050 12 : if (dump_file && (dump_flags & TDF_DETAILS))
9051 0 : fprintf (dump_file, "non-latch backedge %d -> %d "
9052 : "forces iteration of loop %d\n",
9053 0 : e->src->index, e->dest->index, loop->num);
9054 : non_latch_backedge = true;
9055 : }
9056 : else
9057 2127 : e->flags |= EDGE_EXECUTABLE;
9058 : }
9059 2108 : rpo_state[bb_to_rpo[header->index]].iterate = non_latch_backedge;
9060 4437963 : }
9061 : }
9062 :
9063 6366283 : uint64_t nblk = 0;
9064 6366283 : int idx = 0;
9065 4437963 : if (iterate)
9066 : /* Go and process all blocks, iterating as necessary. */
9067 50725984 : do
9068 : {
9069 50725984 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
9070 :
9071 : /* If the block has incoming backedges remember unwind state. This
9072 : is required even for non-executable blocks since in irreducible
9073 : regions we might reach them via the backedge and re-start iterating
9074 : from there.
9075 : Note we can individually mark blocks with incoming backedges to
9076 : not iterate where we then handle PHIs conservatively. We do that
9077 : heuristically to reduce compile-time for degenerate cases. */
9078 50725984 : if (rpo_state[idx].iterate)
9079 4474265 : record_unwind_state (&rpo_state[idx]);
9080 :
9081 50725984 : if (!(bb->flags & BB_EXECUTABLE))
9082 : {
9083 1042770 : if (dump_file && (dump_flags & TDF_DETAILS))
9084 2 : fprintf (dump_file, "Block %d: BB%d found not executable\n",
9085 : idx, bb->index);
9086 1042770 : idx++;
9087 2989257 : continue;
9088 : }
9089 :
9090 49683214 : if (dump_file && (dump_flags & TDF_DETAILS))
9091 334 : fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
9092 49683214 : nblk++;
9093 99366428 : todo |= process_bb (avail, bb,
9094 49683214 : rpo_state[idx].visited != 0,
9095 : rpo_state[idx].iterate,
9096 : iterate, eliminate, do_region, exit_bbs, false);
9097 49683214 : rpo_state[idx].visited++;
9098 :
9099 : /* Verify if changed values flow over executable outgoing backedges
9100 : and those change destination PHI values (that's the thing we
9101 : can easily verify). Reduce over all such edges to the farthest
9102 : away PHI. */
9103 49683214 : int iterate_to = -1;
9104 49683214 : edge_iterator ei;
9105 49683214 : edge e;
9106 119684980 : FOR_EACH_EDGE (e, ei, bb->succs)
9107 70001766 : if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE))
9108 : == (EDGE_DFS_BACK|EDGE_EXECUTABLE)
9109 4477336 : && rpo_state[bb_to_rpo[e->dest->index]].iterate)
9110 : {
9111 4474570 : int destidx = bb_to_rpo[e->dest->index];
9112 4474570 : if (!rpo_state[destidx].visited)
9113 : {
9114 134 : if (dump_file && (dump_flags & TDF_DETAILS))
9115 0 : fprintf (dump_file, "Unvisited destination %d\n",
9116 : e->dest->index);
9117 134 : if (iterate_to == -1 || destidx < iterate_to)
9118 134 : iterate_to = destidx;
9119 134 : continue;
9120 : }
9121 4474436 : if (dump_file && (dump_flags & TDF_DETAILS))
9122 53 : fprintf (dump_file, "Looking for changed values of backedge"
9123 : " %d->%d destination PHIs\n",
9124 53 : e->src->index, e->dest->index);
9125 4474436 : vn_context_bb = e->dest;
9126 4474436 : gphi_iterator gsi;
9127 4474436 : for (gsi = gsi_start_phis (e->dest);
9128 10169432 : !gsi_end_p (gsi); gsi_next (&gsi))
9129 : {
9130 7642286 : bool inserted = false;
9131 : /* While we'd ideally just iterate on value changes
9132 : we CSE PHIs and do that even across basic-block
9133 : boundaries. So even hashtable state changes can
9134 : be important (which is roughly equivalent to
9135 : PHI argument value changes). To not excessively
9136 : iterate because of that we track whether a PHI
9137 : was CSEd to with GF_PLF_1. */
9138 7642286 : bool phival_changed;
9139 7642286 : if ((phival_changed = visit_phi (gsi.phi (),
9140 : &inserted, false))
9141 9055248 : || (inserted && gimple_plf (gsi.phi (), GF_PLF_1)))
9142 : {
9143 1947290 : if (!phival_changed
9144 1947290 : && dump_file && (dump_flags & TDF_DETAILS))
9145 0 : fprintf (dump_file, "PHI was CSEd and hashtable "
9146 : "state (changed)\n");
9147 1947290 : if (iterate_to == -1 || destidx < iterate_to)
9148 1947205 : iterate_to = destidx;
9149 1947290 : break;
9150 : }
9151 : }
9152 4474436 : vn_context_bb = NULL;
9153 : }
9154 49683214 : if (iterate_to != -1)
9155 : {
9156 1946487 : do_unwind (&rpo_state[iterate_to], avail);
9157 1946487 : idx = iterate_to;
9158 1946487 : if (dump_file && (dump_flags & TDF_DETAILS))
9159 20 : fprintf (dump_file, "Iterating to %d BB%d\n",
9160 20 : iterate_to, rpo[iterate_to]);
9161 1946487 : continue;
9162 : }
9163 :
9164 47736727 : idx++;
9165 : }
9166 50725984 : while (idx < n);
9167 :
9168 : else /* !iterate */
9169 : {
9170 : /* Process all blocks greedily with a worklist that enforces RPO
9171 : processing of reachable blocks. */
9172 1928320 : auto_bitmap worklist;
9173 1928320 : bitmap_set_bit (worklist, 0);
9174 17787502 : while (!bitmap_empty_p (worklist))
9175 : {
9176 13930862 : int idx = bitmap_clear_first_set_bit (worklist);
9177 13930862 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
9178 13930862 : gcc_assert ((bb->flags & BB_EXECUTABLE)
9179 : && !rpo_state[idx].visited);
9180 :
9181 13930862 : if (dump_file && (dump_flags & TDF_DETAILS))
9182 36166 : fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
9183 :
9184 : /* When we run into predecessor edges where we cannot trust its
9185 : executable state mark them executable so PHI processing will
9186 : be conservative.
9187 : ??? Do we need to force arguments flowing over that edge
9188 : to be varying or will they even always be? */
9189 13930862 : edge_iterator ei;
9190 13930862 : edge e;
9191 33781334 : FOR_EACH_EDGE (e, ei, bb->preds)
9192 19850472 : if (!(e->flags & EDGE_EXECUTABLE)
9193 1038102 : && (bb == entry->dest
9194 983729 : || (!rpo_state[bb_to_rpo[e->src->index]].visited
9195 944770 : && (rpo_state[bb_to_rpo[e->src->index]].max_rpo
9196 : >= (int)idx))))
9197 : {
9198 975432 : if (dump_file && (dump_flags & TDF_DETAILS))
9199 11632 : fprintf (dump_file, "Cannot trust state of predecessor "
9200 : "edge %d -> %d, marking executable\n",
9201 11632 : e->src->index, e->dest->index);
9202 975432 : e->flags |= EDGE_EXECUTABLE;
9203 : }
9204 :
9205 13930862 : nblk++;
9206 27861724 : todo |= process_bb (avail, bb, false, false, false, eliminate,
9207 : do_region, exit_bbs,
9208 52214 : skip_entry_phis && bb == entry->dest);
9209 13930862 : rpo_state[idx].visited++;
9210 :
9211 34435359 : FOR_EACH_EDGE (e, ei, bb->succs)
9212 20504497 : if ((e->flags & EDGE_EXECUTABLE)
9213 20423841 : && e->dest->index != EXIT_BLOCK
9214 19224898 : && (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index))
9215 38358521 : && !rpo_state[bb_to_rpo[e->dest->index]].visited)
9216 16884050 : bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]);
9217 : }
9218 1928320 : }
9219 :
9220 : /* If statistics or dump file active. */
9221 6366283 : int nex = 0;
9222 6366283 : unsigned max_visited = 1;
9223 58769994 : for (int i = 0; i < n; ++i)
9224 : {
9225 52403711 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
9226 52403711 : if (bb->flags & BB_EXECUTABLE)
9227 51759805 : nex++;
9228 52403711 : statistics_histogram_event (cfun, "RPO block visited times",
9229 52403711 : rpo_state[i].visited);
9230 52403711 : if (rpo_state[i].visited > max_visited)
9231 : max_visited = rpo_state[i].visited;
9232 : }
9233 6366283 : unsigned nvalues = 0, navail = 0;
9234 176098934 : for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
9235 176098934 : i != vn_ssa_aux_hash->end (); ++i)
9236 : {
9237 169732651 : nvalues++;
9238 169732651 : vn_avail *av = (*i)->avail;
9239 250708815 : while (av)
9240 : {
9241 80976164 : navail++;
9242 80976164 : av = av->next;
9243 : }
9244 : }
9245 6366283 : statistics_counter_event (cfun, "RPO blocks", n);
9246 6366283 : statistics_counter_event (cfun, "RPO blocks visited", nblk);
9247 6366283 : statistics_counter_event (cfun, "RPO blocks executable", nex);
9248 6366283 : statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex);
9249 6366283 : statistics_histogram_event (cfun, "RPO num values", nvalues);
9250 6366283 : statistics_histogram_event (cfun, "RPO num avail", navail);
9251 6366283 : statistics_histogram_event (cfun, "RPO num lattice",
9252 6366283 : vn_ssa_aux_hash->elements ());
9253 6366283 : if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS)))
9254 : {
9255 11537 : fprintf (dump_file, "RPO iteration over %d blocks visited %" PRIu64
9256 : " blocks in total discovering %d executable blocks iterating "
9257 : "%d.%d times, a block was visited max. %u times\n",
9258 : n, nblk, nex,
9259 11537 : (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10),
9260 : max_visited);
9261 11537 : fprintf (dump_file, "RPO tracked %d values available at %d locations "
9262 : "and %" PRIu64 " lattice elements\n",
9263 11537 : nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ());
9264 : }
9265 :
9266 6366283 : if (eliminate)
9267 : {
9268 : /* When !iterate we already performed elimination during the RPO
9269 : walk. */
9270 1908717 : if (iterate)
9271 : {
9272 : /* Elimination for region-based VN needs to be done within the
9273 : RPO walk. */
9274 0 : gcc_assert (! do_region);
9275 : /* Note we can't use avail.walk here because that gets confused
9276 : by the existing availability and it will be less efficient
9277 : as well. */
9278 0 : todo |= eliminate_with_rpo_vn (NULL);
9279 : }
9280 : else
9281 1908717 : todo |= avail.eliminate_cleanup (do_region);
9282 : }
9283 :
9284 6366283 : vn_valueize = NULL;
9285 6366283 : rpo_avail = NULL;
9286 6366283 : vn_bb_to_rpo = NULL;
9287 :
9288 6366283 : XDELETEVEC (rpo);
9289 6366283 : XDELETEVEC (rpo_state);
9290 :
9291 6366283 : return todo;
9292 6366283 : }
9293 :
9294 : /* Region-based entry for RPO VN. Performs value-numbering and elimination
9295 : on the SEME region specified by ENTRY and EXIT_BBS. If ENTRY is not
9296 : the only edge into the region at ENTRY->dest PHI nodes in ENTRY->dest
9297 : are not considered.
9298 : If ITERATE is true then treat backedges optimistically as not
9299 : executed and iterate. If ELIMINATE is true then perform
9300 : elimination, otherwise leave that to the caller.
9301 : If SKIP_ENTRY_PHIS is true then force PHI nodes in ENTRY->dest to VARYING.
9302 : KIND specifies the amount of work done for handling memory operations. */
9303 :
9304 : unsigned
9305 718975 : do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
9306 : bool iterate, bool eliminate, bool skip_entry_phis,
9307 : vn_lookup_kind kind)
9308 : {
9309 718975 : auto_timevar tv (TV_TREE_RPO_VN);
9310 :
9311 : /* We don't support elimination in region-based iteration. */
9312 718975 : gcc_assert (!entry || !iterate || !eliminate);
9313 : /* When iterating, finalize does the elimination; otherwise the
9314 : constructor's walk does. */
9315 718975 : vn_driver vn (fn, entry, exit_bbs, iterate, eliminate && !iterate,
9316 718975 : skip_entry_phis, kind);
9317 718975 : return eliminate ? vn.finalize () : vn.todo ();
9318 718975 : }
9319 :
9320 5647308 : vn_driver::vn_driver (function *fn, bool iterate, bool eliminate,
9321 : bool want_value_ids, vn_lookup_kind kind)
9322 5647308 : : vn_driver (fn, NULL, NULL, iterate, eliminate, false, kind)
9323 : {
9324 5647308 : if (want_value_ids)
9325 988750 : assign_value_ids ();
9326 5647308 : }
9327 :
9328 : /* Value-number the region ENTRY leads into, which exits to EXIT_BBS, or all of
9329 : FN if ENTRY is NULL. */
9330 :
9331 6366283 : vn_driver::vn_driver (function *fn, edge entry, bitmap exit_bbs,
9332 : bool iterate, bool eliminate, bool skip_entry_phis,
9333 : vn_lookup_kind kind)
9334 6366283 : : m_eliminate (eliminate)
9335 : {
9336 6366283 : basic_block entry_bb
9337 6366283 : = entry ? entry->dest : single_succ (ENTRY_BLOCK_PTR_FOR_FN (fn));
9338 6366283 : m_avail = new rpo_elim (entry_bb);
9339 6366283 : m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
9340 12732566 : m_todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate,
9341 6366283 : skip_entry_phis, kind, *m_avail, m_bb_to_rpo);
9342 6366283 : }
9343 :
9344 6366283 : vn_driver::~vn_driver ()
9345 : {
9346 6366283 : free_rpo_vn ();
9347 6366283 : XDELETEVEC (m_bb_to_rpo);
9348 6366283 : delete m_avail;
9349 6366283 : }
9350 :
9351 : /* Finish elimination and return the TODO flags. */
9352 :
9353 : unsigned
9354 6346680 : vn_driver::finalize (bitmap inserted_exprs)
9355 : {
9356 : /* If ELIMINATE was passed to the constructor, finish the elimination. */
9357 6346680 : if (m_eliminate)
9358 1908717 : return m_todo;
9359 :
9360 : /* PRE eliminates after its insertions, when the RPO map no longer
9361 : describes the IL. Return only its flags, as PRE always has, to avoid
9362 : an extra CFG cleanup. */
9363 4437963 : if (inserted_exprs)
9364 988750 : return eliminate_with_rpo_vn (inserted_exprs);
9365 :
9366 : /* Otherwise do full elimination. */
9367 3449213 : rpo_avail = m_avail;
9368 3449213 : vn_bb_to_rpo = m_bb_to_rpo;
9369 3449213 : vn_valueize = rpo_vn_valueize;
9370 3449213 : unsigned todo = m_todo | eliminate_with_rpo_vn (NULL);
9371 3449213 : vn_valueize = NULL;
9372 3449213 : rpo_avail = NULL;
9373 3449213 : vn_bb_to_rpo = NULL;
9374 3449213 : return todo;
9375 : }
9376 :
9377 :
9378 : namespace {
9379 :
9380 : const pass_data pass_data_fre =
9381 : {
9382 : GIMPLE_PASS, /* type */
9383 : "fre", /* name */
9384 : OPTGROUP_NONE, /* optinfo_flags */
9385 : TV_TREE_FRE, /* tv_id */
9386 : ( PROP_cfg | PROP_ssa ), /* properties_required */
9387 : 0, /* properties_provided */
9388 : 0, /* properties_destroyed */
9389 : 0, /* todo_flags_start */
9390 : 0, /* todo_flags_finish */
9391 : };
9392 :
9393 : class pass_fre : public gimple_opt_pass
9394 : {
9395 : public:
9396 1472680 : pass_fre (gcc::context *ctxt)
9397 2945360 : : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
9398 : {}
9399 :
9400 : /* opt_pass methods: */
9401 1178144 : opt_pass * clone () final override { return new pass_fre (m_ctxt); }
9402 1472680 : void set_pass_param (unsigned int n, bool param) final override
9403 : {
9404 1472680 : gcc_assert (n == 0);
9405 1472680 : may_iterate = param;
9406 1472680 : }
9407 4739544 : bool gate (function *) final override
9408 : {
9409 4739544 : return flag_tree_fre != 0 && (may_iterate || optimize > 1);
9410 : }
9411 : unsigned int execute (function *) final override;
9412 :
9413 : private:
9414 : bool may_iterate;
9415 : }; // class pass_fre
9416 :
9417 : unsigned int
9418 4658558 : pass_fre::execute (function *fun)
9419 : {
9420 4658558 : unsigned todo = 0;
9421 :
9422 : /* At -O[1g] use the cheap non-iterating mode. */
9423 4658558 : bool iterate_p = may_iterate && (optimize > 1);
9424 4658558 : calculate_dominance_info (CDI_DOMINATORS);
9425 4658558 : if (iterate_p)
9426 3449213 : loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
9427 :
9428 4658558 : {
9429 : /* When iterating, finalize below does the elimination; otherwise the
9430 : constructor's walk does. */
9431 4658558 : vn_driver vn (fun, iterate_p, !iterate_p);
9432 4658558 : todo = vn.finalize ();
9433 4658558 : }
9434 :
9435 4658558 : if (iterate_p)
9436 3449213 : loop_optimizer_finalize ();
9437 :
9438 4658558 : if (scev_initialized_p ())
9439 32613 : scev_reset_htab ();
9440 :
9441 : /* For late FRE after IVOPTs and unrolling, see if we can
9442 : remove some TREE_ADDRESSABLE and rewrite stuff into SSA. */
9443 4658558 : if (!may_iterate)
9444 1021145 : todo |= TODO_update_address_taken;
9445 :
9446 4658558 : return todo;
9447 : }
9448 :
9449 : } // anon namespace
9450 :
9451 : gimple_opt_pass *
9452 294536 : make_pass_fre (gcc::context *ctxt)
9453 : {
9454 294536 : return new pass_fre (ctxt);
9455 : }
9456 :
9457 : #undef BB_EXECUTABLE
|