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 774798947 : vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
158 : {
159 774798947 : 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 982812406 : vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
167 : {
168 982812406 : 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 25441212 : vn_phi_hasher::hash (const vn_phi_s *vp1)
190 : {
191 25441212 : return vp1->hashcode;
192 : }
193 :
194 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
195 :
196 : inline bool
197 46408257 : vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
198 : {
199 46408257 : 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 25918172 : vn_reference_op_eq (const void *p1, const void *p2)
211 : {
212 25918172 : const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
213 25918172 : const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
214 :
215 25918172 : return (vro1->opcode == vro2->opcode
216 : /* We do not care for differences in type qualification. */
217 25916324 : && (vro1->type == vro2->type
218 1190146 : || (vro1->type && vro2->type
219 1190146 : && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
220 1190146 : TYPE_MAIN_VARIANT (vro2->type))))
221 24914465 : && expressions_equal_p (vro1->op0, vro2->op0)
222 24872822 : && expressions_equal_p (vro1->op1, vro2->op1)
223 24872822 : && expressions_equal_p (vro1->op2, vro2->op2)
224 50790994 : && (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 3861738613 : vn_reference_hasher::hash (const vn_reference_s *vr1)
248 : {
249 3861738613 : return vr1->hashcode;
250 : }
251 :
252 : inline bool
253 4582084270 : vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
254 : {
255 4582084270 : 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 1304 : 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 12339117 : vn_constant_hasher::hash (const vn_constant_s *vc1)
346 : {
347 12339117 : return vc1->hashcode;
348 : }
349 :
350 : /* Hash table equality function for vn_constant_t. */
351 :
352 : inline bool
353 14881878 : vn_constant_hasher::equal (const vn_constant_s *vc1, const vn_constant_s *vc2)
354 : {
355 14881878 : if (vc1->hashcode != vc2->hashcode)
356 : return false;
357 :
358 2237395 : 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 82633 : vn_valueize_for_srt (tree t, void* context ATTRIBUTE_UNUSED)
389 : {
390 82633 : 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 82633 : if (!SSA_NAME_IS_DEFAULT_DEF (t))
397 78804 : vn_context_bb = gimple_bb (SSA_NAME_DEF_STMT (t));
398 82633 : tree res = vn_valueize (t);
399 82633 : vn_context_bb = saved_vn_context_bb;
400 82633 : 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 >13800*10^7 : static inline bool is_empty (value_type &e) { return e == NULL; }
430 : };
431 :
432 : hashval_t
433 45449642326 : vn_ssa_aux_hasher::hash (const value_type &entry)
434 : {
435 45449642326 : return SSA_NAME_VERSION (entry->name);
436 : }
437 :
438 : bool
439 52003168940 : vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name)
440 : {
441 52003168940 : 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 5172516 : has_VN_INFO (tree name)
462 : {
463 5172516 : return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name));
464 : }
465 :
466 : vn_ssa_aux_t
467 3993994481 : VN_INFO (tree name)
468 : {
469 3993994481 : vn_ssa_aux_t *res
470 3993994481 : = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name),
471 : INSERT);
472 3993994481 : if (*res != NULL)
473 : return *res;
474 :
475 175055016 : vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
476 175055016 : memset (newinfo, 0, sizeof (struct vn_ssa_aux));
477 175055016 : newinfo->name = name;
478 175055016 : 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 175055016 : 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 175055016 : if (SSA_NAME_IS_DEFAULT_DEF (name))
486 9395366 : switch (TREE_CODE (SSA_NAME_VAR (name)))
487 : {
488 1693579 : case VAR_DECL:
489 : /* All undefined vars are VARYING. */
490 1693579 : newinfo->valnum = name;
491 1693579 : newinfo->visited = true;
492 1693579 : break;
493 :
494 7641997 : case PARM_DECL:
495 : /* Parameters are VARYING but we can record a condition
496 : if we know it is a non-NULL pointer. */
497 7641997 : newinfo->visited = true;
498 7641997 : newinfo->valnum = name;
499 11763061 : if (POINTER_TYPE_P (TREE_TYPE (name))
500 8804676 : && nonnull_arg_p (SSA_NAME_VAR (name)))
501 : {
502 2361928 : tree ops[2];
503 2361928 : ops[0] = name;
504 2361928 : ops[1] = build_int_cst (TREE_TYPE (name), 0);
505 2361928 : vn_nary_op_t nary;
506 : /* Allocate from non-unwinding stack. */
507 2361928 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
508 2361928 : init_vn_nary_op_from_pieces (nary, 2, NE_EXPR,
509 : boolean_type_node, ops);
510 2361928 : nary->predicated_values = 0;
511 2361928 : nary->u.result = boolean_true_node;
512 2361928 : vn_nary_op_insert_into (nary, valid_info->nary);
513 2361928 : gcc_assert (nary->unwind_to == NULL);
514 : /* Also do not link it into the undo chain. */
515 2361928 : last_inserted_nary = nary->next;
516 2361928 : nary->next = (vn_nary_op_t)(void *)-1;
517 2361928 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
518 2361928 : init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR,
519 : boolean_type_node, ops);
520 2361928 : nary->predicated_values = 0;
521 2361928 : nary->u.result = boolean_false_node;
522 2361928 : vn_nary_op_insert_into (nary, valid_info->nary);
523 2361928 : gcc_assert (nary->unwind_to == NULL);
524 2361928 : last_inserted_nary = nary->next;
525 2361928 : nary->next = (vn_nary_op_t)(void *)-1;
526 2361928 : 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 59790 : 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 59790 : newinfo->visited = true;
540 59790 : newinfo->valnum = name;
541 59790 : 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 3484632283 : SSA_VAL (tree x, bool *visited = NULL)
553 : {
554 3484632283 : vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
555 3484632283 : if (visited)
556 1417886259 : *visited = tem && tem->visited;
557 3484632283 : 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 1286446001 : vuse_ssa_val (tree x)
566 : {
567 1286446001 : if (!x)
568 : return NULL_TREE;
569 :
570 1283056358 : do
571 : {
572 1283056358 : x = SSA_VAL (x);
573 1283056358 : gcc_assert (x != VN_TOP);
574 : }
575 1283056358 : 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 1087751064 : vuse_valueize (tree vuse)
586 : {
587 1087751064 : do
588 : {
589 1087751064 : bool visited;
590 1087751064 : vuse = SSA_VAL (vuse, &visited);
591 1087751064 : if (!visited)
592 16337188 : return NULL_TREE;
593 1071413876 : gcc_assert (vuse != VN_TOP);
594 : }
595 1071413876 : 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 103936125 : vn_get_stmt_kind (gimple *stmt)
605 : {
606 103936125 : switch (gimple_code (stmt))
607 : {
608 : case GIMPLE_CALL:
609 : return VN_REFERENCE;
610 : case GIMPLE_PHI:
611 : return VN_PHI;
612 103936125 : case GIMPLE_ASSIGN:
613 103936125 : {
614 103936125 : enum tree_code code = gimple_assign_rhs_code (stmt);
615 103936125 : tree rhs1 = gimple_assign_rhs1 (stmt);
616 103936125 : 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 48650939 : case GIMPLE_SINGLE_RHS:
623 48650939 : switch (TREE_CODE_CLASS (code))
624 : {
625 36675788 : case tcc_reference:
626 : /* VOP-less references can go through unary case. */
627 36675788 : if ((code == REALPART_EXPR
628 : || code == IMAGPART_EXPR
629 36675788 : || code == VIEW_CONVERT_EXPR
630 36675788 : || code == BIT_FIELD_REF)
631 36675788 : && (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
632 662242 : || is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
633 2256150 : 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 5980244 : default:
643 5980244 : if (code == ADDR_EXPR)
644 3233228 : return (is_gimple_min_invariant (rhs1)
645 3233228 : ? VN_CONSTANT : VN_REFERENCE);
646 2747016 : 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 29047290 : get_or_alloc_constant_value_id (tree constant)
681 : {
682 29047290 : vn_constant_s **slot;
683 29047290 : struct vn_constant_s vc;
684 29047290 : 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 29047290 : if (!constant_to_value_id)
689 : return 0;
690 :
691 4767846 : vc.hashcode = vn_hash_constant_with_type (constant);
692 4767846 : vc.constant = constant;
693 4767846 : slot = constant_to_value_id->find_slot (&vc, INSERT);
694 4767846 : if (*slot)
695 2219968 : return (*slot)->value_id;
696 :
697 2547878 : vcp = XNEW (struct vn_constant_s);
698 2547878 : vcp->hashcode = vc.hashcode;
699 2547878 : vcp->constant = constant;
700 2547878 : vcp->value_id = get_next_constant_value_id ();
701 2547878 : *slot = vcp;
702 2547878 : return vcp->value_id;
703 : }
704 :
705 : /* Compute the hash for a reference operand VRO1. */
706 :
707 : static void
708 137373827 : vn_reference_op_compute_hash (const vn_reference_op_t vro1, inchash::hash &hstate)
709 : {
710 137373827 : hstate.add_int (vro1->opcode);
711 137373827 : if (vro1->opcode == CALL_EXPR && !vro1->op0)
712 555552 : hstate.add_int (vro1->clique);
713 137373827 : if (vro1->op0)
714 130998882 : inchash::add_expr (vro1->op0, hstate);
715 137373827 : if (vro1->op1)
716 12143088 : inchash::add_expr (vro1->op1, hstate);
717 137373827 : if (vro1->op2)
718 13853791 : inchash::add_expr (vro1->op2, hstate);
719 137373827 : }
720 :
721 : /* Compute a hash for the reference operation VR1 and return it. */
722 :
723 : hashval_t
724 205261246 : vn_reference_compute_hash (const vn_reference_t vr1)
725 : {
726 205261246 : inchash::hash hstate;
727 205261246 : hashval_t result;
728 205261246 : int i;
729 205261246 : vn_reference_op_t vro;
730 205261246 : poly_offset_int off = -1;
731 205261246 : bool deref = false;
732 :
733 835029712 : FOR_EACH_VEC_ELT (vr1->operands, i, vro)
734 : {
735 629768466 : if (vro->opcode == MEM_REF)
736 : deref = true;
737 435149162 : else if (vro->opcode != ADDR_EXPR)
738 304731180 : deref = false;
739 629768466 : if (maybe_ne (vro->off, -1))
740 : {
741 370222458 : if (known_eq (off, -1))
742 197019954 : off = 0;
743 629768466 : off += vro->off;
744 : }
745 : else
746 : {
747 259546008 : if (maybe_ne (off, -1)
748 259546008 : && maybe_ne (off, 0))
749 104347395 : hstate.add_poly_hwi (off.force_shwi ());
750 259546008 : off = -1;
751 259546008 : if (deref
752 122391398 : && vro->opcode == ADDR_EXPR)
753 : {
754 122172181 : if (vro->op0)
755 : {
756 122172181 : tree op = TREE_OPERAND (vro->op0, 0);
757 122172181 : hstate.add_int (TREE_CODE (op));
758 122172181 : inchash::add_expr (op, hstate);
759 : }
760 : }
761 : else
762 137373827 : 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 205261246 : result = hstate.end ();
768 : /* ??? We would ICE later if we hash instead of adding that in. */
769 205261246 : if (vr1->vuse)
770 200313643 : result += SSA_NAME_VERSION (vr1->vuse);
771 :
772 205261246 : 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 4577211986 : vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2,
781 : bool lexical)
782 : {
783 4577211986 : unsigned i, j;
784 :
785 : /* Early out if this is not a hash collision. */
786 4577211986 : if (vr1->hashcode != vr2->hashcode)
787 : return false;
788 :
789 : /* The VOP needs to be the same. */
790 17946989 : 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 17946549 : if (maybe_ne (vr1->offset, vr2->offset)
796 17946549 : || maybe_ne (vr1->max_size, vr2->max_size))
797 : {
798 : /* But nothing known in the prevailing entry is OK to be used. */
799 6986330 : 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 35800990 : if (vr1->operands == vr2->operands)
805 : return true;
806 :
807 17900495 : if (!vr1->type || !vr2->type)
808 : {
809 551022 : if (vr1->type != vr2->type)
810 : return false;
811 : }
812 17349473 : else if (vr1->type == vr2->type)
813 : ;
814 2225565 : else if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
815 2225565 : || (COMPLETE_TYPE_P (vr1->type)
816 2225565 : && !expressions_equal_p (TYPE_SIZE (vr1->type),
817 2225565 : TYPE_SIZE (vr2->type))))
818 790622 : return false;
819 1434943 : else if (vr1->operands[0].opcode == CALL_EXPR
820 1434943 : && !types_compatible_p (vr1->type, vr2->type))
821 : return false;
822 1434943 : else if (INTEGRAL_TYPE_P (vr1->type)
823 577570 : && INTEGRAL_TYPE_P (vr2->type))
824 : {
825 537458 : if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
826 : return false;
827 : }
828 897485 : else if (INTEGRAL_TYPE_P (vr1->type)
829 897485 : && (TYPE_PRECISION (vr1->type)
830 40112 : != TREE_INT_CST_LOW (TYPE_SIZE (vr1->type))))
831 : return false;
832 897439 : else if (INTEGRAL_TYPE_P (vr2->type)
833 897439 : && (TYPE_PRECISION (vr2->type)
834 9317 : != TREE_INT_CST_LOW (TYPE_SIZE (vr2->type))))
835 : return false;
836 19614 : else if (VECTOR_BOOLEAN_TYPE_P (vr1->type)
837 896844 : && 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 896844 : else if (TYPE_MODE (vr1->type) != TYPE_MODE (vr2->type)
857 896844 : && (!mode_can_transfer_bits (TYPE_MODE (vr1->type))
858 45192 : || !mode_can_transfer_bits (TYPE_MODE (vr2->type))))
859 1037 : return false;
860 :
861 : i = 0;
862 : j = 0;
863 22018440 : do
864 : {
865 22018440 : poly_offset_int off1 = 0, off2 = 0;
866 22018440 : vn_reference_op_t vro1, vro2;
867 22018440 : vn_reference_op_s tem1, tem2;
868 22018440 : bool deref1 = false, deref2 = false;
869 22018440 : bool reverse1 = false, reverse2 = false;
870 71568977 : for (; vr1->operands.iterate (i, &vro1); i++)
871 : {
872 49550537 : if (vro1->opcode == MEM_REF)
873 : deref1 = true;
874 : /* Do not look through a storage order barrier. */
875 33889770 : else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
876 72540 : return false;
877 49550537 : reverse1 |= vro1->reverse;
878 49550537 : if (lexical || known_eq (vro1->off, -1))
879 : break;
880 27532097 : off1 += vro1->off;
881 : }
882 49695400 : for (; vr2->operands.iterate (j, &vro2); j++)
883 : {
884 49695400 : if (vro2->opcode == MEM_REF)
885 : deref2 = true;
886 : /* Do not look through a storage order barrier. */
887 34010953 : else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
888 : return false;
889 49695400 : reverse2 |= vro2->reverse;
890 49695400 : if (lexical || known_eq (vro2->off, -1))
891 : break;
892 27676960 : off2 += vro2->off;
893 : }
894 22018440 : if (maybe_ne (off1, off2) || reverse1 != reverse2)
895 : return false;
896 22018302 : if (deref1 && vro1->opcode == ADDR_EXPR)
897 : {
898 8338204 : memset (&tem1, 0, sizeof (tem1));
899 8338204 : tem1.op0 = TREE_OPERAND (vro1->op0, 0);
900 8338204 : tem1.type = TREE_TYPE (tem1.op0);
901 8338204 : tem1.opcode = TREE_CODE (tem1.op0);
902 8338204 : vro1 = &tem1;
903 8338204 : deref1 = false;
904 : }
905 22018302 : if (deref2 && vro2->opcode == ADDR_EXPR)
906 : {
907 8338214 : memset (&tem2, 0, sizeof (tem2));
908 8338214 : tem2.op0 = TREE_OPERAND (vro2->op0, 0);
909 8338214 : tem2.type = TREE_TYPE (tem2.op0);
910 8338214 : tem2.opcode = TREE_CODE (tem2.op0);
911 8338214 : vro2 = &tem2;
912 8338214 : deref2 = false;
913 : }
914 22018302 : if (deref1 != deref2)
915 : return false;
916 21961848 : 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 21949698 : if (lexical
924 2237537 : && (vro1->opcode == MEM_REF
925 2237537 : || vro1->opcode == TARGET_MEM_REF)
926 22684282 : && (TYPE_ALIGN (vro1->type) != TYPE_ALIGN (vro2->type)
927 734377 : || (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 2203113 : || (get_deref_alias_set (vro1->opcode == MEM_REF
933 734371 : ? TREE_TYPE (vro1->op0)
934 0 : : TREE_TYPE (vro1->op2))
935 1468742 : != get_deref_alias_set (vro2->opcode == MEM_REF
936 734371 : ? TREE_TYPE (vro2->op0)
937 0 : : TREE_TYPE (vro2->op2)))))
938 3798 : return false;
939 21945900 : ++j;
940 21945900 : ++i;
941 : }
942 43891800 : while (vr1->operands.length () != i
943 65837700 : || 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 224506069 : 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 224506069 : tree orig = ref;
956 779099845 : while (ref)
957 : {
958 554593776 : vn_reference_op_s temp;
959 :
960 554593776 : memset (&temp, 0, sizeof (temp));
961 554593776 : temp.type = TREE_TYPE (ref);
962 554593776 : temp.opcode = TREE_CODE (ref);
963 554593776 : temp.off = -1;
964 :
965 554593776 : switch (temp.opcode)
966 : {
967 15106787 : case MODIFY_EXPR:
968 15106787 : temp.op0 = TREE_OPERAND (ref, 1);
969 15106787 : break;
970 137 : case WITH_SIZE_EXPR:
971 137 : temp.op0 = TREE_OPERAND (ref, 1);
972 137 : temp.off = 0;
973 137 : break;
974 118418940 : case MEM_REF:
975 : /* The base address gets its own vn_reference_op_s structure. */
976 118418940 : temp.op0 = TREE_OPERAND (ref, 1);
977 118418940 : if (!mem_ref_offset (ref).to_shwi (&temp.off))
978 0 : temp.off = -1;
979 118418940 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
980 118418940 : temp.base = MR_DEPENDENCE_BASE (ref);
981 118418940 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
982 118418940 : break;
983 2512653 : case TARGET_MEM_REF:
984 : /* The base address gets its own vn_reference_op_s structure. */
985 2512653 : temp.op0 = TMR_INDEX (ref);
986 2512653 : temp.op1 = TMR_STEP (ref);
987 2512653 : temp.op2 = TMR_OFFSET (ref);
988 2512653 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
989 2512653 : temp.base = MR_DEPENDENCE_BASE (ref);
990 2512653 : result->safe_push (temp);
991 2512653 : memset (&temp, 0, sizeof (temp));
992 2512653 : temp.type = NULL_TREE;
993 2512653 : temp.opcode = ERROR_MARK;
994 2512653 : temp.op0 = TMR_INDEX2 (ref);
995 2512653 : temp.off = -1;
996 2512653 : break;
997 787059 : case BIT_FIELD_REF:
998 : /* Record bits, position and storage order. */
999 787059 : temp.op0 = TREE_OPERAND (ref, 1);
1000 787059 : temp.op1 = TREE_OPERAND (ref, 2);
1001 1573420 : if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
1002 698 : temp.off = -1;
1003 787059 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
1004 787059 : break;
1005 147649642 : case COMPONENT_REF:
1006 : /* The field decl is enough to unambiguously specify the field,
1007 : so use its type here. */
1008 147649642 : temp.type = TREE_TYPE (TREE_OPERAND (ref, 1));
1009 147649642 : temp.op0 = TREE_OPERAND (ref, 1);
1010 147649642 : temp.op1 = TREE_OPERAND (ref, 2);
1011 295296852 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1012 295296587 : && TYPE_REVERSE_STORAGE_ORDER
1013 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1014 147649642 : {
1015 147649642 : tree this_offset = component_ref_field_offset (ref);
1016 147649642 : if (this_offset
1017 147649642 : && poly_int_tree_p (this_offset))
1018 : {
1019 147647506 : tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1));
1020 147647506 : if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0)
1021 : {
1022 147168388 : poly_offset_int off
1023 147168388 : = (wi::to_poly_offset (this_offset)
1024 147168388 : + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT));
1025 : /* Prohibit value-numbering zero offset components
1026 : of addresses the same before the pass folding
1027 : __builtin_object_size had a chance to run. Likewise
1028 : for components of zero size at arbitrary offset. */
1029 147168388 : if (TREE_CODE (orig) != ADDR_EXPR
1030 4843576 : || (TYPE_SIZE (temp.type)
1031 4830560 : && integer_nonzerop (TYPE_SIZE (temp.type))
1032 6267337 : && maybe_ne (off, 0))
1033 150165778 : || (cfun->curr_properties & PROP_objsz))
1034 145729461 : off.to_shwi (&temp.off);
1035 : }
1036 : }
1037 : }
1038 : break;
1039 38999642 : case ARRAY_RANGE_REF:
1040 38999642 : case ARRAY_REF:
1041 38999642 : {
1042 38999642 : tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
1043 : /* Record index as operand. */
1044 38999642 : temp.op0 = TREE_OPERAND (ref, 1);
1045 : /* Always record lower bounds and element size. */
1046 38999642 : temp.op1 = array_ref_low_bound (ref);
1047 : /* But record element size in units of the type alignment. */
1048 38999642 : temp.op2 = TREE_OPERAND (ref, 3);
1049 38999642 : temp.align = eltype->type_common.align;
1050 38999642 : if (! temp.op2)
1051 38789366 : temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
1052 : size_int (TYPE_ALIGN_UNIT (eltype)));
1053 : /* Prohibit value-numbering addresses of one-after-the-last
1054 : element ARRAY_REFs the same as addresses of other components
1055 : before the pass folding __builtin_object_size had a chance
1056 : to run. */
1057 38999642 : bool avoid_oob = true;
1058 38999642 : if (TREE_CODE (orig) != ADDR_EXPR
1059 478086 : || cfun->curr_properties & PROP_objsz)
1060 : avoid_oob = false;
1061 224636 : else if (poly_int_tree_p (temp.op0))
1062 : {
1063 75329 : tree ub = array_ref_up_bound (ref);
1064 75329 : if (ub
1065 73691 : && poly_int_tree_p (ub)
1066 : /* ??? The C frontend for T[0] uses [0:] and the
1067 : C++ frontend [0:-1U]. See layout_type for how
1068 : awkward this is. */
1069 65370 : && !integer_minus_onep (ub)
1070 149020 : && known_le (wi::to_poly_offset (temp.op0),
1071 : wi::to_poly_offset (ub)))
1072 64533 : avoid_oob = false;
1073 : }
1074 38999642 : if (poly_int_tree_p (temp.op0)
1075 22343003 : && poly_int_tree_p (temp.op1)
1076 22342975 : && TREE_CODE (temp.op2) == INTEGER_CST
1077 61282009 : && !avoid_oob)
1078 : {
1079 44544852 : poly_offset_int off = ((wi::to_poly_offset (temp.op0)
1080 66817278 : - wi::to_poly_offset (temp.op1))
1081 44544852 : * wi::to_offset (temp.op2)
1082 22272426 : * vn_ref_op_align_unit (&temp));
1083 22272426 : off.to_shwi (&temp.off);
1084 : }
1085 38999642 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1086 38999642 : && TYPE_REVERSE_STORAGE_ORDER
1087 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1088 : }
1089 38999642 : break;
1090 82816329 : case VAR_DECL:
1091 82816329 : if (DECL_HARD_REGISTER (ref))
1092 : {
1093 20325 : temp.op0 = ref;
1094 20325 : break;
1095 : }
1096 : /* Fallthru. */
1097 86209103 : case PARM_DECL:
1098 86209103 : case CONST_DECL:
1099 86209103 : case RESULT_DECL:
1100 : /* Canonicalize decls to MEM[&decl] which is what we end up with
1101 : when valueizing MEM[ptr] with ptr = &decl. */
1102 86209103 : temp.opcode = MEM_REF;
1103 86209103 : temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
1104 86209103 : temp.off = 0;
1105 86209103 : result->safe_push (temp);
1106 86209103 : temp.opcode = ADDR_EXPR;
1107 86209103 : temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
1108 86209103 : temp.type = TREE_TYPE (temp.op0);
1109 86209103 : temp.off = -1;
1110 86209103 : break;
1111 96748204 : case STRING_CST:
1112 96748204 : case INTEGER_CST:
1113 96748204 : case POLY_INT_CST:
1114 96748204 : case COMPLEX_CST:
1115 96748204 : case VECTOR_CST:
1116 96748204 : case REAL_CST:
1117 96748204 : case FIXED_CST:
1118 96748204 : case CONSTRUCTOR:
1119 96748204 : case SSA_NAME:
1120 96748204 : temp.op0 = ref;
1121 96748204 : break;
1122 45696665 : case ADDR_EXPR:
1123 45696665 : if (is_gimple_min_invariant (ref))
1124 : {
1125 41528437 : temp.op0 = ref;
1126 41528437 : break;
1127 : }
1128 : break;
1129 : /* These are only interesting for their operands, their
1130 : existence, and their type. They will never be the last
1131 : ref in the chain of references (IE they require an
1132 : operand), so we don't have to put anything
1133 : for op* as it will be handled by the iteration */
1134 494050 : case REALPART_EXPR:
1135 494050 : temp.off = 0;
1136 494050 : break;
1137 1452121 : case VIEW_CONVERT_EXPR:
1138 1452121 : temp.off = 0;
1139 1452121 : temp.reverse = storage_order_barrier_p (ref);
1140 1452121 : break;
1141 498448 : case IMAGPART_EXPR:
1142 : /* This is only interesting for its constant offset. */
1143 498448 : temp.off = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (ref)));
1144 498448 : break;
1145 0 : default:
1146 0 : gcc_unreachable ();
1147 : }
1148 554593776 : result->safe_push (temp);
1149 :
1150 554593776 : if (REFERENCE_CLASS_P (ref)
1151 243781221 : || TREE_CODE (ref) == MODIFY_EXPR
1152 228674434 : || TREE_CODE (ref) == WITH_SIZE_EXPR
1153 783268073 : || (TREE_CODE (ref) == ADDR_EXPR
1154 45696665 : && !is_gimple_min_invariant (ref)))
1155 330087707 : ref = TREE_OPERAND (ref, 0);
1156 : else
1157 : ref = NULL_TREE;
1158 : }
1159 224506069 : }
1160 :
1161 : /* Build a alias-oracle reference abstraction in *REF from the vn_reference
1162 : operands in *OPS, the reference alias set SET and the reference type TYPE.
1163 : Return true if something useful was produced. */
1164 :
1165 : bool
1166 14680967 : ao_ref_init_from_vn_reference (ao_ref *ref,
1167 : alias_set_type set, alias_set_type base_set,
1168 : tree type, const vec<vn_reference_op_s> &ops)
1169 : {
1170 14680967 : unsigned i;
1171 14680967 : tree base = NULL_TREE;
1172 14680967 : tree *op0_p = &base;
1173 14680967 : poly_offset_int offset = 0;
1174 14680967 : poly_offset_int max_size;
1175 14680967 : poly_offset_int size = -1;
1176 14680967 : tree size_tree = NULL_TREE;
1177 :
1178 : /* We don't handle calls. */
1179 14680967 : if (!type)
1180 : return false;
1181 :
1182 14680967 : machine_mode mode = TYPE_MODE (type);
1183 14680967 : if (mode == BLKmode)
1184 60188 : size_tree = TYPE_SIZE (type);
1185 : else
1186 29241558 : size = GET_MODE_BITSIZE (mode);
1187 14620779 : if (size_tree != NULL_TREE
1188 60188 : && poly_int_tree_p (size_tree))
1189 60188 : size = wi::to_poly_offset (size_tree);
1190 :
1191 : /* Lower the final access size from the outermost expression. */
1192 14680967 : const_vn_reference_op_t cst_op = &ops[0];
1193 : /* Cast away constness for the sake of the const-unsafe
1194 : FOR_EACH_VEC_ELT(). */
1195 14680967 : vn_reference_op_t op = const_cast<vn_reference_op_t>(cst_op);
1196 14680967 : size_tree = NULL_TREE;
1197 14680967 : if (op->opcode == COMPONENT_REF)
1198 5084063 : size_tree = DECL_SIZE (op->op0);
1199 9596904 : else if (op->opcode == BIT_FIELD_REF)
1200 69855 : size_tree = op->op0;
1201 5153918 : if (size_tree != NULL_TREE
1202 5153918 : && poly_int_tree_p (size_tree)
1203 10307836 : && (!known_size_p (size)
1204 14680967 : || known_lt (wi::to_poly_offset (size_tree), size)))
1205 39101 : size = wi::to_poly_offset (size_tree);
1206 :
1207 : /* Initially, maxsize is the same as the accessed element size.
1208 : In the following it will only grow (or become -1). */
1209 14680967 : max_size = size;
1210 :
1211 : /* Compute cumulative bit-offset for nested component-refs and array-refs,
1212 : and find the ultimate containing object. */
1213 56514671 : FOR_EACH_VEC_ELT (ops, i, op)
1214 : {
1215 41979664 : switch (op->opcode)
1216 : {
1217 : case CALL_EXPR:
1218 : return false;
1219 :
1220 : /* Record the base objects. */
1221 14229807 : case MEM_REF:
1222 14229807 : *op0_p = build2 (MEM_REF, op->type,
1223 : NULL_TREE, op->op0);
1224 14229807 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1225 14229807 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1226 14229807 : op0_p = &TREE_OPERAND (*op0_p, 0);
1227 14229807 : break;
1228 :
1229 304664 : case TARGET_MEM_REF:
1230 913992 : *op0_p = build5 (TARGET_MEM_REF, op->type,
1231 : NULL_TREE, op->op2, op->op0,
1232 304664 : op->op1, ops[i+1].op0);
1233 304664 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1234 304664 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1235 304664 : op0_p = &TREE_OPERAND (*op0_p, 0);
1236 304664 : ++i;
1237 304664 : break;
1238 :
1239 : /* Unwrap some of the wrapped decls. */
1240 6685681 : case ADDR_EXPR:
1241 : /* Apart from ADDR_EXPR arguments to MEM_REF. */
1242 6685681 : if (base != NULL_TREE
1243 6685680 : && TREE_CODE (base) == MEM_REF
1244 6650636 : && op->op0
1245 13336317 : && DECL_P (TREE_OPERAND (op->op0, 0)))
1246 : {
1247 6643331 : const_vn_reference_op_t pop = &ops[i-1];
1248 6643331 : base = TREE_OPERAND (op->op0, 0);
1249 6643331 : if (known_eq (pop->off, -1))
1250 : {
1251 25 : max_size = -1;
1252 25 : offset = 0;
1253 : }
1254 : else
1255 19929918 : offset += poly_offset_int (pop->off) * BITS_PER_UNIT;
1256 : op0_p = NULL;
1257 : break;
1258 : }
1259 : /* Fallthru. */
1260 7891676 : case PARM_DECL:
1261 7891676 : case CONST_DECL:
1262 7891676 : case RESULT_DECL:
1263 : /* ??? We shouldn't see these, but un-canonicalize what
1264 : copy_reference_ops_from_ref does when visiting MEM_REF. */
1265 7891676 : case VAR_DECL:
1266 : /* ??? And for this only have DECL_HARD_REGISTER. */
1267 7891676 : case STRING_CST:
1268 : /* This can show up in ARRAY_REF bases. */
1269 7891676 : case INTEGER_CST:
1270 7891676 : case SSA_NAME:
1271 7891676 : *op0_p = op->op0;
1272 7891676 : op0_p = NULL;
1273 7891676 : break;
1274 :
1275 : /* And now the usual component-reference style ops. */
1276 69855 : case BIT_FIELD_REF:
1277 69855 : offset += wi::to_poly_offset (op->op1);
1278 69855 : break;
1279 :
1280 8372940 : case COMPONENT_REF:
1281 8372940 : {
1282 8372940 : tree field = op->op0;
1283 : /* We do not have a complete COMPONENT_REF tree here so we
1284 : cannot use component_ref_field_offset. Do the interesting
1285 : parts manually. */
1286 8372940 : tree this_offset = DECL_FIELD_OFFSET (field);
1287 :
1288 8372940 : if (op->op1 || !poly_int_tree_p (this_offset))
1289 234 : max_size = -1;
1290 : else
1291 : {
1292 8372706 : poly_offset_int woffset = (wi::to_poly_offset (this_offset)
1293 8372706 : << LOG2_BITS_PER_UNIT);
1294 8372706 : woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
1295 8372706 : offset += woffset;
1296 : }
1297 : break;
1298 : }
1299 :
1300 3113828 : case ARRAY_RANGE_REF:
1301 3113828 : case ARRAY_REF:
1302 : /* Use the recorded constant offset. */
1303 3113828 : if (maybe_eq (op->off, -1))
1304 1203878 : max_size = -1;
1305 : else
1306 5729850 : offset += poly_offset_int (op->off) * BITS_PER_UNIT;
1307 : break;
1308 :
1309 : case REALPART_EXPR:
1310 : break;
1311 :
1312 : case IMAGPART_EXPR:
1313 41833704 : offset += size;
1314 : break;
1315 :
1316 : case VIEW_CONVERT_EXPR:
1317 : break;
1318 :
1319 : case POLY_INT_CST:
1320 : case COMPLEX_CST:
1321 : case VECTOR_CST:
1322 : case REAL_CST:
1323 : case FIXED_CST:
1324 : case CONSTRUCTOR:
1325 : return false;
1326 :
1327 : default:
1328 : return false;
1329 : }
1330 : }
1331 :
1332 14535007 : if (base == NULL_TREE)
1333 : return false;
1334 :
1335 14535007 : ref->ref = NULL_TREE;
1336 14535007 : ref->base = base;
1337 14535007 : ref->ref_alias_set = set;
1338 14535007 : ref->base_alias_set = base_set;
1339 : /* We discount volatiles from value-numbering elsewhere. */
1340 14535007 : ref->volatile_p = false;
1341 :
1342 14535007 : if (!size.to_shwi (&ref->size) || maybe_lt (ref->size, 0))
1343 : {
1344 0 : ref->offset = 0;
1345 0 : ref->size = -1;
1346 0 : ref->max_size = -1;
1347 0 : return true;
1348 : }
1349 :
1350 14535007 : if (!offset.to_shwi (&ref->offset))
1351 : {
1352 26 : ref->offset = 0;
1353 26 : ref->max_size = -1;
1354 26 : return true;
1355 : }
1356 :
1357 14534981 : if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0))
1358 1053243 : ref->max_size = -1;
1359 :
1360 : return true;
1361 : }
1362 :
1363 : /* Copy the operations present in load/store/call REF into RESULT, a vector of
1364 : vn_reference_op_s's. */
1365 :
1366 : static void
1367 9233573 : copy_reference_ops_from_call (gcall *call,
1368 : vec<vn_reference_op_s> *result)
1369 : {
1370 9233573 : vn_reference_op_s temp;
1371 9233573 : unsigned i;
1372 9233573 : tree lhs = gimple_call_lhs (call);
1373 9233573 : int lr;
1374 :
1375 : /* If 2 calls have a different non-ssa lhs, vdef value numbers should be
1376 : different. By adding the lhs here in the vector, we ensure that the
1377 : hashcode is different, guaranteeing a different value number. */
1378 9233573 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
1379 : {
1380 450855 : memset (&temp, 0, sizeof (temp));
1381 450855 : temp.opcode = MODIFY_EXPR;
1382 450855 : temp.type = TREE_TYPE (lhs);
1383 450855 : temp.op0 = lhs;
1384 450855 : temp.off = -1;
1385 450855 : result->safe_push (temp);
1386 : }
1387 :
1388 : /* Copy the type, opcode, function, static chain and EH region, if any. */
1389 9233573 : memset (&temp, 0, sizeof (temp));
1390 9233573 : temp.type = gimple_call_fntype (call);
1391 9233573 : temp.opcode = CALL_EXPR;
1392 9233573 : temp.op0 = gimple_call_fn (call);
1393 9233573 : if (gimple_call_internal_p (call))
1394 540566 : temp.clique = gimple_call_internal_fn (call);
1395 9233573 : temp.op1 = gimple_call_chain (call);
1396 9233573 : if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0)
1397 607832 : temp.op2 = size_int (lr);
1398 9233573 : temp.off = -1;
1399 9233573 : result->safe_push (temp);
1400 :
1401 : /* Copy the call arguments. As they can be references as well,
1402 : just chain them together. */
1403 27383954 : for (i = 0; i < gimple_call_num_args (call); ++i)
1404 : {
1405 18150381 : tree callarg = gimple_call_arg (call, i);
1406 18150381 : copy_reference_ops_from_ref (callarg, result);
1407 : }
1408 9233573 : }
1409 :
1410 : /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates
1411 : *I_P to point to the last element of the replacement. */
1412 : static bool
1413 128325274 : vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
1414 : unsigned int *i_p)
1415 : {
1416 128325274 : unsigned int i = *i_p;
1417 128325274 : vn_reference_op_t op = &(*ops)[i];
1418 128325274 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1419 128325274 : tree addr_base;
1420 128325274 : poly_int64 addr_offset = 0;
1421 :
1422 : /* The only thing we have to do is from &OBJ.foo.bar add the offset
1423 : from .foo.bar to the preceding MEM_REF offset and replace the
1424 : address with &OBJ. */
1425 128325274 : addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (op->op0, 0),
1426 : &addr_offset, vn_valueize);
1427 128325274 : gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
1428 128325274 : if (addr_base != TREE_OPERAND (op->op0, 0))
1429 : {
1430 679631 : poly_offset_int off
1431 679631 : = (poly_offset_int::from (wi::to_poly_wide (mem_op->op0),
1432 : SIGNED)
1433 679631 : + addr_offset);
1434 679631 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1435 679631 : op->op0 = build_fold_addr_expr (addr_base);
1436 679631 : if (tree_fits_shwi_p (mem_op->op0))
1437 679564 : mem_op->off = tree_to_shwi (mem_op->op0);
1438 : else
1439 67 : mem_op->off = -1;
1440 679631 : return true;
1441 : }
1442 : return false;
1443 : }
1444 :
1445 : /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates
1446 : *I_P to point to the last element of the replacement. */
1447 : static bool
1448 86044253 : vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
1449 : unsigned int *i_p)
1450 : {
1451 86044253 : bool changed = false;
1452 93481760 : vn_reference_op_t op;
1453 :
1454 93481760 : do
1455 : {
1456 93481760 : unsigned int i = *i_p;
1457 93481760 : op = &(*ops)[i];
1458 93481760 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1459 93481760 : gimple *def_stmt;
1460 93481760 : enum tree_code code;
1461 93481760 : poly_offset_int off;
1462 :
1463 93481760 : def_stmt = SSA_NAME_DEF_STMT (op->op0);
1464 93481760 : if (!is_gimple_assign (def_stmt))
1465 86042302 : return changed;
1466 :
1467 37831155 : code = gimple_assign_rhs_code (def_stmt);
1468 37831155 : if (code != ADDR_EXPR
1469 37831155 : && code != POINTER_PLUS_EXPR)
1470 : return changed;
1471 :
1472 20111511 : off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);
1473 :
1474 : /* The only thing we have to do is from &OBJ.foo.bar add the offset
1475 : from .foo.bar to the preceding MEM_REF offset and replace the
1476 : address with &OBJ. */
1477 20111511 : if (code == ADDR_EXPR)
1478 : {
1479 954224 : tree addr, addr_base;
1480 954224 : poly_int64 addr_offset;
1481 :
1482 954224 : addr = gimple_assign_rhs1 (def_stmt);
1483 954224 : addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (addr, 0),
1484 : &addr_offset,
1485 : vn_valueize);
1486 : /* If that didn't work because the address isn't invariant propagate
1487 : the reference tree from the address operation in case the current
1488 : dereference isn't offsetted. */
1489 954224 : if (!addr_base
1490 286364 : && *i_p == ops->length () - 1
1491 143182 : && known_eq (off, 0)
1492 : /* This makes us disable this transform for PRE where the
1493 : reference ops might be also used for code insertion which
1494 : is invalid. */
1495 1040439 : && default_vn_walk_kind == VN_WALKREWRITE)
1496 : {
1497 86125 : auto_vec<vn_reference_op_s, 32> tem;
1498 86125 : copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
1499 : /* Make sure to preserve TBAA info. The only objects not
1500 : wrapped in MEM_REFs that can have their address taken are
1501 : STRING_CSTs. */
1502 86125 : if (tem.length () >= 2
1503 86125 : && tem[tem.length () - 2].opcode == MEM_REF)
1504 : {
1505 86110 : vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
1506 86110 : new_mem_op->op0
1507 86110 : = wide_int_to_tree (TREE_TYPE (mem_op->op0),
1508 172220 : wi::to_poly_wide (new_mem_op->op0));
1509 : }
1510 : /* Do not forward addresses of TARGET_MEM_REF. */
1511 15 : else if (tem[0].opcode == TARGET_MEM_REF)
1512 : return changed;
1513 : else
1514 15 : gcc_assert (tem.last ().opcode == STRING_CST);
1515 86125 : ops->pop ();
1516 86125 : ops->pop ();
1517 86125 : ops->safe_splice (tem);
1518 86125 : --*i_p;
1519 86125 : return true;
1520 86125 : }
1521 868099 : if (!addr_base
1522 811042 : || TREE_CODE (addr_base) != MEM_REF
1523 1677332 : || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
1524 807372 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
1525 : 0))))
1526 : return changed;
1527 :
1528 809233 : off += addr_offset;
1529 809233 : off += mem_ref_offset (addr_base);
1530 809233 : op->op0 = TREE_OPERAND (addr_base, 0);
1531 : }
1532 : else
1533 : {
1534 19157287 : tree ptr, ptroff;
1535 19157287 : ptr = gimple_assign_rhs1 (def_stmt);
1536 19157287 : ptroff = gimple_assign_rhs2 (def_stmt);
1537 19157287 : if (TREE_CODE (ptr) != SSA_NAME
1538 17448801 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
1539 : /* Make sure to not endlessly recurse.
1540 : See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily
1541 : happen when we value-number a PHI to its backedge value. */
1542 17447404 : || SSA_VAL (ptr) == op->op0
1543 36604691 : || !poly_int_tree_p (ptroff))
1544 12527062 : return changed;
1545 :
1546 6630225 : off += wi::to_poly_offset (ptroff);
1547 6630225 : op->op0 = ptr;
1548 : }
1549 :
1550 7439458 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1551 7439458 : if (tree_fits_shwi_p (mem_op->op0))
1552 7129174 : mem_op->off = tree_to_shwi (mem_op->op0);
1553 : else
1554 310284 : mem_op->off = -1;
1555 : /* ??? Can end up with endless recursion here!?
1556 : gcc.c-torture/execute/strcmp-1.c */
1557 7439458 : if (TREE_CODE (op->op0) == SSA_NAME)
1558 7437597 : op->op0 = SSA_VAL (op->op0);
1559 7439458 : if (TREE_CODE (op->op0) != SSA_NAME)
1560 1951 : op->opcode = TREE_CODE (op->op0);
1561 :
1562 7439458 : changed = true;
1563 : }
1564 : /* Tail-recurse. */
1565 7439458 : while (TREE_CODE (op->op0) == SSA_NAME);
1566 :
1567 : /* Fold a remaining *&. */
1568 1951 : if (TREE_CODE (op->op0) == ADDR_EXPR)
1569 261 : vn_reference_fold_indirect (ops, i_p);
1570 :
1571 : return changed;
1572 : }
1573 :
1574 : /* Optimize the reference REF to a constant if possible or return
1575 : NULL_TREE if not. */
1576 :
1577 : tree
1578 110854956 : fully_constant_vn_reference_p (vn_reference_t ref)
1579 : {
1580 110854956 : vec<vn_reference_op_s> operands = ref->operands;
1581 110854956 : vn_reference_op_t op;
1582 :
1583 : /* Try to simplify the translated expression if it is
1584 : a call to a builtin function with at most two arguments. */
1585 110854956 : op = &operands[0];
1586 110854956 : if (op->opcode == CALL_EXPR
1587 87893 : && (!op->op0
1588 80373 : || (TREE_CODE (op->op0) == ADDR_EXPR
1589 80373 : && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
1590 80373 : && fndecl_built_in_p (TREE_OPERAND (op->op0, 0),
1591 : BUILT_IN_NORMAL)))
1592 70898 : && operands.length () >= 2
1593 110925822 : && operands.length () <= 3)
1594 : {
1595 33919 : vn_reference_op_t arg0, arg1 = NULL;
1596 33919 : bool anyconst = false;
1597 33919 : arg0 = &operands[1];
1598 33919 : if (operands.length () > 2)
1599 5596 : arg1 = &operands[2];
1600 33919 : if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
1601 33919 : || (arg0->opcode == ADDR_EXPR
1602 13869 : && is_gimple_min_invariant (arg0->op0)))
1603 : anyconst = true;
1604 33919 : if (arg1
1605 33919 : && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
1606 4072 : || (arg1->opcode == ADDR_EXPR
1607 587 : && is_gimple_min_invariant (arg1->op0))))
1608 : anyconst = true;
1609 31808 : if (anyconst)
1610 : {
1611 22419 : combined_fn fn;
1612 22419 : if (op->op0)
1613 21463 : fn = as_combined_fn (DECL_FUNCTION_CODE
1614 21463 : (TREE_OPERAND (op->op0, 0)));
1615 : else
1616 956 : fn = as_combined_fn ((internal_fn) op->clique);
1617 22419 : tree folded;
1618 22419 : if (arg1)
1619 2721 : folded = fold_const_call (fn, ref->type, arg0->op0, arg1->op0);
1620 : else
1621 19698 : folded = fold_const_call (fn, ref->type, arg0->op0);
1622 22419 : if (folded
1623 22419 : && is_gimple_min_invariant (folded))
1624 : return folded;
1625 : }
1626 : }
1627 :
1628 : /* Simplify reads from constants or constant initializers. */
1629 110821037 : else if (BITS_PER_UNIT == 8
1630 110821037 : && ref->type
1631 110821037 : && COMPLETE_TYPE_P (ref->type)
1632 221642032 : && is_gimple_reg_type (ref->type))
1633 : {
1634 106453786 : poly_int64 off = 0;
1635 106453786 : HOST_WIDE_INT size;
1636 106453786 : if (INTEGRAL_TYPE_P (ref->type))
1637 54122097 : size = TYPE_PRECISION (ref->type);
1638 52331689 : else if (tree_fits_shwi_p (TYPE_SIZE (ref->type)))
1639 52331689 : size = tree_to_shwi (TYPE_SIZE (ref->type));
1640 : else
1641 110854956 : return NULL_TREE;
1642 106453786 : if (size % BITS_PER_UNIT != 0
1643 104653712 : || size > MAX_BITSIZE_MODE_ANY_MODE)
1644 : return NULL_TREE;
1645 104652385 : size /= BITS_PER_UNIT;
1646 104652385 : unsigned i;
1647 193561040 : for (i = 0; i < operands.length (); ++i)
1648 : {
1649 193561040 : if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant)
1650 : {
1651 309 : ++i;
1652 309 : break;
1653 : }
1654 193560731 : if (operands[i].reverse)
1655 : return NULL_TREE;
1656 193552373 : if (known_eq (operands[i].off, -1))
1657 : return NULL_TREE;
1658 179683426 : off += operands[i].off;
1659 179683426 : if (operands[i].opcode == MEM_REF)
1660 : {
1661 90774771 : ++i;
1662 90774771 : break;
1663 : }
1664 : }
1665 90775080 : vn_reference_op_t base = &operands[--i];
1666 90775080 : tree ctor = error_mark_node;
1667 90775080 : tree decl = NULL_TREE;
1668 90775080 : if (TREE_CODE_CLASS (base->opcode) == tcc_constant)
1669 309 : ctor = base->op0;
1670 90774771 : else if (base->opcode == MEM_REF
1671 90774771 : && base[1].opcode == ADDR_EXPR
1672 149258613 : && (VAR_P (TREE_OPERAND (base[1].op0, 0))
1673 3586035 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL
1674 3585975 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST))
1675 : {
1676 54903820 : decl = TREE_OPERAND (base[1].op0, 0);
1677 54903820 : if (TREE_CODE (decl) == STRING_CST)
1678 : ctor = decl;
1679 : else
1680 54897867 : ctor = ctor_for_folding (decl);
1681 : }
1682 90769127 : if (ctor == NULL_TREE)
1683 386 : return build_zero_cst (ref->type);
1684 90774694 : else if (ctor != error_mark_node)
1685 : {
1686 100853 : HOST_WIDE_INT const_off;
1687 100853 : if (decl)
1688 : {
1689 201088 : tree res = fold_ctor_reference (ref->type, ctor,
1690 100544 : off * BITS_PER_UNIT,
1691 100544 : size * BITS_PER_UNIT, decl);
1692 100544 : if (res)
1693 : {
1694 58828 : STRIP_USELESS_TYPE_CONVERSION (res);
1695 58828 : if (is_gimple_min_invariant (res))
1696 110854956 : return res;
1697 : }
1698 : }
1699 309 : else if (off.is_constant (&const_off))
1700 : {
1701 309 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
1702 309 : int len = native_encode_expr (ctor, buf, size, const_off);
1703 309 : if (len > 0)
1704 139 : return native_interpret_expr (ref->type, buf, len);
1705 : }
1706 : }
1707 : }
1708 :
1709 : return NULL_TREE;
1710 : }
1711 :
1712 : /* Return true if OPS contain a storage order barrier. */
1713 :
1714 : static bool
1715 59851808 : contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
1716 : {
1717 59851808 : vn_reference_op_t op;
1718 59851808 : unsigned i;
1719 :
1720 234372430 : FOR_EACH_VEC_ELT (ops, i, op)
1721 174520622 : if (op->opcode == VIEW_CONVERT_EXPR && op->reverse)
1722 : return true;
1723 :
1724 : return false;
1725 : }
1726 :
1727 : /* Return true if OPS represent an access with reverse storage order. */
1728 :
1729 : static bool
1730 59860076 : reverse_storage_order_for_component_p (vec<vn_reference_op_s> ops)
1731 : {
1732 59860076 : unsigned i = 0;
1733 59860076 : if (ops[i].opcode == REALPART_EXPR || ops[i].opcode == IMAGPART_EXPR)
1734 : ++i;
1735 59860076 : switch (ops[i].opcode)
1736 : {
1737 57782274 : case ARRAY_REF:
1738 57782274 : case COMPONENT_REF:
1739 57782274 : case BIT_FIELD_REF:
1740 57782274 : case MEM_REF:
1741 57782274 : return ops[i].reverse;
1742 : default:
1743 : return false;
1744 : }
1745 : }
1746 :
1747 : /* Transform any SSA_NAME's in a vector of vn_reference_op_s
1748 : structures into their value numbers. This is done in-place, and
1749 : the vector passed in is returned. *VALUEIZED_ANYTHING will specify
1750 : whether any operands were valueized. */
1751 :
1752 : static void
1753 221512080 : valueize_refs_1 (vec<vn_reference_op_s> *orig, bool *valueized_anything,
1754 : bool with_avail = false)
1755 : {
1756 221512080 : *valueized_anything = false;
1757 :
1758 893684529 : for (unsigned i = 0; i < orig->length (); ++i)
1759 : {
1760 672172449 : re_valueize:
1761 676112249 : vn_reference_op_t vro = &(*orig)[i];
1762 676112249 : if (vro->opcode == SSA_NAME
1763 578123845 : || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
1764 : {
1765 122693181 : tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0);
1766 122693181 : if (tem != vro->op0)
1767 : {
1768 18327008 : *valueized_anything = true;
1769 18327008 : vro->op0 = tem;
1770 : }
1771 : /* If it transforms from an SSA_NAME to a constant, update
1772 : the opcode. */
1773 122693181 : if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
1774 2148309 : vro->opcode = TREE_CODE (vro->op0);
1775 : }
1776 676112249 : if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
1777 : {
1778 26286 : tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1);
1779 26286 : if (tem != vro->op1)
1780 : {
1781 609 : *valueized_anything = true;
1782 609 : vro->op1 = tem;
1783 : }
1784 : }
1785 676112249 : if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
1786 : {
1787 205472 : tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2);
1788 205472 : if (tem != vro->op2)
1789 : {
1790 119592 : *valueized_anything = true;
1791 119592 : vro->op2 = tem;
1792 : }
1793 : }
1794 : /* If it transforms from an SSA_NAME to an address, fold with
1795 : a preceding indirect reference. */
1796 676112249 : if (i > 0
1797 454520598 : && vro->op0
1798 451015434 : && TREE_CODE (vro->op0) == ADDR_EXPR
1799 810366409 : && (*orig)[i - 1].opcode == MEM_REF)
1800 : {
1801 128325013 : if (vn_reference_fold_indirect (orig, &i))
1802 679631 : *valueized_anything = true;
1803 : }
1804 547787236 : else if (i > 0
1805 326195585 : && vro->opcode == SSA_NAME
1806 643627331 : && (*orig)[i - 1].opcode == MEM_REF)
1807 : {
1808 86044253 : if (vn_reference_maybe_forwprop_address (orig, &i))
1809 : {
1810 3939800 : *valueized_anything = true;
1811 : /* Re-valueize the current operand. */
1812 3939800 : goto re_valueize;
1813 : }
1814 : }
1815 : /* If it transforms a non-constant ARRAY_REF into a constant
1816 : one, adjust the constant offset. */
1817 461742983 : else if ((vro->opcode == ARRAY_REF
1818 461742983 : || vro->opcode == ARRAY_RANGE_REF)
1819 40100903 : && known_eq (vro->off, -1)
1820 17451778 : && poly_int_tree_p (vro->op0)
1821 5012647 : && poly_int_tree_p (vro->op1)
1822 466755630 : && TREE_CODE (vro->op2) == INTEGER_CST)
1823 : {
1824 : /* Prohibit value-numbering addresses of one-after-the-last
1825 : element ARRAY_REFs the same as addresses of other components
1826 : before the pass folding __builtin_object_size had a chance
1827 : to run. */
1828 4878936 : if (!(cfun->curr_properties & PROP_objsz)
1829 6132384 : && (*orig)[0].opcode == ADDR_EXPR)
1830 : {
1831 35717 : tree dom = TYPE_DOMAIN ((*orig)[i + 1].type);
1832 54297 : if (!dom
1833 35567 : || !TYPE_MAX_VALUE (dom)
1834 25587 : || !poly_int_tree_p (TYPE_MAX_VALUE (dom))
1835 52930 : || integer_minus_onep (TYPE_MAX_VALUE (dom)))
1836 19387 : continue;
1837 17137 : if (!known_le (wi::to_poly_offset (vro->op0),
1838 : wi::to_poly_offset (TYPE_MAX_VALUE (dom))))
1839 807 : continue;
1840 : }
1841 :
1842 9719098 : poly_offset_int off = ((wi::to_poly_offset (vro->op0)
1843 14578647 : - wi::to_poly_offset (vro->op1))
1844 9719098 : * wi::to_offset (vro->op2)
1845 4859549 : * vn_ref_op_align_unit (vro));
1846 4859549 : off.to_shwi (&vro->off);
1847 : }
1848 : }
1849 221512080 : }
1850 :
1851 : static void
1852 12724500 : valueize_refs (vec<vn_reference_op_s> *orig)
1853 : {
1854 12724500 : bool tem;
1855 0 : valueize_refs_1 (orig, &tem);
1856 0 : }
1857 :
1858 : static vec<vn_reference_op_s> shared_lookup_references;
1859 :
1860 : /* Create a vector of vn_reference_op_s structures from REF, a
1861 : REFERENCE_CLASS_P tree. The vector is shared among all callers of
1862 : this function. *VALUEIZED_ANYTHING will specify whether any
1863 : operands were valueized. */
1864 :
1865 : static vec<vn_reference_op_s>
1866 182477210 : valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
1867 : {
1868 182477210 : if (!ref)
1869 0 : return vNULL;
1870 182477210 : shared_lookup_references.truncate (0);
1871 182477210 : copy_reference_ops_from_ref (ref, &shared_lookup_references);
1872 182477210 : valueize_refs_1 (&shared_lookup_references, valueized_anything);
1873 182477210 : return shared_lookup_references;
1874 : }
1875 :
1876 : /* Create a vector of vn_reference_op_s structures from CALL, a
1877 : call statement. The vector is shared among all callers of
1878 : this function. */
1879 :
1880 : static vec<vn_reference_op_s>
1881 9233573 : valueize_shared_reference_ops_from_call (gcall *call)
1882 : {
1883 9233573 : if (!call)
1884 0 : return vNULL;
1885 9233573 : shared_lookup_references.truncate (0);
1886 9233573 : copy_reference_ops_from_call (call, &shared_lookup_references);
1887 9233573 : valueize_refs (&shared_lookup_references);
1888 9233573 : return shared_lookup_references;
1889 : }
1890 :
1891 : /* Lookup a SCCVN reference operation VR in the current hash table.
1892 : Returns the resulting value number if it exists in the hash table,
1893 : NULL_TREE otherwise. VNRESULT will be filled in with the actual
1894 : vn_reference_t stored in the hashtable if something is found. */
1895 :
1896 : static tree
1897 66057819 : vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
1898 : {
1899 66057819 : vn_reference_s **slot;
1900 66057819 : hashval_t hash;
1901 :
1902 66057819 : hash = vr->hashcode;
1903 66057819 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
1904 66057819 : if (slot)
1905 : {
1906 8212642 : if (vnresult)
1907 8212642 : *vnresult = (vn_reference_t)*slot;
1908 8212642 : return ((vn_reference_t)*slot)->result;
1909 : }
1910 :
1911 : return NULL_TREE;
1912 : }
1913 :
1914 :
1915 : /* Partial definition tracking support. */
1916 :
1917 : struct pd_range
1918 : {
1919 : HOST_WIDE_INT offset;
1920 : HOST_WIDE_INT size;
1921 : pd_range *m_children[2];
1922 : };
1923 :
1924 : struct pd_data
1925 : {
1926 : tree rhs;
1927 : HOST_WIDE_INT rhs_off;
1928 : HOST_WIDE_INT offset;
1929 : HOST_WIDE_INT size;
1930 : };
1931 :
1932 : /* Context for alias walking. */
1933 :
1934 : struct vn_walk_cb_data
1935 : {
1936 61872751 : vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
1937 : vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_,
1938 : bool redundant_store_removal_p_)
1939 61872751 : : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
1940 61872751 : mask (mask_), masked_result (NULL_TREE), same_val (NULL_TREE),
1941 61872751 : vn_walk_kind (vn_walk_kind_),
1942 61872751 : tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_),
1943 123745502 : saved_operands (vNULL), first_range (), first_set (-2),
1944 123745502 : first_base_set (-2)
1945 : {
1946 61872751 : if (!last_vuse_ptr)
1947 28720942 : last_vuse_ptr = &last_vuse;
1948 61872751 : ao_ref_init (&orig_ref, orig_ref_);
1949 61872751 : if (mask)
1950 : {
1951 304163 : wide_int w = wi::to_wide (mask);
1952 304163 : unsigned int pos = 0, prec = w.get_precision ();
1953 304163 : pd_data pd;
1954 304163 : pd.rhs = build_constructor (NULL_TREE, NULL);
1955 304163 : pd.rhs_off = 0;
1956 : /* When bitwise and with a constant is done on a memory load,
1957 : we don't really need all the bits to be defined or defined
1958 : to constants, we don't really care what is in the position
1959 : corresponding to 0 bits in the mask.
1960 : So, push the ranges of those 0 bits in the mask as artificial
1961 : zero stores and let the partial def handling code do the
1962 : rest. */
1963 652178 : while (pos < prec)
1964 : {
1965 631700 : int tz = wi::ctz (w);
1966 631700 : if (pos + tz > prec)
1967 283685 : tz = prec - pos;
1968 631700 : if (tz)
1969 : {
1970 479081 : if (BYTES_BIG_ENDIAN)
1971 : pd.offset = prec - pos - tz;
1972 : else
1973 479081 : pd.offset = pos;
1974 479081 : pd.size = tz;
1975 479081 : void *r = push_partial_def (pd, 0, 0, 0, prec);
1976 479081 : gcc_assert (r == NULL_TREE);
1977 : }
1978 631700 : pos += tz;
1979 631700 : if (pos == prec)
1980 : break;
1981 348015 : w = wi::lrshift (w, tz);
1982 348015 : tz = wi::ctz (wi::bit_not (w));
1983 348015 : if (pos + tz > prec)
1984 0 : tz = prec - pos;
1985 348015 : pos += tz;
1986 348015 : w = wi::lrshift (w, tz);
1987 : }
1988 304163 : }
1989 61872751 : }
1990 : ~vn_walk_cb_data ();
1991 : void *finish (alias_set_type, alias_set_type, tree);
1992 : void *push_partial_def (pd_data pd,
1993 : alias_set_type, alias_set_type, HOST_WIDE_INT,
1994 : HOST_WIDE_INT);
1995 :
1996 : vn_reference_t vr;
1997 : ao_ref orig_ref;
1998 : tree *last_vuse_ptr;
1999 : tree last_vuse;
2000 : tree mask;
2001 : tree masked_result;
2002 : tree same_val;
2003 : vn_lookup_kind vn_walk_kind;
2004 : bool tbaa_p;
2005 : bool redundant_store_removal_p;
2006 : vec<vn_reference_op_s> saved_operands;
2007 :
2008 : /* The VDEFs of partial defs we come along. */
2009 : auto_vec<pd_data, 2> partial_defs;
2010 : /* The first defs range to avoid splay tree setup in most cases. */
2011 : pd_range first_range;
2012 : alias_set_type first_set;
2013 : alias_set_type first_base_set;
2014 : default_splay_tree<pd_range *> known_ranges;
2015 : obstack ranges_obstack;
2016 : static constexpr HOST_WIDE_INT bufsize = 64;
2017 : };
2018 :
2019 61872751 : vn_walk_cb_data::~vn_walk_cb_data ()
2020 : {
2021 61872751 : if (known_ranges)
2022 170507 : obstack_free (&ranges_obstack, NULL);
2023 61872751 : saved_operands.release ();
2024 61872751 : }
2025 :
2026 : void *
2027 1569751 : vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
2028 : {
2029 1569751 : if (first_set != -2)
2030 : {
2031 444648 : set = first_set;
2032 444648 : base_set = first_base_set;
2033 : }
2034 1569751 : if (mask)
2035 : {
2036 459 : masked_result = val;
2037 459 : return (void *) -1;
2038 : }
2039 1569292 : if (same_val && !operand_equal_p (val, same_val))
2040 : return (void *) -1;
2041 1565510 : vec<vn_reference_op_s> &operands
2042 1565510 : = saved_operands.exists () ? saved_operands : vr->operands;
2043 1565510 : return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
2044 : vr->offset, vr->max_size,
2045 1565510 : vr->type, operands, val);
2046 : }
2047 :
2048 : /* Push PD to the vector of partial definitions returning a
2049 : value when we are ready to combine things with VUSE, SET and MAXSIZEI,
2050 : NULL when we want to continue looking for partial defs or -1
2051 : on failure. */
2052 :
2053 : void *
2054 563469 : vn_walk_cb_data::push_partial_def (pd_data pd,
2055 : alias_set_type set, alias_set_type base_set,
2056 : HOST_WIDE_INT offseti,
2057 : HOST_WIDE_INT maxsizei)
2058 : {
2059 : /* We're using a fixed buffer for encoding so fail early if the object
2060 : we want to interpret is bigger. */
2061 563469 : if (maxsizei > bufsize * BITS_PER_UNIT
2062 : || CHAR_BIT != 8
2063 : || BITS_PER_UNIT != 8
2064 : /* Not prepared to handle PDP endian. */
2065 : || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2066 : return (void *)-1;
2067 :
2068 : /* Turn too large constant stores into non-constant stores. */
2069 563394 : if (CONSTANT_CLASS_P (pd.rhs) && pd.size > bufsize * BITS_PER_UNIT)
2070 0 : pd.rhs = error_mark_node;
2071 :
2072 : /* And for non-constant or CONSTRUCTOR stores shrink them to only keep at
2073 : most a partial byte before and/or after the region. */
2074 563394 : if (!CONSTANT_CLASS_P (pd.rhs))
2075 : {
2076 522887 : if (pd.offset < offseti)
2077 : {
2078 8652 : HOST_WIDE_INT o = ROUND_DOWN (offseti - pd.offset, BITS_PER_UNIT);
2079 8652 : gcc_assert (pd.size > o);
2080 8652 : pd.size -= o;
2081 8652 : pd.offset += o;
2082 : }
2083 522887 : if (pd.size > maxsizei)
2084 7757 : pd.size = maxsizei + ((pd.size - maxsizei) % BITS_PER_UNIT);
2085 : }
2086 :
2087 563394 : pd.offset -= offseti;
2088 :
2089 1126788 : bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
2090 563394 : || CONSTANT_CLASS_P (pd.rhs));
2091 563394 : pd_range *r;
2092 563394 : if (partial_defs.is_empty ())
2093 : {
2094 : /* If we get a clobber upfront, fail. */
2095 361341 : if (TREE_CLOBBER_P (pd.rhs))
2096 : return (void *)-1;
2097 360986 : if (!pd_constant_p)
2098 : return (void *)-1;
2099 328344 : partial_defs.safe_push (pd);
2100 328344 : first_range.offset = pd.offset;
2101 328344 : first_range.size = pd.size;
2102 328344 : first_set = set;
2103 328344 : first_base_set = base_set;
2104 328344 : last_vuse_ptr = NULL;
2105 328344 : r = &first_range;
2106 : /* Go check if the first partial definition was a full one in case
2107 : the caller didn't optimize for this. */
2108 : }
2109 : else
2110 : {
2111 202053 : if (!known_ranges)
2112 : {
2113 : /* ??? Optimize the case where the 2nd partial def completes
2114 : things. */
2115 170507 : gcc_obstack_init (&ranges_obstack);
2116 170507 : known_ranges.insert_max_node (&first_range);
2117 : }
2118 : /* Lookup the offset and see if we need to merge. */
2119 202053 : int comparison = known_ranges.lookup_le
2120 408406 : ([&] (pd_range *r) { return pd.offset < r->offset; },
2121 181254 : [&] (pd_range *r) { return pd.offset > r->offset; });
2122 202053 : r = known_ranges.root ();
2123 202053 : if (comparison >= 0
2124 202053 : && ranges_known_overlap_p (r->offset, r->size + 1,
2125 : pd.offset, pd.size))
2126 : {
2127 : /* Ignore partial defs already covered. Here we also drop shadowed
2128 : clobbers arriving here at the floor. */
2129 5906 : if (known_subrange_p (pd.offset, pd.size, r->offset, r->size))
2130 : return NULL;
2131 5006 : r->size = MAX (r->offset + r->size, pd.offset + pd.size) - r->offset;
2132 : }
2133 : else
2134 : {
2135 : /* pd.offset wasn't covered yet, insert the range. */
2136 196147 : void *addr = XOBNEW (&ranges_obstack, pd_range);
2137 196147 : r = new (addr) pd_range { pd.offset, pd.size, {} };
2138 196147 : known_ranges.insert_relative (comparison, r);
2139 : }
2140 : /* Merge r which now contains pd's range and is a member of the splay
2141 : tree with adjacent overlapping ranges. */
2142 201153 : if (known_ranges.splay_next_node ())
2143 22906 : do
2144 : {
2145 22906 : pd_range *rafter = known_ranges.root ();
2146 22906 : if (!ranges_known_overlap_p (r->offset, r->size + 1,
2147 22906 : rafter->offset, rafter->size))
2148 : break;
2149 22636 : r->size = MAX (r->offset + r->size,
2150 22636 : rafter->offset + rafter->size) - r->offset;
2151 : }
2152 22636 : while (known_ranges.remove_root_and_splay_next ());
2153 : /* If we get a clobber, fail. */
2154 201153 : if (TREE_CLOBBER_P (pd.rhs))
2155 : return (void *)-1;
2156 : /* Non-constants are OK as long as they are shadowed by a constant. */
2157 198960 : if (!pd_constant_p)
2158 : return (void *)-1;
2159 192532 : partial_defs.safe_push (pd);
2160 : }
2161 :
2162 : /* Now we have merged pd's range into the range tree. When we have covered
2163 : [offseti, sizei] then the tree will contain exactly one node which has
2164 : the desired properties and it will be 'r'. */
2165 520876 : if (!known_subrange_p (0, maxsizei, r->offset, r->size))
2166 : /* Continue looking for partial defs. */
2167 : return NULL;
2168 :
2169 : /* Now simply native encode all partial defs in reverse order. */
2170 8927 : unsigned ndefs = partial_defs.length ();
2171 : /* We support up to 512-bit values (for V8DFmode). */
2172 8927 : unsigned char buffer[bufsize + 1];
2173 8927 : unsigned char this_buffer[bufsize + 1];
2174 8927 : int len;
2175 :
2176 8927 : memset (buffer, 0, bufsize + 1);
2177 8927 : unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
2178 43909 : while (!partial_defs.is_empty ())
2179 : {
2180 26055 : pd_data pd = partial_defs.pop ();
2181 26055 : unsigned int amnt;
2182 26055 : if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
2183 : {
2184 : /* Empty CONSTRUCTOR. */
2185 2204 : if (pd.size >= needed_len * BITS_PER_UNIT)
2186 2204 : len = needed_len;
2187 : else
2188 1843 : len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
2189 2204 : memset (this_buffer, 0, len);
2190 : }
2191 23851 : else if (pd.rhs_off >= 0)
2192 : {
2193 47702 : len = native_encode_expr (pd.rhs, this_buffer, bufsize,
2194 23851 : (MAX (0, -pd.offset)
2195 23851 : + pd.rhs_off) / BITS_PER_UNIT);
2196 23851 : if (len <= 0
2197 23851 : || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
2198 23851 : - MAX (0, -pd.offset) / BITS_PER_UNIT))
2199 : {
2200 0 : if (dump_file && (dump_flags & TDF_DETAILS))
2201 0 : fprintf (dump_file, "Failed to encode %u "
2202 : "partial definitions\n", ndefs);
2203 0 : return (void *)-1;
2204 : }
2205 : }
2206 : else /* negative pd.rhs_off indicates we want to chop off first bits */
2207 : {
2208 0 : if (-pd.rhs_off >= bufsize)
2209 : return (void *)-1;
2210 0 : len = native_encode_expr (pd.rhs,
2211 0 : this_buffer + -pd.rhs_off / BITS_PER_UNIT,
2212 0 : bufsize - -pd.rhs_off / BITS_PER_UNIT,
2213 0 : MAX (0, -pd.offset) / BITS_PER_UNIT);
2214 0 : if (len <= 0
2215 0 : || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
2216 0 : - MAX (0, -pd.offset) / BITS_PER_UNIT))
2217 : {
2218 0 : if (dump_file && (dump_flags & TDF_DETAILS))
2219 0 : fprintf (dump_file, "Failed to encode %u "
2220 : "partial definitions\n", ndefs);
2221 0 : return (void *)-1;
2222 : }
2223 : }
2224 :
2225 26055 : unsigned char *p = buffer;
2226 26055 : HOST_WIDE_INT size = pd.size;
2227 26055 : if (pd.offset < 0)
2228 314 : size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
2229 26055 : this_buffer[len] = 0;
2230 26055 : if (BYTES_BIG_ENDIAN)
2231 : {
2232 : /* LSB of this_buffer[len - 1] byte should be at
2233 : pd.offset + pd.size - 1 bits in buffer. */
2234 : amnt = ((unsigned HOST_WIDE_INT) pd.offset
2235 : + pd.size) % BITS_PER_UNIT;
2236 : if (amnt)
2237 : shift_bytes_in_array_right (this_buffer, len + 1, amnt);
2238 : unsigned char *q = this_buffer;
2239 : unsigned int off = 0;
2240 : if (pd.offset >= 0)
2241 : {
2242 : unsigned int msk;
2243 : off = pd.offset / BITS_PER_UNIT;
2244 : gcc_assert (off < needed_len);
2245 : p = buffer + off;
2246 : if (size <= amnt)
2247 : {
2248 : msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
2249 : *p = (*p & ~msk) | (this_buffer[len] & msk);
2250 : size = 0;
2251 : }
2252 : else
2253 : {
2254 : if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2255 : q = (this_buffer + len
2256 : - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2257 : / BITS_PER_UNIT));
2258 : if (pd.offset % BITS_PER_UNIT)
2259 : {
2260 : msk = -1U << (BITS_PER_UNIT
2261 : - (pd.offset % BITS_PER_UNIT));
2262 : *p = (*p & msk) | (*q & ~msk);
2263 : p++;
2264 : q++;
2265 : off++;
2266 : size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
2267 : gcc_assert (size >= 0);
2268 : }
2269 : }
2270 : }
2271 : else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2272 : {
2273 : q = (this_buffer + len
2274 : - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2275 : / BITS_PER_UNIT));
2276 : if (pd.offset % BITS_PER_UNIT)
2277 : {
2278 : q++;
2279 : size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
2280 : % BITS_PER_UNIT);
2281 : gcc_assert (size >= 0);
2282 : }
2283 : }
2284 : if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
2285 : > needed_len)
2286 : size = (needed_len - off) * BITS_PER_UNIT;
2287 : memcpy (p, q, size / BITS_PER_UNIT);
2288 : if (size % BITS_PER_UNIT)
2289 : {
2290 : unsigned int msk
2291 : = -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
2292 : p += size / BITS_PER_UNIT;
2293 : q += size / BITS_PER_UNIT;
2294 : *p = (*q & msk) | (*p & ~msk);
2295 : }
2296 : }
2297 : else
2298 : {
2299 26055 : if (pd.offset >= 0)
2300 : {
2301 : /* LSB of this_buffer[0] byte should be at pd.offset bits
2302 : in buffer. */
2303 25741 : unsigned int msk;
2304 25741 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2305 25741 : amnt = pd.offset % BITS_PER_UNIT;
2306 25741 : if (amnt)
2307 1516 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2308 25741 : unsigned int off = pd.offset / BITS_PER_UNIT;
2309 25741 : gcc_assert (off < needed_len);
2310 25741 : size = MIN (size,
2311 : (HOST_WIDE_INT) (needed_len - off) * BITS_PER_UNIT);
2312 25741 : p = buffer + off;
2313 25741 : if (amnt + size < BITS_PER_UNIT)
2314 : {
2315 : /* Low amnt bits come from *p, then size bits
2316 : from this_buffer[0] and the remaining again from
2317 : *p. */
2318 1088 : msk = ((1 << size) - 1) << amnt;
2319 1088 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2320 1088 : size = 0;
2321 : }
2322 24653 : else if (amnt)
2323 : {
2324 1140 : msk = -1U << amnt;
2325 1140 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2326 1140 : p++;
2327 1140 : size -= (BITS_PER_UNIT - amnt);
2328 : }
2329 : }
2330 : else
2331 : {
2332 314 : amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
2333 314 : if (amnt)
2334 16 : size -= BITS_PER_UNIT - amnt;
2335 314 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2336 314 : if (amnt)
2337 16 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2338 : }
2339 26055 : memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
2340 26055 : p += size / BITS_PER_UNIT;
2341 26055 : if (size % BITS_PER_UNIT)
2342 : {
2343 626 : unsigned int msk = -1U << (size % BITS_PER_UNIT);
2344 626 : *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
2345 626 : & ~msk) | (*p & msk);
2346 : }
2347 : }
2348 : }
2349 :
2350 8927 : tree type = vr->type;
2351 : /* Make sure to interpret in a type that has a range covering the whole
2352 : access size. */
2353 8927 : if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
2354 : {
2355 0 : if (BITINT_TYPE_P (vr->type)
2356 26 : && maxsizei > MAX_FIXED_MODE_SIZE)
2357 13 : type = build_bitint_type (maxsizei, TYPE_UNSIGNED (type));
2358 : else
2359 0 : type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
2360 : }
2361 8927 : tree val;
2362 8927 : if (BYTES_BIG_ENDIAN)
2363 : {
2364 : unsigned sz = needed_len;
2365 : if (maxsizei % BITS_PER_UNIT)
2366 : shift_bytes_in_array_right (buffer, needed_len,
2367 : BITS_PER_UNIT
2368 : - (maxsizei % BITS_PER_UNIT));
2369 : if (INTEGRAL_TYPE_P (type))
2370 : {
2371 : if (TYPE_MODE (type) != BLKmode)
2372 : sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
2373 : else
2374 : sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
2375 : }
2376 : if (sz > needed_len)
2377 : {
2378 : memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
2379 : val = native_interpret_expr (type, this_buffer, sz);
2380 : }
2381 : else
2382 : val = native_interpret_expr (type, buffer, needed_len);
2383 : }
2384 : else
2385 8927 : val = native_interpret_expr (type, buffer, bufsize);
2386 : /* If we chop off bits because the types precision doesn't match the memory
2387 : access size this is ok when optimizing reads but not when called from
2388 : the DSE code during elimination. */
2389 8927 : if (val && type != vr->type)
2390 : {
2391 13 : if (! int_fits_type_p (val, vr->type))
2392 : val = NULL_TREE;
2393 : else
2394 13 : val = fold_convert (vr->type, val);
2395 : }
2396 :
2397 8923 : if (val)
2398 : {
2399 8923 : if (dump_file && (dump_flags & TDF_DETAILS))
2400 0 : fprintf (dump_file,
2401 : "Successfully combined %u partial definitions\n", ndefs);
2402 : /* We are using the alias-set of the first store we encounter which
2403 : should be appropriate here. */
2404 8923 : return finish (first_set, first_base_set, val);
2405 : }
2406 : else
2407 : {
2408 4 : if (dump_file && (dump_flags & TDF_DETAILS))
2409 0 : fprintf (dump_file,
2410 : "Failed to interpret %u encoded partial definitions\n", ndefs);
2411 4 : return (void *)-1;
2412 : }
2413 : }
2414 :
2415 : /* Callback for walk_non_aliased_vuses. Adjusts the vn_reference_t VR_
2416 : with the current VUSE and performs the expression lookup. */
2417 :
2418 : static void *
2419 1095720516 : vn_reference_lookup_2 (ao_ref *op, tree vuse, void *data_)
2420 : {
2421 1095720516 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2422 1095720516 : vn_reference_t vr = data->vr;
2423 1095720516 : vn_reference_s **slot;
2424 1095720516 : hashval_t hash;
2425 :
2426 : /* If we have partial definitions recorded we have to go through
2427 : vn_reference_lookup_3. */
2428 2183471580 : if (!data->partial_defs.is_empty ())
2429 : return NULL;
2430 :
2431 1094932117 : if (data->last_vuse_ptr)
2432 : {
2433 1073634570 : *data->last_vuse_ptr = vuse;
2434 1073634570 : data->last_vuse = vuse;
2435 : }
2436 :
2437 : /* Fixup vuse and hash. */
2438 1094932117 : if (vr->vuse)
2439 1094932117 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2440 1094932117 : vr->vuse = vuse_ssa_val (vuse);
2441 1094932117 : if (vr->vuse)
2442 1094932117 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2443 :
2444 1094932117 : hash = vr->hashcode;
2445 1094932117 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
2446 1094932117 : if (slot)
2447 : {
2448 7968276 : if ((*slot)->result && data->saved_operands.exists ())
2449 429891 : return data->finish (vr->set, vr->base_set, (*slot)->result);
2450 : return *slot;
2451 : }
2452 :
2453 1086963841 : if (SSA_NAME_IS_DEFAULT_DEF (vuse))
2454 : {
2455 18365428 : HOST_WIDE_INT op_offset, op_size;
2456 18365428 : tree v = NULL_TREE;
2457 18365428 : tree base = ao_ref_base (op);
2458 :
2459 18365428 : if (base
2460 18365428 : && op->offset.is_constant (&op_offset)
2461 18365428 : && op->size.is_constant (&op_size)
2462 18365428 : && op->max_size_known_p ()
2463 36276171 : && known_eq (op->size, op->max_size))
2464 : {
2465 17608808 : if (TREE_CODE (base) == PARM_DECL)
2466 677834 : v = ipcp_get_aggregate_const (cfun, base, false, op_offset,
2467 : op_size);
2468 16930974 : else if (TREE_CODE (base) == MEM_REF
2469 7018117 : && integer_zerop (TREE_OPERAND (base, 1))
2470 5643233 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
2471 5638028 : && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0))
2472 20680351 : && (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (base, 0)))
2473 : == PARM_DECL))
2474 3697313 : v = ipcp_get_aggregate_const (cfun,
2475 3697313 : SSA_NAME_VAR (TREE_OPERAND (base, 0)),
2476 : true, op_offset, op_size);
2477 : }
2478 4375147 : if (v)
2479 1176 : return data->finish (vr->set, vr->base_set, v);
2480 : }
2481 :
2482 : return NULL;
2483 : }
2484 :
2485 : /* Lookup an existing or insert a new vn_reference entry into the
2486 : value table for the VUSE, SET, TYPE, OPERANDS reference which
2487 : has the value VALUE which is either a constant or an SSA name. */
2488 :
2489 : static vn_reference_t
2490 1565510 : vn_reference_lookup_or_insert_for_pieces (tree vuse,
2491 : alias_set_type set,
2492 : alias_set_type base_set,
2493 : poly_int64 offset,
2494 : poly_int64 max_size,
2495 : tree type,
2496 : vec<vn_reference_op_s,
2497 : va_heap> operands,
2498 : tree value)
2499 : {
2500 1565510 : vn_reference_s vr1;
2501 1565510 : vn_reference_t result;
2502 1565510 : unsigned value_id;
2503 1565510 : vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
2504 1565510 : vr1.operands = operands;
2505 1565510 : vr1.type = type;
2506 1565510 : vr1.set = set;
2507 1565510 : vr1.base_set = base_set;
2508 1565510 : vr1.offset = offset;
2509 1565510 : vr1.max_size = max_size;
2510 1565510 : vr1.hashcode = vn_reference_compute_hash (&vr1);
2511 1565510 : if (vn_reference_lookup_1 (&vr1, &result))
2512 8344 : return result;
2513 :
2514 1557166 : if (TREE_CODE (value) == SSA_NAME)
2515 357997 : value_id = VN_INFO (value)->value_id;
2516 : else
2517 1199169 : value_id = get_or_alloc_constant_value_id (value);
2518 1557166 : return vn_reference_insert_pieces (vuse, set, base_set, offset, max_size,
2519 1557166 : type, operands.copy (), value, value_id);
2520 : }
2521 :
2522 : /* Return a value-number for RCODE OPS... either by looking up an existing
2523 : value-number for the possibly simplified result or by inserting the
2524 : operation if INSERT is true. If SIMPLIFY is false, return a value
2525 : number for the unsimplified expression. */
2526 :
2527 : static tree
2528 18896012 : vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
2529 : bool simplify)
2530 : {
2531 18896012 : tree result = NULL_TREE;
2532 : /* We will be creating a value number for
2533 : RCODE (OPS...).
2534 : So first simplify and lookup this expression to see if it
2535 : is already available. */
2536 : /* For simplification valueize. */
2537 18896012 : unsigned i = 0;
2538 18896012 : if (simplify)
2539 43841865 : for (i = 0; i < res_op->num_ops; ++i)
2540 24951534 : if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
2541 : {
2542 16015905 : tree tem = vn_valueize (res_op->ops[i]);
2543 16015905 : if (!tem)
2544 : break;
2545 16015905 : res_op->ops[i] = tem;
2546 : }
2547 : /* If valueization of an operand fails (it is not available), skip
2548 : simplification. */
2549 18896012 : bool res = false;
2550 18896012 : if (i == res_op->num_ops)
2551 : {
2552 : /* Do not leak not available operands into the simplified expression
2553 : when called from PRE context. */
2554 18890331 : if (rpo_avail)
2555 11342913 : mprts_hook = vn_lookup_simplify_result;
2556 18890331 : res = res_op->resimplify (NULL, vn_valueize);
2557 18890331 : mprts_hook = NULL;
2558 : }
2559 32547858 : gimple *new_stmt = NULL;
2560 18890331 : if (res
2561 18890331 : && gimple_simplified_result_is_gimple_val (res_op))
2562 : {
2563 : /* The expression is already available. */
2564 5238485 : result = res_op->ops[0];
2565 : /* Valueize it, simplification returns sth in AVAIL only. */
2566 5238485 : if (TREE_CODE (result) == SSA_NAME)
2567 291219 : result = SSA_VAL (result);
2568 : }
2569 : else
2570 : {
2571 13657527 : tree val = vn_lookup_simplify_result (res_op);
2572 : /* ??? In weird cases we can end up with internal-fn calls,
2573 : but this isn't expected so throw the result away. See
2574 : PR123040 for an example. */
2575 13657527 : if (!val && insert && res_op->code.is_tree_code ())
2576 : {
2577 146610 : gimple_seq stmts = NULL;
2578 146610 : result = maybe_push_res_to_seq (res_op, &stmts);
2579 146610 : if (result)
2580 : {
2581 146604 : gcc_assert (gimple_seq_singleton_p (stmts));
2582 146604 : new_stmt = gimple_seq_first_stmt (stmts);
2583 : }
2584 : }
2585 : else
2586 : /* The expression is already available. */
2587 : result = val;
2588 : }
2589 291225 : if (new_stmt)
2590 : {
2591 : /* The expression is not yet available, value-number lhs to
2592 : the new SSA_NAME we created. */
2593 : /* Initialize value-number information properly. */
2594 146604 : vn_ssa_aux_t result_info = VN_INFO (result);
2595 146604 : result_info->valnum = result;
2596 146604 : result_info->value_id = get_next_value_id ();
2597 146604 : result_info->visited = 1;
2598 146604 : gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
2599 : new_stmt);
2600 146604 : result_info->needs_insertion = true;
2601 : /* ??? PRE phi-translation inserts NARYs without corresponding
2602 : SSA name result. Re-use those but set their result according
2603 : to the stmt we just built. */
2604 146604 : vn_nary_op_t nary = NULL;
2605 146604 : vn_nary_op_lookup_stmt (new_stmt, &nary);
2606 146604 : if (nary)
2607 : {
2608 0 : gcc_assert (! nary->predicated_values && nary->u.result == NULL_TREE);
2609 0 : nary->u.result = gimple_assign_lhs (new_stmt);
2610 : }
2611 : /* As all "inserted" statements are singleton SCCs, insert
2612 : to the valid table. This is strictly needed to
2613 : avoid re-generating new value SSA_NAMEs for the same
2614 : expression during SCC iteration over and over (the
2615 : optimistic table gets cleared after each iteration).
2616 : We do not need to insert into the optimistic table, as
2617 : lookups there will fall back to the valid table. */
2618 : else
2619 : {
2620 146604 : unsigned int length = vn_nary_length_from_stmt (new_stmt);
2621 146604 : vn_nary_op_t vno1
2622 146604 : = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack);
2623 146604 : vno1->value_id = result_info->value_id;
2624 146604 : vno1->length = length;
2625 146604 : vno1->predicated_values = 0;
2626 146604 : vno1->u.result = result;
2627 146604 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (new_stmt));
2628 146604 : vn_nary_op_insert_into (vno1, valid_info->nary);
2629 : /* Also do not link it into the undo chain. */
2630 146604 : last_inserted_nary = vno1->next;
2631 146604 : vno1->next = (vn_nary_op_t)(void *)-1;
2632 : }
2633 146604 : if (dump_file && (dump_flags & TDF_DETAILS))
2634 : {
2635 595 : fprintf (dump_file, "Inserting name ");
2636 595 : print_generic_expr (dump_file, result);
2637 595 : fprintf (dump_file, " for expression ");
2638 595 : print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
2639 595 : fprintf (dump_file, "\n");
2640 : }
2641 : }
2642 18896012 : return result;
2643 : }
2644 :
2645 : /* Return a value-number for RCODE OPS... either by looking up an existing
2646 : value-number for the simplified result or by inserting the operation. */
2647 :
2648 : static tree
2649 193650 : vn_nary_build_or_lookup (gimple_match_op *res_op)
2650 : {
2651 0 : return vn_nary_build_or_lookup_1 (res_op, true, true);
2652 : }
2653 :
2654 : /* Try to simplify the expression RCODE OPS... of type TYPE and return
2655 : its value if present. Update NARY with a simplified expression if
2656 : it fits. */
2657 :
2658 : tree
2659 7544400 : vn_nary_simplify (vn_nary_op_t nary)
2660 : {
2661 7544400 : if (nary->length > gimple_match_op::MAX_NUM_OPS
2662 : /* For CONSTRUCTOR the vn_nary_op_t and gimple_match_op representation
2663 : does not match. */
2664 7543854 : || nary->opcode == CONSTRUCTOR)
2665 : return NULL_TREE;
2666 7541153 : gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
2667 7541153 : nary->type, nary->length);
2668 7541153 : memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
2669 7541153 : tree res = vn_nary_build_or_lookup_1 (&op, false, true);
2670 : /* Do not update *NARY with a simplified result that contains abnormals.
2671 : This matches what maybe_push_res_to_seq does when requesting insertion. */
2672 19789654 : for (unsigned i = 0; i < op.num_ops; ++i)
2673 12248582 : if (TREE_CODE (op.ops[i]) == SSA_NAME
2674 12248582 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op.ops[i]))
2675 : return res;
2676 7541072 : if (op.code.is_tree_code ()
2677 7541072 : && op.num_ops <= nary->length
2678 15081329 : && (tree_code) op.code != CONSTRUCTOR)
2679 : {
2680 7540256 : nary->opcode = (tree_code) op.code;
2681 7540256 : nary->length = op.num_ops;
2682 19787090 : for (unsigned i = 0; i < op.num_ops; ++i)
2683 12246834 : nary->op[i] = op.ops[i];
2684 : }
2685 : return res;
2686 : }
2687 :
2688 : /* Elimination engine. */
2689 :
2690 : class eliminate_dom_walker : public dom_walker
2691 : {
2692 : public:
2693 : eliminate_dom_walker (cdi_direction, bitmap);
2694 : ~eliminate_dom_walker ();
2695 :
2696 : edge before_dom_children (basic_block) final override;
2697 : void after_dom_children (basic_block) final override;
2698 :
2699 : virtual tree eliminate_avail (basic_block, tree op);
2700 : virtual void eliminate_push_avail (basic_block, tree op);
2701 : tree eliminate_insert (basic_block, gimple_stmt_iterator *gsi, tree val);
2702 :
2703 : void eliminate_stmt (basic_block, gimple_stmt_iterator *);
2704 :
2705 : unsigned eliminate_cleanup (bool region_p = false);
2706 :
2707 : bool do_pre;
2708 : unsigned int el_todo;
2709 : unsigned int eliminations;
2710 : unsigned int insertions;
2711 :
2712 : /* SSA names that had their defs inserted by PRE if do_pre. */
2713 : bitmap inserted_exprs;
2714 :
2715 : /* Blocks with statements that have had their EH properties changed. */
2716 : bitmap need_eh_cleanup;
2717 :
2718 : /* Blocks with statements that have had their AB properties changed. */
2719 : bitmap need_ab_cleanup;
2720 :
2721 : /* Local state for the eliminate domwalk. */
2722 : auto_vec<gimple *> to_remove;
2723 : auto_vec<gimple *> to_fixup;
2724 : auto_vec<tree> avail;
2725 : auto_vec<tree> avail_stack;
2726 : };
2727 :
2728 : /* Adaptor to the elimination engine using RPO availability. */
2729 :
2730 12460942 : class rpo_elim : public eliminate_dom_walker
2731 : {
2732 : public:
2733 6230471 : rpo_elim(basic_block entry_)
2734 12460942 : : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
2735 12460942 : m_avail_freelist (NULL) {}
2736 :
2737 : tree eliminate_avail (basic_block, tree op) final override;
2738 :
2739 : void eliminate_push_avail (basic_block, tree) final override;
2740 :
2741 : basic_block entry;
2742 : /* Freelist of avail entries which are allocated from the vn_ssa_aux
2743 : obstack. */
2744 : vn_avail *m_avail_freelist;
2745 : };
2746 :
2747 : /* Return true if BASE1 and BASE2 can be adjusted so they have the
2748 : same address and adjust *OFFSET1 and *OFFSET2 accordingly.
2749 : Otherwise return false. */
2750 :
2751 : static bool
2752 6870585 : adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
2753 : tree base2, poly_int64 *offset2)
2754 : {
2755 6870585 : poly_int64 soff;
2756 6870585 : if (TREE_CODE (base1) == MEM_REF
2757 3126367 : && TREE_CODE (base2) == MEM_REF)
2758 : {
2759 2509618 : if (mem_ref_offset (base1).to_shwi (&soff))
2760 : {
2761 2509618 : base1 = TREE_OPERAND (base1, 0);
2762 2509618 : *offset1 += soff * BITS_PER_UNIT;
2763 : }
2764 2509618 : if (mem_ref_offset (base2).to_shwi (&soff))
2765 : {
2766 2509618 : base2 = TREE_OPERAND (base2, 0);
2767 2509618 : *offset2 += soff * BITS_PER_UNIT;
2768 : }
2769 2509618 : return operand_equal_p (base1, base2, 0);
2770 : }
2771 4360967 : return operand_equal_p (base1, base2, OEP_ADDRESS_OF);
2772 : }
2773 :
2774 : /* Callback for walk_non_aliased_vuses. Tries to perform a lookup
2775 : from the statement defining VUSE and if not successful tries to
2776 : translate *REFP and VR_ through an aggregate copy at the definition
2777 : of VUSE. If *DISAMBIGUATE_ONLY is true then do not perform translation
2778 : of *REF and *VR. If only disambiguation was performed then
2779 : *DISAMBIGUATE_ONLY is set to true. */
2780 :
2781 : static void *
2782 42829424 : vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
2783 : translate_flags *disambiguate_only)
2784 : {
2785 42829424 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2786 42829424 : vn_reference_t vr = data->vr;
2787 42829424 : gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
2788 42829424 : tree base = ao_ref_base (ref);
2789 42829424 : HOST_WIDE_INT offseti = 0, maxsizei, sizei = 0;
2790 42829424 : static vec<vn_reference_op_s> lhs_ops;
2791 42829424 : ao_ref lhs_ref;
2792 42829424 : bool lhs_ref_ok = false;
2793 42829424 : poly_int64 copy_size;
2794 :
2795 : /* First try to disambiguate after value-replacing in the definitions LHS. */
2796 42829424 : if (is_gimple_assign (def_stmt))
2797 : {
2798 21058905 : tree lhs = gimple_assign_lhs (def_stmt);
2799 21058905 : bool valueized_anything = false;
2800 : /* Avoid re-allocation overhead. */
2801 21058905 : lhs_ops.truncate (0);
2802 21058905 : basic_block saved_rpo_bb = vn_context_bb;
2803 21058905 : vn_context_bb = gimple_bb (def_stmt);
2804 21058905 : if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE)
2805 : {
2806 13707570 : copy_reference_ops_from_ref (lhs, &lhs_ops);
2807 13707570 : valueize_refs_1 (&lhs_ops, &valueized_anything, true);
2808 : }
2809 21058905 : vn_context_bb = saved_rpo_bb;
2810 21058905 : ao_ref_init (&lhs_ref, lhs);
2811 21058905 : lhs_ref_ok = true;
2812 21058905 : if (valueized_anything
2813 2015862 : && ao_ref_init_from_vn_reference
2814 2015862 : (&lhs_ref, ao_ref_alias_set (&lhs_ref),
2815 2015862 : ao_ref_base_alias_set (&lhs_ref), TREE_TYPE (lhs), lhs_ops)
2816 23074767 : && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
2817 : {
2818 1723919 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2819 8363797 : return NULL;
2820 : }
2821 :
2822 : /* When the def is a CLOBBER we can optimistically disambiguate
2823 : against it since any overlap it would be undefined behavior.
2824 : Avoid this for obvious must aliases to save compile-time though.
2825 : We also may not do this when the query is used for redundant
2826 : store removal. */
2827 19334986 : if (!data->redundant_store_removal_p
2828 10650796 : && gimple_clobber_p (def_stmt)
2829 19836029 : && !operand_equal_p (ao_ref_base (&lhs_ref), base, OEP_ADDRESS_OF))
2830 : {
2831 475740 : *disambiguate_only = TR_DISAMBIGUATE;
2832 475740 : return NULL;
2833 : }
2834 :
2835 : /* Besides valueizing the LHS we can also use access-path based
2836 : disambiguation on the original non-valueized ref. */
2837 18859246 : if (!ref->ref
2838 : && lhs_ref_ok
2839 2713846 : && data->orig_ref.ref)
2840 : {
2841 : /* We want to use the non-valueized LHS for this, but avoid redundant
2842 : work. */
2843 1893417 : ao_ref *lref = &lhs_ref;
2844 1893417 : ao_ref lref_alt;
2845 1893417 : if (valueized_anything)
2846 : {
2847 114158 : ao_ref_init (&lref_alt, lhs);
2848 114158 : lref = &lref_alt;
2849 : }
2850 1893417 : if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
2851 : {
2852 313334 : *disambiguate_only = (valueized_anything
2853 156667 : ? TR_VALUEIZE_AND_DISAMBIGUATE
2854 : : TR_DISAMBIGUATE);
2855 156667 : return NULL;
2856 : }
2857 : }
2858 :
2859 : /* If we reach a clobbering statement try to skip it and see if
2860 : we find a VN result with exactly the same value as the
2861 : possible clobber. In this case we can ignore the clobber
2862 : and return the found value. */
2863 18702579 : if (!gimple_has_volatile_ops (def_stmt)
2864 17316085 : && ((is_gimple_reg_type (TREE_TYPE (lhs))
2865 12716583 : && types_compatible_p (TREE_TYPE (lhs), vr->type)
2866 9921818 : && !storage_order_barrier_p (lhs)
2867 9921818 : && !reverse_storage_order_for_component_p (lhs))
2868 7394271 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == CONSTRUCTOR)
2869 10990921 : && (ref->ref || data->orig_ref.ref)
2870 10518287 : && !data->mask
2871 10495746 : && data->partial_defs.is_empty ()
2872 10493394 : && multiple_p (get_object_alignment
2873 : (ref->ref ? ref->ref : data->orig_ref.ref),
2874 : ref->size)
2875 41833705 : && multiple_p (get_object_alignment (lhs), ref->size))
2876 : {
2877 10098593 : HOST_WIDE_INT offset2i, size2i;
2878 10098593 : poly_int64 offset = ref->offset;
2879 10098593 : poly_int64 maxsize = ref->max_size;
2880 :
2881 10098593 : gcc_assert (lhs_ref_ok);
2882 10098593 : tree base2 = ao_ref_base (&lhs_ref);
2883 10098593 : poly_int64 offset2 = lhs_ref.offset;
2884 10098593 : poly_int64 size2 = lhs_ref.size;
2885 10098593 : poly_int64 maxsize2 = lhs_ref.max_size;
2886 :
2887 10098593 : tree rhs = gimple_assign_rhs1 (def_stmt);
2888 10098593 : if (TREE_CODE (rhs) == CONSTRUCTOR)
2889 1039866 : rhs = integer_zero_node;
2890 : /* ??? We may not compare to ahead values which might be from
2891 : a different loop iteration but only to loop invariants. Use
2892 : CONSTANT_CLASS_P (unvalueized!) as conservative approximation.
2893 : The one-hop lookup below doesn't have this issue since there's
2894 : a virtual PHI before we ever reach a backedge to cross.
2895 : We can skip multiple defs as long as they are from the same
2896 : value though. */
2897 10098593 : if (data->same_val
2898 10098593 : && !operand_equal_p (data->same_val, rhs))
2899 : ;
2900 : /* When this is a (partial) must-def, leave it to handling
2901 : below in case we are interested in the value. */
2902 9804381 : else if (!(*disambiguate_only > TR_TRANSLATE)
2903 3352372 : && base2
2904 3352372 : && known_eq (maxsize2, size2)
2905 2357058 : && adjust_offsets_for_equal_base_address (base, &offset,
2906 : base2, &offset2)
2907 1155657 : && offset2.is_constant (&offset2i)
2908 1155657 : && size2.is_constant (&size2i)
2909 1155657 : && maxsize.is_constant (&maxsizei)
2910 1155657 : && offset.is_constant (&offseti)
2911 10960038 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
2912 : size2i))
2913 : ;
2914 8744328 : else if (CONSTANT_CLASS_P (rhs))
2915 : {
2916 4218545 : if (dump_file && (dump_flags & TDF_DETAILS))
2917 : {
2918 2191 : fprintf (dump_file,
2919 : "Skipping possible redundant definition ");
2920 2191 : print_gimple_stmt (dump_file, def_stmt, 0);
2921 : }
2922 : /* Delay the actual compare of the values to the end of the walk
2923 : but do not update last_vuse from here. */
2924 4218545 : data->last_vuse_ptr = NULL;
2925 4218545 : data->same_val = rhs;
2926 4283552 : return NULL;
2927 : }
2928 : else
2929 : {
2930 4525783 : tree saved_vuse = vr->vuse;
2931 4525783 : hashval_t saved_hashcode = vr->hashcode;
2932 4525783 : if (vr->vuse)
2933 4525783 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2934 9051566 : vr->vuse = vuse_ssa_val (gimple_vuse (def_stmt));
2935 4525783 : if (vr->vuse)
2936 4525783 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2937 4525783 : vn_reference_t vnresult = NULL;
2938 : /* Do not use vn_reference_lookup_2 since that might perform
2939 : expression hashtable insertion but this lookup crosses
2940 : a possible may-alias making such insertion conditionally
2941 : invalid. */
2942 4525783 : vn_reference_lookup_1 (vr, &vnresult);
2943 : /* Need to restore vr->vuse and vr->hashcode. */
2944 4525783 : vr->vuse = saved_vuse;
2945 4525783 : vr->hashcode = saved_hashcode;
2946 4525783 : if (vnresult)
2947 : {
2948 248886 : if (TREE_CODE (rhs) == SSA_NAME)
2949 247365 : rhs = SSA_VAL (rhs);
2950 248886 : if (vnresult->result
2951 248886 : && operand_equal_p (vnresult->result, rhs, 0))
2952 65007 : return vnresult;
2953 : }
2954 : }
2955 : }
2956 : }
2957 21770519 : else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE
2958 19563984 : && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
2959 23863970 : && gimple_call_num_args (def_stmt) <= 4)
2960 : {
2961 : /* For builtin calls valueize its arguments and call the
2962 : alias oracle again. Valueization may improve points-to
2963 : info of pointers and constify size and position arguments.
2964 : Originally this was motivated by PR61034 which has
2965 : conditional calls to free falsely clobbering ref because
2966 : of imprecise points-to info of the argument. */
2967 : tree oldargs[4];
2968 : bool valueized_anything = false;
2969 4933142 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2970 : {
2971 3399260 : oldargs[i] = gimple_call_arg (def_stmt, i);
2972 3399260 : tree val = vn_valueize (oldargs[i]);
2973 3399260 : if (val != oldargs[i])
2974 : {
2975 126035 : gimple_call_set_arg (def_stmt, i, val);
2976 126035 : valueized_anything = true;
2977 : }
2978 : }
2979 1533882 : if (valueized_anything)
2980 : {
2981 194598 : bool res = call_may_clobber_ref_p_1 (as_a <gcall *> (def_stmt),
2982 97299 : ref, data->tbaa_p);
2983 354519 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2984 257220 : gimple_call_set_arg (def_stmt, i, oldargs[i]);
2985 97299 : if (!res)
2986 : {
2987 29404 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2988 29404 : return NULL;
2989 : }
2990 : }
2991 : }
2992 :
2993 36160142 : if (*disambiguate_only > TR_TRANSLATE)
2994 : return (void *)-1;
2995 :
2996 : /* If we cannot constrain the size of the reference we cannot
2997 : test if anything kills it. */
2998 24122832 : if (!ref->max_size_known_p ())
2999 : return (void *)-1;
3000 :
3001 23697134 : poly_int64 offset = ref->offset;
3002 23697134 : poly_int64 maxsize = ref->max_size;
3003 :
3004 : /* def_stmt may-defs *ref. See if we can derive a value for *ref
3005 : from that definition.
3006 : 1) Memset. */
3007 23697134 : if (is_gimple_reg_type (vr->type)
3008 23691321 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
3009 23601979 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
3010 89876 : && (integer_zerop (gimple_call_arg (def_stmt, 1))
3011 32076 : || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
3012 8893 : || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
3013 : && CHAR_BIT == 8
3014 : && BITS_PER_UNIT == 8
3015 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
3016 30797 : && offset.is_constant (&offseti)
3017 30797 : && ref->size.is_constant (&sizei)
3018 30797 : && (offseti % BITS_PER_UNIT == 0
3019 39 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST)))
3020 88597 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
3021 36337 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3022 36337 : && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
3023 23749961 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3024 29774 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
3025 : {
3026 52786 : tree base2;
3027 52786 : poly_int64 offset2, size2, maxsize2;
3028 52786 : bool reverse;
3029 52786 : tree ref2 = gimple_call_arg (def_stmt, 0);
3030 52786 : if (TREE_CODE (ref2) == SSA_NAME)
3031 : {
3032 29733 : ref2 = SSA_VAL (ref2);
3033 29733 : if (TREE_CODE (ref2) == SSA_NAME
3034 29733 : && (TREE_CODE (base) != MEM_REF
3035 19105 : || TREE_OPERAND (base, 0) != ref2))
3036 : {
3037 23425 : gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
3038 23425 : if (gimple_assign_single_p (def_stmt)
3039 23425 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3040 828 : ref2 = gimple_assign_rhs1 (def_stmt);
3041 : }
3042 : }
3043 52786 : if (TREE_CODE (ref2) == ADDR_EXPR)
3044 : {
3045 26806 : ref2 = TREE_OPERAND (ref2, 0);
3046 26806 : base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
3047 : &reverse);
3048 26806 : if (!known_size_p (maxsize2)
3049 26766 : || !known_eq (maxsize2, size2)
3050 53504 : || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
3051 56304 : return (void *)-1;
3052 : }
3053 25980 : else if (TREE_CODE (ref2) == SSA_NAME)
3054 : {
3055 25980 : poly_int64 soff;
3056 25980 : if (TREE_CODE (base) != MEM_REF
3057 44474 : || !(mem_ref_offset (base)
3058 36988 : << LOG2_BITS_PER_UNIT).to_shwi (&soff))
3059 21930 : return (void *)-1;
3060 18494 : offset += soff;
3061 18494 : offset2 = 0;
3062 18494 : if (TREE_OPERAND (base, 0) != ref2)
3063 : {
3064 15111 : gimple *def = SSA_NAME_DEF_STMT (ref2);
3065 15111 : if (is_gimple_assign (def)
3066 13691 : && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
3067 11841 : && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
3068 15808 : && poly_int_tree_p (gimple_assign_rhs2 (def)))
3069 : {
3070 667 : tree rhs2 = gimple_assign_rhs2 (def);
3071 667 : if (!(poly_offset_int::from (wi::to_poly_wide (rhs2),
3072 : SIGNED)
3073 667 : << LOG2_BITS_PER_UNIT).to_shwi (&offset2))
3074 : return (void *)-1;
3075 667 : ref2 = gimple_assign_rhs1 (def);
3076 667 : if (TREE_CODE (ref2) == SSA_NAME)
3077 667 : ref2 = SSA_VAL (ref2);
3078 : }
3079 : else
3080 : return (void *)-1;
3081 : }
3082 : }
3083 : else
3084 : return (void *)-1;
3085 26975 : tree len = gimple_call_arg (def_stmt, 2);
3086 26975 : HOST_WIDE_INT leni, offset2i;
3087 26975 : if (TREE_CODE (len) == SSA_NAME)
3088 259 : len = SSA_VAL (len);
3089 : /* Sometimes the above trickery is smarter than alias analysis. Take
3090 : advantage of that. */
3091 26975 : if (!ranges_maybe_overlap_p (offset, maxsize, offset2,
3092 53950 : (wi::to_poly_offset (len)
3093 26975 : << LOG2_BITS_PER_UNIT)))
3094 : return NULL;
3095 53892 : if (data->partial_defs.is_empty ()
3096 26917 : && known_subrange_p (offset, maxsize, offset2,
3097 26917 : wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
3098 : {
3099 26409 : tree val;
3100 26409 : if (integer_zerop (gimple_call_arg (def_stmt, 1)))
3101 21521 : val = build_zero_cst (vr->type);
3102 4888 : else if (INTEGRAL_TYPE_P (vr->type)
3103 3748 : && known_eq (ref->size, 8)
3104 7873 : && offseti % BITS_PER_UNIT == 0)
3105 : {
3106 2985 : gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
3107 2985 : vr->type, gimple_call_arg (def_stmt, 1));
3108 2985 : val = vn_nary_build_or_lookup (&res_op);
3109 2985 : if (!val
3110 2985 : || (TREE_CODE (val) == SSA_NAME
3111 616 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
3112 0 : return (void *)-1;
3113 : }
3114 : else
3115 : {
3116 1903 : unsigned buflen
3117 1903 : = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)) + 1;
3118 1903 : if (INTEGRAL_TYPE_P (vr->type)
3119 1903 : && TYPE_MODE (vr->type) != BLKmode)
3120 1524 : buflen = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (vr->type)) + 1;
3121 1903 : unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
3122 1903 : memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
3123 : buflen);
3124 1903 : if (BYTES_BIG_ENDIAN)
3125 : {
3126 : unsigned int amnt
3127 : = (((unsigned HOST_WIDE_INT) offseti + sizei)
3128 : % BITS_PER_UNIT);
3129 : if (amnt)
3130 : {
3131 : shift_bytes_in_array_right (buf, buflen,
3132 : BITS_PER_UNIT - amnt);
3133 : buf++;
3134 : buflen--;
3135 : }
3136 : }
3137 1903 : else if (offseti % BITS_PER_UNIT != 0)
3138 : {
3139 7 : unsigned int amnt
3140 : = BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) offseti
3141 7 : % BITS_PER_UNIT);
3142 7 : shift_bytes_in_array_left (buf, buflen, amnt);
3143 7 : buf++;
3144 7 : buflen--;
3145 : }
3146 1903 : val = native_interpret_expr (vr->type, buf, buflen);
3147 1903 : if (!val)
3148 : return (void *)-1;
3149 : }
3150 26409 : return data->finish (0, 0, val);
3151 : }
3152 : /* For now handle clearing memory with partial defs. */
3153 566 : else if (known_eq (ref->size, maxsize)
3154 490 : && integer_zerop (gimple_call_arg (def_stmt, 1))
3155 207 : && tree_fits_poly_int64_p (len)
3156 203 : && tree_to_poly_int64 (len).is_constant (&leni)
3157 203 : && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
3158 203 : && offset.is_constant (&offseti)
3159 203 : && offset2.is_constant (&offset2i)
3160 203 : && maxsize.is_constant (&maxsizei)
3161 566 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
3162 566 : leni << LOG2_BITS_PER_UNIT))
3163 : {
3164 203 : pd_data pd;
3165 203 : pd.rhs = build_constructor (NULL_TREE, NULL);
3166 203 : pd.rhs_off = 0;
3167 203 : pd.offset = offset2i;
3168 203 : pd.size = leni << LOG2_BITS_PER_UNIT;
3169 203 : return data->push_partial_def (pd, 0, 0, offseti, maxsizei);
3170 : }
3171 : }
3172 :
3173 : /* 2) Assignment from an empty CONSTRUCTOR. */
3174 23644348 : else if (is_gimple_reg_type (vr->type)
3175 23638535 : && gimple_assign_single_p (def_stmt)
3176 7800196 : && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
3177 1963615 : && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0
3178 25607963 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)))
3179 : {
3180 1963583 : tree base2;
3181 1963583 : poly_int64 offset2, size2, maxsize2;
3182 1963583 : HOST_WIDE_INT offset2i, size2i;
3183 1963583 : gcc_assert (lhs_ref_ok);
3184 1963583 : base2 = ao_ref_base (&lhs_ref);
3185 1963583 : offset2 = lhs_ref.offset;
3186 1963583 : size2 = lhs_ref.size;
3187 1963583 : maxsize2 = lhs_ref.max_size;
3188 1963583 : if (known_size_p (maxsize2)
3189 1963545 : && known_eq (maxsize2, size2)
3190 3927082 : && adjust_offsets_for_equal_base_address (base, &offset,
3191 : base2, &offset2))
3192 : {
3193 1936320 : if (data->partial_defs.is_empty ()
3194 1932750 : && known_subrange_p (offset, maxsize, offset2, size2))
3195 : {
3196 : /* While technically undefined behavior do not optimize
3197 : a full read from a clobber. */
3198 1931837 : if (gimple_clobber_p (def_stmt))
3199 1936270 : return (void *)-1;
3200 990530 : tree val = build_zero_cst (vr->type);
3201 990530 : return data->finish (ao_ref_alias_set (&lhs_ref),
3202 990530 : ao_ref_base_alias_set (&lhs_ref), val);
3203 : }
3204 4483 : else if (known_eq (ref->size, maxsize)
3205 4433 : && maxsize.is_constant (&maxsizei)
3206 4433 : && offset.is_constant (&offseti)
3207 4433 : && offset2.is_constant (&offset2i)
3208 4433 : && size2.is_constant (&size2i)
3209 4483 : && ranges_known_overlap_p (offseti, maxsizei,
3210 : offset2i, size2i))
3211 : {
3212 : /* Let clobbers be consumed by the partial-def tracker
3213 : which can choose to ignore them if they are shadowed
3214 : by a later def. */
3215 4433 : pd_data pd;
3216 4433 : pd.rhs = gimple_assign_rhs1 (def_stmt);
3217 4433 : pd.rhs_off = 0;
3218 4433 : pd.offset = offset2i;
3219 4433 : pd.size = size2i;
3220 4433 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3221 : ao_ref_base_alias_set (&lhs_ref),
3222 : offseti, maxsizei);
3223 : }
3224 : }
3225 : }
3226 :
3227 : /* 3) Assignment from a constant. We can use folds native encode/interpret
3228 : routines to extract the assigned bits. */
3229 21680765 : else if (known_eq (ref->size, maxsize)
3230 21155807 : && is_gimple_reg_type (vr->type)
3231 21149994 : && !reverse_storage_order_for_component_p (vr->operands)
3232 21147238 : && !contains_storage_order_barrier_p (vr->operands)
3233 21147238 : && gimple_assign_single_p (def_stmt)
3234 5513686 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
3235 : && CHAR_BIT == 8
3236 : && BITS_PER_UNIT == 8
3237 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
3238 : /* native_encode and native_decode operate on arrays of bytes
3239 : and so fundamentally need a compile-time size and offset. */
3240 5510725 : && maxsize.is_constant (&maxsizei)
3241 5510725 : && offset.is_constant (&offseti)
3242 27191490 : && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
3243 4666776 : || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
3244 1885284 : && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
3245 : {
3246 860673 : tree lhs = gimple_assign_lhs (def_stmt);
3247 860673 : tree base2;
3248 860673 : poly_int64 offset2, size2, maxsize2;
3249 860673 : HOST_WIDE_INT offset2i, size2i;
3250 860673 : bool reverse;
3251 860673 : gcc_assert (lhs_ref_ok);
3252 860673 : base2 = ao_ref_base (&lhs_ref);
3253 860673 : offset2 = lhs_ref.offset;
3254 860673 : size2 = lhs_ref.size;
3255 860673 : maxsize2 = lhs_ref.max_size;
3256 860673 : reverse = reverse_storage_order_for_component_p (lhs);
3257 860673 : if (base2
3258 860673 : && !reverse
3259 859845 : && !storage_order_barrier_p (lhs)
3260 859845 : && known_eq (maxsize2, size2)
3261 827987 : && adjust_offsets_for_equal_base_address (base, &offset,
3262 : base2, &offset2)
3263 84643 : && offset.is_constant (&offseti)
3264 84643 : && offset2.is_constant (&offset2i)
3265 860673 : && size2.is_constant (&size2i))
3266 : {
3267 84643 : if (data->partial_defs.is_empty ()
3268 67572 : && known_subrange_p (offseti, maxsizei, offset2, size2))
3269 : {
3270 : /* We support up to 512-bit values (for V8DFmode). */
3271 44021 : unsigned char buffer[65];
3272 44021 : int len;
3273 :
3274 44021 : tree rhs = gimple_assign_rhs1 (def_stmt);
3275 44021 : if (TREE_CODE (rhs) == SSA_NAME)
3276 1765 : rhs = SSA_VAL (rhs);
3277 88042 : len = native_encode_expr (rhs,
3278 : buffer, sizeof (buffer) - 1,
3279 44021 : (offseti - offset2i) / BITS_PER_UNIT);
3280 44021 : if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
3281 : {
3282 40999 : tree type = vr->type;
3283 40999 : unsigned char *buf = buffer;
3284 40999 : unsigned int amnt = 0;
3285 : /* Make sure to interpret in a type that has a range
3286 : covering the whole access size. */
3287 40999 : if (INTEGRAL_TYPE_P (vr->type)
3288 40999 : && maxsizei != TYPE_PRECISION (vr->type))
3289 : {
3290 1012 : bool uns = TYPE_UNSIGNED (type);
3291 1011 : if (BITINT_TYPE_P (vr->type)
3292 1013 : && maxsizei > MAX_FIXED_MODE_SIZE)
3293 1 : type = build_bitint_type (maxsizei, uns);
3294 : else
3295 1011 : type = build_nonstandard_integer_type (maxsizei, uns);
3296 : }
3297 40999 : if (BYTES_BIG_ENDIAN)
3298 : {
3299 : /* For big-endian native_encode_expr stored the rhs
3300 : such that the LSB of it is the LSB of buffer[len - 1].
3301 : That bit is stored into memory at position
3302 : offset2 + size2 - 1, i.e. in byte
3303 : base + (offset2 + size2 - 1) / BITS_PER_UNIT.
3304 : E.g. for offset2 1 and size2 14, rhs -1 and memory
3305 : previously cleared that is:
3306 : 0 1
3307 : 01111111|11111110
3308 : Now, if we want to extract offset 2 and size 12 from
3309 : it using native_interpret_expr (which actually works
3310 : for integral bitfield types in terms of byte size of
3311 : the mode), the native_encode_expr stored the value
3312 : into buffer as
3313 : XX111111|11111111
3314 : and returned len 2 (the X bits are outside of
3315 : precision).
3316 : Let sz be maxsize / BITS_PER_UNIT if not extracting
3317 : a bitfield, and GET_MODE_SIZE otherwise.
3318 : We need to align the LSB of the value we want to
3319 : extract as the LSB of buf[sz - 1].
3320 : The LSB from memory we need to read is at position
3321 : offset + maxsize - 1. */
3322 : HOST_WIDE_INT sz = maxsizei / BITS_PER_UNIT;
3323 : if (INTEGRAL_TYPE_P (type))
3324 : {
3325 : if (TYPE_MODE (type) != BLKmode)
3326 : sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
3327 : else
3328 : sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
3329 : }
3330 : amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
3331 : - offseti - maxsizei) % BITS_PER_UNIT;
3332 : if (amnt)
3333 : shift_bytes_in_array_right (buffer, len, amnt);
3334 : amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
3335 : - offseti - maxsizei - amnt) / BITS_PER_UNIT;
3336 : if ((unsigned HOST_WIDE_INT) sz + amnt > (unsigned) len)
3337 : len = 0;
3338 : else
3339 : {
3340 : buf = buffer + len - sz - amnt;
3341 : len -= (buf - buffer);
3342 : }
3343 : }
3344 : else
3345 : {
3346 40999 : amnt = ((unsigned HOST_WIDE_INT) offset2i
3347 40999 : - offseti) % BITS_PER_UNIT;
3348 40999 : if (amnt)
3349 : {
3350 315 : buffer[len] = 0;
3351 315 : shift_bytes_in_array_left (buffer, len + 1, amnt);
3352 315 : buf = buffer + 1;
3353 : }
3354 : }
3355 40999 : tree val = native_interpret_expr (type, buf, len);
3356 : /* If we chop off bits because the types precision doesn't
3357 : match the memory access size this is ok when optimizing
3358 : reads but not when called from the DSE code during
3359 : elimination. */
3360 40999 : if (val
3361 40997 : && type != vr->type)
3362 : {
3363 1012 : if (! int_fits_type_p (val, vr->type))
3364 : val = NULL_TREE;
3365 : else
3366 1012 : val = fold_convert (vr->type, val);
3367 : }
3368 :
3369 40997 : if (val)
3370 40997 : return data->finish (ao_ref_alias_set (&lhs_ref),
3371 40997 : ao_ref_base_alias_set (&lhs_ref), val);
3372 : }
3373 : }
3374 40622 : else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
3375 : size2i))
3376 : {
3377 40622 : pd_data pd;
3378 40622 : tree rhs = gimple_assign_rhs1 (def_stmt);
3379 40622 : if (TREE_CODE (rhs) == SSA_NAME)
3380 2234 : rhs = SSA_VAL (rhs);
3381 40622 : pd.rhs = rhs;
3382 40622 : pd.rhs_off = 0;
3383 40622 : pd.offset = offset2i;
3384 40622 : pd.size = size2i;
3385 40622 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3386 : ao_ref_base_alias_set (&lhs_ref),
3387 : offseti, maxsizei);
3388 : }
3389 : }
3390 : }
3391 :
3392 : /* 4) Assignment from an SSA name which definition we may be able
3393 : to access pieces from or we can combine to a larger entity. */
3394 20820092 : else if (known_eq (ref->size, maxsize)
3395 20295134 : && is_gimple_reg_type (vr->type)
3396 20289321 : && !reverse_storage_order_for_component_p (vr->operands)
3397 20286565 : && !contains_storage_order_barrier_p (vr->operands)
3398 20286565 : && gimple_assign_single_p (def_stmt)
3399 4653013 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
3400 25470144 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
3401 : {
3402 1868560 : tree lhs = gimple_assign_lhs (def_stmt);
3403 1868560 : tree base2;
3404 1868560 : poly_int64 offset2, size2, maxsize2;
3405 1868560 : HOST_WIDE_INT offset2i, size2i, offseti;
3406 1868560 : bool reverse;
3407 1868560 : gcc_assert (lhs_ref_ok);
3408 1868560 : base2 = ao_ref_base (&lhs_ref);
3409 1868560 : offset2 = lhs_ref.offset;
3410 1868560 : size2 = lhs_ref.size;
3411 1868560 : maxsize2 = lhs_ref.max_size;
3412 1868560 : reverse = reverse_storage_order_for_component_p (lhs);
3413 1868560 : tree def_rhs = gimple_assign_rhs1 (def_stmt);
3414 1868560 : if (!reverse
3415 1868348 : && !storage_order_barrier_p (lhs)
3416 1868348 : && known_size_p (maxsize2)
3417 1843341 : && known_eq (maxsize2, size2)
3418 3590587 : && adjust_offsets_for_equal_base_address (base, &offset,
3419 : base2, &offset2))
3420 : {
3421 85854 : if (data->partial_defs.is_empty ()
3422 79408 : && known_subrange_p (offset, maxsize, offset2, size2)
3423 : /* ??? We can't handle bitfield precision extracts without
3424 : either using an alternate type for the BIT_FIELD_REF and
3425 : then doing a conversion or possibly adjusting the offset
3426 : according to endianness. */
3427 55285 : && (! INTEGRAL_TYPE_P (vr->type)
3428 41067 : || known_eq (ref->size, TYPE_PRECISION (vr->type)))
3429 96891 : && multiple_p (ref->size, BITS_PER_UNIT))
3430 : {
3431 46735 : tree val = NULL_TREE;
3432 93464 : if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs))
3433 51404 : || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
3434 : {
3435 45644 : gimple_match_op op (gimple_match_cond::UNCOND,
3436 45644 : BIT_FIELD_REF, vr->type,
3437 : SSA_VAL (def_rhs),
3438 : bitsize_int (ref->size),
3439 45644 : bitsize_int (offset - offset2));
3440 45644 : val = vn_nary_build_or_lookup (&op);
3441 : }
3442 1091 : else if (known_eq (ref->size, size2))
3443 : {
3444 1017 : gimple_match_op op (gimple_match_cond::UNCOND,
3445 1017 : VIEW_CONVERT_EXPR, vr->type,
3446 1017 : SSA_VAL (def_rhs));
3447 1017 : val = vn_nary_build_or_lookup (&op);
3448 : }
3449 46661 : if (val
3450 46661 : && (TREE_CODE (val) != SSA_NAME
3451 45857 : || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
3452 46642 : return data->finish (ao_ref_alias_set (&lhs_ref),
3453 85761 : ao_ref_base_alias_set (&lhs_ref), val);
3454 : }
3455 39119 : else if (maxsize.is_constant (&maxsizei)
3456 39119 : && offset.is_constant (&offseti)
3457 39119 : && offset2.is_constant (&offset2i)
3458 39119 : && size2.is_constant (&size2i)
3459 39119 : && ranges_known_overlap_p (offset, maxsize, offset2, size2))
3460 : {
3461 39119 : pd_data pd;
3462 39119 : pd.rhs = SSA_VAL (def_rhs);
3463 39119 : pd.rhs_off = 0;
3464 39119 : pd.offset = offset2i;
3465 39119 : pd.size = size2i;
3466 39119 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3467 : ao_ref_base_alias_set (&lhs_ref),
3468 : offseti, maxsizei);
3469 : }
3470 : }
3471 : }
3472 :
3473 : /* 4b) Assignment done via one of the vectorizer internal store
3474 : functions where we may be able to access pieces from or we can
3475 : combine to a larger entity. */
3476 18951532 : else if (known_eq (ref->size, maxsize)
3477 18426574 : && is_gimple_reg_type (vr->type)
3478 18420761 : && !reverse_storage_order_for_component_p (vr->operands)
3479 18418005 : && !contains_storage_order_barrier_p (vr->operands)
3480 18418005 : && is_gimple_call (def_stmt)
3481 14792739 : && gimple_call_internal_p (def_stmt)
3482 19262926 : && internal_store_fn_p (gimple_call_internal_fn (def_stmt)))
3483 : {
3484 36 : gcall *call = as_a <gcall *> (def_stmt);
3485 36 : internal_fn fn = gimple_call_internal_fn (call);
3486 :
3487 36 : tree mask = NULL_TREE, len = NULL_TREE, bias = NULL_TREE;
3488 36 : switch (fn)
3489 : {
3490 36 : case IFN_MASK_STORE:
3491 36 : mask = gimple_call_arg (call, internal_fn_mask_index (fn));
3492 36 : mask = vn_valueize (mask);
3493 36 : if (TREE_CODE (mask) != VECTOR_CST)
3494 28 : return (void *)-1;
3495 : break;
3496 0 : case IFN_LEN_STORE:
3497 0 : {
3498 0 : int len_index = internal_fn_len_index (fn);
3499 0 : len = gimple_call_arg (call, len_index);
3500 0 : bias = gimple_call_arg (call, len_index + 1);
3501 0 : if (!tree_fits_uhwi_p (len) || !tree_fits_shwi_p (bias))
3502 : return (void *) -1;
3503 : break;
3504 : }
3505 : default:
3506 : return (void *)-1;
3507 : }
3508 14 : tree def_rhs = gimple_call_arg (call,
3509 14 : internal_fn_stored_value_index (fn));
3510 14 : def_rhs = vn_valueize (def_rhs);
3511 14 : if (TREE_CODE (def_rhs) != VECTOR_CST)
3512 : return (void *)-1;
3513 :
3514 14 : ao_ref_init_from_ptr_and_size (&lhs_ref,
3515 : vn_valueize (gimple_call_arg (call, 0)),
3516 14 : TYPE_SIZE_UNIT (TREE_TYPE (def_rhs)));
3517 14 : tree base2;
3518 14 : poly_int64 offset2, size2, maxsize2;
3519 14 : HOST_WIDE_INT offset2i, size2i, offseti;
3520 14 : base2 = ao_ref_base (&lhs_ref);
3521 14 : offset2 = lhs_ref.offset;
3522 14 : size2 = lhs_ref.size;
3523 14 : maxsize2 = lhs_ref.max_size;
3524 14 : if (known_size_p (maxsize2)
3525 14 : && known_eq (maxsize2, size2)
3526 14 : && adjust_offsets_for_equal_base_address (base, &offset,
3527 : base2, &offset2)
3528 6 : && maxsize.is_constant (&maxsizei)
3529 6 : && offset.is_constant (&offseti)
3530 6 : && offset2.is_constant (&offset2i)
3531 14 : && size2.is_constant (&size2i))
3532 : {
3533 6 : if (!ranges_maybe_overlap_p (offset, maxsize, offset2, size2))
3534 : /* Poor-mans disambiguation. */
3535 : return NULL;
3536 6 : else if (ranges_known_overlap_p (offset, maxsize, offset2, size2))
3537 : {
3538 6 : pd_data pd;
3539 6 : pd.rhs = def_rhs;
3540 6 : tree aa = gimple_call_arg (call, 1);
3541 6 : alias_set_type set = get_deref_alias_set (TREE_TYPE (aa));
3542 6 : tree vectype = TREE_TYPE (def_rhs);
3543 6 : unsigned HOST_WIDE_INT elsz
3544 6 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype)));
3545 6 : if (mask)
3546 : {
3547 : HOST_WIDE_INT start = 0, length = 0;
3548 : unsigned mask_idx = 0;
3549 48 : do
3550 : {
3551 48 : if (integer_zerop (VECTOR_CST_ELT (mask, mask_idx)))
3552 : {
3553 24 : if (length != 0)
3554 : {
3555 18 : pd.rhs_off = start;
3556 18 : pd.offset = offset2i + start;
3557 18 : pd.size = length;
3558 18 : if (ranges_known_overlap_p
3559 18 : (offset, maxsize, pd.offset, pd.size))
3560 : {
3561 0 : void *res = data->push_partial_def
3562 0 : (pd, set, set, offseti, maxsizei);
3563 0 : if (res != NULL)
3564 6 : return res;
3565 : }
3566 : }
3567 24 : start = (mask_idx + 1) * elsz;
3568 24 : length = 0;
3569 : }
3570 : else
3571 24 : length += elsz;
3572 48 : mask_idx++;
3573 : }
3574 48 : while (known_lt (mask_idx, TYPE_VECTOR_SUBPARTS (vectype)));
3575 6 : if (length != 0)
3576 : {
3577 6 : pd.rhs_off = start;
3578 6 : pd.offset = offset2i + start;
3579 6 : pd.size = length;
3580 6 : if (ranges_known_overlap_p (offset, maxsize,
3581 : pd.offset, pd.size))
3582 2 : return data->push_partial_def (pd, set, set,
3583 2 : offseti, maxsizei);
3584 : }
3585 : }
3586 0 : else if (fn == IFN_LEN_STORE)
3587 : {
3588 0 : pd.offset = offset2i;
3589 0 : pd.size = (tree_to_uhwi (len)
3590 0 : + -tree_to_shwi (bias)) * BITS_PER_UNIT;
3591 0 : if (BYTES_BIG_ENDIAN)
3592 : pd.rhs_off = pd.size - tree_to_uhwi (TYPE_SIZE (vectype));
3593 : else
3594 0 : pd.rhs_off = 0;
3595 0 : if (ranges_known_overlap_p (offset, maxsize,
3596 : pd.offset, pd.size))
3597 0 : return data->push_partial_def (pd, set, set,
3598 0 : offseti, maxsizei);
3599 : }
3600 : else
3601 0 : gcc_unreachable ();
3602 4 : return NULL;
3603 : }
3604 : }
3605 : }
3606 :
3607 : /* 5) For aggregate copies translate the reference through them if
3608 : the copy kills ref. */
3609 18951496 : else if (data->vn_walk_kind == VN_WALKREWRITE
3610 15323419 : && gimple_assign_single_p (def_stmt)
3611 2571502 : && !gimple_has_volatile_ops (def_stmt)
3612 21520700 : && (DECL_P (gimple_assign_rhs1 (def_stmt))
3613 1990282 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
3614 1578067 : || handled_component_p (gimple_assign_rhs1 (def_stmt))))
3615 : {
3616 2360307 : tree base2;
3617 2360307 : int i, j, k;
3618 2360307 : auto_vec<vn_reference_op_s> rhs;
3619 2360307 : vn_reference_op_t vro;
3620 2360307 : ao_ref r;
3621 :
3622 2360307 : gcc_assert (lhs_ref_ok);
3623 :
3624 : /* See if the assignment kills REF. */
3625 2360307 : base2 = ao_ref_base (&lhs_ref);
3626 2360307 : if (!lhs_ref.max_size_known_p ()
3627 2359732 : || (base != base2
3628 87478 : && (TREE_CODE (base) != MEM_REF
3629 71765 : || TREE_CODE (base2) != MEM_REF
3630 54671 : || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
3631 18725 : || !tree_int_cst_equal (TREE_OPERAND (base, 1),
3632 18725 : TREE_OPERAND (base2, 1))))
3633 4649691 : || !stmt_kills_ref_p (def_stmt, ref))
3634 395495 : return (void *)-1;
3635 :
3636 : /* Find the common base of ref and the lhs. lhs_ops already
3637 : contains valueized operands for the lhs. */
3638 1964812 : poly_int64 extra_off = 0;
3639 1964812 : i = vr->operands.length () - 1;
3640 1964812 : j = lhs_ops.length () - 1;
3641 :
3642 : /* The base should be always equal due to the above check. */
3643 1964812 : if (! vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3644 : return (void *)-1;
3645 1964552 : i--, j--;
3646 :
3647 : /* The 2nd component should always exist and be a MEM_REF. */
3648 1964552 : if (!(i >= 0 && j >= 0))
3649 : ;
3650 1964552 : else if (vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3651 933519 : i--, j--;
3652 1031033 : else if (vr->operands[i].opcode == MEM_REF
3653 1029549 : && lhs_ops[j].opcode == MEM_REF
3654 1029549 : && known_ne (lhs_ops[j].off, -1)
3655 2060582 : && known_ne (vr->operands[i].off, -1))
3656 : {
3657 1029549 : bool found = false;
3658 : /* When we ge a mismatch at a MEM_REF that is not the sole component
3659 : try finding a match in one of the outer components and continue
3660 : stripping there. This happens when addresses of components get
3661 : forwarded into dereferences. */
3662 1029549 : if (i > 0)
3663 : {
3664 113175 : int temi = i - 1;
3665 113175 : poly_int64 tem_extra_off = extra_off + vr->operands[i].off;
3666 113175 : while (temi >= 0
3667 246500 : && known_ne (vr->operands[temi].off, -1))
3668 : {
3669 134808 : if (vr->operands[temi].type
3670 134808 : && lhs_ops[j].type
3671 269616 : && (TYPE_MAIN_VARIANT (vr->operands[temi].type)
3672 134808 : == TYPE_MAIN_VARIANT (lhs_ops[j].type)))
3673 : {
3674 1483 : i = temi;
3675 : /* Strip the component that was type matched to
3676 : the MEM_REF. */
3677 1483 : extra_off = (tem_extra_off
3678 1483 : + vr->operands[i].off - lhs_ops[j].off);
3679 1483 : i--, j--;
3680 : /* Strip further equal components. */
3681 1483 : found = true;
3682 1483 : break;
3683 : }
3684 133325 : tem_extra_off += vr->operands[temi].off;
3685 133325 : temi--;
3686 : }
3687 : }
3688 1029549 : if (!found && j > 0)
3689 : {
3690 33083 : int temj = j - 1;
3691 33083 : poly_int64 tem_extra_off = extra_off - lhs_ops[j].off;
3692 33083 : while (temj >= 0
3693 63413 : && known_ne (lhs_ops[temj].off, -1))
3694 : {
3695 35330 : if (vr->operands[i].type
3696 35330 : && lhs_ops[temj].type
3697 70660 : && (TYPE_MAIN_VARIANT (vr->operands[i].type)
3698 35330 : == TYPE_MAIN_VARIANT (lhs_ops[temj].type)))
3699 : {
3700 5000 : j = temj;
3701 : /* Strip the component that was type matched to
3702 : the MEM_REF. */
3703 5000 : extra_off = (tem_extra_off
3704 5000 : + vr->operands[i].off - lhs_ops[j].off);
3705 5000 : i--, j--;
3706 : /* Strip further equal components. */
3707 5000 : found = true;
3708 5000 : break;
3709 : }
3710 30330 : tem_extra_off += -lhs_ops[temj].off;
3711 30330 : temj--;
3712 : }
3713 : }
3714 : /* When we cannot find a common base to reconstruct the full
3715 : reference instead try to reduce the lookup to the new
3716 : base plus a constant offset. */
3717 1029549 : if (!found)
3718 : {
3719 : while (j >= 0
3720 2076088 : && known_ne (lhs_ops[j].off, -1))
3721 : {
3722 1053022 : extra_off += -lhs_ops[j].off;
3723 1053022 : j--;
3724 : }
3725 1023066 : if (j != -1)
3726 : return (void *)-1;
3727 : while (i >= 0
3728 2172230 : && known_ne (vr->operands[i].off, -1))
3729 : {
3730 : /* Punt if the additional ops contain a storage order
3731 : barrier. */
3732 1149164 : if (vr->operands[i].opcode == VIEW_CONVERT_EXPR
3733 1149164 : && vr->operands[i].reverse)
3734 : break;
3735 1149164 : extra_off += vr->operands[i].off;
3736 1149164 : i--;
3737 : }
3738 1023066 : if (i != -1)
3739 : return (void *)-1;
3740 : found = true;
3741 : }
3742 : /* If we did find a match we'd eventually append a MEM_REF
3743 : as component. Don't. */
3744 : if (!found)
3745 : return (void *)-1;
3746 : }
3747 : else
3748 : return (void *)-1;
3749 :
3750 : /* Strip further common components, attempting to consume lhs_ops
3751 : in full. */
3752 1961752 : while (j >= 0 && i >= 0
3753 1961752 : && vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3754 : {
3755 25053 : i--;
3756 25053 : j--;
3757 : }
3758 :
3759 : /* i now points to the first additional op.
3760 : ??? LHS may not be completely contained in VR, one or more
3761 : VIEW_CONVERT_EXPRs could be in its way. We could at least
3762 : try handling outermost VIEW_CONVERT_EXPRs. */
3763 1936699 : if (j != -1)
3764 : return (void *)-1;
3765 :
3766 : /* Punt if the additional ops contain a storage order barrier. */
3767 3028686 : for (k = i; k >= 0; k--)
3768 : {
3769 1094907 : vro = &vr->operands[k];
3770 1094907 : if (vro->opcode == VIEW_CONVERT_EXPR && vro->reverse)
3771 : return (void *)-1;
3772 : }
3773 :
3774 : /* Now re-write REF to be based on the rhs of the assignment. */
3775 1933779 : tree rhs1 = gimple_assign_rhs1 (def_stmt);
3776 1933779 : copy_reference_ops_from_ref (rhs1, &rhs);
3777 :
3778 : /* Apply an extra offset to the inner MEM_REF of the RHS. */
3779 1933779 : bool force_no_tbaa = false;
3780 1933779 : if (maybe_ne (extra_off, 0))
3781 : {
3782 738206 : if (rhs.length () < 2)
3783 : return (void *)-1;
3784 738206 : int ix = rhs.length () - 2;
3785 738206 : if (rhs[ix].opcode != MEM_REF
3786 738206 : || known_eq (rhs[ix].off, -1))
3787 : return (void *)-1;
3788 738188 : rhs[ix].off += extra_off;
3789 738188 : rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
3790 738188 : build_int_cst (TREE_TYPE (rhs[ix].op0),
3791 : extra_off));
3792 : /* When we have offsetted the RHS, reading only parts of it,
3793 : we can no longer use the original TBAA type, force alias-set
3794 : zero. */
3795 738188 : force_no_tbaa = true;
3796 : }
3797 :
3798 : /* Save the operands since we need to use the original ones for
3799 : the hash entry we use. */
3800 1933761 : if (!data->saved_operands.exists ())
3801 1822035 : data->saved_operands = vr->operands.copy ();
3802 :
3803 : /* We need to pre-pend vr->operands[0..i] to rhs. */
3804 1933761 : vec<vn_reference_op_s> old = vr->operands;
3805 5801283 : if (i + 1 + rhs.length () > vr->operands.length ())
3806 1154464 : vr->operands.safe_grow (i + 1 + rhs.length (), true);
3807 : else
3808 779297 : vr->operands.truncate (i + 1 + rhs.length ());
3809 7004645 : FOR_EACH_VEC_ELT (rhs, j, vro)
3810 5070884 : vr->operands[i + 1 + j] = *vro;
3811 1933761 : valueize_refs (&vr->operands);
3812 3867522 : if (old == shared_lookup_references)
3813 1933761 : shared_lookup_references = vr->operands;
3814 1933761 : vr->hashcode = vn_reference_compute_hash (vr);
3815 :
3816 : /* Try folding the new reference to a constant. */
3817 1933761 : tree val = fully_constant_vn_reference_p (vr);
3818 1933761 : if (val)
3819 : {
3820 22125 : if (data->partial_defs.is_empty ())
3821 22116 : return data->finish (ao_ref_alias_set (&lhs_ref),
3822 22116 : ao_ref_base_alias_set (&lhs_ref), val);
3823 : /* This is the only interesting case for partial-def handling
3824 : coming from targets that like to gimplify init-ctors as
3825 : aggregate copies from constant data like aarch64 for
3826 : PR83518. */
3827 9 : if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
3828 : {
3829 9 : pd_data pd;
3830 9 : pd.rhs = val;
3831 9 : pd.rhs_off = 0;
3832 9 : pd.offset = 0;
3833 9 : pd.size = maxsizei;
3834 9 : return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3835 : ao_ref_base_alias_set (&lhs_ref),
3836 : 0, maxsizei);
3837 : }
3838 : }
3839 :
3840 : /* Continuing with partial defs isn't easily possible here, we
3841 : have to find a full def from further lookups from here. Probably
3842 : not worth the special-casing everywhere. */
3843 2344184 : if (!data->partial_defs.is_empty ())
3844 : return (void *)-1;
3845 :
3846 : /* Adjust *ref from the new operands. */
3847 1905634 : ao_ref rhs1_ref;
3848 1905634 : ao_ref_init (&rhs1_ref, rhs1);
3849 3087703 : if (!ao_ref_init_from_vn_reference (&r,
3850 : force_no_tbaa ? 0
3851 1182069 : : ao_ref_alias_set (&rhs1_ref),
3852 : force_no_tbaa ? 0
3853 1182069 : : ao_ref_base_alias_set (&rhs1_ref),
3854 : vr->type, vr->operands))
3855 : return (void *)-1;
3856 : /* This can happen with bitfields. */
3857 1905634 : if (maybe_ne (ref->size, r.size))
3858 : {
3859 : /* If the access lacks some subsetting simply apply that by
3860 : shortening it. That in the end can only be successful
3861 : if we can pun the lookup result which in turn requires
3862 : exact offsets. */
3863 1583 : if (known_eq (r.size, r.max_size)
3864 1583 : && known_lt (ref->size, r.size))
3865 1583 : r.size = r.max_size = ref->size;
3866 : else
3867 : return (void *)-1;
3868 : }
3869 1905634 : *ref = r;
3870 1905634 : vr->offset = r.offset;
3871 1905634 : vr->max_size = r.max_size;
3872 :
3873 : /* Do not update last seen VUSE after translating. */
3874 1905634 : data->last_vuse_ptr = NULL;
3875 : /* Invalidate the original access path since it now contains
3876 : the wrong base. */
3877 1905634 : data->orig_ref.ref = NULL_TREE;
3878 : /* Use the alias-set of this LHS for recording an eventual result. */
3879 1905634 : if (data->first_set == -2)
3880 : {
3881 1795436 : data->first_set = ao_ref_alias_set (&lhs_ref);
3882 1795436 : data->first_base_set = ao_ref_base_alias_set (&lhs_ref);
3883 : }
3884 :
3885 : /* Keep looking for the adjusted *REF / VR pair. */
3886 1905634 : return NULL;
3887 2360307 : }
3888 :
3889 : /* 6) For memcpy copies translate the reference through them if the copy
3890 : kills ref. But we cannot (easily) do this translation if the memcpy is
3891 : a storage order barrier, i.e. is equivalent to a VIEW_CONVERT_EXPR that
3892 : can modify the storage order of objects (see storage_order_barrier_p). */
3893 16591189 : else if (data->vn_walk_kind == VN_WALKREWRITE
3894 12963112 : && is_gimple_reg_type (vr->type)
3895 : /* ??? Handle BCOPY as well. */
3896 12957299 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
3897 12889328 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
3898 12888905 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
3899 12887729 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
3900 12887487 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
3901 12862194 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
3902 95433 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3903 83554 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
3904 95397 : && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
3905 67209 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
3906 95382 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), ©_size)
3907 53963 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3908 53963 : && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)),
3909 : ©_size)))
3910 : /* Handling this is more complicated, give up for now. */
3911 16635201 : && data->partial_defs.is_empty ())
3912 : {
3913 43322 : tree lhs, rhs;
3914 43322 : ao_ref r;
3915 43322 : poly_int64 rhs_offset, lhs_offset;
3916 43322 : vn_reference_op_s op;
3917 43322 : poly_uint64 mem_offset;
3918 43322 : poly_int64 at, byte_maxsize;
3919 :
3920 : /* Only handle non-variable, addressable refs. */
3921 43322 : if (maybe_ne (ref->size, maxsize)
3922 42839 : || !multiple_p (offset, BITS_PER_UNIT, &at)
3923 43322 : || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize))
3924 483 : return (void *)-1;
3925 :
3926 : /* Extract a pointer base and an offset for the destination. */
3927 42839 : lhs = gimple_call_arg (def_stmt, 0);
3928 42839 : lhs_offset = 0;
3929 42839 : if (TREE_CODE (lhs) == SSA_NAME)
3930 : {
3931 32673 : lhs = vn_valueize (lhs);
3932 32673 : if (TREE_CODE (lhs) == SSA_NAME)
3933 : {
3934 32336 : gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
3935 32336 : if (gimple_assign_single_p (def_stmt)
3936 32336 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3937 2474 : lhs = gimple_assign_rhs1 (def_stmt);
3938 : }
3939 : }
3940 42839 : if (TREE_CODE (lhs) == ADDR_EXPR)
3941 : {
3942 18242 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
3943 17945 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (lhs))))
3944 : return (void *)-1;
3945 12837 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0),
3946 : &lhs_offset);
3947 12837 : if (!tem)
3948 : return (void *)-1;
3949 12125 : if (TREE_CODE (tem) == MEM_REF
3950 12125 : && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3951 : {
3952 1762 : lhs = TREE_OPERAND (tem, 0);
3953 1762 : if (TREE_CODE (lhs) == SSA_NAME)
3954 1762 : lhs = vn_valueize (lhs);
3955 1762 : lhs_offset += mem_offset;
3956 : }
3957 10363 : else if (DECL_P (tem))
3958 10363 : lhs = build_fold_addr_expr (tem);
3959 : else
3960 : return (void *)-1;
3961 : }
3962 41987 : if (TREE_CODE (lhs) != SSA_NAME
3963 10364 : && TREE_CODE (lhs) != ADDR_EXPR)
3964 : return (void *)-1;
3965 :
3966 : /* Extract a pointer base and an offset for the source. */
3967 41987 : rhs = gimple_call_arg (def_stmt, 1);
3968 41987 : rhs_offset = 0;
3969 41987 : if (TREE_CODE (rhs) == SSA_NAME)
3970 19670 : rhs = vn_valueize (rhs);
3971 41987 : if (TREE_CODE (rhs) == ADDR_EXPR)
3972 : {
3973 35106 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (rhs)))
3974 24544 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (rhs))))
3975 : return (void *)-1;
3976 23942 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0),
3977 : &rhs_offset);
3978 23942 : if (!tem)
3979 : return (void *)-1;
3980 23942 : if (TREE_CODE (tem) == MEM_REF
3981 23942 : && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3982 : {
3983 0 : rhs = TREE_OPERAND (tem, 0);
3984 0 : rhs_offset += mem_offset;
3985 : }
3986 23942 : else if (DECL_P (tem)
3987 17530 : || TREE_CODE (tem) == STRING_CST)
3988 23942 : rhs = build_fold_addr_expr (tem);
3989 : else
3990 : return (void *)-1;
3991 : }
3992 41987 : if (TREE_CODE (rhs) == SSA_NAME)
3993 18045 : rhs = SSA_VAL (rhs);
3994 23942 : else if (TREE_CODE (rhs) != ADDR_EXPR)
3995 : return (void *)-1;
3996 :
3997 : /* The bases of the destination and the references have to agree. */
3998 41987 : if (TREE_CODE (base) == MEM_REF)
3999 : {
4000 15768 : if (TREE_OPERAND (base, 0) != lhs
4001 15768 : || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset))
4002 12115 : return (void *) -1;
4003 12827 : at += mem_offset;
4004 : }
4005 26219 : else if (!DECL_P (base)
4006 25271 : || TREE_CODE (lhs) != ADDR_EXPR
4007 35394 : || TREE_OPERAND (lhs, 0) != base)
4008 : return (void *)-1;
4009 :
4010 : /* If the access is completely outside of the memcpy destination
4011 : area there is no aliasing. */
4012 12827 : if (!ranges_maybe_overlap_p (lhs_offset, copy_size, at, byte_maxsize))
4013 : return NULL;
4014 : /* And the access has to be contained within the memcpy destination. */
4015 12794 : if (!known_subrange_p (at, byte_maxsize, lhs_offset, copy_size))
4016 : return (void *)-1;
4017 :
4018 : /* Save the operands since we need to use the original ones for
4019 : the hash entry we use. */
4020 12175 : if (!data->saved_operands.exists ())
4021 11742 : data->saved_operands = vr->operands.copy ();
4022 :
4023 : /* Make room for 2 operands in the new reference. */
4024 12175 : if (vr->operands.length () < 2)
4025 : {
4026 0 : vec<vn_reference_op_s> old = vr->operands;
4027 0 : vr->operands.safe_grow_cleared (2, true);
4028 0 : if (old == shared_lookup_references)
4029 0 : shared_lookup_references = vr->operands;
4030 : }
4031 : else
4032 12175 : vr->operands.truncate (2);
4033 :
4034 : /* The looked-through reference is a simple MEM_REF. */
4035 12175 : memset (&op, 0, sizeof (op));
4036 12175 : op.type = vr->type;
4037 12175 : op.opcode = MEM_REF;
4038 12175 : op.op0 = build_int_cst (ptr_type_node, at - lhs_offset + rhs_offset);
4039 12175 : op.off = at - lhs_offset + rhs_offset;
4040 12175 : vr->operands[0] = op;
4041 12175 : op.type = TREE_TYPE (rhs);
4042 12175 : op.opcode = TREE_CODE (rhs);
4043 12175 : op.op0 = rhs;
4044 12175 : op.off = -1;
4045 12175 : vr->operands[1] = op;
4046 12175 : vr->hashcode = vn_reference_compute_hash (vr);
4047 :
4048 : /* Try folding the new reference to a constant. */
4049 12175 : tree val = fully_constant_vn_reference_p (vr);
4050 12175 : if (val)
4051 3067 : return data->finish (0, 0, val);
4052 :
4053 : /* Adjust *ref from the new operands. */
4054 9108 : if (!ao_ref_init_from_vn_reference (&r, 0, 0, vr->type, vr->operands))
4055 : return (void *)-1;
4056 : /* This can happen with bitfields. */
4057 9108 : if (maybe_ne (ref->size, r.size))
4058 : return (void *)-1;
4059 9108 : *ref = r;
4060 9108 : vr->offset = r.offset;
4061 9108 : vr->max_size = r.max_size;
4062 :
4063 : /* Do not update last seen VUSE after translating. */
4064 9108 : data->last_vuse_ptr = NULL;
4065 : /* Invalidate the original access path since it now contains
4066 : the wrong base. */
4067 9108 : data->orig_ref.ref = NULL_TREE;
4068 : /* Use the alias-set of this stmt for recording an eventual result. */
4069 9108 : if (data->first_set == -2)
4070 : {
4071 8726 : data->first_set = 0;
4072 8726 : data->first_base_set = 0;
4073 : }
4074 :
4075 : /* Keep looking for the adjusted *REF / VR pair. */
4076 9108 : return NULL;
4077 : }
4078 :
4079 : /* Bail out and stop walking. */
4080 : return (void *)-1;
4081 : }
4082 :
4083 : /* Return true if E is a backedge with respect to our CFG walk order. */
4084 :
4085 : static bool
4086 124285124 : vn_is_backedge (edge e, void *)
4087 : {
4088 : /* During PRE elimination we no longer have access to this info. */
4089 124285124 : return (!vn_bb_to_rpo
4090 124285124 : || vn_bb_to_rpo[e->dest->index] <= vn_bb_to_rpo[e->src->index]);
4091 : }
4092 :
4093 : /* Return a reference op vector from OP that can be used for
4094 : vn_reference_lookup_pieces. The caller is responsible for releasing
4095 : the vector. */
4096 :
4097 : vec<vn_reference_op_s>
4098 4743195 : vn_reference_operands_for_lookup (tree op)
4099 : {
4100 4743195 : bool valueized;
4101 4743195 : return valueize_shared_reference_ops_from_ref (op, &valueized).copy ();
4102 : }
4103 :
4104 : /* Lookup a reference operation by it's parts, in the current hash table.
4105 : Returns the resulting value number if it exists in the hash table,
4106 : NULL_TREE otherwise. VNRESULT will be filled in with the actual
4107 : vn_reference_t stored in the hashtable if something is found. */
4108 :
4109 : tree
4110 7825695 : vn_reference_lookup_pieces (tree vuse, alias_set_type set,
4111 : alias_set_type base_set, tree type,
4112 : vec<vn_reference_op_s> operands,
4113 : vn_reference_t *vnresult, vn_lookup_kind kind)
4114 : {
4115 7825695 : struct vn_reference_s vr1;
4116 7825695 : vn_reference_t tmp;
4117 7825695 : tree cst;
4118 :
4119 7825695 : if (!vnresult)
4120 0 : vnresult = &tmp;
4121 7825695 : *vnresult = NULL;
4122 :
4123 7825695 : vr1.vuse = vuse_ssa_val (vuse);
4124 7825695 : shared_lookup_references.truncate (0);
4125 15651390 : shared_lookup_references.safe_grow (operands.length (), true);
4126 7825695 : memcpy (shared_lookup_references.address (),
4127 7825695 : operands.address (),
4128 : sizeof (vn_reference_op_s)
4129 7825695 : * operands.length ());
4130 7825695 : bool valueized_p;
4131 7825695 : valueize_refs_1 (&shared_lookup_references, &valueized_p);
4132 7825695 : vr1.operands = shared_lookup_references;
4133 7825695 : vr1.type = type;
4134 7825695 : vr1.set = set;
4135 7825695 : vr1.base_set = base_set;
4136 : /* We can pretend there's no extra info fed in since the ao_refs offset
4137 : and max_size are computed only from the VN reference ops. */
4138 7825695 : vr1.offset = 0;
4139 7825695 : vr1.max_size = -1;
4140 7825695 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4141 7825695 : if ((cst = fully_constant_vn_reference_p (&vr1)))
4142 : return cst;
4143 :
4144 7806109 : vn_reference_lookup_1 (&vr1, vnresult);
4145 7806109 : if (!*vnresult
4146 3039215 : && kind != VN_NOWALK
4147 3039215 : && vr1.vuse)
4148 : {
4149 3009808 : ao_ref r;
4150 3009808 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4151 3009808 : vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE,
4152 3009808 : false);
4153 3009808 : vec<vn_reference_op_s> ops_for_ref;
4154 3009808 : if (!valueized_p)
4155 2916631 : ops_for_ref = vr1.operands;
4156 : else
4157 : {
4158 : /* For ao_ref_from_mem we have to ensure only available SSA names
4159 : end up in base and the only convenient way to make this work
4160 : for PRE is to re-valueize with that in mind. */
4161 186354 : ops_for_ref.create (operands.length ());
4162 186354 : ops_for_ref.quick_grow (operands.length ());
4163 93177 : memcpy (ops_for_ref.address (),
4164 93177 : operands.address (),
4165 : sizeof (vn_reference_op_s)
4166 93177 : * operands.length ());
4167 93177 : valueize_refs_1 (&ops_for_ref, &valueized_p, true);
4168 : }
4169 3009808 : if (ao_ref_init_from_vn_reference (&r, set, base_set, type,
4170 : ops_for_ref))
4171 2941657 : *vnresult
4172 2941657 : = ((vn_reference_t)
4173 2941657 : walk_non_aliased_vuses (&r, vr1.vuse, true, vn_reference_lookup_2,
4174 : vn_reference_lookup_3, vn_is_backedge,
4175 : vuse_valueize, limit, &data));
4176 6019616 : if (ops_for_ref != shared_lookup_references)
4177 93177 : ops_for_ref.release ();
4178 6019616 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4179 3009808 : if (*vnresult
4180 427521 : && data.same_val
4181 3009808 : && (!(*vnresult)->result
4182 0 : || !operand_equal_p ((*vnresult)->result, data.same_val)))
4183 : {
4184 0 : *vnresult = NULL;
4185 0 : return NULL_TREE;
4186 : }
4187 3009808 : }
4188 :
4189 7806109 : if (*vnresult)
4190 5194415 : return (*vnresult)->result;
4191 :
4192 : return NULL_TREE;
4193 : }
4194 :
4195 : /* When OPERANDS is an ADDR_EXPR that can be possibly expressed as a
4196 : POINTER_PLUS_EXPR return true and fill in its operands in OPS. */
4197 :
4198 : bool
4199 2198560 : vn_pp_nary_for_addr (const vec<vn_reference_op_s>& operands, tree ops[2])
4200 : {
4201 4397120 : gcc_assert (operands[0].opcode == ADDR_EXPR
4202 : && operands.last ().opcode == SSA_NAME);
4203 : poly_int64 off = 0;
4204 : vn_reference_op_t vro;
4205 : unsigned i;
4206 7101635 : for (i = 1; operands.iterate (i, &vro); ++i)
4207 : {
4208 7101635 : if (vro->opcode == SSA_NAME)
4209 : break;
4210 4953476 : else if (known_eq (vro->off, -1))
4211 : break;
4212 4903075 : off += vro->off;
4213 : }
4214 2198560 : if (i == operands.length () - 1
4215 2148159 : && maybe_ne (off, 0)
4216 : /* Make sure we the offset we accumulated in a 64bit int
4217 : fits the address computation carried out in target
4218 : offset precision. */
4219 3611853 : && (off.coeffs[0]
4220 1413293 : == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
4221 : {
4222 1412753 : gcc_assert (operands[i-1].opcode == MEM_REF);
4223 1412753 : ops[0] = operands[i].op0;
4224 1412753 : ops[1] = wide_int_to_tree (sizetype, off);
4225 1412753 : return true;
4226 : }
4227 : return false;
4228 : }
4229 :
4230 : /* Lookup OP in the current hash table, and return the resulting value
4231 : number if it exists in the hash table. Return NULL_TREE if it does
4232 : not exist in the hash table or if the result field of the structure
4233 : was NULL.. VNRESULT will be filled in with the vn_reference_t
4234 : stored in the hashtable if one exists. When TBAA_P is false assume
4235 : we are looking up a store and treat it as having alias-set zero.
4236 : *LAST_VUSE_PTR will be updated with the VUSE the value lookup succeeded.
4237 : MASK is either NULL_TREE, or can be an INTEGER_CST if the result of the
4238 : load is bitwise anded with MASK and so we are only interested in a subset
4239 : of the bits and can ignore if the other bits are uninitialized or
4240 : not initialized with constants. When doing redundant store removal
4241 : the caller has to set REDUNDANT_STORE_REMOVAL_P. */
4242 :
4243 : tree
4244 102077261 : vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
4245 : vn_reference_t *vnresult, bool tbaa_p,
4246 : tree *last_vuse_ptr, tree mask,
4247 : bool redundant_store_removal_p)
4248 : {
4249 102077261 : vec<vn_reference_op_s> operands;
4250 102077261 : struct vn_reference_s vr1;
4251 102077261 : bool valueized_anything;
4252 :
4253 102077261 : if (vnresult)
4254 101681811 : *vnresult = NULL;
4255 :
4256 102077261 : vr1.vuse = vuse_ssa_val (vuse);
4257 204154522 : vr1.operands = operands
4258 102077261 : = valueize_shared_reference_ops_from_ref (op, &valueized_anything);
4259 :
4260 : /* Handle &MEM[ptr + 5].b[1].c as POINTER_PLUS_EXPR. Avoid doing
4261 : this before the pass folding __builtin_object_size had a chance to run. */
4262 102077261 : if ((cfun->curr_properties & PROP_objsz)
4263 73987782 : && operands[0].opcode == ADDR_EXPR
4264 103183518 : && operands.last ().opcode == SSA_NAME)
4265 : {
4266 1071724 : tree ops[2];
4267 1071724 : if (vn_pp_nary_for_addr (operands, ops))
4268 : {
4269 689773 : tree res = vn_nary_op_lookup_pieces (2, POINTER_PLUS_EXPR,
4270 689773 : TREE_TYPE (op), ops, NULL);
4271 689773 : if (res)
4272 689773 : return res;
4273 689773 : return NULL_TREE;
4274 : }
4275 : }
4276 :
4277 101387488 : vr1.type = TREE_TYPE (op);
4278 101387488 : ao_ref op_ref;
4279 101387488 : ao_ref_init (&op_ref, op);
4280 101387488 : vr1.set = ao_ref_alias_set (&op_ref);
4281 101387488 : vr1.base_set = ao_ref_base_alias_set (&op_ref);
4282 101387488 : vr1.offset = 0;
4283 101387488 : vr1.max_size = -1;
4284 101387488 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4285 101387488 : if (mask == NULL_TREE)
4286 101083325 : if (tree cst = fully_constant_vn_reference_p (&vr1))
4287 : return cst;
4288 :
4289 101372077 : if (kind != VN_NOWALK && vr1.vuse)
4290 : {
4291 58862943 : vn_reference_t wvnresult;
4292 58862943 : ao_ref r;
4293 58862943 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4294 58862943 : auto_vec<vn_reference_op_s> ops_for_ref;
4295 58862943 : if (valueized_anything)
4296 : {
4297 4683928 : copy_reference_ops_from_ref (op, &ops_for_ref);
4298 4683928 : bool tem;
4299 4683928 : valueize_refs_1 (&ops_for_ref, &tem, true);
4300 : }
4301 : /* Make sure to use a valueized reference if we valueized anything.
4302 : Otherwise preserve the full reference for advanced TBAA. */
4303 58862943 : if (!valueized_anything
4304 58862943 : || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
4305 : vr1.type, ops_for_ref))
4306 : {
4307 54179015 : ao_ref_init (&r, op);
4308 : /* Record the extra info we're getting from the full ref. */
4309 54179015 : ao_ref_base (&r);
4310 54179015 : vr1.offset = r.offset;
4311 54179015 : vr1.max_size = r.max_size;
4312 : }
4313 58862943 : vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
4314 : last_vuse_ptr, kind, tbaa_p, mask,
4315 113041958 : redundant_store_removal_p);
4316 :
4317 58862943 : wvnresult
4318 : = ((vn_reference_t)
4319 58862943 : walk_non_aliased_vuses (&r, vr1.vuse, tbaa_p, vn_reference_lookup_2,
4320 : vn_reference_lookup_3, vn_is_backedge,
4321 : vuse_valueize, limit, &data));
4322 117725886 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4323 58862943 : if (wvnresult)
4324 : {
4325 8737055 : gcc_assert (mask == NULL_TREE);
4326 8737055 : if (data.same_val
4327 8737055 : && (!wvnresult->result
4328 66117 : || !operand_equal_p (wvnresult->result, data.same_val)))
4329 46070 : return NULL_TREE;
4330 8690985 : if (vnresult)
4331 8688432 : *vnresult = wvnresult;
4332 8690985 : return wvnresult->result;
4333 : }
4334 50125888 : else if (mask)
4335 304163 : return data.masked_result;
4336 :
4337 : return NULL_TREE;
4338 58862943 : }
4339 :
4340 42509134 : if (last_vuse_ptr)
4341 1453645 : *last_vuse_ptr = vr1.vuse;
4342 42509134 : if (mask)
4343 : return NULL_TREE;
4344 42509134 : return vn_reference_lookup_1 (&vr1, vnresult);
4345 : }
4346 :
4347 : /* Lookup CALL in the current hash table and return the entry in
4348 : *VNRESULT if found. Populates *VR for the hashtable lookup. */
4349 :
4350 : void
4351 9233573 : vn_reference_lookup_call (gcall *call, vn_reference_t *vnresult,
4352 : vn_reference_t vr)
4353 : {
4354 9233573 : if (vnresult)
4355 9233573 : *vnresult = NULL;
4356 :
4357 9233573 : tree vuse = gimple_vuse (call);
4358 :
4359 9233573 : vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
4360 9233573 : vr->operands = valueize_shared_reference_ops_from_call (call);
4361 9233573 : tree lhs = gimple_call_lhs (call);
4362 : /* For non-SSA return values the reference ops contain the LHS. */
4363 5036880 : vr->type = ((lhs && TREE_CODE (lhs) == SSA_NAME)
4364 13819598 : ? TREE_TYPE (lhs) : NULL_TREE);
4365 9233573 : vr->punned = false;
4366 9233573 : vr->set = 0;
4367 9233573 : vr->base_set = 0;
4368 9233573 : vr->offset = 0;
4369 9233573 : vr->max_size = -1;
4370 9233573 : vr->hashcode = vn_reference_compute_hash (vr);
4371 9233573 : vn_reference_lookup_1 (vr, vnresult);
4372 9233573 : }
4373 :
4374 : /* Insert OP into the current hash table with a value number of RESULT. */
4375 :
4376 : static void
4377 75656754 : vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
4378 : {
4379 75656754 : vn_reference_s **slot;
4380 75656754 : vn_reference_t vr1;
4381 75656754 : bool tem;
4382 :
4383 75656754 : vec<vn_reference_op_s> operands
4384 75656754 : = valueize_shared_reference_ops_from_ref (op, &tem);
4385 : /* Handle &MEM[ptr + 5].b[1].c as POINTER_PLUS_EXPR. Avoid doing this
4386 : before the pass folding __builtin_object_size had a chance to run. */
4387 75656754 : if ((cfun->curr_properties & PROP_objsz)
4388 56724057 : && operands[0].opcode == ADDR_EXPR
4389 76559482 : && operands.last ().opcode == SSA_NAME)
4390 : {
4391 870674 : tree ops[2];
4392 870674 : if (vn_pp_nary_for_addr (operands, ops))
4393 : {
4394 553018 : vn_nary_op_insert_pieces (2, POINTER_PLUS_EXPR,
4395 553018 : TREE_TYPE (op), ops, result,
4396 553018 : VN_INFO (result)->value_id);
4397 553018 : return;
4398 : }
4399 : }
4400 :
4401 75103736 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4402 75103736 : if (TREE_CODE (result) == SSA_NAME)
4403 51863197 : vr1->value_id = VN_INFO (result)->value_id;
4404 : else
4405 23240539 : vr1->value_id = get_or_alloc_constant_value_id (result);
4406 75103736 : vr1->vuse = vuse_ssa_val (vuse);
4407 75103736 : vr1->operands = operands.copy ();
4408 75103736 : vr1->type = TREE_TYPE (op);
4409 75103736 : vr1->punned = false;
4410 75103736 : ao_ref op_ref;
4411 75103736 : ao_ref_init (&op_ref, op);
4412 75103736 : vr1->set = ao_ref_alias_set (&op_ref);
4413 75103736 : vr1->base_set = ao_ref_base_alias_set (&op_ref);
4414 : /* Specifically use an unknown extent here, we're not doing any lookup
4415 : and assume the caller didn't either (or it went VARYING). */
4416 75103736 : vr1->offset = 0;
4417 75103736 : vr1->max_size = -1;
4418 75103736 : vr1->hashcode = vn_reference_compute_hash (vr1);
4419 75103736 : vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
4420 75103736 : vr1->result_vdef = vdef;
4421 :
4422 75103736 : slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
4423 : INSERT);
4424 :
4425 : /* Because IL walking on reference lookup can end up visiting
4426 : a def that is only to be visited later in iteration order
4427 : when we are about to make an irreducible region reducible
4428 : the def can be effectively processed and its ref being inserted
4429 : by vn_reference_lookup_3 already. So we cannot assert (!*slot)
4430 : but save a lookup if we deal with already inserted refs here. */
4431 75103736 : if (*slot)
4432 : {
4433 : /* We cannot assert that we have the same value either because
4434 : when disentangling an irreducible region we may end up visiting
4435 : a use before the corresponding def. That's a missed optimization
4436 : only though. See gcc.dg/tree-ssa/pr87126.c for example. */
4437 0 : if (dump_file && (dump_flags & TDF_DETAILS)
4438 0 : && !operand_equal_p ((*slot)->result, vr1->result, 0))
4439 : {
4440 0 : fprintf (dump_file, "Keeping old value ");
4441 0 : print_generic_expr (dump_file, (*slot)->result);
4442 0 : fprintf (dump_file, " because of collision\n");
4443 : }
4444 0 : free_reference (vr1);
4445 0 : obstack_free (&vn_tables_obstack, vr1);
4446 0 : return;
4447 : }
4448 :
4449 75103736 : *slot = vr1;
4450 75103736 : vr1->next = last_inserted_ref;
4451 75103736 : last_inserted_ref = vr1;
4452 : }
4453 :
4454 : /* Insert a reference by it's pieces into the current hash table with
4455 : a value number of RESULT. Return the resulting reference
4456 : structure we created. */
4457 :
4458 : vn_reference_t
4459 1557166 : vn_reference_insert_pieces (tree vuse, alias_set_type set,
4460 : alias_set_type base_set,
4461 : poly_int64 offset, poly_int64 max_size, tree type,
4462 : vec<vn_reference_op_s> operands,
4463 : tree result, unsigned int value_id)
4464 :
4465 : {
4466 1557166 : vn_reference_s **slot;
4467 1557166 : vn_reference_t vr1;
4468 :
4469 1557166 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4470 1557166 : vr1->value_id = value_id;
4471 1557166 : vr1->vuse = vuse_ssa_val (vuse);
4472 1557166 : vr1->operands = operands;
4473 1557166 : valueize_refs (&vr1->operands);
4474 1557166 : vr1->type = type;
4475 1557166 : vr1->punned = false;
4476 1557166 : vr1->set = set;
4477 1557166 : vr1->base_set = base_set;
4478 1557166 : vr1->offset = offset;
4479 1557166 : vr1->max_size = max_size;
4480 1557166 : vr1->hashcode = vn_reference_compute_hash (vr1);
4481 1557166 : if (result && TREE_CODE (result) == SSA_NAME)
4482 357997 : result = SSA_VAL (result);
4483 1557166 : vr1->result = result;
4484 1557166 : vr1->result_vdef = NULL_TREE;
4485 :
4486 1557166 : slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
4487 : INSERT);
4488 :
4489 : /* At this point we should have all the things inserted that we have
4490 : seen before, and we should never try inserting something that
4491 : already exists. */
4492 1557166 : gcc_assert (!*slot);
4493 :
4494 1557166 : *slot = vr1;
4495 1557166 : vr1->next = last_inserted_ref;
4496 1557166 : last_inserted_ref = vr1;
4497 1557166 : return vr1;
4498 : }
4499 :
4500 : /* Compute and return the hash value for nary operation VBO1. */
4501 :
4502 : hashval_t
4503 307625518 : vn_nary_op_compute_hash (const vn_nary_op_t vno1)
4504 : {
4505 307625518 : inchash::hash hstate;
4506 307625518 : unsigned i;
4507 :
4508 307625518 : if (((vno1->length == 2
4509 258652510 : && commutative_tree_code (vno1->opcode))
4510 140945797 : || (vno1->length == 3
4511 1705692 : && commutative_ternary_tree_code (vno1->opcode)))
4512 474307430 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4513 2492001 : std::swap (vno1->op[0], vno1->op[1]);
4514 305133517 : else if (TREE_CODE_CLASS (vno1->opcode) == tcc_comparison
4515 305133517 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4516 : {
4517 471709 : std::swap (vno1->op[0], vno1->op[1]);
4518 471709 : vno1->opcode = swap_tree_comparison (vno1->opcode);
4519 : }
4520 :
4521 307625518 : hstate.add_int (vno1->opcode);
4522 878099327 : for (i = 0; i < vno1->length; ++i)
4523 570473809 : inchash::add_expr (vno1->op[i], hstate);
4524 :
4525 307625518 : return hstate.end ();
4526 : }
4527 :
4528 : /* Compare nary operations VNO1 and VNO2 and return true if they are
4529 : equivalent. */
4530 :
4531 : bool
4532 972087051 : vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
4533 : {
4534 972087051 : unsigned i;
4535 :
4536 972087051 : if (vno1->hashcode != vno2->hashcode)
4537 : return false;
4538 :
4539 50880037 : if (vno1->length != vno2->length)
4540 : return false;
4541 :
4542 50880037 : if (vno1->opcode != vno2->opcode
4543 50880037 : || !types_compatible_p (vno1->type, vno2->type))
4544 1161975 : return false;
4545 :
4546 143710904 : for (i = 0; i < vno1->length; ++i)
4547 94089729 : if (!expressions_equal_p (vno1->op[i], vno2->op[i]))
4548 : return false;
4549 :
4550 : /* BIT_INSERT_EXPR has an implicit operand as the type precision
4551 : of op1. Need to check to make sure they are the same. */
4552 49621175 : if (vno1->opcode == BIT_INSERT_EXPR
4553 591 : && TREE_CODE (vno1->op[1]) == INTEGER_CST
4554 49621303 : && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
4555 128 : != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
4556 : return false;
4557 :
4558 : return true;
4559 : }
4560 :
4561 : /* Initialize VNO from the pieces provided. */
4562 :
4563 : static void
4564 190366036 : init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
4565 : enum tree_code code, tree type, tree *ops)
4566 : {
4567 190366036 : vno->opcode = code;
4568 190366036 : vno->length = length;
4569 190366036 : vno->type = type;
4570 4723856 : memcpy (&vno->op[0], ops, sizeof (tree) * length);
4571 0 : }
4572 :
4573 : /* Return the number of operands for a vn_nary ops structure from STMT. */
4574 :
4575 : unsigned int
4576 111155834 : vn_nary_length_from_stmt (gimple *stmt)
4577 : {
4578 111155834 : switch (gimple_assign_rhs_code (stmt))
4579 : {
4580 : case REALPART_EXPR:
4581 : case IMAGPART_EXPR:
4582 : case VIEW_CONVERT_EXPR:
4583 : return 1;
4584 :
4585 689987 : case BIT_FIELD_REF:
4586 689987 : return 3;
4587 :
4588 541928 : case CONSTRUCTOR:
4589 541928 : return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4590 :
4591 106231719 : default:
4592 106231719 : return gimple_num_ops (stmt) - 1;
4593 : }
4594 : }
4595 :
4596 : /* Initialize VNO from STMT. */
4597 :
4598 : void
4599 111155834 : init_vn_nary_op_from_stmt (vn_nary_op_t vno, gassign *stmt)
4600 : {
4601 111155834 : unsigned i;
4602 :
4603 111155834 : vno->opcode = gimple_assign_rhs_code (stmt);
4604 111155834 : vno->type = TREE_TYPE (gimple_assign_lhs (stmt));
4605 111155834 : switch (vno->opcode)
4606 : {
4607 3692200 : case REALPART_EXPR:
4608 3692200 : case IMAGPART_EXPR:
4609 3692200 : case VIEW_CONVERT_EXPR:
4610 3692200 : vno->length = 1;
4611 3692200 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4612 3692200 : break;
4613 :
4614 689987 : case BIT_FIELD_REF:
4615 689987 : vno->length = 3;
4616 689987 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4617 689987 : vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
4618 689987 : vno->op[2] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
4619 689987 : break;
4620 :
4621 541928 : case CONSTRUCTOR:
4622 541928 : vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4623 2144751 : for (i = 0; i < vno->length; ++i)
4624 1602823 : vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
4625 : break;
4626 :
4627 106231719 : default:
4628 106231719 : gcc_checking_assert (!gimple_assign_single_p (stmt));
4629 106231719 : vno->length = gimple_num_ops (stmt) - 1;
4630 291122042 : for (i = 0; i < vno->length; ++i)
4631 184890323 : vno->op[i] = gimple_op (stmt, i + 1);
4632 : }
4633 111155834 : }
4634 :
4635 : /* Compute the hashcode for VNO and look for it in the hash table;
4636 : return the resulting value number if it exists in the hash table.
4637 : Return NULL_TREE if it does not exist in the hash table or if the
4638 : result field of the operation is NULL. VNRESULT will contain the
4639 : vn_nary_op_t from the hashtable if it exists. */
4640 :
4641 : static tree
4642 133907473 : vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
4643 : {
4644 133907473 : vn_nary_op_s **slot;
4645 :
4646 133907473 : if (vnresult)
4647 126019905 : *vnresult = NULL;
4648 :
4649 372369110 : for (unsigned i = 0; i < vno->length; ++i)
4650 238461637 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4651 168812176 : vno->op[i] = SSA_VAL (vno->op[i]);
4652 :
4653 133907473 : vno->hashcode = vn_nary_op_compute_hash (vno);
4654 133907473 : slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
4655 133907473 : if (!slot)
4656 : return NULL_TREE;
4657 18017796 : if (vnresult)
4658 17559199 : *vnresult = *slot;
4659 18017796 : return (*slot)->predicated_values ? NULL_TREE : (*slot)->u.result;
4660 : }
4661 :
4662 : /* Lookup a n-ary operation by its pieces and return the resulting value
4663 : number if it exists in the hash table. Return NULL_TREE if it does
4664 : not exist in the hash table or if the result field of the operation
4665 : is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
4666 : if it exists. */
4667 :
4668 : tree
4669 76374299 : vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
4670 : tree type, tree *ops, vn_nary_op_t *vnresult)
4671 : {
4672 76374299 : vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
4673 : sizeof_vn_nary_op (length));
4674 76374299 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4675 76374299 : return vn_nary_op_lookup_1 (vno1, vnresult);
4676 : }
4677 :
4678 : /* Lookup the rhs of STMT in the current hash table, and return the resulting
4679 : value number if it exists in the hash table. Return NULL_TREE if
4680 : it does not exist in the hash table. VNRESULT will contain the
4681 : vn_nary_op_t from the hashtable if it exists. */
4682 :
4683 : tree
4684 57533174 : vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
4685 : {
4686 57533174 : vn_nary_op_t vno1
4687 57533174 : = XALLOCAVAR (struct vn_nary_op_s,
4688 : sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
4689 57533174 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
4690 57533174 : return vn_nary_op_lookup_1 (vno1, vnresult);
4691 : }
4692 :
4693 : /* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
4694 :
4695 : vn_nary_op_t
4696 172726957 : alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
4697 : {
4698 172726957 : return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
4699 : }
4700 :
4701 : /* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's
4702 : obstack. */
4703 :
4704 : static vn_nary_op_t
4705 155231074 : alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
4706 : {
4707 0 : vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack);
4708 :
4709 155231074 : vno1->value_id = value_id;
4710 155231074 : vno1->length = length;
4711 155231074 : vno1->predicated_values = 0;
4712 155231074 : vno1->u.result = result;
4713 :
4714 155231074 : return vno1;
4715 : }
4716 :
4717 : /* Insert VNO into TABLE. */
4718 :
4719 : static vn_nary_op_t
4720 160101534 : vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table)
4721 : {
4722 160101534 : vn_nary_op_s **slot;
4723 :
4724 160101534 : gcc_assert (! vno->predicated_values
4725 : || (! vno->u.values->next
4726 : && vno->u.values->n == 1));
4727 :
4728 468418944 : for (unsigned i = 0; i < vno->length; ++i)
4729 308317410 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4730 200955259 : vno->op[i] = SSA_VAL (vno->op[i]);
4731 :
4732 160101534 : vno->hashcode = vn_nary_op_compute_hash (vno);
4733 160101534 : slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT);
4734 160101534 : vno->unwind_to = *slot;
4735 160101534 : if (*slot)
4736 : {
4737 : /* Prefer non-predicated values.
4738 : ??? Only if those are constant, otherwise, with constant predicated
4739 : value, turn them into predicated values with entry-block validity
4740 : (??? but we always find the first valid result currently). */
4741 30612291 : if ((*slot)->predicated_values
4742 29843965 : && ! vno->predicated_values)
4743 : {
4744 : /* ??? We cannot remove *slot from the unwind stack list.
4745 : For the moment we deal with this by skipping not found
4746 : entries but this isn't ideal ... */
4747 86573 : *slot = vno;
4748 : /* ??? Maintain a stack of states we can unwind in
4749 : vn_nary_op_s? But how far do we unwind? In reality
4750 : we need to push change records somewhere... Or not
4751 : unwind vn_nary_op_s and linking them but instead
4752 : unwind the results "list", linking that, which also
4753 : doesn't move on hashtable resize. */
4754 : /* We can also have a ->unwind_to recording *slot there.
4755 : That way we can make u.values a fixed size array with
4756 : recording the number of entries but of course we then
4757 : have always N copies for each unwind_to-state. Or we
4758 : make sure to only ever append and each unwinding will
4759 : pop off one entry (but how to deal with predicated
4760 : replaced with non-predicated here?) */
4761 86573 : vno->next = last_inserted_nary;
4762 86573 : last_inserted_nary = vno;
4763 86573 : return vno;
4764 : }
4765 30525718 : else if (vno->predicated_values
4766 30525366 : && ! (*slot)->predicated_values)
4767 : return *slot;
4768 29757744 : else if (vno->predicated_values
4769 29757392 : && (*slot)->predicated_values)
4770 : {
4771 : /* ??? Factor this all into a insert_single_predicated_value
4772 : routine. */
4773 29757392 : gcc_assert (!vno->u.values->next && vno->u.values->n == 1);
4774 29757392 : basic_block vno_bb
4775 29757392 : = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]);
4776 29757392 : vn_pval *nval = vno->u.values;
4777 29757392 : vn_pval **next = &vno->u.values;
4778 29757392 : vn_pval *ins = NULL;
4779 29757392 : vn_pval *ins_at = NULL;
4780 : /* Find an existing value to append to. */
4781 55889316 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4782 : {
4783 30775269 : if (expressions_equal_p (val->result, nval->result))
4784 : {
4785 : /* Limit the number of places we register a predicate
4786 : as valid. */
4787 4643345 : if (val->n > 8)
4788 139646 : return *slot;
4789 11601451 : for (unsigned i = 0; i < val->n; ++i)
4790 : {
4791 7337985 : basic_block val_bb
4792 7337985 : = BASIC_BLOCK_FOR_FN (cfun,
4793 : val->valid_dominated_by_p[i]);
4794 7337985 : if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb))
4795 : /* Value registered with more generic predicate. */
4796 240233 : return *slot;
4797 7097752 : else if (flag_checking)
4798 : /* Shouldn't happen, we insert in RPO order. */
4799 7097752 : gcc_assert (!dominated_by_p (CDI_DOMINATORS,
4800 : val_bb, vno_bb));
4801 : }
4802 : /* Append the location. */
4803 4263466 : ins_at = val;
4804 4263466 : ins = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4805 : sizeof (vn_pval)
4806 : + val->n * sizeof (int));
4807 4263466 : ins->next = NULL;
4808 4263466 : ins->result = val->result;
4809 4263466 : ins->n = val->n + 1;
4810 4263466 : memcpy (ins->valid_dominated_by_p,
4811 4263466 : val->valid_dominated_by_p,
4812 4263466 : val->n * sizeof (int));
4813 4263466 : ins->valid_dominated_by_p[val->n] = vno_bb->index;
4814 4263466 : if (dump_file && (dump_flags & TDF_DETAILS))
4815 4 : fprintf (dump_file, "Appending predicate to value.\n");
4816 : break;
4817 : }
4818 : }
4819 : /* Copy the rest of the value chain. */
4820 60654659 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4821 : {
4822 31277146 : if (val == ins_at)
4823 : /* Replace the node we appended to. */
4824 4263466 : *next = ins;
4825 : else
4826 : {
4827 : /* Copy other predicated values. */
4828 27013680 : *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4829 : sizeof (vn_pval)
4830 : + ((val->n-1)
4831 : * sizeof (int)));
4832 27013680 : memcpy (*next, val,
4833 27013680 : sizeof (vn_pval) + (val->n-1) * sizeof (int));
4834 27013680 : (*next)->next = NULL;
4835 : }
4836 31277146 : next = &(*next)->next;
4837 : }
4838 : /* Append the value if we didn't find it. */
4839 29377513 : if (!ins_at)
4840 25114047 : *next = nval;
4841 29377513 : *slot = vno;
4842 29377513 : vno->next = last_inserted_nary;
4843 29377513 : last_inserted_nary = vno;
4844 29377513 : return vno;
4845 : }
4846 :
4847 : /* While we do not want to insert things twice it's awkward to
4848 : avoid it in the case where visit_nary_op pattern-matches stuff
4849 : and ends up simplifying the replacement to itself. We then
4850 : get two inserts, one from visit_nary_op and one from
4851 : vn_nary_build_or_lookup.
4852 : So allow inserts with the same value number. */
4853 352 : if ((*slot)->u.result == vno->u.result)
4854 : return *slot;
4855 : }
4856 :
4857 : /* ??? There's also optimistic vs. previous committed state merging
4858 : that is problematic for the case of unwinding. */
4859 :
4860 : /* ??? We should return NULL if we do not use 'vno' and have the
4861 : caller release it. */
4862 129489243 : gcc_assert (!*slot);
4863 :
4864 129489243 : *slot = vno;
4865 129489243 : vno->next = last_inserted_nary;
4866 129489243 : last_inserted_nary = vno;
4867 129489243 : return vno;
4868 : }
4869 :
4870 : /* Insert a n-ary operation into the current hash table using it's
4871 : pieces. Return the vn_nary_op_t structure we created and put in
4872 : the hashtable. */
4873 :
4874 : vn_nary_op_t
4875 553018 : vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
4876 : tree type, tree *ops,
4877 : tree result, unsigned int value_id)
4878 : {
4879 553018 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
4880 553018 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4881 553018 : return vn_nary_op_insert_into (vno1, valid_info->nary);
4882 : }
4883 :
4884 : /* Return whether we can track a predicate valid when PRED_E is executed. */
4885 :
4886 : static bool
4887 153417468 : can_track_predicate_on_edge (edge pred_e)
4888 : {
4889 : /* ??? As we are currently recording the destination basic-block index in
4890 : vn_pval.valid_dominated_by_p and using dominance for the
4891 : validity check we cannot track predicates on all edges. */
4892 153417468 : if (single_pred_p (pred_e->dest))
4893 : return true;
4894 : /* Never record for backedges. */
4895 12195351 : if (pred_e->flags & EDGE_DFS_BACK)
4896 : return false;
4897 : /* When there's more than one predecessor we cannot track
4898 : predicate validity based on the destination block. The
4899 : exception is when all other incoming edges sources are
4900 : dominated by the destination block. */
4901 11497611 : edge_iterator ei;
4902 11497611 : edge e;
4903 19724835 : FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
4904 17832162 : if (e != pred_e && ! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
4905 : return false;
4906 : return true;
4907 : }
4908 :
4909 : static vn_nary_op_t
4910 108714863 : vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
4911 : tree type, tree *ops,
4912 : tree result, unsigned int value_id,
4913 : edge pred_e)
4914 : {
4915 108714863 : if (flag_checking)
4916 108714043 : gcc_assert (can_track_predicate_on_edge (pred_e));
4917 :
4918 75410 : if (dump_file && (dump_flags & TDF_DETAILS)
4919 : /* ??? Fix dumping, but currently we only get comparisons. */
4920 108786183 : && TREE_CODE_CLASS (code) == tcc_comparison)
4921 : {
4922 71320 : fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index,
4923 71320 : pred_e->dest->index);
4924 71320 : print_generic_expr (dump_file, ops[0], TDF_SLIM);
4925 71320 : fprintf (dump_file, " %s ", get_tree_code_name (code));
4926 71320 : print_generic_expr (dump_file, ops[1], TDF_SLIM);
4927 106609 : fprintf (dump_file, " == %s\n",
4928 71320 : integer_zerop (result) ? "false" : "true");
4929 : }
4930 108714863 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id);
4931 108714863 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4932 108714863 : vno1->predicated_values = 1;
4933 108714863 : vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4934 : sizeof (vn_pval));
4935 108714863 : vno1->u.values->next = NULL;
4936 108714863 : vno1->u.values->result = result;
4937 108714863 : vno1->u.values->n = 1;
4938 108714863 : vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index;
4939 108714863 : return vn_nary_op_insert_into (vno1, valid_info->nary);
4940 : }
4941 :
4942 : static bool
4943 : dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool);
4944 :
4945 : static tree
4946 1776183 : vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb,
4947 : edge e = NULL)
4948 : {
4949 1776183 : if (! vno->predicated_values)
4950 0 : return vno->u.result;
4951 3697543 : for (vn_pval *val = vno->u.values; val; val = val->next)
4952 5704747 : for (unsigned i = 0; i < val->n; ++i)
4953 : {
4954 3783387 : basic_block cand
4955 3783387 : = BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]);
4956 : /* Do not handle backedge executability optimistically since
4957 : when figuring out whether to iterate we do not consider
4958 : changed predication.
4959 : When asking for predicated values on an edge avoid looking
4960 : at edge executability for edges forward in our iteration
4961 : as well. */
4962 3783387 : if (e && (e->flags & EDGE_DFS_BACK))
4963 : {
4964 23382 : if (dominated_by_p (CDI_DOMINATORS, bb, cand))
4965 7779 : return val->result;
4966 : }
4967 3760005 : else if (dominated_by_p_w_unex (bb, cand, false))
4968 543582 : return val->result;
4969 : }
4970 : return NULL_TREE;
4971 : }
4972 :
4973 : static tree
4974 214724 : vn_nary_op_get_predicated_value (vn_nary_op_t vno, edge e)
4975 : {
4976 0 : return vn_nary_op_get_predicated_value (vno, e->src, e);
4977 : }
4978 :
4979 : /* Insert the rhs of STMT into the current hash table with a value number of
4980 : RESULT. */
4981 :
4982 : static vn_nary_op_t
4983 45963193 : vn_nary_op_insert_stmt (gimple *stmt, tree result)
4984 : {
4985 45963193 : vn_nary_op_t vno1
4986 45963193 : = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
4987 45963193 : result, VN_INFO (result)->value_id);
4988 45963193 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
4989 45963193 : return vn_nary_op_insert_into (vno1, valid_info->nary);
4990 : }
4991 :
4992 : /* Compute a hashcode for PHI operation VP1 and return it. */
4993 :
4994 : static inline hashval_t
4995 50421574 : vn_phi_compute_hash (vn_phi_t vp1)
4996 : {
4997 50421574 : inchash::hash hstate;
4998 50421574 : tree phi1op;
4999 50421574 : tree type;
5000 50421574 : edge e;
5001 50421574 : edge_iterator ei;
5002 :
5003 100843148 : hstate.add_int (EDGE_COUNT (vp1->block->preds));
5004 50421574 : switch (EDGE_COUNT (vp1->block->preds))
5005 : {
5006 : case 1:
5007 : break;
5008 43409957 : case 2:
5009 : /* When this is a PHI node subject to CSE for different blocks
5010 : avoid hashing the block index. */
5011 43409957 : if (vp1->cclhs)
5012 : break;
5013 : /* Fallthru. */
5014 33996091 : default:
5015 33996091 : hstate.add_int (vp1->block->index);
5016 : }
5017 :
5018 : /* If all PHI arguments are constants we need to distinguish
5019 : the PHI node via its type. */
5020 50421574 : type = vp1->type;
5021 50421574 : hstate.merge_hash (vn_hash_type (type));
5022 :
5023 175155108 : FOR_EACH_EDGE (e, ei, vp1->block->preds)
5024 : {
5025 : /* Don't hash backedge values they need to be handled as VN_TOP
5026 : for optimistic value-numbering. */
5027 124733534 : if (e->flags & EDGE_DFS_BACK)
5028 27995524 : continue;
5029 :
5030 96738010 : phi1op = vp1->phiargs[e->dest_idx];
5031 96738010 : if (phi1op == VN_TOP)
5032 247134 : continue;
5033 96490876 : inchash::add_expr (phi1op, hstate);
5034 : }
5035 :
5036 50421574 : return hstate.end ();
5037 : }
5038 :
5039 :
5040 : /* Return true if COND1 and COND2 represent the same condition, set
5041 : *INVERTED_P if one needs to be inverted to make it the same as
5042 : the other. */
5043 :
5044 : static bool
5045 3814790 : cond_stmts_equal_p (gcond *cond1, tree lhs1, tree rhs1,
5046 : gcond *cond2, tree lhs2, tree rhs2, bool *inverted_p)
5047 : {
5048 3814790 : enum tree_code code1 = gimple_cond_code (cond1);
5049 3814790 : enum tree_code code2 = gimple_cond_code (cond2);
5050 :
5051 3814790 : *inverted_p = false;
5052 3814790 : if (code1 == code2)
5053 : ;
5054 300686 : else if (code1 == swap_tree_comparison (code2))
5055 : std::swap (lhs2, rhs2);
5056 264731 : else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
5057 131758 : *inverted_p = true;
5058 132973 : else if (code1 == invert_tree_comparison
5059 132973 : (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
5060 : {
5061 10380 : std::swap (lhs2, rhs2);
5062 10380 : *inverted_p = true;
5063 : }
5064 : else
5065 : return false;
5066 :
5067 3692197 : return ((expressions_equal_p (lhs1, lhs2)
5068 108164 : && expressions_equal_p (rhs1, rhs2))
5069 3717260 : || (commutative_tree_code (code1)
5070 1824203 : && expressions_equal_p (lhs1, rhs2)
5071 2349 : && expressions_equal_p (rhs1, lhs2)));
5072 : }
5073 :
5074 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
5075 :
5076 : static int
5077 40780916 : vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
5078 : {
5079 40780916 : if (vp1->hashcode != vp2->hashcode)
5080 : return false;
5081 :
5082 12820986 : if (vp1->block != vp2->block)
5083 : {
5084 11467371 : if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds))
5085 : return false;
5086 :
5087 36609409 : switch (EDGE_COUNT (vp1->block->preds))
5088 : {
5089 : case 1:
5090 : /* Single-arg PHIs are just copies. */
5091 : break;
5092 :
5093 3822457 : case 2:
5094 3822457 : {
5095 : /* Make sure both PHIs are classified as CSEable. */
5096 3822457 : if (! vp1->cclhs || ! vp2->cclhs)
5097 : return false;
5098 :
5099 : /* Rule out backedges into the PHI. */
5100 3822457 : gcc_checking_assert
5101 : (vp1->block->loop_father->header != vp1->block
5102 : && vp2->block->loop_father->header != vp2->block);
5103 :
5104 : /* If the PHI nodes do not have compatible types
5105 : they are not the same. */
5106 3822457 : if (!types_compatible_p (vp1->type, vp2->type))
5107 : return false;
5108 :
5109 : /* If the immediate dominator end in switch stmts multiple
5110 : values may end up in the same PHI arg via intermediate
5111 : CFG merges. */
5112 3814790 : basic_block idom1
5113 3814790 : = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5114 3814790 : basic_block idom2
5115 3814790 : = get_immediate_dominator (CDI_DOMINATORS, vp2->block);
5116 3814790 : gcc_checking_assert (EDGE_COUNT (idom1->succs) == 2
5117 : && EDGE_COUNT (idom2->succs) == 2);
5118 :
5119 : /* Verify the controlling stmt is the same. */
5120 7629580 : gcond *last1 = as_a <gcond *> (*gsi_last_bb (idom1));
5121 7629580 : gcond *last2 = as_a <gcond *> (*gsi_last_bb (idom2));
5122 3814790 : bool inverted_p;
5123 3814790 : if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
5124 3814790 : last2, vp2->cclhs, vp2->ccrhs,
5125 : &inverted_p))
5126 : return false;
5127 :
5128 : /* Get at true/false controlled edges into the PHI. */
5129 83197 : edge te1, te2, fe1, fe2;
5130 83197 : if (! extract_true_false_controlled_edges (idom1, vp1->block,
5131 : &te1, &fe1)
5132 83197 : || ! extract_true_false_controlled_edges (idom2, vp2->block,
5133 : &te2, &fe2))
5134 35590 : return false;
5135 :
5136 : /* Swap edges if the second condition is the inverted of the
5137 : first. */
5138 47607 : if (inverted_p)
5139 2038 : std::swap (te2, fe2);
5140 :
5141 : /* Since we do not know which edge will be executed we have
5142 : to be careful when matching VN_TOP. Be conservative and
5143 : only match VN_TOP == VN_TOP for now, we could allow
5144 : VN_TOP on the not prevailing PHI though. See for example
5145 : PR102920. */
5146 47607 : if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
5147 47607 : vp2->phiargs[te2->dest_idx], false)
5148 93401 : || ! expressions_equal_p (vp1->phiargs[fe1->dest_idx],
5149 45794 : vp2->phiargs[fe2->dest_idx], false))
5150 1813 : return false;
5151 :
5152 : return true;
5153 : }
5154 :
5155 : default:
5156 : return false;
5157 : }
5158 : }
5159 :
5160 : /* If the PHI nodes do not have compatible types
5161 : they are not the same. */
5162 8998529 : if (!types_compatible_p (vp1->type, vp2->type))
5163 : return false;
5164 :
5165 : /* Any phi in the same block will have it's arguments in the
5166 : same edge order, because of how we store phi nodes. */
5167 8997415 : unsigned nargs = EDGE_COUNT (vp1->block->preds);
5168 20859747 : for (unsigned i = 0; i < nargs; ++i)
5169 : {
5170 16688240 : tree phi1op = vp1->phiargs[i];
5171 16688240 : tree phi2op = vp2->phiargs[i];
5172 16688240 : if (phi1op == phi2op)
5173 11766343 : continue;
5174 4921897 : if (!expressions_equal_p (phi1op, phi2op, false))
5175 : return false;
5176 : }
5177 :
5178 : return true;
5179 : }
5180 :
5181 : /* Lookup PHI in the current hash table, and return the resulting
5182 : value number if it exists in the hash table. Return NULL_TREE if
5183 : it does not exist in the hash table. */
5184 :
5185 : static tree
5186 27627649 : vn_phi_lookup (gimple *phi, bool backedges_varying_p)
5187 : {
5188 27627649 : vn_phi_s **slot;
5189 27627649 : struct vn_phi_s *vp1;
5190 27627649 : edge e;
5191 27627649 : edge_iterator ei;
5192 :
5193 27627649 : vp1 = XALLOCAVAR (struct vn_phi_s,
5194 : sizeof (struct vn_phi_s)
5195 : + (gimple_phi_num_args (phi) - 1) * sizeof (tree));
5196 :
5197 : /* Canonicalize the SSA_NAME's to their value number. */
5198 95287729 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5199 : {
5200 67660080 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5201 67660080 : if (TREE_CODE (def) == SSA_NAME
5202 56294993 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5203 : {
5204 53748357 : if (!virtual_operand_p (def)
5205 53748357 : && ssa_undefined_value_p (def, false))
5206 137295 : def = VN_TOP;
5207 : else
5208 53611062 : def = SSA_VAL (def);
5209 : }
5210 67660080 : vp1->phiargs[e->dest_idx] = def;
5211 : }
5212 27627649 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5213 27627649 : vp1->block = gimple_bb (phi);
5214 : /* Extract values of the controlling condition. */
5215 27627649 : vp1->cclhs = NULL_TREE;
5216 27627649 : vp1->ccrhs = NULL_TREE;
5217 27627649 : if (EDGE_COUNT (vp1->block->preds) == 2
5218 27627649 : && vp1->block->loop_father->header != vp1->block)
5219 : {
5220 8667983 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5221 8667983 : if (EDGE_COUNT (idom1->succs) == 2)
5222 17245478 : if (gcond *last1 = safe_dyn_cast <gcond *> (*gsi_last_bb (idom1)))
5223 : {
5224 : /* ??? We want to use SSA_VAL here. But possibly not
5225 : allow VN_TOP. */
5226 8393260 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5227 8393260 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5228 : }
5229 : }
5230 27627649 : vp1->hashcode = vn_phi_compute_hash (vp1);
5231 27627649 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
5232 27627649 : if (!slot)
5233 : return NULL_TREE;
5234 4217301 : return (*slot)->result;
5235 : }
5236 :
5237 : /* Insert PHI into the current hash table with a value number of
5238 : RESULT. */
5239 :
5240 : static vn_phi_t
5241 22793925 : vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
5242 : {
5243 22793925 : vn_phi_s **slot;
5244 22793925 : vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack,
5245 : sizeof (vn_phi_s)
5246 : + ((gimple_phi_num_args (phi) - 1)
5247 : * sizeof (tree)));
5248 22793925 : edge e;
5249 22793925 : edge_iterator ei;
5250 :
5251 : /* Canonicalize the SSA_NAME's to their value number. */
5252 79867379 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5253 : {
5254 57073454 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5255 57073454 : if (TREE_CODE (def) == SSA_NAME
5256 46803049 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5257 : {
5258 44256848 : if (!virtual_operand_p (def)
5259 44256848 : && ssa_undefined_value_p (def, false))
5260 110083 : def = VN_TOP;
5261 : else
5262 44146765 : def = SSA_VAL (def);
5263 : }
5264 57073454 : vp1->phiargs[e->dest_idx] = def;
5265 : }
5266 22793925 : vp1->value_id = VN_INFO (result)->value_id;
5267 22793925 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5268 22793925 : vp1->block = gimple_bb (phi);
5269 : /* Extract values of the controlling condition. */
5270 22793925 : vp1->cclhs = NULL_TREE;
5271 22793925 : vp1->ccrhs = NULL_TREE;
5272 22793925 : if (EDGE_COUNT (vp1->block->preds) == 2
5273 22793925 : && vp1->block->loop_father->header != vp1->block)
5274 : {
5275 8302180 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5276 8302180 : if (EDGE_COUNT (idom1->succs) == 2)
5277 16517612 : if (gcond *last1 = safe_dyn_cast <gcond *> (*gsi_last_bb (idom1)))
5278 : {
5279 : /* ??? We want to use SSA_VAL here. But possibly not
5280 : allow VN_TOP. */
5281 8032223 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5282 8032223 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5283 : }
5284 : }
5285 22793925 : vp1->result = result;
5286 22793925 : vp1->hashcode = vn_phi_compute_hash (vp1);
5287 :
5288 22793925 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
5289 22793925 : gcc_assert (!*slot);
5290 :
5291 22793925 : *slot = vp1;
5292 22793925 : vp1->next = last_inserted_phi;
5293 22793925 : last_inserted_phi = vp1;
5294 22793925 : return vp1;
5295 : }
5296 :
5297 :
5298 : /* Return true if BB1 is dominated by BB2 taking into account edges
5299 : that are not executable. When ALLOW_BACK is false consider not
5300 : executable backedges as executable. */
5301 :
5302 : static bool
5303 75443351 : dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
5304 : {
5305 75443351 : edge_iterator ei;
5306 75443351 : edge e;
5307 :
5308 75443351 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5309 : return true;
5310 :
5311 : /* Before iterating we'd like to know if there exists a
5312 : (executable) path from bb2 to bb1 at all, if not we can
5313 : directly return false. For now simply iterate once. */
5314 :
5315 : /* Iterate to the single executable bb1 predecessor. */
5316 21945847 : if (EDGE_COUNT (bb1->preds) > 1)
5317 : {
5318 3039430 : edge prede = NULL;
5319 6659706 : FOR_EACH_EDGE (e, ei, bb1->preds)
5320 6201363 : if ((e->flags & EDGE_EXECUTABLE)
5321 660754 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5322 : {
5323 5620517 : if (prede)
5324 : {
5325 : prede = NULL;
5326 : break;
5327 : }
5328 : prede = e;
5329 : }
5330 3039430 : if (prede)
5331 : {
5332 458343 : bb1 = prede->src;
5333 :
5334 : /* Re-do the dominance check with changed bb1. */
5335 458343 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5336 : return true;
5337 : }
5338 : }
5339 :
5340 : /* Iterate to the single executable bb2 successor. */
5341 21683576 : if (EDGE_COUNT (bb2->succs) > 1)
5342 : {
5343 6793780 : edge succe = NULL;
5344 13756412 : FOR_EACH_EDGE (e, ei, bb2->succs)
5345 13587813 : if ((e->flags & EDGE_EXECUTABLE)
5346 207617 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5347 : {
5348 13380238 : if (succe)
5349 : {
5350 : succe = NULL;
5351 : break;
5352 : }
5353 : succe = e;
5354 : }
5355 6793780 : if (succe
5356 : /* Limit the number of edges we check, we should bring in
5357 : context from the iteration and compute the single
5358 : executable incoming edge when visiting a block. */
5359 6793780 : && EDGE_COUNT (succe->dest->preds) < 8)
5360 : {
5361 : /* Verify the reached block is only reached through succe.
5362 : If there is only one edge we can spare us the dominator
5363 : check and iterate directly. */
5364 129307 : if (EDGE_COUNT (succe->dest->preds) > 1)
5365 : {
5366 54647 : FOR_EACH_EDGE (e, ei, succe->dest->preds)
5367 42348 : if (e != succe
5368 27513 : && ((e->flags & EDGE_EXECUTABLE)
5369 18151 : || (!allow_back && (e->flags & EDGE_DFS_BACK))))
5370 : {
5371 : succe = NULL;
5372 : break;
5373 : }
5374 : }
5375 129307 : if (succe)
5376 : {
5377 119936 : bb2 = succe->dest;
5378 :
5379 : /* Re-do the dominance check with changed bb2. */
5380 119936 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5381 : return true;
5382 : }
5383 : }
5384 : }
5385 : /* Iterate to the single successor of bb2 with only a single executable
5386 : incoming edge. */
5387 14889796 : else if (EDGE_COUNT (bb2->succs) == 1
5388 14323247 : && EDGE_COUNT (single_succ (bb2)->preds) > 1
5389 : /* Limit the number of edges we check, we should bring in
5390 : context from the iteration and compute the single
5391 : executable incoming edge when visiting a block. */
5392 28956627 : && EDGE_COUNT (single_succ (bb2)->preds) < 8)
5393 : {
5394 5088665 : edge prede = NULL;
5395 11518800 : FOR_EACH_EDGE (e, ei, single_succ (bb2)->preds)
5396 10929180 : if ((e->flags & EDGE_EXECUTABLE)
5397 1393092 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5398 : {
5399 9540517 : if (prede)
5400 : {
5401 : prede = NULL;
5402 : break;
5403 : }
5404 : prede = e;
5405 : }
5406 : /* We might actually get to a query with BB2 not visited yet when
5407 : we're querying for a predicated value. */
5408 5088665 : if (prede && prede->src == bb2)
5409 : {
5410 528082 : bb2 = prede->dest;
5411 :
5412 : /* Re-do the dominance check with changed bb2. */
5413 528082 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5414 : return true;
5415 : }
5416 : }
5417 :
5418 : /* We could now iterate updating bb1 / bb2. */
5419 : return false;
5420 : }
5421 :
5422 : /* Set the value number of FROM to TO, return true if it has changed
5423 : as a result. */
5424 :
5425 : static inline bool
5426 207945103 : set_ssa_val_to (tree from, tree to)
5427 : {
5428 207945103 : vn_ssa_aux_t from_info = VN_INFO (from);
5429 207945103 : tree currval = from_info->valnum; // SSA_VAL (from)
5430 207945103 : poly_int64 toff, coff;
5431 207945103 : bool curr_undefined = false;
5432 207945103 : bool curr_invariant = false;
5433 :
5434 : /* The only thing we allow as value numbers are ssa_names
5435 : and invariants. So assert that here. We don't allow VN_TOP
5436 : as visiting a stmt should produce a value-number other than
5437 : that.
5438 : ??? Still VN_TOP can happen for unreachable code, so force
5439 : it to varying in that case. Not all code is prepared to
5440 : get VN_TOP on valueization. */
5441 207945103 : if (to == VN_TOP)
5442 : {
5443 : /* ??? When iterating and visiting PHI <undef, backedge-value>
5444 : for the first time we rightfully get VN_TOP and we need to
5445 : preserve that to optimize for example gcc.dg/tree-ssa/ssa-sccvn-2.c.
5446 : With SCCVN we were simply lucky we iterated the other PHI
5447 : cycles first and thus visited the backedge-value DEF. */
5448 0 : if (currval == VN_TOP)
5449 0 : goto set_and_exit;
5450 0 : if (dump_file && (dump_flags & TDF_DETAILS))
5451 0 : fprintf (dump_file, "Forcing value number to varying on "
5452 : "receiving VN_TOP\n");
5453 : to = from;
5454 : }
5455 :
5456 207945103 : gcc_checking_assert (to != NULL_TREE
5457 : && ((TREE_CODE (to) == SSA_NAME
5458 : && (to == from || SSA_VAL (to) == to))
5459 : || is_gimple_min_invariant (to)));
5460 :
5461 207945103 : if (from != to)
5462 : {
5463 33306238 : if (currval == from)
5464 : {
5465 13475 : if (dump_file && (dump_flags & TDF_DETAILS))
5466 : {
5467 0 : fprintf (dump_file, "Not changing value number of ");
5468 0 : print_generic_expr (dump_file, from);
5469 0 : fprintf (dump_file, " from VARYING to ");
5470 0 : print_generic_expr (dump_file, to);
5471 0 : fprintf (dump_file, "\n");
5472 : }
5473 13475 : return false;
5474 : }
5475 33292763 : curr_invariant = is_gimple_min_invariant (currval);
5476 66585526 : curr_undefined = (TREE_CODE (currval) == SSA_NAME
5477 3902177 : && !virtual_operand_p (currval)
5478 36964823 : && ssa_undefined_value_p (currval, false));
5479 33292763 : if (currval != VN_TOP
5480 : && !curr_invariant
5481 5441182 : && !curr_undefined
5482 37181721 : && is_gimple_min_invariant (to))
5483 : {
5484 220 : if (dump_file && (dump_flags & TDF_DETAILS))
5485 : {
5486 0 : fprintf (dump_file, "Forcing VARYING instead of changing "
5487 : "value number of ");
5488 0 : print_generic_expr (dump_file, from);
5489 0 : fprintf (dump_file, " from ");
5490 0 : print_generic_expr (dump_file, currval);
5491 0 : fprintf (dump_file, " (non-constant) to ");
5492 0 : print_generic_expr (dump_file, to);
5493 0 : fprintf (dump_file, " (constant)\n");
5494 : }
5495 : to = from;
5496 : }
5497 33292543 : else if (currval != VN_TOP
5498 5440962 : && !curr_undefined
5499 5427743 : && TREE_CODE (to) == SSA_NAME
5500 4572437 : && !virtual_operand_p (to)
5501 37634863 : && ssa_undefined_value_p (to, false))
5502 : {
5503 6 : if (dump_file && (dump_flags & TDF_DETAILS))
5504 : {
5505 0 : fprintf (dump_file, "Forcing VARYING instead of changing "
5506 : "value number of ");
5507 0 : print_generic_expr (dump_file, from);
5508 0 : fprintf (dump_file, " from ");
5509 0 : print_generic_expr (dump_file, currval);
5510 0 : fprintf (dump_file, " (non-undefined) to ");
5511 0 : print_generic_expr (dump_file, to);
5512 0 : fprintf (dump_file, " (undefined)\n");
5513 : }
5514 : to = from;
5515 : }
5516 33292537 : else if (TREE_CODE (to) == SSA_NAME
5517 33292537 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to))
5518 : to = from;
5519 : }
5520 :
5521 174638865 : set_and_exit:
5522 207931628 : if (dump_file && (dump_flags & TDF_DETAILS))
5523 : {
5524 398995 : fprintf (dump_file, "Setting value number of ");
5525 398995 : print_generic_expr (dump_file, from);
5526 398995 : fprintf (dump_file, " to ");
5527 398995 : print_generic_expr (dump_file, to);
5528 : }
5529 :
5530 207931628 : if (currval != to
5531 169719057 : && !operand_equal_p (currval, to, 0)
5532 : /* Different undefined SSA names are not actually different. See
5533 : PR82320 for a testcase were we'd otherwise not terminate iteration. */
5534 169649790 : && !(curr_undefined
5535 3440 : && TREE_CODE (to) == SSA_NAME
5536 608 : && !virtual_operand_p (to)
5537 608 : && ssa_undefined_value_p (to, false))
5538 : /* ??? For addresses involving volatile objects or types operand_equal_p
5539 : does not reliably detect ADDR_EXPRs as equal. We know we are only
5540 : getting invariant gimple addresses here, so can use
5541 : get_addr_base_and_unit_offset to do this comparison. */
5542 377580778 : && !(TREE_CODE (currval) == ADDR_EXPR
5543 468180 : && TREE_CODE (to) == ADDR_EXPR
5544 12 : && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff)
5545 6 : == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
5546 6 : && known_eq (coff, toff)))
5547 : {
5548 169649144 : if (to != from
5549 28876416 : && currval != VN_TOP
5550 1028458 : && !curr_undefined
5551 : /* We do not want to allow lattice transitions from one value
5552 : to another since that may lead to not terminating iteration
5553 : (see PR95049). Since there's no convenient way to check
5554 : for the allowed transition of VAL -> PHI (loop entry value,
5555 : same on two PHIs, to same PHI result) we restrict the check
5556 : to invariants. */
5557 1028458 : && curr_invariant
5558 170332837 : && is_gimple_min_invariant (to))
5559 : {
5560 0 : if (dump_file && (dump_flags & TDF_DETAILS))
5561 0 : fprintf (dump_file, " forced VARYING");
5562 : to = from;
5563 : }
5564 169649144 : if (dump_file && (dump_flags & TDF_DETAILS))
5565 398679 : fprintf (dump_file, " (changed)\n");
5566 169649144 : from_info->valnum = to;
5567 169649144 : return true;
5568 : }
5569 38282484 : if (dump_file && (dump_flags & TDF_DETAILS))
5570 316 : fprintf (dump_file, "\n");
5571 : return false;
5572 : }
5573 :
5574 : /* Set all definitions in STMT to value number to themselves.
5575 : Return true if a value number changed. */
5576 :
5577 : static bool
5578 299246492 : defs_to_varying (gimple *stmt)
5579 : {
5580 299246492 : bool changed = false;
5581 299246492 : ssa_op_iter iter;
5582 299246492 : def_operand_p defp;
5583 :
5584 329299477 : FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
5585 : {
5586 30052985 : tree def = DEF_FROM_PTR (defp);
5587 30052985 : changed |= set_ssa_val_to (def, def);
5588 : }
5589 299246492 : return changed;
5590 : }
5591 :
5592 : /* Visit a copy between LHS and RHS, return true if the value number
5593 : changed. */
5594 :
5595 : static bool
5596 8136485 : visit_copy (tree lhs, tree rhs)
5597 : {
5598 : /* Valueize. */
5599 8136485 : rhs = SSA_VAL (rhs);
5600 :
5601 8136485 : return set_ssa_val_to (lhs, rhs);
5602 : }
5603 :
5604 : /* Lookup a value for OP in type WIDE_TYPE where the value in type of OP
5605 : is the same. */
5606 :
5607 : static tree
5608 2497645 : valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
5609 : {
5610 2497645 : if (TREE_CODE (op) == SSA_NAME)
5611 2193362 : op = vn_valueize (op);
5612 :
5613 : /* Either we have the op widened available. */
5614 2497645 : tree ops[3] = {};
5615 2497645 : ops[0] = op;
5616 2497645 : tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR,
5617 : wide_type, ops, NULL);
5618 2497645 : if (tem)
5619 : return tem;
5620 :
5621 : /* Or the op is truncated from some existing value. */
5622 2203198 : if (allow_truncate && TREE_CODE (op) == SSA_NAME)
5623 : {
5624 556761 : gimple *def = SSA_NAME_DEF_STMT (op);
5625 556761 : if (is_gimple_assign (def)
5626 556761 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5627 : {
5628 300028 : tem = gimple_assign_rhs1 (def);
5629 300028 : if (useless_type_conversion_p (wide_type, TREE_TYPE (tem)))
5630 : {
5631 202754 : if (TREE_CODE (tem) == SSA_NAME)
5632 202754 : tem = vn_valueize (tem);
5633 202754 : return tem;
5634 : }
5635 : }
5636 : }
5637 :
5638 : /* For constants simply extend it. */
5639 2000444 : if (TREE_CODE (op) == INTEGER_CST)
5640 337726 : return wide_int_to_tree (wide_type, wi::to_widest (op));
5641 :
5642 : return NULL_TREE;
5643 : }
5644 :
5645 : /* Return true if RESULT, the result of a value-number lookup, may be
5646 : used at the statement being visited. A result of wrapping type can
5647 : be inserted for code hoisting without introducing undefined
5648 : overflow; anything else has to be available. See PR86554. */
5649 :
5650 : static bool
5651 21714 : vn_nary_result_avail_or_insertable_p (tree result)
5652 : {
5653 21714 : return (TYPE_OVERFLOW_WRAPS (TREE_TYPE (result))
5654 13764 : || (rpo_avail && vn_context_bb
5655 13764 : && rpo_avail->eliminate_avail (vn_context_bb, result)));
5656 : }
5657 :
5658 : /* If OP is an SSA name defined by a conversion from an integral type,
5659 : return the valueized source of the conversion, otherwise return
5660 : NULL_TREE. */
5661 :
5662 : static tree
5663 14162354 : ssa_integral_conversion_op (tree op)
5664 : {
5665 14162354 : if (TREE_CODE (op) != SSA_NAME)
5666 : return NULL_TREE;
5667 13836058 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
5668 11596400 : if (!def || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5669 : return NULL_TREE;
5670 1487130 : const tree src = gimple_assign_rhs1 (def);
5671 1487130 : if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
5672 : return NULL_TREE;
5673 1232316 : return vn_valueize (src);
5674 : }
5675 :
5676 : /* Visit a nary operator RHS, value number it, and return true if the
5677 : value number of LHS has changed as a result. */
5678 :
5679 : static bool
5680 49765087 : visit_nary_op (tree lhs, gassign *stmt)
5681 : {
5682 49765087 : vn_nary_op_t vnresult;
5683 49765087 : tree result = vn_nary_op_lookup_stmt (stmt, &vnresult);
5684 49765087 : if (! result && vnresult)
5685 156477 : result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt));
5686 46035636 : if (result)
5687 3799355 : return set_ssa_val_to (lhs, result);
5688 :
5689 : /* Do some special pattern matching for redundancies of operations
5690 : in different types. */
5691 45965732 : enum tree_code code = gimple_assign_rhs_code (stmt);
5692 45965732 : tree type = TREE_TYPE (lhs);
5693 45965732 : tree rhs1 = gimple_assign_rhs1 (stmt);
5694 45965732 : switch (code)
5695 : {
5696 10164450 : CASE_CONVERT:
5697 : /* Match arithmetic done in a different type where we can easily
5698 : substitute the result from some earlier sign-changed or widened
5699 : operation. */
5700 10164450 : if (INTEGRAL_TYPE_P (type)
5701 9107036 : && TREE_CODE (rhs1) == SSA_NAME
5702 : /* We only handle sign-changes, zero-extension -> & mask or
5703 : sign-extension if we know the inner operation doesn't
5704 : overflow. */
5705 19033760 : && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
5706 5365193 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5707 5364400 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5708 8140885 : && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
5709 6018298 : || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
5710 : {
5711 7759244 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5712 5679976 : if (def
5713 5679976 : && (gimple_assign_rhs_code (def) == PLUS_EXPR
5714 4441274 : || gimple_assign_rhs_code (def) == MINUS_EXPR
5715 4286022 : || gimple_assign_rhs_code (def) == MULT_EXPR))
5716 : {
5717 2011745 : tree ops[3] = {};
5718 : /* When requiring a sign-extension we cannot model a
5719 : previous truncation with a single op so don't bother. */
5720 2011745 : bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
5721 : /* Either we have the op widened available. */
5722 2011745 : ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
5723 : allow_truncate);
5724 2011745 : if (ops[0])
5725 971800 : ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
5726 : allow_truncate);
5727 2011745 : if (ops[0] && ops[1])
5728 : {
5729 349027 : ops[0] = vn_nary_op_lookup_pieces
5730 349027 : (2, gimple_assign_rhs_code (def), type, ops, NULL);
5731 : /* We have wider operation available. */
5732 349027 : if (ops[0] && vn_nary_result_avail_or_insertable_p (ops[0]))
5733 : {
5734 7870 : unsigned lhs_prec = TYPE_PRECISION (type);
5735 7870 : unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
5736 7870 : if (lhs_prec == rhs_prec
5737 7870 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5738 767 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5739 : {
5740 7275 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5741 7275 : NOP_EXPR, type, ops[0]);
5742 7275 : result = vn_nary_build_or_lookup (&match_op);
5743 7275 : if (result)
5744 : {
5745 7275 : bool changed = set_ssa_val_to (lhs, result);
5746 7275 : if (TREE_CODE (result) == SSA_NAME)
5747 7275 : vn_nary_op_insert_stmt (stmt, result);
5748 7275 : return changed;
5749 : }
5750 : }
5751 : else
5752 : {
5753 595 : tree mask = wide_int_to_tree
5754 595 : (type, wi::mask (rhs_prec, false, lhs_prec));
5755 595 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5756 595 : BIT_AND_EXPR,
5757 595 : TREE_TYPE (lhs),
5758 595 : ops[0], mask);
5759 595 : result = vn_nary_build_or_lookup (&match_op);
5760 595 : if (result)
5761 : {
5762 595 : bool changed = set_ssa_val_to (lhs, result);
5763 595 : if (TREE_CODE (result) == SSA_NAME)
5764 595 : vn_nary_op_insert_stmt (stmt, result);
5765 595 : return changed;
5766 : }
5767 : }
5768 : }
5769 : }
5770 : }
5771 : }
5772 : break;
5773 13804472 : case PLUS_EXPR:
5774 13804472 : case MINUS_EXPR:
5775 13804472 : {
5776 : /* Match (T)A +- B against an existing (T)(A +- B'), the inverse
5777 : of the conversion case above, so the redundancy is detected
5778 : regardless of the order the two forms appear in the IL.
5779 : See PR124545. The narrow operation is only ever looked up,
5780 : never created: assuming no overflow is only valid for
5781 : operations the program actually executes, so the narrow
5782 : leader has to be available. Creating the narrow operation
5783 : instead is wrong-code, see PR126415. */
5784 13804472 : const tree narrow1 = ssa_integral_conversion_op (vn_valueize (rhs1));
5785 13804472 : if (!INTEGRAL_TYPE_P (type) || !narrow1)
5786 : break;
5787 1083079 : const tree ntype = TREE_TYPE (narrow1);
5788 : /* A sign-change keeps the value bit-identical; a widening is
5789 : only handled when the narrow operation cannot wrap. */
5790 1083079 : const bool sign_change_p
5791 1083079 : = TYPE_PRECISION (ntype) == TYPE_PRECISION (type);
5792 1083079 : const bool nowrap_widening_p
5793 1083079 : = (TYPE_PRECISION (ntype) < TYPE_PRECISION (type)
5794 1083079 : && TYPE_OVERFLOW_UNDEFINED (ntype));
5795 1083079 : if (!sign_change_p && !nowrap_widening_p)
5796 : break;
5797 : /* Determine the narrow variant of the second operand: a
5798 : constant that narrows and extends back unchanged, or a
5799 : conversion from the same narrow type. */
5800 828103 : const tree rhs2 = gimple_assign_rhs2 (stmt);
5801 828103 : tree narrow2 = NULL_TREE;
5802 828103 : if (TREE_CODE (rhs2) == INTEGER_CST)
5803 : {
5804 470221 : const widest_int cst = wi::to_widest (rhs2);
5805 470221 : const widest_int narrowed
5806 470221 : = wi::ext (cst, TYPE_PRECISION (ntype), TYPE_SIGN (ntype));
5807 470221 : const widest_int extended
5808 470221 : = wi::ext (narrowed, TYPE_PRECISION (type), TYPE_SIGN (type));
5809 470221 : if (cst == extended)
5810 468685 : narrow2 = fold_convert (ntype, rhs2);
5811 470227 : }
5812 357882 : else if (TREE_CODE (rhs2) == SSA_NAME)
5813 : {
5814 357882 : const tree op = ssa_integral_conversion_op (vn_valueize (rhs2));
5815 357882 : if (op && types_compatible_p (TREE_TYPE (op), ntype))
5816 : narrow2 = op;
5817 : }
5818 608751 : if (!narrow2)
5819 : break;
5820 607215 : tree ops[3] = { narrow1, narrow2 };
5821 607215 : const tree narrow_val
5822 607215 : = vn_nary_op_lookup_pieces (2, code, ntype, ops, NULL);
5823 : /* We have a narrower or sign-changed operation available. */
5824 607215 : if (narrow_val && vn_nary_result_avail_or_insertable_p (narrow_val))
5825 : {
5826 11310 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5827 11310 : NOP_EXPR, type, narrow_val);
5828 11310 : result = vn_nary_build_or_lookup (&match_op);
5829 11310 : if (result)
5830 : {
5831 11310 : const bool changed = set_ssa_val_to (lhs, result);
5832 11310 : if (TREE_CODE (result) == SSA_NAME)
5833 11310 : vn_nary_op_insert_stmt (stmt, result);
5834 11310 : return changed;
5835 : }
5836 : }
5837 : }
5838 595905 : break;
5839 1529233 : case BIT_AND_EXPR:
5840 1529233 : if (INTEGRAL_TYPE_P (type)
5841 1487966 : && TREE_CODE (rhs1) == SSA_NAME
5842 1487966 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
5843 904903 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)
5844 904785 : && default_vn_walk_kind != VN_NOWALK
5845 : && CHAR_BIT == 8
5846 : && BITS_PER_UNIT == 8
5847 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
5848 904576 : && TYPE_PRECISION (type) <= vn_walk_cb_data::bufsize * BITS_PER_UNIT
5849 904574 : && !integer_all_onesp (gimple_assign_rhs2 (stmt))
5850 2433807 : && !integer_zerop (gimple_assign_rhs2 (stmt)))
5851 : {
5852 904574 : gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5853 665227 : if (ass
5854 665227 : && !gimple_has_volatile_ops (ass)
5855 663765 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5856 : {
5857 304163 : tree last_vuse = gimple_vuse (ass);
5858 304163 : tree op = gimple_assign_rhs1 (ass);
5859 912489 : tree result = vn_reference_lookup (op, gimple_vuse (ass),
5860 : default_vn_walk_kind,
5861 : NULL, true, &last_vuse,
5862 : gimple_assign_rhs2 (stmt));
5863 304163 : if (result
5864 304622 : && useless_type_conversion_p (TREE_TYPE (result),
5865 459 : TREE_TYPE (op)))
5866 459 : return set_ssa_val_to (lhs, result);
5867 : }
5868 : }
5869 : break;
5870 280893 : case BIT_FIELD_REF:
5871 280893 : if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
5872 : {
5873 280865 : tree op0 = vn_valueize (TREE_OPERAND (rhs1, 0));
5874 280865 : gassign *ass;
5875 280865 : if (TREE_CODE (op0) == SSA_NAME
5876 280865 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)))
5877 235614 : && !gimple_has_volatile_ops (ass)
5878 516396 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5879 : {
5880 99060 : tree last_vuse = gimple_vuse (ass);
5881 99060 : tree op = gimple_assign_rhs1 (ass);
5882 : /* Avoid building invalid and unexpected refs. */
5883 99060 : if (TREE_CODE (op) != TARGET_MEM_REF
5884 : && TREE_CODE (op) != BIT_FIELD_REF
5885 : && TREE_CODE (op) != REALPART_EXPR
5886 : && TREE_CODE (op) != IMAGPART_EXPR)
5887 : {
5888 91287 : tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1),
5889 : gimple_assign_rhs1 (ass),
5890 91287 : TREE_OPERAND (rhs1, 1),
5891 91287 : TREE_OPERAND (rhs1, 2));
5892 182574 : tree result = vn_reference_lookup (op, gimple_vuse (ass),
5893 : default_vn_walk_kind,
5894 : NULL, true, &last_vuse);
5895 91287 : if (result
5896 91287 : && useless_type_conversion_p (type, TREE_TYPE (result)))
5897 2553 : return set_ssa_val_to (lhs, result);
5898 89220 : else if (result
5899 486 : && TYPE_SIZE (type)
5900 486 : && TYPE_SIZE (TREE_TYPE (result))
5901 89706 : && operand_equal_p (TYPE_SIZE (type),
5902 486 : TYPE_SIZE (TREE_TYPE (result))))
5903 : {
5904 486 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5905 486 : VIEW_CONVERT_EXPR,
5906 486 : type, result);
5907 486 : result = vn_nary_build_or_lookup (&match_op);
5908 486 : if (result)
5909 : {
5910 486 : bool changed = set_ssa_val_to (lhs, result);
5911 486 : if (TREE_CODE (result) == SSA_NAME)
5912 474 : vn_nary_op_insert_stmt (stmt, result);
5913 486 : return changed;
5914 : }
5915 : }
5916 : }
5917 : }
5918 : }
5919 : break;
5920 344785 : case TRUNC_DIV_EXPR:
5921 344785 : if (TYPE_UNSIGNED (type))
5922 : break;
5923 : /* Fallthru. */
5924 5579253 : case RDIV_EXPR:
5925 5579253 : case MULT_EXPR:
5926 : /* Match up ([-]a){/,*}([-])b with v=a{/,*}b, replacing it with -v. */
5927 5579253 : if (! HONOR_SIGN_DEPENDENT_ROUNDING (type))
5928 : {
5929 5578343 : tree rhs[2];
5930 5578343 : rhs[0] = rhs1;
5931 5578343 : rhs[1] = gimple_assign_rhs2 (stmt);
5932 16728190 : for (unsigned i = 0; i <= 1; ++i)
5933 : {
5934 11155528 : unsigned j = i == 0 ? 1 : 0;
5935 11155528 : tree ops[2];
5936 11155528 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5937 11155528 : NEGATE_EXPR, type, rhs[i]);
5938 11155528 : ops[i] = vn_nary_build_or_lookup_1 (&match_op, false, true);
5939 11155528 : ops[j] = rhs[j];
5940 11155528 : if (ops[i]
5941 11155528 : && (ops[0] = vn_nary_op_lookup_pieces (2, code,
5942 : type, ops, NULL)))
5943 : {
5944 5681 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5945 5681 : NEGATE_EXPR, type, ops[0]);
5946 5681 : result = vn_nary_build_or_lookup_1 (&match_op, true, false);
5947 5681 : if (result)
5948 : {
5949 5681 : bool changed = set_ssa_val_to (lhs, result);
5950 5681 : if (TREE_CODE (result) == SSA_NAME)
5951 5681 : vn_nary_op_insert_stmt (stmt, result);
5952 5681 : return changed;
5953 : }
5954 : }
5955 : }
5956 : }
5957 : break;
5958 370774 : case LSHIFT_EXPR:
5959 : /* For X << C, use the value number of X * (1 << C). */
5960 370774 : if (INTEGRAL_TYPE_P (type)
5961 354768 : && TYPE_OVERFLOW_WRAPS (type)
5962 560127 : && !TYPE_SATURATING (type))
5963 : {
5964 189353 : tree rhs2 = gimple_assign_rhs2 (stmt);
5965 189353 : if (TREE_CODE (rhs2) == INTEGER_CST
5966 109970 : && tree_fits_uhwi_p (rhs2)
5967 299323 : && tree_to_uhwi (rhs2) < TYPE_PRECISION (type))
5968 : {
5969 109970 : wide_int w = wi::set_bit_in_zero (tree_to_uhwi (rhs2),
5970 109970 : TYPE_PRECISION (type));
5971 219940 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5972 109970 : MULT_EXPR, type, rhs1,
5973 109970 : wide_int_to_tree (type, w));
5974 109970 : result = vn_nary_build_or_lookup (&match_op);
5975 109970 : if (result)
5976 : {
5977 109970 : bool changed = set_ssa_val_to (lhs, result);
5978 109970 : if (TREE_CODE (result) == SSA_NAME)
5979 109969 : vn_nary_op_insert_stmt (stmt, result);
5980 109970 : return changed;
5981 : }
5982 109970 : }
5983 : }
5984 : break;
5985 : default:
5986 : break;
5987 : }
5988 :
5989 45827889 : bool changed = set_ssa_val_to (lhs, lhs);
5990 45827889 : vn_nary_op_insert_stmt (stmt, lhs);
5991 45827889 : return changed;
5992 : }
5993 :
5994 : /* Visit a call STMT storing into LHS. Return true if the value number
5995 : of the LHS has changed as a result. */
5996 :
5997 : static bool
5998 8676497 : visit_reference_op_call (tree lhs, gcall *stmt)
5999 : {
6000 8676497 : bool changed = false;
6001 8676497 : struct vn_reference_s vr1;
6002 8676497 : vn_reference_t vnresult = NULL;
6003 8676497 : tree vdef = gimple_vdef (stmt);
6004 8676497 : modref_summary *summary;
6005 :
6006 : /* Non-ssa lhs is handled in copy_reference_ops_from_call. */
6007 8676497 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
6008 4617585 : lhs = NULL_TREE;
6009 :
6010 8676497 : vn_reference_lookup_call (stmt, &vnresult, &vr1);
6011 :
6012 : /* If the lookup did not succeed for pure functions try to use
6013 : modref info to find a candidate to CSE to. */
6014 8676497 : const unsigned accesses_limit = 8;
6015 8676497 : if (!vnresult
6016 8010069 : && !vdef
6017 8010069 : && lhs
6018 2808816 : && gimple_vuse (stmt)
6019 10241027 : && (((summary = get_modref_function_summary (stmt, NULL))
6020 217808 : && !summary->global_memory_read
6021 86292 : && summary->load_accesses < accesses_limit)
6022 1478591 : || gimple_call_flags (stmt) & ECF_CONST))
6023 : {
6024 : /* First search if we can do something useful and build a
6025 : vector of all loads we have to check. */
6026 86662 : bool unknown_memory_access = false;
6027 86662 : auto_vec<ao_ref, accesses_limit> accesses;
6028 86662 : unsigned load_accesses = summary ? summary->load_accesses : 0;
6029 86662 : if (!unknown_memory_access)
6030 : /* Add loads done as part of setting up the call arguments.
6031 : That's also necessary for CONST functions which will
6032 : not have a modref summary. */
6033 260077 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
6034 : {
6035 173423 : tree arg = gimple_call_arg (stmt, i);
6036 173423 : if (TREE_CODE (arg) != SSA_NAME
6037 173423 : && !is_gimple_min_invariant (arg))
6038 : {
6039 64660 : if (accesses.length () >= accesses_limit - load_accesses)
6040 : {
6041 : unknown_memory_access = true;
6042 : break;
6043 : }
6044 32322 : accesses.quick_grow (accesses.length () + 1);
6045 32322 : ao_ref_init (&accesses.last (), arg);
6046 : }
6047 : }
6048 86662 : if (summary && !unknown_memory_access)
6049 : {
6050 : /* Add loads as analyzed by IPA modref. */
6051 304891 : for (auto base_node : summary->loads->bases)
6052 77461 : if (unknown_memory_access)
6053 : break;
6054 315075 : else for (auto ref_node : base_node->refs)
6055 83643 : if (unknown_memory_access)
6056 : break;
6057 350524 : else for (auto access_node : ref_node->accesses)
6058 : {
6059 232170 : accesses.quick_grow (accesses.length () + 1);
6060 116085 : ao_ref *r = &accesses.last ();
6061 116085 : if (!access_node.get_ao_ref (stmt, r))
6062 : {
6063 : /* Initialize a ref based on the argument and
6064 : unknown offset if possible. */
6065 16454 : tree arg = access_node.get_call_arg (stmt);
6066 16454 : if (arg && TREE_CODE (arg) == SSA_NAME)
6067 2987 : arg = SSA_VAL (arg);
6068 2987 : if (arg
6069 16444 : && TREE_CODE (arg) == ADDR_EXPR
6070 13463 : && (arg = get_base_address (arg))
6071 16450 : && DECL_P (arg))
6072 : {
6073 0 : ao_ref_init (r, arg);
6074 0 : r->ref = NULL_TREE;
6075 0 : r->base = arg;
6076 : }
6077 : else
6078 : {
6079 : unknown_memory_access = true;
6080 : break;
6081 : }
6082 : }
6083 99631 : r->base_alias_set = base_node->base;
6084 99631 : r->ref_alias_set = ref_node->ref;
6085 : }
6086 : }
6087 :
6088 : /* Walk the VUSE->VDEF chain optimistically trying to find an entry
6089 : for the call in the hashtable. */
6090 86662 : unsigned limit = (unknown_memory_access
6091 86662 : ? 0
6092 70200 : : (param_sccvn_max_alias_queries_per_access
6093 70200 : / (accesses.length () + 1)));
6094 86662 : tree saved_vuse = vr1.vuse;
6095 86662 : hashval_t saved_hashcode = vr1.hashcode;
6096 504372 : while (limit > 0 && !vnresult && !SSA_NAME_IS_DEFAULT_DEF (vr1.vuse))
6097 : {
6098 445842 : vr1.hashcode = vr1.hashcode - SSA_NAME_VERSION (vr1.vuse);
6099 445842 : gimple *def = SSA_NAME_DEF_STMT (vr1.vuse);
6100 : /* ??? We could use fancy stuff like in walk_non_aliased_vuses, but
6101 : do not bother for now. */
6102 445842 : if (is_a <gphi *> (def))
6103 : break;
6104 835420 : vr1.vuse = vuse_ssa_val (gimple_vuse (def));
6105 417710 : vr1.hashcode = vr1.hashcode + SSA_NAME_VERSION (vr1.vuse);
6106 417710 : vn_reference_lookup_1 (&vr1, &vnresult);
6107 417710 : limit--;
6108 : }
6109 :
6110 : /* If we found a candidate to CSE to verify it is valid. */
6111 86662 : if (vnresult && !accesses.is_empty ())
6112 : {
6113 1925 : tree vuse = vuse_ssa_val (gimple_vuse (stmt));
6114 7156 : while (vnresult && vuse != vr1.vuse)
6115 : {
6116 3306 : gimple *def = SSA_NAME_DEF_STMT (vuse);
6117 17359 : for (auto &ref : accesses)
6118 : {
6119 : /* ??? stmt_may_clobber_ref_p_1 does per stmt constant
6120 : analysis overhead that we might be able to cache. */
6121 9188 : if (stmt_may_clobber_ref_p_1 (def, &ref, true))
6122 : {
6123 1747 : vnresult = NULL;
6124 1747 : break;
6125 : }
6126 : }
6127 6612 : vuse = vuse_ssa_val (gimple_vuse (def));
6128 : }
6129 : }
6130 86662 : vr1.vuse = saved_vuse;
6131 86662 : vr1.hashcode = saved_hashcode;
6132 86662 : }
6133 :
6134 8676497 : if (vnresult)
6135 : {
6136 666634 : if (vdef)
6137 : {
6138 175380 : if (vnresult->result_vdef)
6139 175380 : changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
6140 0 : else if (!lhs && gimple_call_lhs (stmt))
6141 : /* If stmt has non-SSA_NAME lhs, value number the vdef to itself,
6142 : as the call still acts as a lhs store. */
6143 0 : changed |= set_ssa_val_to (vdef, vdef);
6144 : else
6145 : /* If the call was discovered to be pure or const reflect
6146 : that as far as possible. */
6147 0 : changed |= set_ssa_val_to (vdef,
6148 : vuse_ssa_val (gimple_vuse (stmt)));
6149 : }
6150 :
6151 666634 : if (!vnresult->result && lhs)
6152 0 : vnresult->result = lhs;
6153 :
6154 666634 : if (vnresult->result && lhs)
6155 125044 : changed |= set_ssa_val_to (lhs, vnresult->result);
6156 : }
6157 : else
6158 : {
6159 8009863 : vn_reference_t vr2;
6160 8009863 : vn_reference_s **slot;
6161 8009863 : tree vdef_val = vdef;
6162 8009863 : if (vdef)
6163 : {
6164 : /* If we value numbered an indirect functions function to
6165 : one not clobbering memory value number its VDEF to its
6166 : VUSE. */
6167 4882316 : tree fn = gimple_call_fn (stmt);
6168 4882316 : if (fn && TREE_CODE (fn) == SSA_NAME)
6169 : {
6170 129384 : fn = SSA_VAL (fn);
6171 129384 : if (TREE_CODE (fn) == ADDR_EXPR
6172 1972 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
6173 1972 : && (flags_from_decl_or_type (TREE_OPERAND (fn, 0))
6174 1972 : & (ECF_CONST | ECF_PURE))
6175 : /* If stmt has non-SSA_NAME lhs, value number the
6176 : vdef to itself, as the call still acts as a lhs
6177 : store. */
6178 130757 : && (lhs || gimple_call_lhs (stmt) == NULL_TREE))
6179 2604 : vdef_val = vuse_ssa_val (gimple_vuse (stmt));
6180 : }
6181 4882316 : changed |= set_ssa_val_to (vdef, vdef_val);
6182 : }
6183 8009863 : if (lhs)
6184 3933868 : changed |= set_ssa_val_to (lhs, lhs);
6185 8009863 : vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s);
6186 8009863 : vr2->vuse = vr1.vuse;
6187 : /* As we are not walking the virtual operand chain we know the
6188 : shared_lookup_references are still original so we can re-use
6189 : them here. */
6190 8009863 : vr2->operands = vr1.operands.copy ();
6191 8009863 : vr2->type = vr1.type;
6192 8009863 : vr2->punned = vr1.punned;
6193 8009863 : vr2->set = vr1.set;
6194 8009863 : vr2->offset = vr1.offset;
6195 8009863 : vr2->max_size = vr1.max_size;
6196 8009863 : vr2->base_set = vr1.base_set;
6197 8009863 : vr2->hashcode = vr1.hashcode;
6198 8009863 : vr2->result = lhs;
6199 8009863 : vr2->result_vdef = vdef_val;
6200 8009863 : vr2->value_id = 0;
6201 8009863 : slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
6202 : INSERT);
6203 8009863 : gcc_assert (!*slot);
6204 8009863 : *slot = vr2;
6205 8009863 : vr2->next = last_inserted_ref;
6206 8009863 : last_inserted_ref = vr2;
6207 : }
6208 :
6209 8676497 : return changed;
6210 : }
6211 :
6212 : /* Visit a load from a reference operator RHS, part of STMT, value number it,
6213 : and return true if the value number of the LHS has changed as a result. */
6214 :
6215 : static bool
6216 34914863 : visit_reference_op_load (tree lhs, tree op, gimple *stmt)
6217 : {
6218 34914863 : bool changed = false;
6219 34914863 : tree result;
6220 34914863 : vn_reference_t res;
6221 :
6222 34914863 : tree vuse = gimple_vuse (stmt);
6223 34914863 : tree last_vuse = vuse;
6224 34914863 : result = vn_reference_lookup (op, vuse, default_vn_walk_kind, &res, true, &last_vuse);
6225 :
6226 : /* We handle type-punning through unions by value-numbering based
6227 : on offset and size of the access. Be prepared to handle a
6228 : type-mismatch here via creating a VIEW_CONVERT_EXPR. */
6229 34914863 : if (result
6230 34914863 : && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
6231 : {
6232 18601 : if (CONSTANT_CLASS_P (result))
6233 4233 : result = const_unop (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
6234 : else
6235 : {
6236 : /* We will be setting the value number of lhs to the value number
6237 : of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
6238 : So first simplify and lookup this expression to see if it
6239 : is already available. */
6240 14368 : gimple_match_op res_op (gimple_match_cond::UNCOND,
6241 14368 : VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
6242 14368 : result = vn_nary_build_or_lookup (&res_op);
6243 14368 : if (result
6244 14362 : && TREE_CODE (result) == SSA_NAME
6245 27072 : && VN_INFO (result)->needs_insertion)
6246 : /* Track whether this is the canonical expression for different
6247 : typed loads. We use that as a stopgap measure for code
6248 : hoisting when dealing with floating point loads. */
6249 11436 : res->punned = true;
6250 : }
6251 :
6252 : /* When building the conversion fails avoid inserting the reference
6253 : again. */
6254 18601 : if (!result)
6255 6 : return set_ssa_val_to (lhs, lhs);
6256 : }
6257 :
6258 34896262 : if (result)
6259 5664428 : changed = set_ssa_val_to (lhs, result);
6260 : else
6261 : {
6262 29250429 : changed = set_ssa_val_to (lhs, lhs);
6263 29250429 : vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
6264 29250429 : if (vuse && SSA_VAL (last_vuse) != SSA_VAL (vuse))
6265 : {
6266 9085701 : if (dump_file && (dump_flags & TDF_DETAILS))
6267 : {
6268 23143 : fprintf (dump_file, "Using extra use virtual operand ");
6269 23143 : print_generic_expr (dump_file, last_vuse);
6270 23143 : fprintf (dump_file, "\n");
6271 : }
6272 9085701 : vn_reference_insert (op, lhs, vuse, NULL_TREE);
6273 : }
6274 : }
6275 :
6276 : return changed;
6277 : }
6278 :
6279 :
6280 : /* Visit a store to a reference operator LHS, part of STMT, value number it,
6281 : and return true if the value number of the LHS has changed as a result. */
6282 :
6283 : static bool
6284 33481714 : visit_reference_op_store (tree lhs, tree op, gimple *stmt)
6285 : {
6286 33481714 : bool changed = false;
6287 33481714 : vn_reference_t vnresult = NULL;
6288 33481714 : tree assign;
6289 33481714 : bool resultsame = false;
6290 33481714 : tree vuse = gimple_vuse (stmt);
6291 33481714 : tree vdef = gimple_vdef (stmt);
6292 :
6293 33481714 : if (TREE_CODE (op) == SSA_NAME)
6294 15216033 : op = SSA_VAL (op);
6295 :
6296 : /* First we want to lookup using the *vuses* from the store and see
6297 : if there the last store to this location with the same address
6298 : had the same value.
6299 :
6300 : The vuses represent the memory state before the store. If the
6301 : memory state, address, and value of the store is the same as the
6302 : last store to this location, then this store will produce the
6303 : same memory state as that store.
6304 :
6305 : In this case the vdef versions for this store are value numbered to those
6306 : vuse versions, since they represent the same memory state after
6307 : this store.
6308 :
6309 : Otherwise, the vdefs for the store are used when inserting into
6310 : the table, since the store generates a new memory state. */
6311 :
6312 33481714 : vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
6313 33481714 : if (vnresult
6314 1709521 : && vnresult->result)
6315 : {
6316 1709521 : tree result = vnresult->result;
6317 1709521 : gcc_checking_assert (TREE_CODE (result) != SSA_NAME
6318 : || result == SSA_VAL (result));
6319 1709521 : resultsame = expressions_equal_p (result, op);
6320 1709521 : if (resultsame)
6321 : {
6322 : /* If the TBAA state isn't compatible for downstream reads
6323 : we cannot value-number the VDEFs the same. */
6324 53646 : ao_ref lhs_ref;
6325 53646 : ao_ref_init (&lhs_ref, lhs);
6326 53646 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
6327 53646 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
6328 53646 : if ((vnresult->set != set
6329 929 : && ! alias_set_subset_of (set, vnresult->set))
6330 54250 : || (vnresult->base_set != base_set
6331 8198 : && ! alias_set_subset_of (base_set, vnresult->base_set)))
6332 2704 : resultsame = false;
6333 : }
6334 : }
6335 :
6336 2704 : if (!resultsame)
6337 : {
6338 33430772 : if (dump_file && (dump_flags & TDF_DETAILS))
6339 : {
6340 20387 : fprintf (dump_file, "No store match\n");
6341 20387 : fprintf (dump_file, "Value numbering store ");
6342 20387 : print_generic_expr (dump_file, lhs);
6343 20387 : fprintf (dump_file, " to ");
6344 20387 : print_generic_expr (dump_file, op);
6345 20387 : fprintf (dump_file, "\n");
6346 : }
6347 : /* Have to set value numbers before insert, since insert is
6348 : going to valueize the references in-place. */
6349 33430772 : if (vdef)
6350 33430772 : changed |= set_ssa_val_to (vdef, vdef);
6351 :
6352 : /* Do not insert structure copies into the tables. */
6353 33430772 : if (is_gimple_min_invariant (op)
6354 33430772 : || is_gimple_reg (op))
6355 29787785 : vn_reference_insert (lhs, op, vdef, NULL);
6356 :
6357 : /* Only perform the following when being called from PRE
6358 : which embeds tail merging. */
6359 33430772 : if (default_vn_walk_kind == VN_WALK)
6360 : {
6361 7573948 : assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
6362 7573948 : vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
6363 7573948 : if (!vnresult)
6364 7532839 : vn_reference_insert (assign, lhs, vuse, vdef);
6365 : }
6366 : }
6367 : else
6368 : {
6369 : /* We had a match, so value number the vdef to have the value
6370 : number of the vuse it came from. */
6371 :
6372 50942 : if (dump_file && (dump_flags & TDF_DETAILS))
6373 9 : fprintf (dump_file, "Store matched earlier value, "
6374 : "value numbering store vdefs to matching vuses.\n");
6375 :
6376 50942 : changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
6377 : }
6378 :
6379 33481714 : return changed;
6380 : }
6381 :
6382 : /* Visit and value number PHI, return true if the value number
6383 : changed. When BACKEDGES_VARYING_P is true then assume all
6384 : backedge values are varying. When INSERTED is not NULL then
6385 : this is just a ahead query for a possible iteration, set INSERTED
6386 : to true if we'd insert into the hashtable. */
6387 :
6388 : static bool
6389 34651754 : visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
6390 : {
6391 34651754 : tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
6392 34651754 : bool seen_undef_visited = false;
6393 34651754 : tree backedge_val = NULL_TREE;
6394 34651754 : bool seen_non_backedge = false;
6395 34651754 : tree sameval_base = NULL_TREE;
6396 34651754 : poly_int64 soff, doff;
6397 34651754 : unsigned n_executable = 0;
6398 34651754 : edge sameval_e = NULL;
6399 :
6400 : /* TODO: We could check for this in initialization, and replace this
6401 : with a gcc_assert. */
6402 34651754 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
6403 31295 : return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
6404 :
6405 : /* We track whether a PHI was CSEd to avoid excessive iterations
6406 : that would be necessary only because the PHI changed arguments
6407 : but not value. */
6408 34620459 : if (!inserted)
6409 27003525 : gimple_set_plf (phi, GF_PLF_1, false);
6410 :
6411 34620459 : basic_block bb = gimple_bb (phi);
6412 :
6413 : /* For the equivalence handling below make sure to first process an
6414 : edge with a non-constant. */
6415 34620459 : auto_vec<edge, 2> preds;
6416 69240918 : preds.reserve_exact (EDGE_COUNT (bb->preds));
6417 34620459 : bool seen_nonconstant = false;
6418 114278824 : for (unsigned i = 0; i < EDGE_COUNT (bb->preds); ++i)
6419 : {
6420 79658365 : edge e = EDGE_PRED (bb, i);
6421 79658365 : preds.quick_push (e);
6422 79658365 : if (!seen_nonconstant)
6423 : {
6424 42418458 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6425 42418458 : if (TREE_CODE (def) == SSA_NAME)
6426 : {
6427 32874427 : seen_nonconstant = true;
6428 32874427 : if (i != 0)
6429 5807755 : std::swap (preds[0], preds[i]);
6430 : }
6431 : }
6432 : }
6433 :
6434 : /* See if all non-TOP arguments have the same value. TOP is
6435 : equivalent to everything, so we can ignore it. */
6436 145754720 : for (edge e : preds)
6437 68762439 : if (e->flags & EDGE_EXECUTABLE)
6438 : {
6439 63672325 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6440 :
6441 63672325 : if (def == PHI_RESULT (phi))
6442 339233 : continue;
6443 63358128 : ++n_executable;
6444 63358128 : bool visited = true;
6445 63358128 : if (TREE_CODE (def) == SSA_NAME)
6446 : {
6447 51084300 : tree val = SSA_VAL (def, &visited);
6448 51084300 : if (SSA_NAME_IS_DEFAULT_DEF (def))
6449 2690071 : visited = true;
6450 51084300 : if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
6451 48545163 : def = val;
6452 51084300 : if (e->flags & EDGE_DFS_BACK)
6453 15506127 : backedge_val = def;
6454 : }
6455 63358128 : if (!(e->flags & EDGE_DFS_BACK))
6456 47684126 : seen_non_backedge = true;
6457 63358128 : if (def == VN_TOP)
6458 : ;
6459 : /* Ignore undefined defs for sameval but record one. */
6460 63358128 : else if (TREE_CODE (def) == SSA_NAME
6461 47648613 : && ! virtual_operand_p (def)
6462 87645471 : && ssa_undefined_value_p (def, false))
6463 : {
6464 235011 : if (!seen_undef
6465 : /* Avoid having not visited undefined defs if we also have
6466 : a visited one. */
6467 35154 : || (!seen_undef_visited && visited))
6468 : {
6469 199861 : seen_undef = def;
6470 199861 : seen_undef_visited = visited;
6471 : }
6472 : }
6473 63123117 : else if (sameval == VN_TOP)
6474 : {
6475 : sameval = def;
6476 : sameval_e = e;
6477 : }
6478 28550175 : else if (expressions_equal_p (def, sameval))
6479 : sameval_e = NULL;
6480 44897693 : else if (virtual_operand_p (def))
6481 : {
6482 : sameval = NULL_TREE;
6483 26869096 : break;
6484 : }
6485 : else
6486 : {
6487 : /* We know we're arriving only with invariant addresses here,
6488 : try harder comparing them. We can do some caching here
6489 : which we cannot do in expressions_equal_p. */
6490 16818759 : if (TREE_CODE (def) == ADDR_EXPR
6491 388909 : && TREE_CODE (sameval) == ADDR_EXPR
6492 108309 : && sameval_base != (void *)-1)
6493 : {
6494 108309 : if (!sameval_base)
6495 108307 : sameval_base = get_addr_base_and_unit_offset
6496 108307 : (TREE_OPERAND (sameval, 0), &soff);
6497 108307 : if (!sameval_base)
6498 : sameval_base = (tree)(void *)-1;
6499 108314 : else if ((get_addr_base_and_unit_offset
6500 108309 : (TREE_OPERAND (def, 0), &doff) == sameval_base)
6501 108309 : && known_eq (soff, doff))
6502 5 : continue;
6503 : }
6504 : /* There's also the possibility to use equivalences. */
6505 32543003 : if (!FLOAT_TYPE_P (TREE_TYPE (def))
6506 : /* But only do this if we didn't force any of sameval or
6507 : val to VARYING because of backedge processing rules. */
6508 15618529 : && (TREE_CODE (sameval) != SSA_NAME
6509 12304139 : || SSA_VAL (sameval) == sameval)
6510 32437220 : && (TREE_CODE (def) != SSA_NAME || SSA_VAL (def) == def))
6511 : {
6512 15618454 : vn_nary_op_t vnresult;
6513 15618454 : tree ops[2];
6514 15618454 : ops[0] = def;
6515 15618454 : ops[1] = sameval;
6516 : /* Canonicalize the operands order for eq below. */
6517 15618454 : if (tree_swap_operands_p (ops[0], ops[1]))
6518 9410454 : std::swap (ops[0], ops[1]);
6519 15618454 : tree val = vn_nary_op_lookup_pieces (2, EQ_EXPR,
6520 : boolean_type_node,
6521 : ops, &vnresult);
6522 15618454 : if (! val && vnresult && vnresult->predicated_values)
6523 : {
6524 214724 : val = vn_nary_op_get_predicated_value (vnresult, e);
6525 121027 : if (val && integer_truep (val)
6526 239875 : && !(sameval_e && (sameval_e->flags & EDGE_DFS_BACK)))
6527 : {
6528 25031 : if (dump_file && (dump_flags & TDF_DETAILS))
6529 : {
6530 2 : fprintf (dump_file, "Predication says ");
6531 2 : print_generic_expr (dump_file, def, TDF_NONE);
6532 2 : fprintf (dump_file, " and ");
6533 2 : print_generic_expr (dump_file, sameval, TDF_NONE);
6534 2 : fprintf (dump_file, " are equal on edge %d -> %d\n",
6535 2 : e->src->index, e->dest->index);
6536 : }
6537 25031 : continue;
6538 : }
6539 : }
6540 : }
6541 : sameval = NULL_TREE;
6542 : break;
6543 : }
6544 : }
6545 :
6546 : /* If the value we want to use is flowing over the backedge and we
6547 : should take it as VARYING but it has a non-VARYING value drop to
6548 : VARYING.
6549 : If we value-number a virtual operand never value-number to the
6550 : value from the backedge as that confuses the alias-walking code.
6551 : See gcc.dg/torture/pr87176.c. If the value is the same on a
6552 : non-backedge everything is OK though. */
6553 34620459 : bool visited_p;
6554 34620459 : if ((backedge_val
6555 34620459 : && !seen_non_backedge
6556 2023 : && TREE_CODE (backedge_val) == SSA_NAME
6557 1756 : && sameval == backedge_val
6558 311 : && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
6559 40 : || SSA_VAL (backedge_val) != backedge_val))
6560 : /* Do not value-number a virtual operand to sth not visited though
6561 : given that allows us to escape a region in alias walking. */
6562 34622211 : || (sameval
6563 7751092 : && TREE_CODE (sameval) == SSA_NAME
6564 4593618 : && !SSA_NAME_IS_DEFAULT_DEF (sameval)
6565 3884716 : && SSA_NAME_IS_VIRTUAL_OPERAND (sameval)
6566 1949961 : && (SSA_VAL (sameval, &visited_p), !visited_p)))
6567 : /* Note this just drops to VARYING without inserting the PHI into
6568 : the hashes. */
6569 299555 : result = PHI_RESULT (phi);
6570 : /* If none of the edges was executable keep the value-number at VN_TOP,
6571 : if only a single edge is executable use its value. */
6572 34320904 : else if (n_executable <= 1)
6573 6687728 : result = seen_undef ? seen_undef : sameval;
6574 : /* If we saw only undefined values and VN_TOP use one of the
6575 : undefined values. */
6576 27633176 : else if (sameval == VN_TOP)
6577 7267688 : result = (seen_undef && seen_undef_visited) ? seen_undef : sameval;
6578 : /* First see if it is equivalent to a phi node in this block. We prefer
6579 : this as it allows IV elimination - see PRs 66502 and 67167. */
6580 27627649 : else if ((result = vn_phi_lookup (phi, backedges_varying_p)))
6581 : {
6582 4217301 : if (!inserted
6583 70470 : && TREE_CODE (result) == SSA_NAME
6584 4287771 : && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI)
6585 : {
6586 70470 : gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true);
6587 70470 : if (dump_file && (dump_flags & TDF_DETAILS))
6588 : {
6589 6 : fprintf (dump_file, "Marking CSEd to PHI node ");
6590 6 : print_gimple_expr (dump_file, SSA_NAME_DEF_STMT (result),
6591 : 0, TDF_SLIM);
6592 6 : fprintf (dump_file, "\n");
6593 : }
6594 : }
6595 : }
6596 : /* If all values are the same use that, unless we've seen undefined
6597 : values as well and the value isn't constant.
6598 : CCP/copyprop have the same restriction to not remove uninit warnings. */
6599 23410348 : else if (sameval
6600 23410348 : && (! seen_undef || is_gimple_min_invariant (sameval)))
6601 : result = sameval;
6602 : else
6603 : {
6604 22793925 : result = PHI_RESULT (phi);
6605 : /* Only insert PHIs that are varying, for constant value numbers
6606 : we mess up equivalences otherwise as we are only comparing
6607 : the immediate controlling predicates. */
6608 22793925 : vn_phi_insert (phi, result, backedges_varying_p);
6609 22793925 : if (inserted)
6610 3313397 : *inserted = true;
6611 : }
6612 :
6613 34620459 : return set_ssa_val_to (PHI_RESULT (phi), result);
6614 34620459 : }
6615 :
6616 : /* Try to simplify RHS using equivalences and constant folding. */
6617 :
6618 : static tree
6619 129049600 : try_to_simplify (gassign *stmt)
6620 : {
6621 129049600 : enum tree_code code = gimple_assign_rhs_code (stmt);
6622 129049600 : tree tem;
6623 :
6624 : /* For stores we can end up simplifying a SSA_NAME rhs. Just return
6625 : in this case, there is no point in doing extra work. */
6626 129049600 : if (code == SSA_NAME)
6627 : return NULL_TREE;
6628 :
6629 : /* First try constant folding based on our current lattice. */
6630 113833239 : mprts_hook = vn_lookup_simplify_result;
6631 113833239 : tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
6632 113833239 : mprts_hook = NULL;
6633 113833239 : if (tem
6634 113833239 : && (TREE_CODE (tem) == SSA_NAME
6635 25304414 : || is_gimple_min_invariant (tem)))
6636 25412126 : return tem;
6637 :
6638 : return NULL_TREE;
6639 : }
6640 :
6641 : /* Visit and value number STMT, return true if the value number
6642 : changed. */
6643 :
6644 : static bool
6645 469070980 : visit_stmt (gimple *stmt, bool backedges_varying_p = false)
6646 : {
6647 469070980 : bool changed = false;
6648 :
6649 469070980 : if (dump_file && (dump_flags & TDF_DETAILS))
6650 : {
6651 411454 : fprintf (dump_file, "Value numbering stmt = ");
6652 411454 : print_gimple_stmt (dump_file, stmt, 0);
6653 : }
6654 :
6655 469070980 : if (gimple_code (stmt) == GIMPLE_PHI)
6656 27024975 : changed = visit_phi (stmt, NULL, backedges_varying_p);
6657 616104711 : else if (gimple_has_volatile_ops (stmt))
6658 9076262 : changed = defs_to_varying (stmt);
6659 432969743 : else if (gassign *ass = dyn_cast <gassign *> (stmt))
6660 : {
6661 134165702 : enum tree_code code = gimple_assign_rhs_code (ass);
6662 134165702 : tree lhs = gimple_assign_lhs (ass);
6663 134165702 : tree rhs1 = gimple_assign_rhs1 (ass);
6664 134165702 : tree simplified;
6665 :
6666 : /* Shortcut for copies. Simplifying copies is pointless,
6667 : since we copy the expression and value they represent. */
6668 134165702 : if (code == SSA_NAME
6669 20332463 : && TREE_CODE (lhs) == SSA_NAME)
6670 : {
6671 5116102 : changed = visit_copy (lhs, rhs1);
6672 5116102 : goto done;
6673 : }
6674 129049600 : simplified = try_to_simplify (ass);
6675 129049600 : if (simplified)
6676 : {
6677 25412126 : if (dump_file && (dump_flags & TDF_DETAILS))
6678 : {
6679 14763 : fprintf (dump_file, "RHS ");
6680 14763 : print_gimple_expr (dump_file, ass, 0);
6681 14763 : fprintf (dump_file, " simplified to ");
6682 14763 : print_generic_expr (dump_file, simplified);
6683 14763 : fprintf (dump_file, "\n");
6684 : }
6685 : }
6686 : /* Setting value numbers to constants will occasionally
6687 : screw up phi congruence because constants are not
6688 : uniquely associated with a single ssa name that can be
6689 : looked up. */
6690 25412126 : if (simplified
6691 25412126 : && is_gimple_min_invariant (simplified)
6692 22392036 : && TREE_CODE (lhs) == SSA_NAME)
6693 : {
6694 7763496 : changed = set_ssa_val_to (lhs, simplified);
6695 7763496 : goto done;
6696 : }
6697 121286104 : else if (simplified
6698 17648630 : && TREE_CODE (simplified) == SSA_NAME
6699 3020090 : && TREE_CODE (lhs) == SSA_NAME)
6700 : {
6701 3020090 : changed = visit_copy (lhs, simplified);
6702 3020090 : goto done;
6703 : }
6704 :
6705 118266014 : if ((TREE_CODE (lhs) == SSA_NAME
6706 : /* We can substitute SSA_NAMEs that are live over
6707 : abnormal edges with their constant value. */
6708 84783998 : && !(gimple_assign_copy_p (ass)
6709 26 : && is_gimple_min_invariant (rhs1))
6710 84783972 : && !(simplified
6711 0 : && is_gimple_min_invariant (simplified))
6712 84783972 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
6713 : /* Stores or copies from SSA_NAMEs that are live over
6714 : abnormal edges are a problem. */
6715 203048683 : || (code == SSA_NAME
6716 15216361 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
6717 1631 : changed = defs_to_varying (ass);
6718 118264383 : else if (REFERENCE_CLASS_P (lhs)
6719 118264383 : || DECL_P (lhs))
6720 33481714 : changed = visit_reference_op_store (lhs, rhs1, ass);
6721 84782669 : else if (TREE_CODE (lhs) == SSA_NAME)
6722 : {
6723 84782669 : if ((gimple_assign_copy_p (ass)
6724 26 : && is_gimple_min_invariant (rhs1))
6725 84782695 : || (simplified
6726 0 : && is_gimple_min_invariant (simplified)))
6727 : {
6728 0 : if (simplified)
6729 0 : changed = set_ssa_val_to (lhs, simplified);
6730 : else
6731 0 : changed = set_ssa_val_to (lhs, rhs1);
6732 : }
6733 : else
6734 : {
6735 : /* Visit the original statement. */
6736 84782669 : switch (vn_get_stmt_kind (ass))
6737 : {
6738 49765087 : case VN_NARY:
6739 49765087 : changed = visit_nary_op (lhs, ass);
6740 49765087 : break;
6741 34914863 : case VN_REFERENCE:
6742 34914863 : changed = visit_reference_op_load (lhs, rhs1, ass);
6743 34914863 : break;
6744 102719 : default:
6745 102719 : changed = defs_to_varying (ass);
6746 102719 : break;
6747 : }
6748 : }
6749 : }
6750 : else
6751 0 : changed = defs_to_varying (ass);
6752 : }
6753 298804041 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
6754 : {
6755 25043979 : tree lhs = gimple_call_lhs (call_stmt);
6756 25043979 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
6757 : {
6758 : /* Try constant folding based on our current lattice. */
6759 8422417 : tree simplified = gimple_fold_stmt_to_constant_1 (call_stmt,
6760 : vn_valueize);
6761 8422417 : if (simplified)
6762 : {
6763 67867 : if (dump_file && (dump_flags & TDF_DETAILS))
6764 : {
6765 1 : fprintf (dump_file, "call ");
6766 1 : print_gimple_expr (dump_file, call_stmt, 0);
6767 1 : fprintf (dump_file, " simplified to ");
6768 1 : print_generic_expr (dump_file, simplified);
6769 1 : fprintf (dump_file, "\n");
6770 : }
6771 : }
6772 : /* Setting value numbers to constants will occasionally
6773 : screw up phi congruence because constants are not
6774 : uniquely associated with a single ssa name that can be
6775 : looked up. */
6776 67867 : if (simplified
6777 67867 : && is_gimple_min_invariant (simplified))
6778 : {
6779 61371 : changed = set_ssa_val_to (lhs, simplified);
6780 122742 : if (gimple_vdef (call_stmt))
6781 740 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6782 : SSA_VAL (gimple_vuse (call_stmt)));
6783 61371 : goto done;
6784 : }
6785 8361046 : else if (simplified
6786 6496 : && TREE_CODE (simplified) == SSA_NAME)
6787 : {
6788 293 : changed = visit_copy (lhs, simplified);
6789 586 : if (gimple_vdef (call_stmt))
6790 0 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6791 : SSA_VAL (gimple_vuse (call_stmt)));
6792 293 : goto done;
6793 : }
6794 8360753 : else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
6795 : {
6796 414 : changed = defs_to_varying (call_stmt);
6797 414 : goto done;
6798 : }
6799 : }
6800 :
6801 : /* Pick up flags from a devirtualization target. */
6802 24981901 : tree fn = gimple_call_fn (stmt);
6803 24981901 : int extra_fnflags = 0;
6804 24981901 : if (fn && TREE_CODE (fn) == SSA_NAME)
6805 : {
6806 537274 : fn = SSA_VAL (fn);
6807 537274 : if (TREE_CODE (fn) == ADDR_EXPR
6808 537274 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
6809 5326 : extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
6810 : }
6811 24981901 : if ((/* Calls to the same function with the same vuse
6812 : and the same operands do not necessarily return the same
6813 : value, unless they're pure or const. */
6814 24981901 : ((gimple_call_flags (call_stmt) | extra_fnflags)
6815 24981901 : & (ECF_PURE | ECF_CONST))
6816 : /* If calls have a vdef, subsequent calls won't have
6817 : the same incoming vuse. So, if 2 calls with vdef have the
6818 : same vuse, we know they're not subsequent.
6819 : We can value number 2 calls to the same function with the
6820 : same vuse and the same operands which are not subsequent
6821 : the same, because there is no code in the program that can
6822 : compare the 2 values... */
6823 21023976 : || (gimple_vdef (call_stmt)
6824 : /* ... unless the call returns a pointer which does
6825 : not alias with anything else. In which case the
6826 : information that the values are distinct are encoded
6827 : in the IL. */
6828 20989114 : && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
6829 : /* Only perform the following when being called from PRE
6830 : which embeds tail merging. */
6831 20433293 : && default_vn_walk_kind == VN_WALK))
6832 : /* Do not process .DEFERRED_INIT since that confuses uninit
6833 : analysis. */
6834 29972351 : && !gimple_call_internal_p (call_stmt, IFN_DEFERRED_INIT))
6835 8676497 : changed = visit_reference_op_call (lhs, call_stmt);
6836 : else
6837 16305404 : changed = defs_to_varying (call_stmt);
6838 : }
6839 : else
6840 273760062 : changed = defs_to_varying (stmt);
6841 469070980 : done:
6842 469070980 : return changed;
6843 : }
6844 :
6845 :
6846 : /* Allocate a value number table. */
6847 :
6848 : static void
6849 6230471 : allocate_vn_table (vn_tables_t table, unsigned size)
6850 : {
6851 6230471 : table->phis = new vn_phi_table_type (size);
6852 6230471 : table->nary = new vn_nary_op_table_type (size);
6853 6230471 : table->references = new vn_reference_table_type (size);
6854 6230471 : }
6855 :
6856 : /* Free a value number table. */
6857 :
6858 : static void
6859 6230471 : free_vn_table (vn_tables_t table)
6860 : {
6861 : /* Walk over elements and release vectors. */
6862 6230471 : vn_reference_iterator_type hir;
6863 6230471 : vn_reference_t vr;
6864 148609497 : FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir)
6865 71189513 : vr->operands.release ();
6866 6230471 : delete table->phis;
6867 6230471 : table->phis = NULL;
6868 6230471 : delete table->nary;
6869 6230471 : table->nary = NULL;
6870 6230471 : delete table->references;
6871 6230471 : table->references = NULL;
6872 6230471 : }
6873 :
6874 : /* Set *ID according to RESULT. */
6875 :
6876 : static void
6877 34805277 : set_value_id_for_result (tree result, unsigned int *id)
6878 : {
6879 34805277 : if (result && TREE_CODE (result) == SSA_NAME)
6880 21651207 : *id = VN_INFO (result)->value_id;
6881 9855447 : else if (result && is_gimple_min_invariant (result))
6882 3721374 : *id = get_or_alloc_constant_value_id (result);
6883 : else
6884 9432696 : *id = get_next_value_id ();
6885 34805277 : }
6886 :
6887 : /* Set the value ids in the valid hash tables. */
6888 :
6889 : static void
6890 970230 : set_hashtable_value_ids (void)
6891 : {
6892 970230 : vn_nary_op_iterator_type hin;
6893 970230 : vn_phi_iterator_type hip;
6894 970230 : vn_reference_iterator_type hir;
6895 970230 : vn_nary_op_t vno;
6896 970230 : vn_reference_t vr;
6897 970230 : vn_phi_t vp;
6898 :
6899 : /* Now set the value ids of the things we had put in the hash
6900 : table. */
6901 :
6902 49041218 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin)
6903 24035494 : if (! vno->predicated_values)
6904 7871635 : set_value_id_for_result (vno->u.result, &vno->value_id);
6905 :
6906 9000422 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip)
6907 4015096 : set_value_id_for_result (vp->result, &vp->value_id);
6908 :
6909 46807322 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t,
6910 : hir)
6911 22918546 : set_value_id_for_result (vr->result, &vr->value_id);
6912 970230 : }
6913 :
6914 : /* Return the maximum value id we have ever seen. */
6915 :
6916 : unsigned int
6917 1940460 : get_max_value_id (void)
6918 : {
6919 1940460 : return next_value_id;
6920 : }
6921 :
6922 : /* Return the maximum constant value id we have ever seen. */
6923 :
6924 : unsigned int
6925 1940460 : get_max_constant_value_id (void)
6926 : {
6927 1940460 : return -next_constant_value_id;
6928 : }
6929 :
6930 : /* Return the next unique value id. */
6931 :
6932 : unsigned int
6933 49552024 : get_next_value_id (void)
6934 : {
6935 49552024 : gcc_checking_assert ((int)next_value_id > 0);
6936 49552024 : return next_value_id++;
6937 : }
6938 :
6939 : /* Return the next unique value id for constants. */
6940 :
6941 : unsigned int
6942 2547878 : get_next_constant_value_id (void)
6943 : {
6944 2547878 : gcc_checking_assert (next_constant_value_id < 0);
6945 2547878 : return next_constant_value_id--;
6946 : }
6947 :
6948 :
6949 : /* Compare two expressions E1 and E2 and return true if they are equal.
6950 : If match_vn_top_optimistically is true then VN_TOP is equal to anything,
6951 : otherwise VN_TOP only matches VN_TOP. */
6952 :
6953 : bool
6954 249641164 : expressions_equal_p (tree e1, tree e2, bool match_vn_top_optimistically)
6955 : {
6956 : /* The obvious case. */
6957 249641164 : if (e1 == e2)
6958 : return true;
6959 :
6960 : /* If either one is VN_TOP consider them equal. */
6961 71301976 : if (match_vn_top_optimistically
6962 66376469 : && (e1 == VN_TOP || e2 == VN_TOP))
6963 : return true;
6964 :
6965 : /* If only one of them is null, they cannot be equal. While in general
6966 : this should not happen for operations like TARGET_MEM_REF some
6967 : operands are optional and an identity value we could substitute
6968 : has differing semantics. */
6969 71301976 : if (!e1 || !e2)
6970 : return false;
6971 :
6972 : /* SSA_NAME compare pointer equal. */
6973 71301976 : if (TREE_CODE (e1) == SSA_NAME || TREE_CODE (e2) == SSA_NAME)
6974 : return false;
6975 :
6976 : /* Now perform the actual comparison. */
6977 35504669 : if (TREE_CODE (e1) == TREE_CODE (e2)
6978 35504669 : && operand_equal_p (e1, e2, OEP_PURE_SAME))
6979 : return true;
6980 :
6981 : return false;
6982 : }
6983 :
6984 :
6985 : /* Return true if the nary operation NARY may trap. This is a copy
6986 : of stmt_could_throw_1_p adjusted to the SCCVN IL. */
6987 :
6988 : bool
6989 5704210 : vn_nary_may_trap (vn_nary_op_t nary)
6990 : {
6991 5704210 : tree type;
6992 5704210 : tree rhs2 = NULL_TREE;
6993 5704210 : bool honor_nans = false;
6994 5704210 : bool honor_snans = false;
6995 5704210 : bool fp_operation = false;
6996 5704210 : bool honor_trapv = false;
6997 5704210 : bool handled, ret;
6998 5704210 : unsigned i;
6999 :
7000 5704210 : if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
7001 : || TREE_CODE_CLASS (nary->opcode) == tcc_unary
7002 5704210 : || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
7003 : {
7004 5582968 : type = nary->type;
7005 5582968 : fp_operation = FLOAT_TYPE_P (type);
7006 5582968 : if (fp_operation)
7007 : {
7008 120282 : honor_nans = flag_trapping_math && !flag_finite_math_only;
7009 120282 : honor_snans = flag_signaling_nans != 0;
7010 : }
7011 5462686 : else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
7012 : honor_trapv = true;
7013 : }
7014 5704210 : if (nary->length >= 2)
7015 2285987 : rhs2 = nary->op[1];
7016 5704210 : ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
7017 : honor_trapv, honor_nans, honor_snans,
7018 : rhs2, &handled);
7019 5704210 : if (handled && ret)
7020 : return true;
7021 :
7022 13388951 : for (i = 0; i < nary->length; ++i)
7023 7803965 : if (tree_could_trap_p (nary->op[i]))
7024 : return true;
7025 :
7026 : return false;
7027 : }
7028 :
7029 : /* Return true if the reference operation REF may trap. */
7030 :
7031 : bool
7032 939057 : vn_reference_may_trap (vn_reference_t ref)
7033 : {
7034 939057 : switch (ref->operands[0].opcode)
7035 : {
7036 : case MODIFY_EXPR:
7037 : case CALL_EXPR:
7038 : /* We do not handle calls. */
7039 : return true;
7040 : case ADDR_EXPR:
7041 : /* And toplevel address computations never trap. */
7042 : return false;
7043 : default:;
7044 : }
7045 :
7046 : vn_reference_op_t op;
7047 : unsigned i;
7048 2601562 : FOR_EACH_VEC_ELT (ref->operands, i, op)
7049 : {
7050 2601307 : switch (op->opcode)
7051 : {
7052 : case WITH_SIZE_EXPR:
7053 : case TARGET_MEM_REF:
7054 : /* Always variable. */
7055 : return true;
7056 734975 : case COMPONENT_REF:
7057 734975 : if (op->op1 && TREE_CODE (op->op1) == SSA_NAME)
7058 : return true;
7059 : break;
7060 0 : case ARRAY_RANGE_REF:
7061 0 : if (TREE_CODE (op->op0) == SSA_NAME)
7062 : return true;
7063 : break;
7064 205247 : case ARRAY_REF:
7065 205247 : {
7066 205247 : if (TREE_CODE (op->op0) != INTEGER_CST)
7067 : return true;
7068 :
7069 : /* !in_array_bounds */
7070 185094 : tree domain_type = TYPE_DOMAIN (ref->operands[i+1].type);
7071 185094 : if (!domain_type)
7072 : return true;
7073 :
7074 185048 : tree min = op->op1;
7075 185048 : tree max = TYPE_MAX_VALUE (domain_type);
7076 185048 : if (!min
7077 185048 : || !max
7078 172139 : || TREE_CODE (min) != INTEGER_CST
7079 172139 : || TREE_CODE (max) != INTEGER_CST)
7080 : return true;
7081 :
7082 169474 : if (tree_int_cst_lt (op->op0, min)
7083 169474 : || tree_int_cst_lt (max, op->op0))
7084 325 : return true;
7085 :
7086 : break;
7087 : }
7088 : case MEM_REF:
7089 : /* Nothing interesting in itself, the base is separate. */
7090 : break;
7091 : /* The following are the address bases. */
7092 : case SSA_NAME:
7093 : return true;
7094 538669 : case ADDR_EXPR:
7095 538669 : if (op->op0)
7096 538669 : return tree_could_trap_p (TREE_OPERAND (op->op0, 0));
7097 : return false;
7098 1747032 : default:;
7099 : }
7100 : }
7101 : return false;
7102 : }
7103 :
7104 10560733 : eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction,
7105 10560733 : bitmap inserted_exprs_)
7106 10560733 : : dom_walker (direction), do_pre (inserted_exprs_ != NULL),
7107 10560733 : el_todo (0), eliminations (0), insertions (0),
7108 10560733 : inserted_exprs (inserted_exprs_)
7109 : {
7110 10560733 : need_eh_cleanup = BITMAP_ALLOC (NULL);
7111 10560733 : need_ab_cleanup = BITMAP_ALLOC (NULL);
7112 10560733 : }
7113 :
7114 10560733 : eliminate_dom_walker::~eliminate_dom_walker ()
7115 : {
7116 10560733 : BITMAP_FREE (need_eh_cleanup);
7117 10560733 : BITMAP_FREE (need_ab_cleanup);
7118 10560733 : }
7119 :
7120 : /* Return a leader for OP that is available at the current point of the
7121 : eliminate domwalk. */
7122 :
7123 : tree
7124 184239587 : eliminate_dom_walker::eliminate_avail (basic_block, tree op)
7125 : {
7126 184239587 : tree valnum = VN_INFO (op)->valnum;
7127 184239587 : if (TREE_CODE (valnum) == SSA_NAME)
7128 : {
7129 179065132 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
7130 : return valnum;
7131 311785789 : if (avail.length () > SSA_NAME_VERSION (valnum))
7132 : {
7133 140430645 : tree av = avail[SSA_NAME_VERSION (valnum)];
7134 : /* When PRE discovers a new redundancy there's no way to unite
7135 : the value classes so it instead inserts a copy old-val = new-val.
7136 : Look through such copies here, providing one more level of
7137 : simplification at elimination time. */
7138 140430645 : gassign *ass;
7139 246907445 : if (av && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (av))))
7140 75857595 : if (gimple_assign_rhs_class (ass) == GIMPLE_SINGLE_RHS)
7141 : {
7142 40091592 : tree rhs1 = gimple_assign_rhs1 (ass);
7143 40091592 : if (CONSTANT_CLASS_P (rhs1)
7144 40091592 : || (TREE_CODE (rhs1) == SSA_NAME
7145 10807 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
7146 : av = rhs1;
7147 : }
7148 140430645 : return av;
7149 : }
7150 : }
7151 5174455 : else if (is_gimple_min_invariant (valnum))
7152 : return valnum;
7153 : return NULL_TREE;
7154 : }
7155 :
7156 : /* At the current point of the eliminate domwalk make OP available. */
7157 :
7158 : void
7159 50794584 : eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
7160 : {
7161 50794584 : tree valnum = VN_INFO (op)->valnum;
7162 50794584 : if (TREE_CODE (valnum) == SSA_NAME)
7163 : {
7164 98170047 : if (avail.length () <= SSA_NAME_VERSION (valnum))
7165 17191327 : avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1, true);
7166 50794584 : tree pushop = op;
7167 50794584 : if (avail[SSA_NAME_VERSION (valnum)])
7168 45142 : pushop = avail[SSA_NAME_VERSION (valnum)];
7169 50794584 : avail_stack.safe_push (pushop);
7170 50794584 : avail[SSA_NAME_VERSION (valnum)] = op;
7171 : }
7172 50794584 : }
7173 :
7174 : /* Insert the expression recorded by SCCVN for VAL at *GSI. Returns
7175 : the leader for the expression if insertion was successful. */
7176 :
7177 : tree
7178 137079 : eliminate_dom_walker::eliminate_insert (basic_block bb,
7179 : gimple_stmt_iterator *gsi, tree val)
7180 : {
7181 : /* We can insert a sequence with a single assignment only. */
7182 137079 : gimple_seq stmts = VN_INFO (val)->expr;
7183 137079 : if (!gimple_seq_singleton_p (stmts))
7184 : return NULL_TREE;
7185 240175 : gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts));
7186 137079 : if (!stmt
7187 137079 : || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
7188 : && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
7189 : && gimple_assign_rhs_code (stmt) != NEGATE_EXPR
7190 : && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF
7191 : && (gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
7192 80 : || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)))
7193 : return NULL_TREE;
7194 :
7195 44216 : tree op = gimple_assign_rhs1 (stmt);
7196 44216 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
7197 44216 : || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7198 20385 : op = TREE_OPERAND (op, 0);
7199 44216 : tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op;
7200 44170 : if (!leader)
7201 : return NULL_TREE;
7202 :
7203 33987 : tree res;
7204 33987 : stmts = NULL;
7205 53378 : if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7206 34376 : res = gimple_build (&stmts, BIT_FIELD_REF,
7207 17188 : TREE_TYPE (val), leader,
7208 17188 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
7209 17188 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
7210 16799 : else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
7211 160 : res = gimple_build (&stmts, BIT_AND_EXPR,
7212 80 : TREE_TYPE (val), leader, gimple_assign_rhs2 (stmt));
7213 : else
7214 16719 : res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
7215 16719 : TREE_TYPE (val), leader);
7216 33987 : if (TREE_CODE (res) != SSA_NAME
7217 33986 : || SSA_NAME_IS_DEFAULT_DEF (res)
7218 67973 : || gimple_bb (SSA_NAME_DEF_STMT (res)))
7219 : {
7220 4 : gimple_seq_discard (stmts);
7221 :
7222 : /* During propagation we have to treat SSA info conservatively
7223 : and thus we can end up simplifying the inserted expression
7224 : at elimination time to sth not defined in stmts. */
7225 : /* But then this is a redundancy we failed to detect. Which means
7226 : res now has two values. That doesn't play well with how
7227 : we track availability here, so give up. */
7228 4 : if (dump_file && (dump_flags & TDF_DETAILS))
7229 : {
7230 0 : if (TREE_CODE (res) == SSA_NAME)
7231 0 : res = eliminate_avail (bb, res);
7232 0 : if (res)
7233 : {
7234 0 : fprintf (dump_file, "Failed to insert expression for value ");
7235 0 : print_generic_expr (dump_file, val);
7236 0 : fprintf (dump_file, " which is really fully redundant to ");
7237 0 : print_generic_expr (dump_file, res);
7238 0 : fprintf (dump_file, "\n");
7239 : }
7240 : }
7241 :
7242 4 : return NULL_TREE;
7243 : }
7244 : else
7245 : {
7246 33983 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
7247 33983 : vn_ssa_aux_t vn_info = VN_INFO (res);
7248 33983 : vn_info->valnum = val;
7249 33983 : vn_info->visited = true;
7250 : }
7251 :
7252 33983 : insertions++;
7253 33983 : if (dump_file && (dump_flags & TDF_DETAILS))
7254 : {
7255 501 : fprintf (dump_file, "Inserted ");
7256 501 : print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0);
7257 : }
7258 :
7259 : return res;
7260 : }
7261 :
7262 : void
7263 363379530 : eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
7264 : {
7265 363379530 : tree sprime = NULL_TREE;
7266 363379530 : gimple *stmt = gsi_stmt (*gsi);
7267 363379530 : tree lhs = gimple_get_lhs (stmt);
7268 122395100 : if (lhs && TREE_CODE (lhs) == SSA_NAME
7269 169175958 : && !gimple_has_volatile_ops (stmt)
7270 : /* See PR43491. Do not replace a global register variable when
7271 : it is a the RHS of an assignment. Do replace local register
7272 : variables since gcc does not guarantee a local variable will
7273 : be allocated in register.
7274 : ??? The fix isn't effective here. This should instead
7275 : be ensured by not value-numbering them the same but treating
7276 : them like volatiles? */
7277 446903840 : && !(gimple_assign_single_p (stmt)
7278 36030860 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
7279 2500258 : && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
7280 4184 : && is_global_var (gimple_assign_rhs1 (stmt)))))
7281 : {
7282 83524066 : sprime = eliminate_avail (b, lhs);
7283 83524066 : if (!sprime)
7284 : {
7285 : /* If there is no existing usable leader but SCCVN thinks
7286 : it has an expression it wants to use as replacement,
7287 : insert that. */
7288 70194299 : tree val = VN_INFO (lhs)->valnum;
7289 70194299 : vn_ssa_aux_t vn_info;
7290 70194299 : if (val != VN_TOP
7291 70194299 : && TREE_CODE (val) == SSA_NAME
7292 70194299 : && (vn_info = VN_INFO (val), true)
7293 70194299 : && vn_info->needs_insertion
7294 338860 : && vn_info->expr != NULL
7295 70331378 : && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE)
7296 33983 : eliminate_push_avail (b, sprime);
7297 : }
7298 :
7299 : /* If this now constitutes a copy duplicate points-to
7300 : and range info appropriately. This is especially
7301 : important for inserted code. */
7302 70194299 : if (sprime
7303 13363750 : && TREE_CODE (sprime) == SSA_NAME)
7304 9158703 : maybe_duplicate_ssa_info_at_copy (lhs, sprime);
7305 :
7306 : /* Inhibit the use of an inserted PHI on a loop header when
7307 : the address of the memory reference is a simple induction
7308 : variable. In other cases the vectorizer won't do anything
7309 : anyway (either it's loop invariant or a complicated
7310 : expression). */
7311 9158703 : if (sprime
7312 13363750 : && TREE_CODE (sprime) == SSA_NAME
7313 9158703 : && do_pre
7314 927415 : && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1)
7315 908797 : && loop_outer (b->loop_father)
7316 390461 : && has_zero_uses (sprime)
7317 194059 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
7318 193833 : && gimple_assign_load_p (stmt))
7319 : {
7320 104844 : gimple *def_stmt = SSA_NAME_DEF_STMT (sprime);
7321 104844 : basic_block def_bb = gimple_bb (def_stmt);
7322 104844 : if (gimple_code (def_stmt) == GIMPLE_PHI
7323 104844 : && def_bb->loop_father->header == def_bb)
7324 : {
7325 66718 : loop_p loop = def_bb->loop_father;
7326 66718 : ssa_op_iter iter;
7327 66718 : tree op;
7328 66718 : bool found = false;
7329 84668 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
7330 : {
7331 63050 : affine_iv iv;
7332 63050 : def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
7333 63050 : if (def_bb
7334 56958 : && flow_bb_inside_loop_p (loop, def_bb)
7335 114848 : && simple_iv (loop, loop, op, &iv, true))
7336 : {
7337 45100 : found = true;
7338 45100 : break;
7339 : }
7340 : }
7341 21618 : if (found)
7342 : {
7343 45100 : if (dump_file && (dump_flags & TDF_DETAILS))
7344 : {
7345 3 : fprintf (dump_file, "Not replacing ");
7346 3 : print_gimple_expr (dump_file, stmt, 0);
7347 3 : fprintf (dump_file, " with ");
7348 3 : print_generic_expr (dump_file, sprime);
7349 3 : fprintf (dump_file, " which would add a loop"
7350 : " carried dependence to loop %d\n",
7351 : loop->num);
7352 : }
7353 : /* Don't keep sprime available. */
7354 45100 : sprime = NULL_TREE;
7355 : }
7356 : }
7357 : }
7358 :
7359 83524066 : if (sprime)
7360 : {
7361 : /* If we can propagate the value computed for LHS into
7362 : all uses don't bother doing anything with this stmt. */
7363 13318650 : if (may_propagate_copy (lhs, sprime))
7364 : {
7365 : /* Mark it for removal. */
7366 13316687 : to_remove.safe_push (stmt);
7367 :
7368 : /* ??? Don't count copy/constant propagations. */
7369 13316687 : if (gimple_assign_single_p (stmt)
7370 13316687 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7371 4658464 : || gimple_assign_rhs1 (stmt) == sprime))
7372 14166183 : return;
7373 :
7374 8103826 : if (dump_file && (dump_flags & TDF_DETAILS))
7375 : {
7376 19017 : fprintf (dump_file, "Replaced ");
7377 19017 : print_gimple_expr (dump_file, stmt, 0);
7378 19017 : fprintf (dump_file, " with ");
7379 19017 : print_generic_expr (dump_file, sprime);
7380 19017 : fprintf (dump_file, " in all uses of ");
7381 19017 : print_gimple_stmt (dump_file, stmt, 0);
7382 : }
7383 :
7384 8103826 : eliminations++;
7385 8103826 : return;
7386 : }
7387 :
7388 : /* If this is an assignment from our leader (which
7389 : happens in the case the value-number is a constant)
7390 : then there is nothing to do. Likewise if we run into
7391 : inserted code that needed a conversion because of
7392 : our type-agnostic value-numbering of loads. */
7393 1963 : if ((gimple_assign_single_p (stmt)
7394 1 : || (is_gimple_assign (stmt)
7395 1 : && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
7396 0 : || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)))
7397 1964 : && sprime == gimple_assign_rhs1 (stmt))
7398 : return;
7399 :
7400 : /* Else replace its RHS. */
7401 719 : if (dump_file && (dump_flags & TDF_DETAILS))
7402 : {
7403 0 : fprintf (dump_file, "Replaced ");
7404 0 : print_gimple_expr (dump_file, stmt, 0);
7405 0 : fprintf (dump_file, " with ");
7406 0 : print_generic_expr (dump_file, sprime);
7407 0 : fprintf (dump_file, " in ");
7408 0 : print_gimple_stmt (dump_file, stmt, 0);
7409 : }
7410 719 : eliminations++;
7411 :
7412 719 : bool can_make_abnormal_goto = (is_gimple_call (stmt)
7413 719 : && stmt_can_make_abnormal_goto (stmt));
7414 719 : gimple *orig_stmt = stmt;
7415 719 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
7416 719 : TREE_TYPE (sprime)))
7417 : {
7418 : /* We preserve conversions to but not from function or method
7419 : types. This asymmetry makes it necessary to re-instantiate
7420 : conversions here. */
7421 717 : if (POINTER_TYPE_P (TREE_TYPE (lhs))
7422 717 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (lhs))))
7423 717 : sprime = fold_convert (TREE_TYPE (lhs), sprime);
7424 : else
7425 0 : gcc_unreachable ();
7426 : }
7427 719 : tree vdef = gimple_vdef (stmt);
7428 719 : tree vuse = gimple_vuse (stmt);
7429 719 : propagate_tree_value_into_stmt (gsi, sprime);
7430 719 : stmt = gsi_stmt (*gsi);
7431 719 : update_stmt (stmt);
7432 : /* In case the VDEF on the original stmt was released, value-number
7433 : it to the VUSE. This is to make vuse_ssa_val able to skip
7434 : released virtual operands. */
7435 1438 : if (vdef != gimple_vdef (stmt))
7436 : {
7437 0 : gcc_assert (SSA_NAME_IN_FREE_LIST (vdef));
7438 0 : VN_INFO (vdef)->valnum = vuse;
7439 : }
7440 :
7441 : /* If we removed EH side-effects from the statement, clean
7442 : its EH information. */
7443 719 : if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
7444 : {
7445 0 : bitmap_set_bit (need_eh_cleanup,
7446 0 : gimple_bb (stmt)->index);
7447 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7448 0 : fprintf (dump_file, " Removed EH side-effects.\n");
7449 : }
7450 :
7451 : /* Likewise for AB side-effects. */
7452 719 : if (can_make_abnormal_goto
7453 719 : && !stmt_can_make_abnormal_goto (stmt))
7454 : {
7455 0 : bitmap_set_bit (need_ab_cleanup,
7456 0 : gimple_bb (stmt)->index);
7457 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7458 0 : fprintf (dump_file, " Removed AB side-effects.\n");
7459 : }
7460 :
7461 719 : return;
7462 : }
7463 : }
7464 :
7465 : /* If the statement is a scalar store, see if the expression
7466 : has the same value number as its rhs. If so, the store is
7467 : dead. */
7468 350060880 : if (gimple_assign_single_p (stmt)
7469 129242864 : && !gimple_has_volatile_ops (stmt)
7470 56196186 : && !is_gimple_reg (gimple_assign_lhs (stmt))
7471 28963597 : && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
7472 2846695 : || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
7473 379020468 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7474 16531111 : || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
7475 : {
7476 25842748 : tree rhs = gimple_assign_rhs1 (stmt);
7477 25842748 : vn_reference_t vnresult;
7478 : /* ??? gcc.dg/torture/pr91445.c shows that we lookup a boolean
7479 : typed load of a byte known to be 0x11 as 1 so a store of
7480 : a boolean 1 is detected as redundant. Because of this we
7481 : have to make sure to lookup with a ref where its size
7482 : matches the precision. */
7483 25842748 : tree lookup_lhs = lhs;
7484 51423752 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
7485 13471510 : && (TREE_CODE (lhs) != COMPONENT_REF
7486 8149441 : || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
7487 39113670 : && !type_has_mode_precision_p (TREE_TYPE (lhs)))
7488 : {
7489 836972 : if (BITINT_TYPE_P (TREE_TYPE (lhs))
7490 434902 : && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE)
7491 : lookup_lhs = NULL_TREE;
7492 416667 : else if (TREE_CODE (lhs) == COMPONENT_REF
7493 416667 : || TREE_CODE (lhs) == MEM_REF)
7494 : {
7495 292492 : tree ltype = build_nonstandard_integer_type
7496 292492 : (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhs))),
7497 292492 : TYPE_UNSIGNED (TREE_TYPE (lhs)));
7498 292492 : if (TREE_CODE (lhs) == COMPONENT_REF)
7499 : {
7500 223899 : tree foff = component_ref_field_offset (lhs);
7501 223899 : tree f = TREE_OPERAND (lhs, 1);
7502 223899 : if (!poly_int_tree_p (foff))
7503 : lookup_lhs = NULL_TREE;
7504 : else
7505 447798 : lookup_lhs = build3 (BIT_FIELD_REF, ltype,
7506 223899 : TREE_OPERAND (lhs, 0),
7507 223899 : TYPE_SIZE (TREE_TYPE (lhs)),
7508 : bit_from_pos
7509 223899 : (foff, DECL_FIELD_BIT_OFFSET (f)));
7510 : }
7511 : else
7512 68593 : lookup_lhs = build2 (MEM_REF, ltype,
7513 68593 : TREE_OPERAND (lhs, 0),
7514 68593 : TREE_OPERAND (lhs, 1));
7515 : }
7516 : else
7517 : lookup_lhs = NULL_TREE;
7518 : }
7519 25711286 : tree val = NULL_TREE, tem;
7520 25711286 : if (lookup_lhs)
7521 51422572 : val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
7522 : VN_WALKREWRITE, &vnresult, false,
7523 : NULL, NULL_TREE, true);
7524 25842748 : if (TREE_CODE (rhs) == SSA_NAME)
7525 12428477 : rhs = VN_INFO (rhs)->valnum;
7526 25842748 : gassign *ass;
7527 25842748 : if (val
7528 25842748 : && (operand_equal_p (val, rhs, 0)
7529 : /* Due to the bitfield lookups above we can get bit
7530 : interpretations of the same RHS as values here. Those
7531 : are redundant as well. */
7532 3161890 : || (TREE_CODE (val) == SSA_NAME
7533 1936507 : && gimple_assign_single_p (SSA_NAME_DEF_STMT (val))
7534 1759431 : && (tem = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val)))
7535 1759431 : && TREE_CODE (tem) == VIEW_CONVERT_EXPR
7536 3534 : && TREE_OPERAND (tem, 0) == rhs)
7537 3161888 : || (TREE_CODE (rhs) == SSA_NAME
7538 26322143 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs)))
7539 1508763 : && gimple_assign_rhs1 (ass) == val
7540 705950 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (ass))
7541 9 : && tree_nop_conversion_p (TREE_TYPE (rhs), TREE_TYPE (val)))))
7542 : {
7543 : /* We can only remove the later store if the former aliases
7544 : at least all accesses the later one does or if the store
7545 : was to readonly memory storing the same value. */
7546 250100 : ao_ref lhs_ref;
7547 250100 : ao_ref_init (&lhs_ref, lhs);
7548 250100 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
7549 250100 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
7550 250100 : if (! vnresult
7551 250100 : || ((vnresult->set == set
7552 54477 : || alias_set_subset_of (set, vnresult->set))
7553 231376 : && (vnresult->base_set == base_set
7554 25592 : || alias_set_subset_of (base_set, vnresult->base_set))))
7555 : {
7556 226555 : if (dump_file && (dump_flags & TDF_DETAILS))
7557 : {
7558 17 : fprintf (dump_file, "Deleted redundant store ");
7559 17 : print_gimple_stmt (dump_file, stmt, 0);
7560 : }
7561 :
7562 : /* Queue stmt for removal. */
7563 226555 : to_remove.safe_push (stmt);
7564 226555 : return;
7565 : }
7566 : }
7567 : }
7568 :
7569 : /* If this is a control statement value numbering left edges
7570 : unexecuted on force the condition in a way consistent with
7571 : that. */
7572 349834325 : if (gcond *cond = dyn_cast <gcond *> (stmt))
7573 : {
7574 19230086 : if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
7575 19230086 : ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
7576 : {
7577 620978 : if (dump_file && (dump_flags & TDF_DETAILS))
7578 : {
7579 15 : fprintf (dump_file, "Removing unexecutable edge from ");
7580 15 : print_gimple_stmt (dump_file, stmt, 0);
7581 : }
7582 620978 : if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
7583 620978 : == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
7584 246474 : gimple_cond_make_true (cond);
7585 : else
7586 374504 : gimple_cond_make_false (cond);
7587 620978 : update_stmt (cond);
7588 620978 : el_todo |= TODO_cleanup_cfg;
7589 620978 : return;
7590 : }
7591 : }
7592 :
7593 349213347 : bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
7594 349213347 : bool was_noreturn = (is_gimple_call (stmt)
7595 349213347 : && gimple_call_noreturn_p (stmt));
7596 349213347 : tree vdef = gimple_vdef (stmt);
7597 349213347 : tree vuse = gimple_vuse (stmt);
7598 :
7599 : /* If we didn't replace the whole stmt (or propagate the result
7600 : into all uses), replace all uses on this stmt with their
7601 : leaders. */
7602 349213347 : bool modified = false;
7603 349213347 : use_operand_p use_p;
7604 349213347 : ssa_op_iter iter;
7605 517017576 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
7606 : {
7607 167804229 : tree use = USE_FROM_PTR (use_p);
7608 : /* ??? The call code above leaves stmt operands un-updated. */
7609 167804229 : if (TREE_CODE (use) != SSA_NAME)
7610 0 : continue;
7611 167804229 : tree sprime;
7612 167804229 : if (SSA_NAME_IS_DEFAULT_DEF (use))
7613 : /* ??? For default defs BB shouldn't matter, but we have to
7614 : solve the inconsistency between rpo eliminate and
7615 : dom eliminate avail valueization first. */
7616 26838855 : sprime = eliminate_avail (b, use);
7617 : else
7618 : /* Look for sth available at the definition block of the argument.
7619 : This avoids inconsistencies between availability there which
7620 : decides if the stmt can be removed and availability at the
7621 : use site. The SSA property ensures that things available
7622 : at the definition are also available at uses. */
7623 140965374 : sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use);
7624 167804229 : if (sprime && sprime != use
7625 13414879 : && may_propagate_copy (use, sprime, true)
7626 : /* We substitute into debug stmts to avoid excessive
7627 : debug temporaries created by removed stmts, but we need
7628 : to avoid doing so for inserted sprimes as we never want
7629 : to create debug temporaries for them. */
7630 181218391 : && (!inserted_exprs
7631 1218800 : || TREE_CODE (sprime) != SSA_NAME
7632 1202956 : || !is_gimple_debug (stmt)
7633 390115 : || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
7634 : {
7635 13056715 : propagate_value (use_p, sprime);
7636 13056715 : modified = true;
7637 : }
7638 : }
7639 :
7640 : /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated
7641 : into which is a requirement for the IPA devirt machinery. */
7642 349213347 : gimple *old_stmt = stmt;
7643 349213347 : if (modified)
7644 : {
7645 : /* If a formerly non-invariant ADDR_EXPR is turned into an
7646 : invariant one it was on a separate stmt. */
7647 12143194 : if (gimple_assign_single_p (stmt)
7648 12143194 : && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
7649 243487 : recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
7650 12143194 : gimple_stmt_iterator prev = *gsi;
7651 12143194 : gsi_prev (&prev);
7652 12143194 : if (fold_stmt (gsi, follow_all_ssa_edges))
7653 : {
7654 : /* fold_stmt may have created new stmts in between
7655 : the previous stmt and the folded stmt. Mark
7656 : all defs created there as varying to not confuse
7657 : the SCCVN machinery as we're using that even during
7658 : elimination. */
7659 1033585 : if (gsi_end_p (prev))
7660 223154 : prev = gsi_start_bb (b);
7661 : else
7662 922008 : gsi_next (&prev);
7663 1033585 : if (gsi_stmt (prev) != gsi_stmt (*gsi))
7664 99790 : do
7665 : {
7666 62575 : tree def;
7667 62575 : ssa_op_iter dit;
7668 121094 : FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),
7669 : dit, SSA_OP_ALL_DEFS)
7670 : /* As existing DEFs may move between stmts
7671 : only process new ones. */
7672 58519 : if (! has_VN_INFO (def))
7673 : {
7674 37113 : vn_ssa_aux_t vn_info = VN_INFO (def);
7675 37113 : vn_info->valnum = def;
7676 37113 : vn_info->visited = true;
7677 : }
7678 62575 : if (gsi_stmt (prev) == gsi_stmt (*gsi))
7679 : break;
7680 37215 : gsi_next (&prev);
7681 37215 : }
7682 : while (1);
7683 : }
7684 12143194 : stmt = gsi_stmt (*gsi);
7685 : /* In case we folded the stmt away schedule the NOP for removal. */
7686 12143194 : if (gimple_nop_p (stmt))
7687 823 : to_remove.safe_push (stmt);
7688 : }
7689 :
7690 : /* Visit indirect calls and turn them into direct calls if
7691 : possible using the devirtualization machinery. Do this before
7692 : checking for required EH/abnormal/noreturn cleanup as devird
7693 : may expose more of those. */
7694 349213347 : if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
7695 : {
7696 22573286 : tree fn = gimple_call_fn (call_stmt);
7697 22573286 : if (fn
7698 21757354 : && flag_devirtualize
7699 43585679 : && virtual_method_call_p (fn))
7700 : {
7701 180739 : tree otr_type = obj_type_ref_class (fn);
7702 180739 : unsigned HOST_WIDE_INT otr_tok
7703 180739 : = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));
7704 180739 : tree instance;
7705 180739 : ipa_polymorphic_call_context context (current_function_decl,
7706 180739 : fn, stmt, &instance);
7707 180739 : context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),
7708 : otr_type, stmt, NULL);
7709 180739 : bool final;
7710 180739 : vec <cgraph_node *> targets
7711 180739 : = possible_polymorphic_call_targets (obj_type_ref_class (fn),
7712 : otr_tok, context, &final);
7713 180739 : if (dump_file)
7714 22 : dump_possible_polymorphic_call_targets (dump_file,
7715 : obj_type_ref_class (fn),
7716 : otr_tok, context);
7717 181034 : if (final && targets.length () <= 1 && dbg_cnt (devirt))
7718 : {
7719 73 : tree fn;
7720 73 : if (targets.length () == 1)
7721 73 : fn = targets[0]->decl;
7722 : else
7723 0 : fn = builtin_decl_unreachable ();
7724 73 : if (dump_enabled_p ())
7725 : {
7726 9 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
7727 : "converting indirect call to "
7728 : "function %s\n",
7729 9 : lang_hooks.decl_printable_name (fn, 2));
7730 : }
7731 73 : gimple_call_set_fndecl (call_stmt, fn);
7732 : /* If changing the call to __builtin_unreachable
7733 : or similar noreturn function, adjust gimple_call_fntype
7734 : too. */
7735 73 : if (gimple_call_noreturn_p (call_stmt)
7736 0 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
7737 0 : && TYPE_ARG_TYPES (TREE_TYPE (fn))
7738 73 : && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn)))
7739 0 : == void_type_node))
7740 0 : gimple_call_set_fntype (call_stmt, TREE_TYPE (fn));
7741 73 : maybe_remove_unused_call_args (cfun, call_stmt);
7742 73 : modified = true;
7743 : }
7744 : }
7745 : }
7746 :
7747 349213347 : if (modified)
7748 : {
7749 : /* When changing a call into a noreturn call, cfg cleanup
7750 : is needed to fix up the noreturn call. */
7751 12143215 : if (!was_noreturn
7752 12143215 : && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
7753 56 : to_fixup.safe_push (stmt);
7754 : /* When changing a condition or switch into one we know what
7755 : edge will be executed, schedule a cfg cleanup. */
7756 12143215 : if ((gimple_code (stmt) == GIMPLE_COND
7757 1537792 : && (gimple_cond_true_p (as_a <gcond *> (stmt))
7758 1532253 : || gimple_cond_false_p (as_a <gcond *> (stmt))))
7759 13672670 : || (gimple_code (stmt) == GIMPLE_SWITCH
7760 7691 : && TREE_CODE (gimple_switch_index
7761 : (as_a <gswitch *> (stmt))) == INTEGER_CST))
7762 10141 : el_todo |= TODO_cleanup_cfg;
7763 : /* If we removed EH side-effects from the statement, clean
7764 : its EH information. */
7765 12143215 : if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
7766 : {
7767 1919 : bitmap_set_bit (need_eh_cleanup,
7768 1919 : gimple_bb (stmt)->index);
7769 1919 : if (dump_file && (dump_flags & TDF_DETAILS))
7770 0 : fprintf (dump_file, " Removed EH side-effects.\n");
7771 : }
7772 : /* Likewise for AB side-effects. */
7773 12143215 : if (can_make_abnormal_goto
7774 12143215 : && !stmt_can_make_abnormal_goto (stmt))
7775 : {
7776 0 : bitmap_set_bit (need_ab_cleanup,
7777 0 : gimple_bb (stmt)->index);
7778 0 : if (dump_file && (dump_flags & TDF_DETAILS))
7779 0 : fprintf (dump_file, " Removed AB side-effects.\n");
7780 : }
7781 12143215 : update_stmt (stmt);
7782 : /* In case the VDEF on the original stmt was released, value-number
7783 : it to the VUSE. This is to make vuse_ssa_val able to skip
7784 : released virtual operands. */
7785 15447316 : if (vdef && SSA_NAME_IN_FREE_LIST (vdef))
7786 2143 : VN_INFO (vdef)->valnum = vuse;
7787 : }
7788 :
7789 : /* Make new values available - for fully redundant LHS we
7790 : continue with the next stmt above and skip this.
7791 : But avoid picking up dead defs. */
7792 349213347 : tree def;
7793 420749736 : FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
7794 71536389 : if (! has_zero_uses (def)
7795 71536389 : || (inserted_exprs
7796 211127 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (def))))
7797 70103058 : eliminate_push_avail (b, def);
7798 : }
7799 :
7800 : /* Perform elimination for the basic-block B during the domwalk. */
7801 :
7802 : edge
7803 41707663 : eliminate_dom_walker::before_dom_children (basic_block b)
7804 : {
7805 : /* Mark new bb. */
7806 41707663 : avail_stack.safe_push (NULL_TREE);
7807 :
7808 : /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */
7809 41707663 : if (!(b->flags & BB_EXECUTABLE))
7810 : return NULL;
7811 :
7812 36830263 : vn_context_bb = b;
7813 :
7814 48388608 : for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
7815 : {
7816 11558345 : gphi *phi = gsi.phi ();
7817 11558345 : tree res = PHI_RESULT (phi);
7818 :
7819 23116690 : if (virtual_operand_p (res))
7820 : {
7821 5311065 : gsi_next (&gsi);
7822 5311065 : continue;
7823 : }
7824 :
7825 6247280 : tree sprime = eliminate_avail (b, res);
7826 6247280 : if (sprime
7827 6247280 : && sprime != res)
7828 : {
7829 440056 : if (dump_file && (dump_flags & TDF_DETAILS))
7830 : {
7831 20 : fprintf (dump_file, "Replaced redundant PHI node defining ");
7832 20 : print_generic_expr (dump_file, res);
7833 20 : fprintf (dump_file, " with ");
7834 20 : print_generic_expr (dump_file, sprime);
7835 20 : fprintf (dump_file, "\n");
7836 : }
7837 :
7838 : /* If we inserted this PHI node ourself, it's not an elimination. */
7839 440056 : if (! inserted_exprs
7840 558208 : || ! bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
7841 413979 : eliminations++;
7842 :
7843 : /* If we will propagate into all uses don't bother to do
7844 : anything. */
7845 440056 : if (may_propagate_copy (res, sprime))
7846 : {
7847 : /* Mark the PHI for removal. */
7848 440056 : to_remove.safe_push (phi);
7849 440056 : gsi_next (&gsi);
7850 440056 : continue;
7851 : }
7852 :
7853 0 : remove_phi_node (&gsi, false);
7854 :
7855 0 : if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
7856 0 : sprime = fold_convert (TREE_TYPE (res), sprime);
7857 0 : gimple *stmt = gimple_build_assign (res, sprime);
7858 0 : gimple_stmt_iterator gsi2 = gsi_after_labels (b);
7859 0 : gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
7860 0 : continue;
7861 0 : }
7862 :
7863 5807224 : eliminate_push_avail (b, res);
7864 5807224 : gsi_next (&gsi);
7865 : }
7866 :
7867 73660526 : for (gimple_stmt_iterator gsi = gsi_start_bb (b);
7868 289622887 : !gsi_end_p (gsi);
7869 252792624 : gsi_next (&gsi))
7870 252792624 : eliminate_stmt (b, &gsi);
7871 :
7872 : /* Replace destination PHI arguments. */
7873 36830263 : edge_iterator ei;
7874 36830263 : edge e;
7875 86935079 : FOR_EACH_EDGE (e, ei, b->succs)
7876 50104816 : if (e->flags & EDGE_EXECUTABLE)
7877 49549634 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
7878 79197331 : !gsi_end_p (gsi);
7879 29647697 : gsi_next (&gsi))
7880 : {
7881 29647697 : gphi *phi = gsi.phi ();
7882 29647697 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
7883 29647697 : tree arg = USE_FROM_PTR (use_p);
7884 49073002 : if (TREE_CODE (arg) != SSA_NAME
7885 29647697 : || virtual_operand_p (arg))
7886 19425305 : continue;
7887 10222392 : tree sprime = eliminate_avail (b, arg);
7888 20444784 : if (sprime && may_propagate_copy (arg, sprime,
7889 10222392 : !(e->flags & EDGE_ABNORMAL)))
7890 10210021 : propagate_value (use_p, sprime);
7891 : }
7892 :
7893 36830263 : vn_context_bb = NULL;
7894 :
7895 36830263 : return NULL;
7896 : }
7897 :
7898 : /* Make no longer available leaders no longer available. */
7899 :
7900 : void
7901 41707663 : eliminate_dom_walker::after_dom_children (basic_block)
7902 : {
7903 41707663 : tree entry;
7904 92502247 : while ((entry = avail_stack.pop ()) != NULL_TREE)
7905 : {
7906 50794584 : tree valnum = VN_INFO (entry)->valnum;
7907 50794584 : tree old = avail[SSA_NAME_VERSION (valnum)];
7908 50794584 : if (old == entry)
7909 50749442 : avail[SSA_NAME_VERSION (valnum)] = NULL_TREE;
7910 : else
7911 45142 : avail[SSA_NAME_VERSION (valnum)] = entry;
7912 : }
7913 41707663 : }
7914 :
7915 : /* Remove queued stmts and perform delayed cleanups. */
7916 :
7917 : unsigned
7918 6210868 : eliminate_dom_walker::eliminate_cleanup (bool region_p)
7919 : {
7920 6210868 : statistics_counter_event (cfun, "Eliminated", eliminations);
7921 6210868 : statistics_counter_event (cfun, "Insertions", insertions);
7922 :
7923 : /* We cannot remove stmts during BB walk, especially not release SSA
7924 : names there as this confuses the VN machinery. The stmts ending
7925 : up in to_remove are either stores or simple copies.
7926 : Remove stmts in reverse order to make debug stmt creation possible. */
7927 33946273 : while (!to_remove.is_empty ())
7928 : {
7929 15313613 : bool do_release_defs = true;
7930 15313613 : gimple *stmt = to_remove.pop ();
7931 :
7932 : /* When we are value-numbering a region we do not require exit PHIs to
7933 : be present so we have to make sure to deal with uses outside of the
7934 : region of stmts that we thought are eliminated.
7935 : ??? Note we may be confused by uses in dead regions we didn't run
7936 : elimination on. Rather than checking individual uses we accept
7937 : dead copies to be generated here (gcc.c-torture/execute/20060905-1.c
7938 : contains such example). */
7939 15313613 : if (region_p)
7940 : {
7941 1808860 : if (gphi *phi = dyn_cast <gphi *> (stmt))
7942 : {
7943 1127389 : tree lhs = gimple_phi_result (phi);
7944 1127389 : if (!has_zero_uses (lhs))
7945 : {
7946 23889 : if (dump_file && (dump_flags & TDF_DETAILS))
7947 3 : fprintf (dump_file, "Keeping eliminated stmt live "
7948 : "as copy because of out-of-region uses\n");
7949 23889 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7950 23889 : gimple *copy = gimple_build_assign (lhs, sprime);
7951 23889 : gimple_stmt_iterator gsi
7952 23889 : = gsi_after_labels (gimple_bb (stmt));
7953 23889 : gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
7954 23889 : do_release_defs = false;
7955 : }
7956 : }
7957 681471 : else if (tree lhs = gimple_get_lhs (stmt))
7958 681471 : if (TREE_CODE (lhs) == SSA_NAME
7959 681471 : && !has_zero_uses (lhs))
7960 : {
7961 2053 : if (dump_file && (dump_flags & TDF_DETAILS))
7962 0 : fprintf (dump_file, "Keeping eliminated stmt live "
7963 : "as copy because of out-of-region uses\n");
7964 2053 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7965 2053 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7966 2053 : if (is_gimple_assign (stmt))
7967 : {
7968 2053 : gimple_assign_set_rhs_from_tree (&gsi, sprime);
7969 2053 : stmt = gsi_stmt (gsi);
7970 2053 : update_stmt (stmt);
7971 2053 : if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
7972 0 : bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
7973 2053 : continue;
7974 : }
7975 : else
7976 : {
7977 0 : gimple *copy = gimple_build_assign (lhs, sprime);
7978 0 : gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
7979 0 : do_release_defs = false;
7980 : }
7981 : }
7982 : }
7983 :
7984 15311560 : if (dump_file && (dump_flags & TDF_DETAILS))
7985 : {
7986 21750 : fprintf (dump_file, "Removing dead stmt ");
7987 21750 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
7988 : }
7989 :
7990 15311560 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7991 15311560 : if (gimple_code (stmt) == GIMPLE_PHI)
7992 1769548 : remove_phi_node (&gsi, do_release_defs);
7993 : else
7994 : {
7995 13542012 : basic_block bb = gimple_bb (stmt);
7996 13542012 : unlink_stmt_vdef (stmt);
7997 13542012 : if (gsi_remove (&gsi, true))
7998 26582 : bitmap_set_bit (need_eh_cleanup, bb->index);
7999 13542012 : if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt))
8000 2 : bitmap_set_bit (need_ab_cleanup, bb->index);
8001 13542012 : if (do_release_defs)
8002 13542012 : release_defs (stmt);
8003 : }
8004 :
8005 : /* Removing a stmt may expose a forwarder block. */
8006 15311560 : el_todo |= TODO_cleanup_cfg;
8007 : }
8008 :
8009 : /* Fixup stmts that became noreturn calls. This may require splitting
8010 : blocks and thus isn't possible during the dominator walk. Do this
8011 : in reverse order so we don't inadvertently remove a stmt we want to
8012 : fixup by visiting a dominating now noreturn call first. */
8013 6210924 : while (!to_fixup.is_empty ())
8014 : {
8015 56 : gimple *stmt = to_fixup.pop ();
8016 :
8017 56 : if (dump_file && (dump_flags & TDF_DETAILS))
8018 : {
8019 0 : fprintf (dump_file, "Fixing up noreturn call ");
8020 0 : print_gimple_stmt (dump_file, stmt, 0);
8021 : }
8022 :
8023 56 : if (fixup_noreturn_call (stmt))
8024 56 : el_todo |= TODO_cleanup_cfg;
8025 : }
8026 :
8027 6210868 : bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
8028 6210868 : bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
8029 :
8030 6210868 : if (do_eh_cleanup)
8031 10680 : gimple_purge_all_dead_eh_edges (need_eh_cleanup);
8032 :
8033 6210868 : if (do_ab_cleanup)
8034 2 : gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
8035 :
8036 6210868 : if (do_eh_cleanup || do_ab_cleanup)
8037 10682 : el_todo |= TODO_cleanup_cfg;
8038 :
8039 6210868 : return el_todo;
8040 : }
8041 :
8042 : /* Eliminate fully redundant computations. */
8043 :
8044 : unsigned
8045 4330262 : eliminate_with_rpo_vn (bitmap inserted_exprs)
8046 : {
8047 4330262 : eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);
8048 :
8049 4330262 : eliminate_dom_walker *saved_rpo_avail = rpo_avail;
8050 4330262 : rpo_avail = &walker;
8051 4330262 : walker.walk (cfun->cfg->x_entry_block_ptr);
8052 4330262 : rpo_avail = saved_rpo_avail;
8053 :
8054 4330262 : return walker.eliminate_cleanup ();
8055 4330262 : }
8056 :
8057 : static unsigned
8058 : do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
8059 : bool iterate, bool eliminate, bool skip_entry_phis,
8060 : vn_lookup_kind kind);
8061 :
8062 : void
8063 970230 : run_rpo_vn (vn_lookup_kind kind)
8064 : {
8065 970230 : do_rpo_vn_1 (cfun, NULL, NULL, true, false, false, kind);
8066 :
8067 : /* ??? Prune requirement of these. */
8068 970230 : constant_to_value_id = new hash_table<vn_constant_hasher> (23);
8069 :
8070 : /* Initialize the value ids and prune out remaining VN_TOPs
8071 : from dead code. */
8072 970230 : tree name;
8073 970230 : unsigned i;
8074 47713138 : FOR_EACH_SSA_NAME (i, name, cfun)
8075 : {
8076 33896690 : vn_ssa_aux_t info = VN_INFO (name);
8077 33896690 : if (!info->visited
8078 33818952 : || info->valnum == VN_TOP)
8079 77738 : info->valnum = name;
8080 33896690 : if (info->valnum == name)
8081 32743377 : info->value_id = get_next_value_id ();
8082 1153313 : else if (is_gimple_min_invariant (info->valnum))
8083 39803 : info->value_id = get_or_alloc_constant_value_id (info->valnum);
8084 : }
8085 :
8086 : /* Propagate. */
8087 47713138 : FOR_EACH_SSA_NAME (i, name, cfun)
8088 : {
8089 33896690 : vn_ssa_aux_t info = VN_INFO (name);
8090 33896690 : if (TREE_CODE (info->valnum) == SSA_NAME
8091 33856887 : && info->valnum != name
8092 35010200 : && info->value_id != VN_INFO (info->valnum)->value_id)
8093 1113510 : info->value_id = VN_INFO (info->valnum)->value_id;
8094 : }
8095 :
8096 970230 : set_hashtable_value_ids ();
8097 :
8098 970230 : if (dump_file && (dump_flags & TDF_DETAILS))
8099 : {
8100 14 : fprintf (dump_file, "Value numbers:\n");
8101 406 : FOR_EACH_SSA_NAME (i, name, cfun)
8102 : {
8103 307 : if (VN_INFO (name)->visited
8104 307 : && SSA_VAL (name) != name)
8105 : {
8106 33 : print_generic_expr (dump_file, name);
8107 33 : fprintf (dump_file, " = ");
8108 33 : print_generic_expr (dump_file, SSA_VAL (name));
8109 33 : fprintf (dump_file, " (%04d)\n", VN_INFO (name)->value_id);
8110 : }
8111 : }
8112 : }
8113 970230 : }
8114 :
8115 : /* Free VN associated data structures. */
8116 :
8117 : void
8118 6230471 : free_rpo_vn (void)
8119 : {
8120 6230471 : free_vn_table (valid_info);
8121 6230471 : XDELETE (valid_info);
8122 6230471 : obstack_free (&vn_tables_obstack, NULL);
8123 6230471 : obstack_free (&vn_tables_insert_obstack, NULL);
8124 :
8125 6230471 : vn_ssa_aux_iterator_type it;
8126 6230471 : vn_ssa_aux_t info;
8127 356340503 : FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it)
8128 175055016 : if (info->needs_insertion)
8129 4193824 : release_ssa_name (info->name);
8130 6230471 : obstack_free (&vn_ssa_aux_obstack, NULL);
8131 6230471 : delete vn_ssa_aux_hash;
8132 :
8133 6230471 : delete constant_to_value_id;
8134 6230471 : constant_to_value_id = NULL;
8135 6230471 : }
8136 :
8137 : /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
8138 :
8139 : static tree
8140 23524677 : vn_lookup_simplify_result (gimple_match_op *res_op)
8141 : {
8142 23524677 : if (!res_op->code.is_tree_code ())
8143 : return NULL_TREE;
8144 23521469 : tree *ops = res_op->ops;
8145 23521469 : unsigned int length = res_op->num_ops;
8146 23521469 : if (res_op->code == CONSTRUCTOR
8147 : /* ??? We're arriving here with SCCVNs view, decomposed CONSTRUCTOR
8148 : and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree. */
8149 23521469 : && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR)
8150 : {
8151 1056 : length = CONSTRUCTOR_NELTS (res_op->ops[0]);
8152 1056 : ops = XALLOCAVEC (tree, length);
8153 4764 : for (unsigned i = 0; i < length; ++i)
8154 3708 : ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value;
8155 : }
8156 23521469 : vn_nary_op_t vnresult = NULL;
8157 23521469 : tree res = vn_nary_op_lookup_pieces (length, (tree_code) res_op->code,
8158 : res_op->type, ops, &vnresult);
8159 : /* If this is used from expression simplification make sure to
8160 : return an available expression. */
8161 23521469 : if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail)
8162 2292757 : res = rpo_avail->eliminate_avail (vn_context_bb, res);
8163 : return res;
8164 : }
8165 :
8166 : /* Return a leader for OPs value that is valid at BB. */
8167 :
8168 : tree
8169 277100934 : rpo_elim::eliminate_avail (basic_block bb, tree op)
8170 : {
8171 277100934 : bool visited;
8172 277100934 : tree valnum = SSA_VAL (op, &visited);
8173 : /* If we didn't visit OP then it must be defined outside of the
8174 : region we process and also dominate it. So it is available. */
8175 277100934 : if (!visited)
8176 : return op;
8177 274904959 : if (TREE_CODE (valnum) == SSA_NAME)
8178 : {
8179 260384046 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
8180 : return valnum;
8181 253551014 : vn_ssa_aux_t valnum_info = VN_INFO (valnum);
8182 253551014 : vn_avail *av = valnum_info->avail;
8183 253551014 : if (!av)
8184 : {
8185 : /* See above. But when there's availability info prefer
8186 : what we recorded there for example to preserve LC SSA. */
8187 84882866 : if (!valnum_info->visited)
8188 : return valnum;
8189 : return NULL_TREE;
8190 : }
8191 168668148 : if (av->location == bb->index)
8192 : /* On tramp3d 90% of the cases are here. */
8193 111230752 : return ssa_name (av->leader);
8194 71683346 : do
8195 : {
8196 71683346 : basic_block abb = BASIC_BLOCK_FOR_FN (cfun, av->location);
8197 : /* ??? During elimination we have to use availability at the
8198 : definition site of a use we try to replace. This
8199 : is required to not run into inconsistencies because
8200 : of dominated_by_p_w_unex behavior and removing a definition
8201 : while not replacing all uses.
8202 : ??? We could try to consistently walk dominators
8203 : ignoring non-executable regions. The nearest common
8204 : dominator of bb and abb is where we can stop walking. We
8205 : may also be able to "pre-compute" (bits of) the next immediate
8206 : (non-)dominator during the RPO walk when marking edges as
8207 : executable. */
8208 71683346 : if (dominated_by_p_w_unex (bb, abb, true))
8209 : {
8210 53440119 : tree leader = ssa_name (av->leader);
8211 : /* Prevent eliminations that break loop-closed SSA. */
8212 53440119 : if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
8213 3585743 : && ! SSA_NAME_IS_DEFAULT_DEF (leader)
8214 57025862 : && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT
8215 3585743 : (leader))->loop_father,
8216 : bb))
8217 : return NULL_TREE;
8218 53360187 : if (dump_file && (dump_flags & TDF_DETAILS))
8219 : {
8220 3782 : print_generic_expr (dump_file, leader);
8221 3782 : fprintf (dump_file, " is available for ");
8222 3782 : print_generic_expr (dump_file, valnum);
8223 3782 : fprintf (dump_file, "\n");
8224 : }
8225 : /* On tramp3d 99% of the _remaining_ cases succeed at
8226 : the first enty. */
8227 53360187 : return leader;
8228 : }
8229 : /* ??? Can we somehow skip to the immediate dominator
8230 : RPO index (bb_to_rpo)? Again, maybe not worth, on
8231 : tramp3d the worst number of elements in the vector is 9. */
8232 18243227 : av = av->next;
8233 : }
8234 18243227 : while (av);
8235 : /* While we prefer avail we have to fallback to using the value
8236 : directly if defined outside of the region when none of the
8237 : available defs suit. */
8238 3997277 : if (!valnum_info->visited)
8239 : return valnum;
8240 : }
8241 14520913 : else if (valnum != VN_TOP)
8242 : /* valnum is is_gimple_min_invariant. */
8243 : return valnum;
8244 : return NULL_TREE;
8245 : }
8246 :
8247 : /* Make LEADER a leader for its value at BB. */
8248 :
8249 : void
8250 98403140 : rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
8251 : {
8252 98403140 : tree valnum = VN_INFO (leader)->valnum;
8253 98403140 : if (valnum == VN_TOP
8254 98403140 : || is_gimple_min_invariant (valnum))
8255 0 : return;
8256 98403140 : if (dump_file && (dump_flags & TDF_DETAILS))
8257 : {
8258 325052 : fprintf (dump_file, "Making available beyond BB%d ", bb->index);
8259 325052 : print_generic_expr (dump_file, leader);
8260 325052 : fprintf (dump_file, " for value ");
8261 325052 : print_generic_expr (dump_file, valnum);
8262 325052 : fprintf (dump_file, "\n");
8263 : }
8264 98403140 : vn_ssa_aux_t value = VN_INFO (valnum);
8265 98403140 : vn_avail *av;
8266 98403140 : if (m_avail_freelist)
8267 : {
8268 18943831 : av = m_avail_freelist;
8269 18943831 : m_avail_freelist = m_avail_freelist->next;
8270 : }
8271 : else
8272 79459309 : av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
8273 98403140 : av->location = bb->index;
8274 98403140 : av->leader = SSA_NAME_VERSION (leader);
8275 98403140 : av->next = value->avail;
8276 98403140 : av->next_undo = last_pushed_avail;
8277 98403140 : last_pushed_avail = value;
8278 98403140 : value->avail = av;
8279 : }
8280 :
8281 : /* Valueization hook for RPO VN plus required state. */
8282 :
8283 : tree
8284 2156938074 : rpo_vn_valueize (tree name)
8285 : {
8286 2156938074 : if (TREE_CODE (name) == SSA_NAME)
8287 : {
8288 2110297911 : vn_ssa_aux_t val = VN_INFO (name);
8289 2110297911 : if (val)
8290 : {
8291 2110297911 : tree tem = val->valnum;
8292 2110297911 : if (tem != VN_TOP && tem != name)
8293 : {
8294 115084323 : if (TREE_CODE (tem) != SSA_NAME)
8295 : return tem;
8296 : /* For all values we only valueize to an available leader
8297 : which means we can use SSA name info without restriction. */
8298 97521612 : tem = rpo_avail->eliminate_avail (vn_context_bb, tem);
8299 97521612 : if (tem)
8300 : return tem;
8301 : }
8302 : }
8303 : }
8304 : return name;
8305 : }
8306 :
8307 : /* Insert on PRED_E predicates derived from CODE OPS being true besides the
8308 : inverted condition. */
8309 :
8310 : static void
8311 27693725 : insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e)
8312 : {
8313 27693725 : switch (code)
8314 : {
8315 1384578 : case LT_EXPR:
8316 : /* a < b -> a {!,<}= b */
8317 1384578 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8318 : ops, boolean_true_node, 0, pred_e);
8319 1384578 : vn_nary_op_insert_pieces_predicated (2, LE_EXPR, boolean_type_node,
8320 : ops, boolean_true_node, 0, pred_e);
8321 : /* a < b -> ! a {>,=} b */
8322 1384578 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8323 : ops, boolean_false_node, 0, pred_e);
8324 1384578 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8325 : ops, boolean_false_node, 0, pred_e);
8326 1384578 : break;
8327 3466355 : case GT_EXPR:
8328 : /* a > b -> a {!,>}= b */
8329 3466355 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8330 : ops, boolean_true_node, 0, pred_e);
8331 3466355 : vn_nary_op_insert_pieces_predicated (2, GE_EXPR, boolean_type_node,
8332 : ops, boolean_true_node, 0, pred_e);
8333 : /* a > b -> ! a {<,=} b */
8334 3466355 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8335 : ops, boolean_false_node, 0, pred_e);
8336 3466355 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8337 : ops, boolean_false_node, 0, pred_e);
8338 3466355 : break;
8339 9511320 : case EQ_EXPR:
8340 : /* a == b -> ! a {<,>} b */
8341 9511320 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8342 : ops, boolean_false_node, 0, pred_e);
8343 9511320 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8344 : ops, boolean_false_node, 0, pred_e);
8345 9511320 : break;
8346 : case LE_EXPR:
8347 : case GE_EXPR:
8348 : case NE_EXPR:
8349 : /* Nothing besides inverted condition. */
8350 : break;
8351 27693725 : default:;
8352 : }
8353 27693725 : }
8354 :
8355 : /* Insert on the TRUE_E true and FALSE_E false predicates
8356 : derived from LHS CODE RHS. */
8357 :
8358 : static void
8359 23644492 : insert_predicates_for_cond (tree_code code, tree lhs, tree rhs,
8360 : edge true_e, edge false_e)
8361 : {
8362 : /* If both edges are null, then there is nothing to be done. */
8363 23644492 : if (!true_e && !false_e)
8364 1345704 : return;
8365 :
8366 : /* Canonicalize the comparison if needed, putting
8367 : the constant in the rhs. */
8368 22302280 : if (tree_swap_operands_p (lhs, rhs))
8369 : {
8370 16899 : std::swap (lhs, rhs);
8371 16899 : code = swap_tree_comparison (code);
8372 : }
8373 :
8374 : /* If the lhs is not a ssa name, don't record anything. */
8375 22302280 : if (TREE_CODE (lhs) != SSA_NAME)
8376 : return;
8377 :
8378 22298788 : tree_code icode = invert_tree_comparison (code, HONOR_NANS (lhs));
8379 22298788 : tree ops[2];
8380 22298788 : ops[0] = lhs;
8381 22298788 : ops[1] = rhs;
8382 22298788 : if (true_e)
8383 18191593 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8384 : boolean_true_node, 0, true_e);
8385 22298788 : if (false_e)
8386 17132562 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8387 : boolean_false_node, 0, false_e);
8388 22298788 : if (icode != ERROR_MARK)
8389 : {
8390 22047559 : if (true_e)
8391 18034705 : vn_nary_op_insert_pieces_predicated (2, icode, boolean_type_node, ops,
8392 : boolean_false_node, 0, true_e);
8393 22047559 : if (false_e)
8394 16929631 : vn_nary_op_insert_pieces_predicated (2, icode, boolean_type_node, ops,
8395 : boolean_true_node, 0, false_e);
8396 : }
8397 : /* Relax for non-integers, inverted condition handled
8398 : above. */
8399 22298788 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
8400 : {
8401 17475060 : if (true_e)
8402 14323530 : insert_related_predicates_on_edge (code, ops, true_e);
8403 17475060 : if (false_e)
8404 13370195 : insert_related_predicates_on_edge (icode, ops, false_e);
8405 : }
8406 22298788 : if (integer_zerop (rhs)
8407 22298788 : && (code == NE_EXPR || code == EQ_EXPR))
8408 : {
8409 9327153 : gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
8410 : /* (A CMP B) != 0 is the same as (A CMP B).
8411 : (A CMP B) == 0 is just (A CMP B) with the edges swapped. */
8412 9327153 : if (is_gimple_assign (def_stmt)
8413 9327153 : && TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
8414 : {
8415 439236 : tree_code nc = gimple_assign_rhs_code (def_stmt);
8416 439236 : tree nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
8417 439236 : tree nrhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8418 439236 : edge nt = true_e;
8419 439236 : edge nf = false_e;
8420 439236 : if (code == EQ_EXPR)
8421 313557 : std::swap (nt, nf);
8422 439236 : if (lhs != nlhs)
8423 439236 : insert_predicates_for_cond (nc, nlhs, nrhs, nt, nf);
8424 : }
8425 : /* (a | b) == 0 ->
8426 : on true edge assert: a == 0 & b == 0. */
8427 : /* (a | b) != 0 ->
8428 : on false edge assert: a == 0 & b == 0. */
8429 9327153 : if (is_gimple_assign (def_stmt)
8430 9327153 : && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
8431 : {
8432 262905 : edge e = code == EQ_EXPR ? true_e : false_e;
8433 262905 : tree nlhs;
8434 :
8435 262905 : nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
8436 : /* A valueization of the `a` might return the old lhs
8437 : which is already handled above. */
8438 262905 : if (nlhs != lhs)
8439 262905 : insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
8440 :
8441 : /* A valueization of the `b` might return the old lhs
8442 : which is already handled above. */
8443 262905 : nlhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8444 262905 : if (nlhs != lhs)
8445 262905 : insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
8446 : }
8447 : }
8448 : }
8449 :
8450 : /* Main stmt worker for RPO VN, process BB. */
8451 :
8452 : static unsigned
8453 62056100 : process_bb (rpo_elim &avail, basic_block bb,
8454 : bool bb_visited, bool iterate_phis, bool iterate, bool eliminate,
8455 : bool do_region, bitmap exit_bbs, bool skip_phis)
8456 : {
8457 62056100 : unsigned todo = 0;
8458 62056100 : edge_iterator ei;
8459 62056100 : edge e;
8460 :
8461 62056100 : vn_context_bb = bb;
8462 :
8463 : /* If we are in loop-closed SSA preserve this state. This is
8464 : relevant when called on regions from outside of FRE/PRE. */
8465 62056100 : bool lc_phi_nodes = false;
8466 62056100 : if (!skip_phis
8467 62056100 : && loops_state_satisfies_p (LOOP_CLOSED_SSA))
8468 3833919 : FOR_EACH_EDGE (e, ei, bb->preds)
8469 2317924 : if (e->src->loop_father != e->dest->loop_father
8470 2317924 : && flow_loop_nested_p (e->dest->loop_father,
8471 : e->src->loop_father))
8472 : {
8473 : lc_phi_nodes = true;
8474 : break;
8475 : }
8476 :
8477 : /* When we visit a loop header substitute into loop info. */
8478 62056100 : if (!iterate && eliminate && bb->loop_father->header == bb)
8479 : {
8480 : /* Keep fields in sync with substitute_in_loop_info. */
8481 948711 : if (bb->loop_father->nb_iterations)
8482 155920 : bb->loop_father->nb_iterations
8483 155920 : = simplify_replace_tree (bb->loop_father->nb_iterations,
8484 : NULL_TREE, NULL_TREE, &vn_valueize_for_srt);
8485 : }
8486 :
8487 : /* Value-number all defs in the basic-block. */
8488 62056100 : if (!skip_phis)
8489 89051716 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8490 27024975 : gsi_next (&gsi))
8491 : {
8492 27024975 : gphi *phi = gsi.phi ();
8493 27024975 : tree res = PHI_RESULT (phi);
8494 27024975 : vn_ssa_aux_t res_info = VN_INFO (res);
8495 27024975 : if (!bb_visited)
8496 : {
8497 19074685 : gcc_assert (!res_info->visited);
8498 19074685 : res_info->valnum = VN_TOP;
8499 19074685 : res_info->visited = true;
8500 : }
8501 :
8502 : /* When not iterating force backedge values to varying. */
8503 27024975 : visit_stmt (phi, !iterate_phis);
8504 54049950 : if (virtual_operand_p (res))
8505 10701478 : continue;
8506 :
8507 : /* Eliminate */
8508 : /* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness
8509 : how we handle backedges and availability.
8510 : And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization. */
8511 16323497 : tree val = res_info->valnum;
8512 16323497 : if (res != val && !iterate && eliminate)
8513 : {
8514 1450233 : if (tree leader = avail.eliminate_avail (bb, res))
8515 : {
8516 1330021 : if (leader != res
8517 : /* Preserve loop-closed SSA form. */
8518 1330021 : && (! lc_phi_nodes
8519 6404 : || is_gimple_min_invariant (leader)))
8520 : {
8521 1329492 : if (dump_file && (dump_flags & TDF_DETAILS))
8522 : {
8523 209 : fprintf (dump_file, "Replaced redundant PHI node "
8524 : "defining ");
8525 209 : print_generic_expr (dump_file, res);
8526 209 : fprintf (dump_file, " with ");
8527 209 : print_generic_expr (dump_file, leader);
8528 209 : fprintf (dump_file, "\n");
8529 : }
8530 1329492 : avail.eliminations++;
8531 :
8532 1329492 : if (may_propagate_copy (res, leader))
8533 : {
8534 : /* Schedule for removal. */
8535 1329492 : avail.to_remove.safe_push (phi);
8536 1329492 : continue;
8537 : }
8538 : /* ??? Else generate a copy stmt. */
8539 : }
8540 : }
8541 : }
8542 : /* Only make defs available that not already are. But make
8543 : sure loop-closed SSA PHI node defs are picked up for
8544 : downstream uses. */
8545 14994005 : if (lc_phi_nodes
8546 14994005 : || res == val
8547 14994005 : || ! avail.eliminate_avail (bb, res))
8548 11450085 : avail.eliminate_push_avail (bb, res);
8549 : }
8550 :
8551 : /* For empty BBs mark outgoing edges executable. For non-empty BBs
8552 : we do this when processing the last stmt as we have to do this
8553 : before elimination which otherwise forces GIMPLE_CONDs to
8554 : if (1 != 0) style when seeing non-executable edges. */
8555 124112200 : if (gsi_end_p (gsi_start_bb (bb)))
8556 : {
8557 14015464 : FOR_EACH_EDGE (e, ei, bb->succs)
8558 : {
8559 7007732 : if (!(e->flags & EDGE_EXECUTABLE))
8560 : {
8561 4794343 : if (dump_file && (dump_flags & TDF_DETAILS))
8562 6231 : fprintf (dump_file,
8563 : "marking outgoing edge %d -> %d executable\n",
8564 6231 : e->src->index, e->dest->index);
8565 4794343 : e->flags |= EDGE_EXECUTABLE;
8566 4794343 : e->dest->flags |= BB_EXECUTABLE;
8567 : }
8568 2213389 : else if (!(e->dest->flags & BB_EXECUTABLE))
8569 : {
8570 0 : if (dump_file && (dump_flags & TDF_DETAILS))
8571 0 : fprintf (dump_file,
8572 : "marking destination block %d reachable\n",
8573 : e->dest->index);
8574 0 : e->dest->flags |= BB_EXECUTABLE;
8575 : }
8576 : }
8577 : }
8578 124112200 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
8579 504102105 : !gsi_end_p (gsi); gsi_next (&gsi))
8580 : {
8581 442046005 : ssa_op_iter i;
8582 442046005 : tree op;
8583 442046005 : if (!bb_visited)
8584 : {
8585 503155070 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
8586 : {
8587 140111737 : vn_ssa_aux_t op_info = VN_INFO (op);
8588 140111737 : gcc_assert (!op_info->visited);
8589 140111737 : op_info->valnum = VN_TOP;
8590 140111737 : op_info->visited = true;
8591 : }
8592 :
8593 : /* We somehow have to deal with uses that are not defined
8594 : in the processed region. Forcing unvisited uses to
8595 : varying here doesn't play well with def-use following during
8596 : expression simplification, so we deal with this by checking
8597 : the visited flag in SSA_VAL. */
8598 : }
8599 :
8600 442046005 : visit_stmt (gsi_stmt (gsi));
8601 :
8602 442046005 : gimple *last = gsi_stmt (gsi);
8603 442046005 : e = NULL;
8604 442046005 : switch (gimple_code (last))
8605 : {
8606 114228 : case GIMPLE_SWITCH:
8607 114228 : e = find_taken_edge (bb, vn_valueize (gimple_switch_index
8608 114228 : (as_a <gswitch *> (last))));
8609 114228 : break;
8610 24930799 : case GIMPLE_COND:
8611 24930799 : {
8612 24930799 : tree lhs = vn_valueize (gimple_cond_lhs (last));
8613 24930799 : tree rhs = vn_valueize (gimple_cond_rhs (last));
8614 24930799 : tree_code cmpcode = gimple_cond_code (last);
8615 : /* Canonicalize the comparison if needed, putting
8616 : the constant in the rhs. */
8617 24930799 : if (tree_swap_operands_p (lhs, rhs))
8618 : {
8619 843130 : std::swap (lhs, rhs);
8620 843130 : cmpcode = swap_tree_comparison (cmpcode);
8621 : }
8622 24930799 : tree val = gimple_simplify (cmpcode,
8623 : boolean_type_node, lhs, rhs,
8624 : NULL, vn_valueize);
8625 : /* If the condition didn't simplify see if we have recorded
8626 : an expression from sofar taken edges. */
8627 24930799 : if (! val || TREE_CODE (val) != INTEGER_CST)
8628 : {
8629 23039892 : vn_nary_op_t vnresult;
8630 23039892 : tree ops[2];
8631 23039892 : ops[0] = lhs;
8632 23039892 : ops[1] = rhs;
8633 23039892 : val = vn_nary_op_lookup_pieces (2, cmpcode,
8634 : boolean_type_node, ops,
8635 : &vnresult);
8636 : /* Got back a ssa name, then try looking up `val != 0`
8637 : as it might have been recorded that way. */
8638 23039892 : if (val && TREE_CODE (val) == SSA_NAME)
8639 : {
8640 173565 : ops[0] = val;
8641 173565 : ops[1] = build_zero_cst (TREE_TYPE (val));
8642 173565 : val = vn_nary_op_lookup_pieces (2, NE_EXPR,
8643 : boolean_type_node, ops,
8644 : &vnresult);
8645 : }
8646 : /* Did we get a predicated value? */
8647 23039876 : if (! val && vnresult && vnresult->predicated_values)
8648 : {
8649 1404982 : val = vn_nary_op_get_predicated_value (vnresult, bb);
8650 1404982 : if (val && dump_file && (dump_flags & TDF_DETAILS))
8651 : {
8652 2 : fprintf (dump_file, "Got predicated value ");
8653 2 : print_generic_expr (dump_file, val, TDF_NONE);
8654 2 : fprintf (dump_file, " for ");
8655 2 : print_gimple_stmt (dump_file, last, TDF_SLIM);
8656 : }
8657 : }
8658 : }
8659 23039892 : if (val)
8660 2251353 : e = find_taken_edge (bb, val);
8661 24930799 : if (! e)
8662 : {
8663 : /* If we didn't manage to compute the taken edge then
8664 : push predicated expressions for the condition itself
8665 : and related conditions to the hashtables. This allows
8666 : simplification of redundant conditions which is
8667 : important as early cleanup. */
8668 22679446 : edge true_e, false_e;
8669 22679446 : extract_true_false_edges_from_block (bb, &true_e, &false_e);
8670 553791 : if ((do_region && bitmap_bit_p (exit_bbs, true_e->dest->index))
8671 22918523 : || !can_track_predicate_on_edge (true_e))
8672 5009614 : true_e = NULL;
8673 553791 : if ((do_region && bitmap_bit_p (exit_bbs, false_e->dest->index))
8674 22892484 : || !can_track_predicate_on_edge (false_e))
8675 5948531 : false_e = NULL;
8676 22679446 : insert_predicates_for_cond (cmpcode, lhs, rhs, true_e, false_e);
8677 : }
8678 : break;
8679 : }
8680 1436 : case GIMPLE_GOTO:
8681 1436 : e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last)));
8682 1436 : break;
8683 : default:
8684 : e = NULL;
8685 : }
8686 442046005 : if (e)
8687 : {
8688 2254987 : todo = TODO_cleanup_cfg;
8689 2254987 : if (!(e->flags & EDGE_EXECUTABLE))
8690 : {
8691 1782258 : if (dump_file && (dump_flags & TDF_DETAILS))
8692 35 : fprintf (dump_file,
8693 : "marking known outgoing %sedge %d -> %d executable\n",
8694 35 : e->flags & EDGE_DFS_BACK ? "back-" : "",
8695 35 : e->src->index, e->dest->index);
8696 1782258 : e->flags |= EDGE_EXECUTABLE;
8697 1782258 : e->dest->flags |= BB_EXECUTABLE;
8698 : }
8699 472729 : else if (!(e->dest->flags & BB_EXECUTABLE))
8700 : {
8701 27320 : if (dump_file && (dump_flags & TDF_DETAILS))
8702 1 : fprintf (dump_file,
8703 : "marking destination block %d reachable\n",
8704 : e->dest->index);
8705 27320 : e->dest->flags |= BB_EXECUTABLE;
8706 : }
8707 : }
8708 879582036 : else if (gsi_one_before_end_p (gsi))
8709 : {
8710 129501970 : FOR_EACH_EDGE (e, ei, bb->succs)
8711 : {
8712 76708589 : if (!(e->flags & EDGE_EXECUTABLE))
8713 : {
8714 56248640 : if (dump_file && (dump_flags & TDF_DETAILS))
8715 18527 : fprintf (dump_file,
8716 : "marking outgoing edge %d -> %d executable\n",
8717 18527 : e->src->index, e->dest->index);
8718 56248640 : e->flags |= EDGE_EXECUTABLE;
8719 56248640 : e->dest->flags |= BB_EXECUTABLE;
8720 : }
8721 20459949 : else if (!(e->dest->flags & BB_EXECUTABLE))
8722 : {
8723 2586623 : if (dump_file && (dump_flags & TDF_DETAILS))
8724 6002 : fprintf (dump_file,
8725 : "marking destination block %d reachable\n",
8726 : e->dest->index);
8727 2586623 : e->dest->flags |= BB_EXECUTABLE;
8728 : }
8729 : }
8730 : }
8731 :
8732 : /* Eliminate. That also pushes to avail. */
8733 442046005 : if (eliminate && ! iterate)
8734 110586906 : avail.eliminate_stmt (bb, &gsi);
8735 : else
8736 : /* If not eliminating, make all not already available defs
8737 : available. But avoid picking up dead defs. */
8738 412697089 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF)
8739 81237990 : if (! has_zero_uses (op)
8740 81237990 : && ! avail.eliminate_avail (bb, op))
8741 61803374 : avail.eliminate_push_avail (bb, op);
8742 : }
8743 :
8744 : /* Eliminate in destination PHI arguments. Always substitute in dest
8745 : PHIs, even for non-executable edges. This handles region
8746 : exits PHIs. */
8747 62056100 : if (!iterate && eliminate)
8748 33228881 : FOR_EACH_EDGE (e, ei, bb->succs)
8749 19795460 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
8750 38347027 : !gsi_end_p (gsi); gsi_next (&gsi))
8751 : {
8752 18551567 : gphi *phi = gsi.phi ();
8753 18551567 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
8754 18551567 : tree arg = USE_FROM_PTR (use_p);
8755 28235072 : if (TREE_CODE (arg) != SSA_NAME
8756 18551567 : || virtual_operand_p (arg))
8757 9683505 : continue;
8758 8868062 : tree sprime;
8759 8868062 : if (SSA_NAME_IS_DEFAULT_DEF (arg))
8760 : {
8761 117847 : sprime = SSA_VAL (arg);
8762 117847 : gcc_assert (TREE_CODE (sprime) != SSA_NAME
8763 : || SSA_NAME_IS_DEFAULT_DEF (sprime));
8764 : }
8765 : else
8766 : /* Look for sth available at the definition block of the argument.
8767 : This avoids inconsistencies between availability there which
8768 : decides if the stmt can be removed and availability at the
8769 : use site. The SSA property ensures that things available
8770 : at the definition are also available at uses. */
8771 8750215 : sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)),
8772 : arg);
8773 8868062 : if (sprime
8774 8868062 : && sprime != arg
8775 8868062 : && may_propagate_copy (arg, sprime, !(e->flags & EDGE_ABNORMAL)))
8776 1556105 : propagate_value (use_p, sprime);
8777 : }
8778 :
8779 62056100 : vn_context_bb = NULL;
8780 62056100 : return todo;
8781 : }
8782 :
8783 : /* Unwind state per basic-block. */
8784 :
8785 : struct unwind_state
8786 : {
8787 : /* Times this block has been visited. */
8788 : unsigned visited;
8789 : /* Whether to handle this as iteration point or whether to treat
8790 : incoming backedge PHI values as varying. */
8791 : bool iterate;
8792 : /* Maximum RPO index this block is reachable from. */
8793 : int max_rpo;
8794 : /* Unwind state. */
8795 : void *ob_top;
8796 : vn_reference_t ref_top;
8797 : vn_phi_t phi_top;
8798 : vn_nary_op_t nary_top;
8799 : vn_avail *avail_top;
8800 : };
8801 :
8802 : /* Unwind the RPO VN state for iteration. */
8803 :
8804 : static void
8805 1918924 : do_unwind (unwind_state *to, rpo_elim &avail)
8806 : {
8807 1918924 : gcc_assert (to->iterate);
8808 35120394 : for (; last_inserted_nary != to->nary_top;
8809 33201470 : last_inserted_nary = last_inserted_nary->next)
8810 : {
8811 33201470 : vn_nary_op_t *slot;
8812 33201470 : slot = valid_info->nary->find_slot_with_hash
8813 33201470 : (last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT);
8814 : /* Predication causes the need to restore previous state. */
8815 33201470 : if ((*slot)->unwind_to)
8816 6723499 : *slot = (*slot)->unwind_to;
8817 : else
8818 26477971 : valid_info->nary->clear_slot (slot);
8819 : }
8820 7546265 : for (; last_inserted_phi != to->phi_top;
8821 5627341 : last_inserted_phi = last_inserted_phi->next)
8822 : {
8823 5627341 : vn_phi_t *slot;
8824 5627341 : slot = valid_info->phis->find_slot_with_hash
8825 5627341 : (last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT);
8826 5627341 : valid_info->phis->clear_slot (slot);
8827 : }
8828 15400176 : for (; last_inserted_ref != to->ref_top;
8829 13481252 : last_inserted_ref = last_inserted_ref->next)
8830 : {
8831 13481252 : vn_reference_t *slot;
8832 13481252 : slot = valid_info->references->find_slot_with_hash
8833 13481252 : (last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT);
8834 13481252 : (*slot)->operands.release ();
8835 13481252 : valid_info->references->clear_slot (slot);
8836 : }
8837 1918924 : obstack_free (&vn_tables_obstack, to->ob_top);
8838 :
8839 : /* Prune [rpo_idx, ] from avail. */
8840 20862755 : for (; last_pushed_avail && last_pushed_avail->avail != to->avail_top;)
8841 : {
8842 18943831 : vn_ssa_aux_t val = last_pushed_avail;
8843 18943831 : vn_avail *av = val->avail;
8844 18943831 : val->avail = av->next;
8845 18943831 : last_pushed_avail = av->next_undo;
8846 18943831 : av->next = avail.m_avail_freelist;
8847 18943831 : avail.m_avail_freelist = av;
8848 : }
8849 1918924 : }
8850 :
8851 : /* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
8852 : If ITERATE is true then treat backedges optimistically as not
8853 : executed and iterate. If ELIMINATE is true then perform
8854 : elimination, otherwise leave that to the caller. If SKIP_ENTRY_PHIS
8855 : is true then force PHI nodes in ENTRY->dest to VARYING. */
8856 :
8857 : static unsigned
8858 6230471 : do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
8859 : bool iterate, bool eliminate, bool skip_entry_phis,
8860 : vn_lookup_kind kind)
8861 : {
8862 6230471 : unsigned todo = 0;
8863 6230471 : default_vn_walk_kind = kind;
8864 :
8865 : /* We currently do not support region-based iteration when
8866 : elimination is requested. */
8867 6230471 : gcc_assert (!entry || !iterate || !eliminate);
8868 : /* When iterating we need loop info up-to-date. */
8869 6230471 : gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP));
8870 :
8871 6230471 : bool do_region = entry != NULL;
8872 6230471 : if (!do_region)
8873 : {
8874 5538427 : entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn));
8875 5538427 : exit_bbs = BITMAP_ALLOC (NULL);
8876 5538427 : bitmap_set_bit (exit_bbs, EXIT_BLOCK);
8877 : }
8878 :
8879 : /* Clear EDGE_DFS_BACK on "all" entry edges, RPO order compute will
8880 : re-mark those that are contained in the region. */
8881 6230471 : edge_iterator ei;
8882 6230471 : edge e;
8883 12521921 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8884 6291450 : e->flags &= ~EDGE_DFS_BACK;
8885 :
8886 6230471 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS);
8887 6230471 : auto_vec<std::pair<int, int> > toplevel_scc_extents;
8888 6230471 : int n = rev_post_order_and_mark_dfs_back_seme
8889 8130680 : (fn, entry, exit_bbs, true, rpo, !iterate ? &toplevel_scc_extents : NULL);
8890 :
8891 6230471 : if (!do_region)
8892 5538427 : BITMAP_FREE (exit_bbs);
8893 :
8894 : /* If there are any non-DFS_BACK edges into entry->dest skip
8895 : processing PHI nodes for that block. This supports
8896 : value-numbering loop bodies w/o the actual loop. */
8897 12521920 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8898 6291450 : if (e != entry
8899 60979 : && !(e->flags & EDGE_DFS_BACK))
8900 : break;
8901 6230471 : if (e != NULL && dump_file && (dump_flags & TDF_DETAILS))
8902 0 : fprintf (dump_file, "Region does not contain all edges into "
8903 : "the entry block, skipping its PHIs.\n");
8904 6230471 : skip_entry_phis |= e != NULL;
8905 :
8906 6230471 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
8907 57205156 : for (int i = 0; i < n; ++i)
8908 50974685 : bb_to_rpo[rpo[i]] = i;
8909 6230471 : vn_bb_to_rpo = bb_to_rpo;
8910 :
8911 6230471 : unwind_state *rpo_state = XNEWVEC (unwind_state, n);
8912 :
8913 6230471 : rpo_elim avail (entry->dest);
8914 6230471 : rpo_avail = &avail;
8915 :
8916 : /* Verify we have no extra entries into the region. */
8917 6230471 : if (flag_checking && do_region)
8918 : {
8919 692038 : auto_bb_flag bb_in_region (fn);
8920 2125167 : for (int i = 0; i < n; ++i)
8921 : {
8922 1433129 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8923 1433129 : bb->flags |= bb_in_region;
8924 : }
8925 : /* We can't merge the first two loops because we cannot rely
8926 : on EDGE_DFS_BACK for edges not within the region. But if
8927 : we decide to always have the bb_in_region flag we can
8928 : do the checking during the RPO walk itself (but then it's
8929 : also easy to handle MEME conservatively). */
8930 2125167 : for (int i = 0; i < n; ++i)
8931 : {
8932 1433129 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8933 1433129 : edge e;
8934 1433129 : edge_iterator ei;
8935 3138539 : FOR_EACH_EDGE (e, ei, bb->preds)
8936 1705410 : gcc_assert (e == entry
8937 : || (skip_entry_phis && bb == entry->dest)
8938 : || (e->src->flags & bb_in_region));
8939 : }
8940 2125167 : for (int i = 0; i < n; ++i)
8941 : {
8942 1433129 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8943 1433129 : bb->flags &= ~bb_in_region;
8944 : }
8945 692038 : }
8946 :
8947 : /* Create the VN state. For the initial size of the various hashtables
8948 : use a heuristic based on region size and number of SSA names. */
8949 6230471 : unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names)
8950 6230471 : / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS));
8951 6230471 : VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
8952 6230471 : next_value_id = 1;
8953 6230471 : next_constant_value_id = -1;
8954 :
8955 6230471 : vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2);
8956 6230471 : gcc_obstack_init (&vn_ssa_aux_obstack);
8957 :
8958 6230471 : gcc_obstack_init (&vn_tables_obstack);
8959 6230471 : gcc_obstack_init (&vn_tables_insert_obstack);
8960 6230471 : valid_info = XCNEW (struct vn_tables_s);
8961 6230471 : allocate_vn_table (valid_info, region_size);
8962 6230471 : last_inserted_ref = NULL;
8963 6230471 : last_inserted_phi = NULL;
8964 6230471 : last_inserted_nary = NULL;
8965 6230471 : last_pushed_avail = NULL;
8966 :
8967 6230471 : vn_valueize = rpo_vn_valueize;
8968 :
8969 : /* Initialize the unwind state and edge/BB executable state. */
8970 6230471 : unsigned curr_scc = 0;
8971 57205156 : for (int i = 0; i < n; ++i)
8972 : {
8973 50974685 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8974 50974685 : rpo_state[i].visited = 0;
8975 50974685 : rpo_state[i].max_rpo = i;
8976 59507454 : if (!iterate && curr_scc < toplevel_scc_extents.length ())
8977 : {
8978 7126868 : if (i >= toplevel_scc_extents[curr_scc].first
8979 7126868 : && i <= toplevel_scc_extents[curr_scc].second)
8980 3905453 : rpo_state[i].max_rpo = toplevel_scc_extents[curr_scc].second;
8981 7126868 : if (i == toplevel_scc_extents[curr_scc].second)
8982 734934 : curr_scc++;
8983 : }
8984 50974685 : bb->flags &= ~BB_EXECUTABLE;
8985 50974685 : bool has_backedges = false;
8986 50974685 : edge e;
8987 50974685 : edge_iterator ei;
8988 120953646 : FOR_EACH_EDGE (e, ei, bb->preds)
8989 : {
8990 69978961 : if (e->flags & EDGE_DFS_BACK)
8991 2865340 : has_backedges = true;
8992 69978961 : e->flags &= ~EDGE_EXECUTABLE;
8993 69978961 : if (iterate || e == entry || (skip_entry_phis && bb == entry->dest))
8994 69978961 : continue;
8995 : }
8996 50974685 : rpo_state[i].iterate = iterate && has_backedges;
8997 : }
8998 6230471 : entry->flags |= EDGE_EXECUTABLE;
8999 6230471 : entry->dest->flags |= BB_EXECUTABLE;
9000 :
9001 : /* As heuristic to improve compile-time we handle only the N innermost
9002 : loops and the outermost one optimistically. */
9003 6230471 : if (iterate)
9004 : {
9005 4330262 : unsigned max_depth = param_rpo_vn_max_loop_depth;
9006 14550126 : for (auto loop : loops_list (cfun, LI_ONLY_INNERMOST))
9007 1561749 : if (loop_depth (loop) > max_depth)
9008 2108 : for (unsigned i = 2;
9009 9034 : i < loop_depth (loop) - max_depth; ++i)
9010 : {
9011 2108 : basic_block header = superloop_at_depth (loop, i)->header;
9012 2108 : bool non_latch_backedge = false;
9013 2108 : edge e;
9014 2108 : edge_iterator ei;
9015 6355 : FOR_EACH_EDGE (e, ei, header->preds)
9016 4247 : if (e->flags & EDGE_DFS_BACK)
9017 : {
9018 : /* There can be a non-latch backedge into the header
9019 : which is part of an outer irreducible region. We
9020 : cannot avoid iterating this block then. */
9021 2139 : if (!dominated_by_p (CDI_DOMINATORS,
9022 2139 : e->src, e->dest))
9023 : {
9024 12 : if (dump_file && (dump_flags & TDF_DETAILS))
9025 0 : fprintf (dump_file, "non-latch backedge %d -> %d "
9026 : "forces iteration of loop %d\n",
9027 0 : e->src->index, e->dest->index, loop->num);
9028 : non_latch_backedge = true;
9029 : }
9030 : else
9031 2127 : e->flags |= EDGE_EXECUTABLE;
9032 : }
9033 2108 : rpo_state[bb_to_rpo[header->index]].iterate = non_latch_backedge;
9034 4330262 : }
9035 : }
9036 :
9037 6230471 : uint64_t nblk = 0;
9038 6230471 : int idx = 0;
9039 4330262 : if (iterate)
9040 : /* Go and process all blocks, iterating as necessary. */
9041 49484803 : do
9042 : {
9043 49484803 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
9044 :
9045 : /* If the block has incoming backedges remember unwind state. This
9046 : is required even for non-executable blocks since in irreducible
9047 : regions we might reach them via the backedge and re-start iterating
9048 : from there.
9049 : Note we can individually mark blocks with incoming backedges to
9050 : not iterate where we then handle PHIs conservatively. We do that
9051 : heuristically to reduce compile-time for degenerate cases. */
9052 49484803 : if (rpo_state[idx].iterate)
9053 : {
9054 4421148 : rpo_state[idx].ob_top = obstack_alloc (&vn_tables_obstack, 0);
9055 4421148 : rpo_state[idx].ref_top = last_inserted_ref;
9056 4421148 : rpo_state[idx].phi_top = last_inserted_phi;
9057 4421148 : rpo_state[idx].nary_top = last_inserted_nary;
9058 4421148 : rpo_state[idx].avail_top
9059 4421148 : = last_pushed_avail ? last_pushed_avail->avail : NULL;
9060 : }
9061 :
9062 49484803 : if (!(bb->flags & BB_EXECUTABLE))
9063 : {
9064 971188 : if (dump_file && (dump_flags & TDF_DETAILS))
9065 2 : fprintf (dump_file, "Block %d: BB%d found not executable\n",
9066 : idx, bb->index);
9067 971188 : idx++;
9068 2890112 : continue;
9069 : }
9070 :
9071 48513615 : if (dump_file && (dump_flags & TDF_DETAILS))
9072 334 : fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
9073 48513615 : nblk++;
9074 97027230 : todo |= process_bb (avail, bb,
9075 48513615 : rpo_state[idx].visited != 0,
9076 : rpo_state[idx].iterate,
9077 : iterate, eliminate, do_region, exit_bbs, false);
9078 48513615 : rpo_state[idx].visited++;
9079 :
9080 : /* Verify if changed values flow over executable outgoing backedges
9081 : and those change destination PHI values (that's the thing we
9082 : can easily verify). Reduce over all such edges to the farthest
9083 : away PHI. */
9084 48513615 : int iterate_to = -1;
9085 48513615 : edge_iterator ei;
9086 48513615 : edge e;
9087 116826914 : FOR_EACH_EDGE (e, ei, bb->succs)
9088 68313299 : if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE))
9089 : == (EDGE_DFS_BACK|EDGE_EXECUTABLE)
9090 4431120 : && rpo_state[bb_to_rpo[e->dest->index]].iterate)
9091 : {
9092 4428354 : int destidx = bb_to_rpo[e->dest->index];
9093 4428354 : if (!rpo_state[destidx].visited)
9094 : {
9095 134 : if (dump_file && (dump_flags & TDF_DETAILS))
9096 0 : fprintf (dump_file, "Unvisited destination %d\n",
9097 : e->dest->index);
9098 134 : if (iterate_to == -1 || destidx < iterate_to)
9099 134 : iterate_to = destidx;
9100 134 : continue;
9101 : }
9102 4428220 : if (dump_file && (dump_flags & TDF_DETAILS))
9103 53 : fprintf (dump_file, "Looking for changed values of backedge"
9104 : " %d->%d destination PHIs\n",
9105 53 : e->src->index, e->dest->index);
9106 4428220 : vn_context_bb = e->dest;
9107 4428220 : gphi_iterator gsi;
9108 4428220 : for (gsi = gsi_start_phis (e->dest);
9109 10135912 : !gsi_end_p (gsi); gsi_next (&gsi))
9110 : {
9111 7626779 : bool inserted = false;
9112 : /* While we'd ideally just iterate on value changes
9113 : we CSE PHIs and do that even across basic-block
9114 : boundaries. So even hashtable state changes can
9115 : be important (which is roughly equivalent to
9116 : PHI argument value changes). To not excessively
9117 : iterate because of that we track whether a PHI
9118 : was CSEd to with GF_PLF_1. */
9119 7626779 : bool phival_changed;
9120 7626779 : if ((phival_changed = visit_phi (gsi.phi (),
9121 : &inserted, false))
9122 9025744 : || (inserted && gimple_plf (gsi.phi (), GF_PLF_1)))
9123 : {
9124 1919087 : if (!phival_changed
9125 1919087 : && dump_file && (dump_flags & TDF_DETAILS))
9126 0 : fprintf (dump_file, "PHI was CSEd and hashtable "
9127 : "state (changed)\n");
9128 1919087 : if (iterate_to == -1 || destidx < iterate_to)
9129 1919002 : iterate_to = destidx;
9130 1919087 : break;
9131 : }
9132 : }
9133 4428220 : vn_context_bb = NULL;
9134 : }
9135 48513615 : if (iterate_to != -1)
9136 : {
9137 1918924 : do_unwind (&rpo_state[iterate_to], avail);
9138 1918924 : idx = iterate_to;
9139 1918924 : if (dump_file && (dump_flags & TDF_DETAILS))
9140 20 : fprintf (dump_file, "Iterating to %d BB%d\n",
9141 20 : iterate_to, rpo[iterate_to]);
9142 1918924 : continue;
9143 : }
9144 :
9145 46594691 : idx++;
9146 : }
9147 49484803 : while (idx < n);
9148 :
9149 : else /* !iterate */
9150 : {
9151 : /* Process all blocks greedily with a worklist that enforces RPO
9152 : processing of reachable blocks. */
9153 1900209 : auto_bitmap worklist;
9154 1900209 : bitmap_set_bit (worklist, 0);
9155 17342903 : while (!bitmap_empty_p (worklist))
9156 : {
9157 13542485 : int idx = bitmap_clear_first_set_bit (worklist);
9158 13542485 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
9159 13542485 : gcc_assert ((bb->flags & BB_EXECUTABLE)
9160 : && !rpo_state[idx].visited);
9161 :
9162 13542485 : if (dump_file && (dump_flags & TDF_DETAILS))
9163 35272 : fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
9164 :
9165 : /* When we run into predecessor edges where we cannot trust its
9166 : executable state mark them executable so PHI processing will
9167 : be conservative.
9168 : ??? Do we need to force arguments flowing over that edge
9169 : to be varying or will they even always be? */
9170 13542485 : edge_iterator ei;
9171 13542485 : edge e;
9172 32827625 : FOR_EACH_EDGE (e, ei, bb->preds)
9173 19285140 : if (!(e->flags & EDGE_EXECUTABLE)
9174 1027267 : && (bb == entry->dest
9175 969627 : || (!rpo_state[bb_to_rpo[e->src->index]].visited
9176 932127 : && (rpo_state[bb_to_rpo[e->src->index]].max_rpo
9177 : >= (int)idx))))
9178 : {
9179 966208 : if (dump_file && (dump_flags & TDF_DETAILS))
9180 11334 : fprintf (dump_file, "Cannot trust state of predecessor "
9181 : "edge %d -> %d, marking executable\n",
9182 11334 : e->src->index, e->dest->index);
9183 966208 : e->flags |= EDGE_EXECUTABLE;
9184 : }
9185 :
9186 13542485 : nblk++;
9187 13542485 : todo |= process_bb (avail, bb, false, false, false, eliminate,
9188 : do_region, exit_bbs,
9189 13542485 : skip_entry_phis && bb == entry->dest);
9190 13542485 : rpo_state[idx].visited++;
9191 :
9192 33470605 : FOR_EACH_EDGE (e, ei, bb->succs)
9193 19928120 : if ((e->flags & EDGE_EXECUTABLE)
9194 19849329 : && e->dest->index != EXIT_BLOCK
9195 18670981 : && (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index))
9196 37246377 : && !rpo_state[bb_to_rpo[e->dest->index]].visited)
9197 16357664 : bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]);
9198 : }
9199 1900209 : }
9200 :
9201 : /* If statistics or dump file active. */
9202 6230471 : int nex = 0;
9203 6230471 : unsigned max_visited = 1;
9204 57205156 : for (int i = 0; i < n; ++i)
9205 : {
9206 50974685 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
9207 50974685 : if (bb->flags & BB_EXECUTABLE)
9208 50361196 : nex++;
9209 50974685 : statistics_histogram_event (cfun, "RPO block visited times",
9210 50974685 : rpo_state[i].visited);
9211 50974685 : if (rpo_state[i].visited > max_visited)
9212 : max_visited = rpo_state[i].visited;
9213 : }
9214 6230471 : unsigned nvalues = 0, navail = 0;
9215 172431286 : for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
9216 338632101 : i != vn_ssa_aux_hash->end (); ++i)
9217 : {
9218 166200815 : nvalues++;
9219 166200815 : vn_avail *av = (*i)->avail;
9220 245660124 : while (av)
9221 : {
9222 79459309 : navail++;
9223 79459309 : av = av->next;
9224 : }
9225 : }
9226 6230471 : statistics_counter_event (cfun, "RPO blocks", n);
9227 6230471 : statistics_counter_event (cfun, "RPO blocks visited", nblk);
9228 6230471 : statistics_counter_event (cfun, "RPO blocks executable", nex);
9229 6230471 : statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex);
9230 6230471 : statistics_histogram_event (cfun, "RPO num values", nvalues);
9231 6230471 : statistics_histogram_event (cfun, "RPO num avail", navail);
9232 6230471 : statistics_histogram_event (cfun, "RPO num lattice",
9233 6230471 : vn_ssa_aux_hash->elements ());
9234 6230471 : if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS)))
9235 : {
9236 11239 : fprintf (dump_file, "RPO iteration over %d blocks visited %" PRIu64
9237 : " blocks in total discovering %d executable blocks iterating "
9238 : "%d.%d times, a block was visited max. %u times\n",
9239 : n, nblk, nex,
9240 11239 : (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10),
9241 : max_visited);
9242 11239 : fprintf (dump_file, "RPO tracked %d values available at %d locations "
9243 : "and %" PRIu64 " lattice elements\n",
9244 11239 : nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ());
9245 : }
9246 :
9247 6230471 : if (eliminate)
9248 : {
9249 : /* When !iterate we already performed elimination during the RPO
9250 : walk. */
9251 5240638 : if (iterate)
9252 : {
9253 : /* Elimination for region-based VN needs to be done within the
9254 : RPO walk. */
9255 3360032 : gcc_assert (! do_region);
9256 : /* Note we can't use avail.walk here because that gets confused
9257 : by the existing availability and it will be less efficient
9258 : as well. */
9259 3360032 : todo |= eliminate_with_rpo_vn (NULL);
9260 : }
9261 : else
9262 1880606 : todo |= avail.eliminate_cleanup (do_region);
9263 : }
9264 :
9265 6230471 : vn_valueize = NULL;
9266 6230471 : rpo_avail = NULL;
9267 6230471 : vn_bb_to_rpo = NULL;
9268 :
9269 6230471 : XDELETEVEC (bb_to_rpo);
9270 6230471 : XDELETEVEC (rpo);
9271 6230471 : XDELETEVEC (rpo_state);
9272 :
9273 6230471 : return todo;
9274 6230471 : }
9275 :
9276 : /* Region-based entry for RPO VN. Performs value-numbering and elimination
9277 : on the SEME region specified by ENTRY and EXIT_BBS. If ENTRY is not
9278 : the only edge into the region at ENTRY->dest PHI nodes in ENTRY->dest
9279 : are not considered.
9280 : If ITERATE is true then treat backedges optimistically as not
9281 : executed and iterate. If ELIMINATE is true then perform
9282 : elimination, otherwise leave that to the caller.
9283 : If SKIP_ENTRY_PHIS is true then force PHI nodes in ENTRY->dest to VARYING.
9284 : KIND specifies the amount of work done for handling memory operations. */
9285 :
9286 : unsigned
9287 711647 : do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
9288 : bool iterate, bool eliminate, bool skip_entry_phis,
9289 : vn_lookup_kind kind)
9290 : {
9291 711647 : auto_timevar tv (TV_TREE_RPO_VN);
9292 711647 : unsigned todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate,
9293 : skip_entry_phis, kind);
9294 711647 : free_rpo_vn ();
9295 1423294 : return todo;
9296 711647 : }
9297 :
9298 :
9299 : namespace {
9300 :
9301 : const pass_data pass_data_fre =
9302 : {
9303 : GIMPLE_PASS, /* type */
9304 : "fre", /* name */
9305 : OPTGROUP_NONE, /* optinfo_flags */
9306 : TV_TREE_FRE, /* tv_id */
9307 : ( PROP_cfg | PROP_ssa ), /* properties_required */
9308 : 0, /* properties_provided */
9309 : 0, /* properties_destroyed */
9310 : 0, /* todo_flags_start */
9311 : 0, /* todo_flags_finish */
9312 : };
9313 :
9314 : class pass_fre : public gimple_opt_pass
9315 : {
9316 : public:
9317 1469140 : pass_fre (gcc::context *ctxt)
9318 2938280 : : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
9319 : {}
9320 :
9321 : /* opt_pass methods: */
9322 1175312 : opt_pass * clone () final override { return new pass_fre (m_ctxt); }
9323 1469140 : void set_pass_param (unsigned int n, bool param) final override
9324 : {
9325 1469140 : gcc_assert (n == 0);
9326 1469140 : may_iterate = param;
9327 1469140 : }
9328 4628722 : bool gate (function *) final override
9329 : {
9330 4628722 : return flag_tree_fre != 0 && (may_iterate || optimize > 1);
9331 : }
9332 : unsigned int execute (function *) final override;
9333 :
9334 : private:
9335 : bool may_iterate;
9336 : }; // class pass_fre
9337 :
9338 : unsigned int
9339 4548594 : pass_fre::execute (function *fun)
9340 : {
9341 4548594 : unsigned todo = 0;
9342 :
9343 : /* At -O[1g] use the cheap non-iterating mode. */
9344 4548594 : bool iterate_p = may_iterate && (optimize > 1);
9345 4548594 : calculate_dominance_info (CDI_DOMINATORS);
9346 4548594 : if (iterate_p)
9347 3360032 : loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
9348 :
9349 4548594 : todo = do_rpo_vn_1 (fun, NULL, NULL, iterate_p, true, false, VN_WALKREWRITE);
9350 4548594 : free_rpo_vn ();
9351 :
9352 4548594 : if (iterate_p)
9353 3360032 : loop_optimizer_finalize ();
9354 :
9355 4548594 : if (scev_initialized_p ())
9356 32297 : scev_reset_htab ();
9357 :
9358 : /* For late FRE after IVOPTs and unrolling, see if we can
9359 : remove some TREE_ADDRESSABLE and rewrite stuff into SSA. */
9360 4548594 : if (!may_iterate)
9361 1002299 : todo |= TODO_update_address_taken;
9362 :
9363 4548594 : return todo;
9364 : }
9365 :
9366 : } // anon namespace
9367 :
9368 : gimple_opt_pass *
9369 293828 : make_pass_fre (gcc::context *ctxt)
9370 : {
9371 293828 : return new pass_fre (ctxt);
9372 : }
9373 :
9374 : #undef BB_EXECUTABLE
|