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 779653297 : vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
158 : {
159 779653297 : 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 988385438 : vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
167 : {
168 988385438 : 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 25652036 : vn_phi_hasher::hash (const vn_phi_s *vp1)
190 : {
191 25652036 : return vp1->hashcode;
192 : }
193 :
194 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
195 :
196 : inline bool
197 46226085 : vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
198 : {
199 46226085 : 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 26236186 : vn_reference_op_eq (const void *p1, const void *p2)
211 : {
212 26236186 : const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
213 26236186 : const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
214 :
215 26236186 : return (vro1->opcode == vro2->opcode
216 : /* We do not care for differences in type qualification. */
217 26234318 : && (vro1->type == vro2->type
218 1196025 : || (vro1->type && vro2->type
219 1196025 : && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
220 1196025 : TYPE_MAIN_VARIANT (vro2->type))))
221 25228468 : && expressions_equal_p (vro1->op0, vro2->op0)
222 25186490 : && expressions_equal_p (vro1->op1, vro2->op1)
223 25186490 : && expressions_equal_p (vro1->op2, vro2->op2)
224 51422676 : && (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 3767633423 : vn_reference_hasher::hash (const vn_reference_s *vr1)
248 : {
249 3767633423 : return vr1->hashcode;
250 : }
251 :
252 : inline bool
253 4486825173 : vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
254 : {
255 4486825173 : return v == c || vn_reference_eq (v, c);
256 : }
257 :
258 : typedef hash_table<vn_reference_hasher> vn_reference_table_type;
259 : typedef vn_reference_table_type::iterator vn_reference_iterator_type;
260 :
261 : /* Pretty-print OPS to OUTFILE. */
262 :
263 : void
264 287 : print_vn_reference_ops (FILE *outfile, const vec<vn_reference_op_s> ops)
265 : {
266 287 : vn_reference_op_t vro;
267 287 : unsigned int i;
268 287 : fprintf (outfile, "{");
269 1591 : for (i = 0; ops.iterate (i, &vro); i++)
270 : {
271 1017 : bool closebrace = false;
272 1017 : if (vro->opcode != SSA_NAME
273 803 : && TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
274 : {
275 803 : fprintf (outfile, "%s", get_tree_code_name (vro->opcode));
276 803 : if (vro->op0 || vro->opcode == CALL_EXPR)
277 : {
278 803 : fprintf (outfile, "<");
279 803 : closebrace = true;
280 : }
281 : }
282 1017 : if (vro->opcode == MEM_REF || vro->opcode == TARGET_MEM_REF)
283 275 : fprintf (outfile, "(A%d)", TYPE_ALIGN (vro->type));
284 1017 : if (vro->op0 || vro->opcode == CALL_EXPR)
285 : {
286 1017 : if (!vro->op0)
287 0 : fprintf (outfile, internal_fn_name ((internal_fn)vro->clique));
288 : else
289 : {
290 1017 : if (vro->opcode == MEM_REF || vro->opcode == TARGET_MEM_REF)
291 : {
292 275 : fprintf (outfile, "(");
293 275 : print_generic_expr (outfile, TREE_TYPE (vro->op0));
294 275 : fprintf (outfile, ")");
295 : }
296 1017 : print_generic_expr (outfile, vro->op0);
297 : }
298 1017 : if (vro->op1)
299 : {
300 185 : fprintf (outfile, ",");
301 185 : print_generic_expr (outfile, vro->op1);
302 : }
303 1017 : if (vro->op2)
304 : {
305 185 : fprintf (outfile, ",");
306 185 : print_generic_expr (outfile, vro->op2);
307 : }
308 : }
309 1017 : if (closebrace)
310 803 : fprintf (outfile, ">");
311 1017 : if (i != ops.length () - 1)
312 730 : fprintf (outfile, ",");
313 : }
314 287 : fprintf (outfile, "}");
315 287 : }
316 :
317 : DEBUG_FUNCTION void
318 0 : debug_vn_reference_ops (const vec<vn_reference_op_s> ops)
319 : {
320 0 : print_vn_reference_ops (stderr, ops);
321 0 : fputc ('\n', stderr);
322 0 : }
323 :
324 : /* The set of VN hashtables. */
325 :
326 : typedef struct vn_tables_s
327 : {
328 : vn_nary_op_table_type *nary;
329 : vn_phi_table_type *phis;
330 : vn_reference_table_type *references;
331 : } *vn_tables_t;
332 :
333 :
334 : /* vn_constant hashtable helpers. */
335 :
336 : struct vn_constant_hasher : free_ptr_hash <vn_constant_s>
337 : {
338 : static inline hashval_t hash (const vn_constant_s *);
339 : static inline bool equal (const vn_constant_s *, const vn_constant_s *);
340 : };
341 :
342 : /* Hash table hash function for vn_constant_t. */
343 :
344 : inline hashval_t
345 12459078 : vn_constant_hasher::hash (const vn_constant_s *vc1)
346 : {
347 12459078 : return vc1->hashcode;
348 : }
349 :
350 : /* Hash table equality function for vn_constant_t. */
351 :
352 : inline bool
353 15022401 : vn_constant_hasher::equal (const vn_constant_s *vc1, const vn_constant_s *vc2)
354 : {
355 15022401 : if (vc1->hashcode != vc2->hashcode)
356 : return false;
357 :
358 2261612 : 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 82699 : vn_valueize_for_srt (tree t, void* context ATTRIBUTE_UNUSED)
389 : {
390 82699 : 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 82699 : if (!SSA_NAME_IS_DEFAULT_DEF (t))
397 78860 : vn_context_bb = gimple_bb (SSA_NAME_DEF_STMT (t));
398 82699 : tree res = vn_valueize (t);
399 82699 : vn_context_bb = saved_vn_context_bb;
400 82699 : 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 >14058*10^7 : static inline bool is_empty (value_type &e) { return e == NULL; }
430 : };
431 :
432 : hashval_t
433 46254732365 : vn_ssa_aux_hasher::hash (const value_type &entry)
434 : {
435 46254732365 : return SSA_NAME_VERSION (entry->name);
436 : }
437 :
438 : bool
439 52929881530 : vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name)
440 : {
441 52929881530 : 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 5272532 : has_VN_INFO (tree name)
462 : {
463 5272532 : return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name));
464 : }
465 :
466 : vn_ssa_aux_t
467 4118326309 : VN_INFO (tree name)
468 : {
469 4118326309 : vn_ssa_aux_t *res
470 4118326309 : = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name),
471 : INSERT);
472 4118326309 : if (*res != NULL)
473 : return *res;
474 :
475 177023353 : vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
476 177023353 : memset (newinfo, 0, sizeof (struct vn_ssa_aux));
477 177023353 : newinfo->name = name;
478 177023353 : 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 177023353 : 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 177023353 : if (SSA_NAME_IS_DEFAULT_DEF (name))
486 9536083 : switch (TREE_CODE (SSA_NAME_VAR (name)))
487 : {
488 1711642 : case VAR_DECL:
489 : /* All undefined vars are VARYING. */
490 1711642 : newinfo->valnum = name;
491 1711642 : newinfo->visited = true;
492 1711642 : break;
493 :
494 7763179 : case PARM_DECL:
495 : /* Parameters are VARYING but we can record a condition
496 : if we know it is a non-NULL pointer. */
497 7763179 : newinfo->visited = true;
498 7763179 : newinfo->valnum = name;
499 11938353 : if (POINTER_TYPE_P (TREE_TYPE (name))
500 8940326 : && nonnull_arg_p (SSA_NAME_VAR (name)))
501 : {
502 2415960 : tree ops[2];
503 2415960 : ops[0] = name;
504 2415960 : ops[1] = build_int_cst (TREE_TYPE (name), 0);
505 2415960 : vn_nary_op_t nary;
506 : /* Allocate from non-unwinding stack. */
507 2415960 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
508 2415960 : init_vn_nary_op_from_pieces (nary, 2, NE_EXPR,
509 : boolean_type_node, ops);
510 2415960 : nary->predicated_values = 0;
511 2415960 : nary->u.result = boolean_true_node;
512 2415960 : vn_nary_op_insert_into (nary, valid_info->nary);
513 2415960 : gcc_assert (nary->unwind_to == NULL);
514 : /* Also do not link it into the undo chain. */
515 2415960 : last_inserted_nary = nary->next;
516 2415960 : nary->next = (vn_nary_op_t)(void *)-1;
517 2415960 : nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
518 2415960 : init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR,
519 : boolean_type_node, ops);
520 2415960 : nary->predicated_values = 0;
521 2415960 : nary->u.result = boolean_false_node;
522 2415960 : vn_nary_op_insert_into (nary, valid_info->nary);
523 2415960 : gcc_assert (nary->unwind_to == NULL);
524 2415960 : last_inserted_nary = nary->next;
525 2415960 : nary->next = (vn_nary_op_t)(void *)-1;
526 2415960 : 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 61262 : 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 61262 : newinfo->visited = true;
540 61262 : newinfo->valnum = name;
541 61262 : 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 3505827763 : SSA_VAL (tree x, bool *visited = NULL)
553 : {
554 3505827763 : vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
555 3505827763 : if (visited)
556 1426859460 : *visited = tem && tem->visited;
557 3505827763 : 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 1291613691 : vuse_ssa_val (tree x)
566 : {
567 1291613691 : if (!x)
568 : return NULL_TREE;
569 :
570 1288138680 : do
571 : {
572 1288138680 : x = SSA_VAL (x);
573 1288138680 : gcc_assert (x != VN_TOP);
574 : }
575 1288138680 : 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 1090841866 : vuse_valueize (tree vuse)
586 : {
587 1090841866 : do
588 : {
589 1090841866 : bool visited;
590 1090841866 : vuse = SSA_VAL (vuse, &visited);
591 1090841866 : if (!visited)
592 16436987 : return NULL_TREE;
593 1074404879 : gcc_assert (vuse != VN_TOP);
594 : }
595 1074404879 : 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 104898205 : vn_get_stmt_kind (gimple *stmt)
605 : {
606 104898205 : switch (gimple_code (stmt))
607 : {
608 : case GIMPLE_CALL:
609 : return VN_REFERENCE;
610 : case GIMPLE_PHI:
611 : return VN_PHI;
612 104898205 : case GIMPLE_ASSIGN:
613 104898205 : {
614 104898205 : enum tree_code code = gimple_assign_rhs_code (stmt);
615 104898205 : tree rhs1 = gimple_assign_rhs1 (stmt);
616 104898205 : 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 49329420 : case GIMPLE_SINGLE_RHS:
623 49329420 : switch (TREE_CODE_CLASS (code))
624 : {
625 37211145 : case tcc_reference:
626 : /* VOP-less references can go through unary case. */
627 37211145 : if ((code == REALPART_EXPR
628 : || code == IMAGPART_EXPR
629 37211145 : || code == VIEW_CONVERT_EXPR
630 37211145 : || code == BIT_FIELD_REF)
631 37211145 : && (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
632 670040 : || is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
633 : return VN_NARY;
634 :
635 : /* Fallthrough. */
636 : case tcc_declaration:
637 : return VN_REFERENCE;
638 :
639 : case tcc_constant:
640 : return VN_CONSTANT;
641 :
642 6098223 : default:
643 6098223 : if (code == ADDR_EXPR)
644 3307296 : return (is_gimple_min_invariant (rhs1)
645 3307296 : ? VN_CONSTANT : VN_REFERENCE);
646 2790927 : 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 29286040 : get_or_alloc_constant_value_id (tree constant)
681 : {
682 29286040 : vn_constant_s **slot;
683 29286040 : struct vn_constant_s vc;
684 29286040 : 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 29286040 : if (!constant_to_value_id)
689 : return 0;
690 :
691 4819418 : vc.hashcode = vn_hash_constant_with_type (constant);
692 4819418 : vc.constant = constant;
693 4819418 : slot = constant_to_value_id->find_slot (&vc, INSERT);
694 4819418 : if (*slot)
695 2243887 : return (*slot)->value_id;
696 :
697 2575531 : vcp = XNEW (struct vn_constant_s);
698 2575531 : vcp->hashcode = vc.hashcode;
699 2575531 : vcp->constant = constant;
700 2575531 : vcp->value_id = get_next_constant_value_id ();
701 2575531 : *slot = vcp;
702 2575531 : return vcp->value_id;
703 : }
704 :
705 : /* Compute the hash for a reference operand VRO1. */
706 :
707 : static void
708 139168338 : vn_reference_op_compute_hash (const vn_reference_op_t vro1, inchash::hash &hstate)
709 : {
710 139168338 : hstate.add_int (vro1->opcode);
711 139168338 : if (vro1->opcode == CALL_EXPR && !vro1->op0)
712 558169 : hstate.add_int (vro1->clique);
713 139168338 : if (vro1->op0)
714 132682825 : inchash::add_expr (vro1->op0, hstate);
715 139168338 : if (vro1->op1)
716 12107304 : inchash::add_expr (vro1->op1, hstate);
717 139168338 : if (vro1->op2)
718 13859995 : inchash::add_expr (vro1->op2, hstate);
719 139168338 : }
720 :
721 : /* Compute a hash for the reference operation VR1 and return it. */
722 :
723 : hashval_t
724 207464975 : vn_reference_compute_hash (const vn_reference_t vr1)
725 : {
726 207464975 : inchash::hash hstate;
727 207464975 : hashval_t result;
728 207464975 : int i;
729 207464975 : vn_reference_op_t vro;
730 207464975 : poly_offset_int off = -1;
731 207464975 : bool deref = false;
732 :
733 844619025 : FOR_EACH_VEC_ELT (vr1->operands, i, vro)
734 : {
735 637154050 : if (vro->opcode == MEM_REF)
736 : deref = true;
737 440517334 : else if (vro->opcode != ADDR_EXPR)
738 309109523 : deref = false;
739 637154050 : if (maybe_ne (vro->off, -1))
740 : {
741 374931564 : if (known_eq (off, -1))
742 199043262 : off = 0;
743 637154050 : off += vro->off;
744 : }
745 : else
746 : {
747 262222486 : if (maybe_ne (off, -1)
748 262222486 : && maybe_ne (off, 0))
749 105774487 : hstate.add_poly_hwi (off.force_shwi ());
750 262222486 : off = -1;
751 262222486 : if (deref
752 123277289 : && vro->opcode == ADDR_EXPR)
753 : {
754 123054148 : if (vro->op0)
755 : {
756 123054148 : tree op = TREE_OPERAND (vro->op0, 0);
757 123054148 : hstate.add_int (TREE_CODE (op));
758 123054148 : inchash::add_expr (op, hstate);
759 : }
760 : }
761 : else
762 139168338 : 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 207464975 : result = hstate.end ();
768 : /* ??? We would ICE later if we hash instead of adding that in. */
769 207464975 : if (vr1->vuse)
770 202409211 : result += SSA_NAME_VERSION (vr1->vuse);
771 :
772 207464975 : 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 4481890827 : vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2,
781 : bool lexical)
782 : {
783 4481890827 : unsigned i, j;
784 :
785 : /* Early out if this is not a hash collision. */
786 4481890827 : if (vr1->hashcode != vr2->hashcode)
787 : return false;
788 :
789 : /* The VOP needs to be the same. */
790 18215881 : 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 18215427 : if (maybe_ne (vr1->offset, vr2->offset)
796 18215427 : || maybe_ne (vr1->max_size, vr2->max_size))
797 : {
798 : /* But nothing known in the prevailing entry is OK to be used. */
799 7075913 : 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 36338574 : if (vr1->operands == vr2->operands)
805 : return true;
806 :
807 18169287 : if (!vr1->type || !vr2->type)
808 : {
809 583919 : if (vr1->type != vr2->type)
810 : return false;
811 : }
812 17585368 : else if (vr1->type == vr2->type)
813 : ;
814 2263532 : else if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
815 2263532 : || (COMPLETE_TYPE_P (vr1->type)
816 2263532 : && !expressions_equal_p (TYPE_SIZE (vr1->type),
817 2263532 : TYPE_SIZE (vr2->type))))
818 : return false;
819 1466884 : else if (vr1->operands[0].opcode == CALL_EXPR
820 1466884 : && !types_compatible_p (vr1->type, vr2->type))
821 : return false;
822 1466884 : else if (INTEGRAL_TYPE_P (vr1->type)
823 586890 : && INTEGRAL_TYPE_P (vr2->type))
824 : {
825 546760 : if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
826 : return false;
827 : }
828 920124 : else if (INTEGRAL_TYPE_P (vr1->type)
829 920124 : && (TYPE_PRECISION (vr1->type)
830 40130 : != TREE_INT_CST_LOW (TYPE_SIZE (vr1->type))))
831 : return false;
832 920078 : else if (INTEGRAL_TYPE_P (vr2->type)
833 920078 : && (TYPE_PRECISION (vr2->type)
834 9364 : != TREE_INT_CST_LOW (TYPE_SIZE (vr2->type))))
835 : return false;
836 19622 : else if (VECTOR_BOOLEAN_TYPE_P (vr1->type)
837 919483 : && 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 919483 : else if (TYPE_MODE (vr1->type) != TYPE_MODE (vr2->type)
857 919483 : && (!mode_can_transfer_bits (TYPE_MODE (vr1->type))
858 45192 : || !mode_can_transfer_bits (TYPE_MODE (vr2->type))))
859 : return false;
860 :
861 17259355 : i = 0;
862 17259355 : j = 0;
863 22330884 : do
864 : {
865 22330884 : poly_offset_int off1 = 0, off2 = 0;
866 22330884 : vn_reference_op_t vro1, vro2;
867 22330884 : vn_reference_op_s tem1, tem2;
868 22330884 : bool deref1 = false, deref2 = false;
869 22330884 : bool reverse1 = false, reverse2 = false;
870 72733490 : for (; vr1->operands.iterate (i, &vro1); i++)
871 : {
872 50402606 : if (vro1->opcode == MEM_REF)
873 : deref1 = true;
874 : /* Do not look through a storage order barrier. */
875 34524446 : else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
876 75361 : return false;
877 50402606 : reverse1 |= vro1->reverse;
878 50402606 : if (lexical || known_eq (vro1->off, -1))
879 : break;
880 28071722 : off1 += vro1->off;
881 : }
882 50570899 : for (; vr2->operands.iterate (j, &vro2); j++)
883 : {
884 50570899 : if (vro2->opcode == MEM_REF)
885 : deref2 = true;
886 : /* Do not look through a storage order barrier. */
887 34668695 : else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
888 : return false;
889 50570899 : reverse2 |= vro2->reverse;
890 50570899 : if (lexical || known_eq (vro2->off, -1))
891 : break;
892 28240015 : off2 += vro2->off;
893 : }
894 22330884 : if (maybe_ne (off1, off2) || reverse1 != reverse2)
895 : return false;
896 22330709 : if (deref1 && vro1->opcode == ADDR_EXPR)
897 : {
898 8418855 : memset (&tem1, 0, sizeof (tem1));
899 8418855 : tem1.op0 = TREE_OPERAND (vro1->op0, 0);
900 8418855 : tem1.type = TREE_TYPE (tem1.op0);
901 8418855 : tem1.opcode = TREE_CODE (tem1.op0);
902 8418855 : vro1 = &tem1;
903 8418855 : deref1 = false;
904 : }
905 22330709 : if (deref2 && vro2->opcode == ADDR_EXPR)
906 : {
907 8418865 : memset (&tem2, 0, sizeof (tem2));
908 8418865 : tem2.op0 = TREE_OPERAND (vro2->op0, 0);
909 8418865 : tem2.type = TREE_TYPE (tem2.op0);
910 8418865 : tem2.opcode = TREE_CODE (tem2.op0);
911 8418865 : vro2 = &tem2;
912 8418865 : deref2 = false;
913 : }
914 22330709 : if (deref1 != deref2)
915 : return false;
916 22271579 : 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 22259321 : if (lexical
924 2270723 : && (vro1->opcode == MEM_REF
925 2270723 : || vro1->opcode == TARGET_MEM_REF)
926 23001309 : && (TYPE_ALIGN (vro1->type) != TYPE_ALIGN (vro2->type)
927 741781 : || (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 2225325 : || (get_deref_alias_set (vro1->opcode == MEM_REF
933 741775 : ? TREE_TYPE (vro1->op0)
934 0 : : TREE_TYPE (vro1->op2))
935 1483550 : != get_deref_alias_set (vro2->opcode == MEM_REF
936 741775 : ? TREE_TYPE (vro2->op0)
937 0 : : TREE_TYPE (vro2->op2)))))
938 : return false;
939 22255523 : ++j;
940 22255523 : ++i;
941 : }
942 44511046 : while (vr1->operands.length () != i
943 66766569 : || 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 226972591 : 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 226972591 : tree orig = ref;
956 789048646 : while (ref)
957 : {
958 562076055 : vn_reference_op_s temp;
959 :
960 562076055 : memset (&temp, 0, sizeof (temp));
961 562076055 : temp.type = TREE_TYPE (ref);
962 562076055 : temp.opcode = TREE_CODE (ref);
963 562076055 : temp.off = -1;
964 :
965 562076055 : switch (temp.opcode)
966 : {
967 15231632 : case MODIFY_EXPR:
968 15231632 : temp.op0 = TREE_OPERAND (ref, 1);
969 15231632 : break;
970 137 : case WITH_SIZE_EXPR:
971 137 : temp.op0 = TREE_OPERAND (ref, 1);
972 137 : temp.off = 0;
973 137 : break;
974 120256063 : case MEM_REF:
975 : /* The base address gets its own vn_reference_op_s structure. */
976 120256063 : temp.op0 = TREE_OPERAND (ref, 1);
977 120256063 : if (!mem_ref_offset (ref).to_shwi (&temp.off))
978 0 : temp.off = -1;
979 120256063 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
980 120256063 : temp.base = MR_DEPENDENCE_BASE (ref);
981 120256063 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
982 120256063 : break;
983 2542526 : case TARGET_MEM_REF:
984 : /* The base address gets its own vn_reference_op_s structure. */
985 2542526 : temp.op0 = TMR_INDEX (ref);
986 2542526 : temp.op1 = TMR_STEP (ref);
987 2542526 : temp.op2 = TMR_OFFSET (ref);
988 2542526 : temp.clique = MR_DEPENDENCE_CLIQUE (ref);
989 2542526 : temp.base = MR_DEPENDENCE_BASE (ref);
990 2542526 : result->safe_push (temp);
991 2542526 : memset (&temp, 0, sizeof (temp));
992 2542526 : temp.type = NULL_TREE;
993 2542526 : temp.opcode = ERROR_MARK;
994 2542526 : temp.op0 = TMR_INDEX2 (ref);
995 2542526 : temp.off = -1;
996 2542526 : break;
997 806418 : case BIT_FIELD_REF:
998 : /* Record bits, position and storage order. */
999 806418 : temp.op0 = TREE_OPERAND (ref, 1);
1000 806418 : temp.op1 = TREE_OPERAND (ref, 2);
1001 1612138 : if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
1002 698 : temp.off = -1;
1003 806418 : temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
1004 806418 : break;
1005 150540314 : case COMPONENT_REF:
1006 : /* The field decl is enough to unambiguously specify the field,
1007 : so use its type here. */
1008 150540314 : temp.type = TREE_TYPE (TREE_OPERAND (ref, 1));
1009 150540314 : temp.op0 = TREE_OPERAND (ref, 1);
1010 150540314 : temp.op1 = TREE_OPERAND (ref, 2);
1011 301078196 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1012 301077931 : && TYPE_REVERSE_STORAGE_ORDER
1013 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1014 150540314 : {
1015 150540314 : tree this_offset = component_ref_field_offset (ref);
1016 150540314 : if (this_offset
1017 150540314 : && poly_int_tree_p (this_offset))
1018 : {
1019 150538178 : tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1));
1020 150538178 : if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0)
1021 : {
1022 150054870 : poly_offset_int off
1023 150054870 : = (wi::to_poly_offset (this_offset)
1024 150054870 : + (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 150054870 : if (TREE_CODE (orig) != ADDR_EXPR
1030 5020666 : || (TYPE_SIZE (temp.type)
1031 5007642 : && integer_nonzerop (TYPE_SIZE (temp.type))
1032 153132710 : && maybe_ne (off, 0))
1033 153147884 : || (cfun->curr_properties & PROP_objsz))
1034 148589866 : off.to_shwi (&temp.off);
1035 : }
1036 : }
1037 : }
1038 : break;
1039 39002811 : case ARRAY_RANGE_REF:
1040 39002811 : case ARRAY_REF:
1041 39002811 : {
1042 39002811 : tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
1043 : /* Record index as operand. */
1044 39002811 : temp.op0 = TREE_OPERAND (ref, 1);
1045 : /* Always record lower bounds and element size. */
1046 39002811 : temp.op1 = array_ref_low_bound (ref);
1047 : /* But record element size in units of the type alignment. */
1048 39002811 : temp.op2 = TREE_OPERAND (ref, 3);
1049 39002811 : temp.align = eltype->type_common.align;
1050 39002811 : if (! temp.op2)
1051 38790946 : 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 39002811 : bool avoid_oob = true;
1058 39002811 : if (TREE_CODE (orig) != ADDR_EXPR
1059 482946 : || cfun->curr_properties & PROP_objsz)
1060 : avoid_oob = false;
1061 225791 : else if (poly_int_tree_p (temp.op0))
1062 : {
1063 76428 : tree ub = array_ref_up_bound (ref);
1064 76428 : if (ub
1065 74790 : && 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 65380 : && !integer_minus_onep (ub)
1070 151218 : && known_le (wi::to_poly_offset (temp.op0),
1071 : wi::to_poly_offset (ub)))
1072 64543 : avoid_oob = false;
1073 : }
1074 39002811 : if (poly_int_tree_p (temp.op0)
1075 22413076 : && poly_int_tree_p (temp.op1)
1076 22413048 : && TREE_CODE (temp.op2) == INTEGER_CST
1077 61354414 : && !avoid_oob)
1078 : {
1079 44681662 : poly_offset_int off = ((wi::to_poly_offset (temp.op0)
1080 67022493 : - wi::to_poly_offset (temp.op1))
1081 44681662 : * wi::to_offset (temp.op2)
1082 22340831 : * vn_ref_op_align_unit (&temp));
1083 22340831 : off.to_shwi (&temp.off);
1084 : }
1085 39002811 : temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
1086 39002811 : && TYPE_REVERSE_STORAGE_ORDER
1087 : (TREE_TYPE (TREE_OPERAND (ref, 0))));
1088 : }
1089 39002811 : break;
1090 83185175 : case VAR_DECL:
1091 83185175 : if (DECL_HARD_REGISTER (ref))
1092 : {
1093 20325 : temp.op0 = ref;
1094 20325 : break;
1095 : }
1096 : /* Fallthru. */
1097 86585528 : case PARM_DECL:
1098 86585528 : case CONST_DECL:
1099 86585528 : 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 86585528 : temp.opcode = MEM_REF;
1103 86585528 : temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
1104 86585528 : temp.off = 0;
1105 86585528 : result->safe_push (temp);
1106 86585528 : temp.opcode = ADDR_EXPR;
1107 86585528 : temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
1108 86585528 : temp.type = TREE_TYPE (temp.op0);
1109 86585528 : temp.off = -1;
1110 86585528 : break;
1111 98296172 : case STRING_CST:
1112 98296172 : case INTEGER_CST:
1113 98296172 : case POLY_INT_CST:
1114 98296172 : case COMPLEX_CST:
1115 98296172 : case VECTOR_CST:
1116 98296172 : case REAL_CST:
1117 98296172 : case FIXED_CST:
1118 98296172 : case CONSTRUCTOR:
1119 98296172 : case SSA_NAME:
1120 98296172 : temp.op0 = ref;
1121 98296172 : break;
1122 46358959 : case ADDR_EXPR:
1123 46358959 : if (is_gimple_min_invariant (ref))
1124 : {
1125 42070566 : temp.op0 = ref;
1126 42070566 : 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 492597 : case REALPART_EXPR:
1135 492597 : temp.off = 0;
1136 492597 : break;
1137 1445541 : case VIEW_CONVERT_EXPR:
1138 1445541 : temp.off = 0;
1139 1445541 : temp.reverse = storage_order_barrier_p (ref);
1140 1445541 : break;
1141 497032 : case IMAGPART_EXPR:
1142 : /* This is only interesting for its constant offset. */
1143 497032 : temp.off = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (ref)));
1144 497032 : break;
1145 0 : default:
1146 0 : gcc_unreachable ();
1147 : }
1148 562076055 : result->safe_push (temp);
1149 :
1150 562076055 : if (REFERENCE_CLASS_P (ref)
1151 246492753 : || TREE_CODE (ref) == MODIFY_EXPR
1152 231261121 : || TREE_CODE (ref) == WITH_SIZE_EXPR
1153 793337039 : || (TREE_CODE (ref) == ADDR_EXPR
1154 46358959 : && !is_gimple_min_invariant (ref)))
1155 335103464 : ref = TREE_OPERAND (ref, 0);
1156 : else
1157 : ref = NULL_TREE;
1158 : }
1159 226972591 : }
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 14783285 : 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 14783285 : unsigned i;
1171 14783285 : tree base = NULL_TREE;
1172 14783285 : tree *op0_p = &base;
1173 14783285 : poly_offset_int offset = 0;
1174 14783285 : poly_offset_int max_size;
1175 14783285 : poly_offset_int size = -1;
1176 14783285 : tree size_tree = NULL_TREE;
1177 :
1178 : /* We don't handle calls. */
1179 14783285 : if (!type)
1180 : return false;
1181 :
1182 14783285 : machine_mode mode = TYPE_MODE (type);
1183 14783285 : if (mode == BLKmode)
1184 66401 : size_tree = TYPE_SIZE (type);
1185 : else
1186 29433768 : size = GET_MODE_BITSIZE (mode);
1187 14716884 : if (size_tree != NULL_TREE
1188 66401 : && poly_int_tree_p (size_tree))
1189 66401 : size = wi::to_poly_offset (size_tree);
1190 :
1191 : /* Lower the final access size from the outermost expression. */
1192 14783285 : 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 14783285 : vn_reference_op_t op = const_cast<vn_reference_op_t>(cst_op);
1196 14783285 : size_tree = NULL_TREE;
1197 14783285 : if (op->opcode == COMPONENT_REF)
1198 5133690 : size_tree = DECL_SIZE (op->op0);
1199 9649595 : else if (op->opcode == BIT_FIELD_REF)
1200 75049 : size_tree = op->op0;
1201 5208739 : if (size_tree != NULL_TREE
1202 5208739 : && poly_int_tree_p (size_tree)
1203 10417478 : && (!known_size_p (size)
1204 14783285 : || known_lt (wi::to_poly_offset (size_tree), size)))
1205 40720 : 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 14783285 : max_size = size;
1210 :
1211 : /* Compute cumulative bit-offset for nested component-refs and array-refs,
1212 : and find the ultimate containing object. */
1213 56827909 : FOR_EACH_VEC_ELT (ops, i, op)
1214 : {
1215 42194660 : switch (op->opcode)
1216 : {
1217 : case CALL_EXPR:
1218 : return false;
1219 :
1220 : /* Record the base objects. */
1221 14325917 : case MEM_REF:
1222 14325917 : *op0_p = build2 (MEM_REF, op->type,
1223 : NULL_TREE, op->op0);
1224 14325917 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1225 14325917 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1226 14325917 : op0_p = &TREE_OPERAND (*op0_p, 0);
1227 14325917 : break;
1228 :
1229 306796 : case TARGET_MEM_REF:
1230 920388 : *op0_p = build5 (TARGET_MEM_REF, op->type,
1231 : NULL_TREE, op->op2, op->op0,
1232 306796 : op->op1, ops[i+1].op0);
1233 306796 : MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1234 306796 : MR_DEPENDENCE_BASE (*op0_p) = op->base;
1235 306796 : op0_p = &TREE_OPERAND (*op0_p, 0);
1236 306796 : ++i;
1237 306796 : break;
1238 :
1239 : /* Unwrap some of the wrapped decls. */
1240 6685883 : case ADDR_EXPR:
1241 : /* Apart from ADDR_EXPR arguments to MEM_REF. */
1242 6685883 : if (base != NULL_TREE
1243 6685882 : && TREE_CODE (base) == MEM_REF
1244 6650666 : && op->op0
1245 13336549 : && DECL_P (TREE_OPERAND (op->op0, 0)))
1246 : {
1247 6643344 : const_vn_reference_op_t pop = &ops[i-1];
1248 6643344 : base = TREE_OPERAND (op->op0, 0);
1249 6643344 : if (known_eq (pop->off, -1))
1250 : {
1251 25 : max_size = -1;
1252 25 : offset = 0;
1253 : }
1254 : else
1255 19929957 : offset += poly_offset_int (pop->off) * BITS_PER_UNIT;
1256 : op0_p = NULL;
1257 : break;
1258 : }
1259 : /* Fallthru. */
1260 7989905 : case PARM_DECL:
1261 7989905 : case CONST_DECL:
1262 7989905 : 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 7989905 : case VAR_DECL:
1266 : /* ??? And for this only have DECL_HARD_REGISTER. */
1267 7989905 : case STRING_CST:
1268 : /* This can show up in ARRAY_REF bases. */
1269 7989905 : case INTEGER_CST:
1270 7989905 : case SSA_NAME:
1271 7989905 : *op0_p = op->op0;
1272 7989905 : op0_p = NULL;
1273 7989905 : break;
1274 :
1275 : /* And now the usual component-reference style ops. */
1276 75049 : case BIT_FIELD_REF:
1277 75049 : offset += wi::to_poly_offset (op->op1);
1278 75049 : break;
1279 :
1280 8388812 : case COMPONENT_REF:
1281 8388812 : {
1282 8388812 : 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 8388812 : tree this_offset = DECL_FIELD_OFFSET (field);
1287 :
1288 8388812 : if (op->op1 || !poly_int_tree_p (this_offset))
1289 234 : max_size = -1;
1290 : else
1291 : {
1292 8388578 : poly_offset_int woffset = (wi::to_poly_offset (this_offset)
1293 8388578 : << LOG2_BITS_PER_UNIT);
1294 8388578 : woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
1295 8388578 : offset += woffset;
1296 : }
1297 : break;
1298 : }
1299 :
1300 3113715 : case ARRAY_RANGE_REF:
1301 3113715 : case ARRAY_REF:
1302 : /* Use the recorded constant offset. */
1303 3113715 : if (maybe_eq (op->off, -1))
1304 1211077 : max_size = -1;
1305 : else
1306 5707914 : offset += poly_offset_int (op->off) * BITS_PER_UNIT;
1307 : break;
1308 :
1309 : case REALPART_EXPR:
1310 : break;
1311 :
1312 : case IMAGPART_EXPR:
1313 42044624 : 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 14633249 : if (base == NULL_TREE)
1333 : return false;
1334 :
1335 14633249 : ref->ref = NULL_TREE;
1336 14633249 : ref->base = base;
1337 14633249 : ref->ref_alias_set = set;
1338 14633249 : ref->base_alias_set = base_set;
1339 : /* We discount volatiles from value-numbering elsewhere. */
1340 14633249 : ref->volatile_p = false;
1341 :
1342 14633249 : 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 14633249 : 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 14633223 : if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0))
1358 1062750 : 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 9390191 : copy_reference_ops_from_call (gcall *call,
1368 : vec<vn_reference_op_s> *result)
1369 : {
1370 9390191 : vn_reference_op_s temp;
1371 9390191 : unsigned i;
1372 9390191 : tree lhs = gimple_call_lhs (call);
1373 9390191 : 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 9390191 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
1379 : {
1380 451362 : memset (&temp, 0, sizeof (temp));
1381 451362 : temp.opcode = MODIFY_EXPR;
1382 451362 : temp.type = TREE_TYPE (lhs);
1383 451362 : temp.op0 = lhs;
1384 451362 : temp.off = -1;
1385 451362 : result->safe_push (temp);
1386 : }
1387 :
1388 : /* Copy the type, opcode, function, static chain and EH region, if any. */
1389 9390191 : memset (&temp, 0, sizeof (temp));
1390 9390191 : temp.type = gimple_call_fntype (call);
1391 9390191 : temp.opcode = CALL_EXPR;
1392 9390191 : temp.op0 = gimple_call_fn (call);
1393 9390191 : if (gimple_call_internal_p (call))
1394 543173 : temp.clique = gimple_call_internal_fn (call);
1395 9390191 : temp.op1 = gimple_call_chain (call);
1396 9390191 : if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0)
1397 625682 : temp.op2 = size_int (lr);
1398 9390191 : temp.off = -1;
1399 9390191 : result->safe_push (temp);
1400 :
1401 : /* Copy the call arguments. As they can be references as well,
1402 : just chain them together. */
1403 37156156 : for (i = 0; i < gimple_call_num_args (call); ++i)
1404 : {
1405 18375774 : tree callarg = gimple_call_arg (call, i);
1406 18375774 : copy_reference_ops_from_ref (callarg, result);
1407 : }
1408 9390191 : }
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 129246008 : vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
1414 : unsigned int *i_p)
1415 : {
1416 129246008 : unsigned int i = *i_p;
1417 129246008 : vn_reference_op_t op = &(*ops)[i];
1418 129246008 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1419 129246008 : tree addr_base;
1420 129246008 : 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 129246008 : addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (op->op0, 0),
1426 : &addr_offset, vn_valueize);
1427 129246008 : gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
1428 129246008 : if (addr_base != TREE_OPERAND (op->op0, 0))
1429 : {
1430 686433 : poly_offset_int off
1431 686433 : = (poly_offset_int::from (wi::to_poly_wide (mem_op->op0),
1432 : SIGNED)
1433 686433 : + addr_offset);
1434 686433 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1435 686433 : op->op0 = build_fold_addr_expr (addr_base);
1436 686433 : if (tree_fits_shwi_p (mem_op->op0))
1437 686366 : mem_op->off = tree_to_shwi (mem_op->op0);
1438 : else
1439 : mem_op->off = -1;
1440 686433 : 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 87430296 : vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
1449 : unsigned int *i_p)
1450 : {
1451 87430296 : bool changed = false;
1452 94903976 : vn_reference_op_t op;
1453 :
1454 94903976 : do
1455 : {
1456 94903976 : unsigned int i = *i_p;
1457 94903976 : op = &(*ops)[i];
1458 94903976 : vn_reference_op_t mem_op = &(*ops)[i - 1];
1459 94903976 : gimple *def_stmt;
1460 94903976 : enum tree_code code;
1461 94903976 : poly_offset_int off;
1462 :
1463 94903976 : def_stmt = SSA_NAME_DEF_STMT (op->op0);
1464 94903976 : if (!is_gimple_assign (def_stmt))
1465 87428345 : return changed;
1466 :
1467 38347246 : code = gimple_assign_rhs_code (def_stmt);
1468 38347246 : if (code != ADDR_EXPR
1469 38347246 : && code != POINTER_PLUS_EXPR)
1470 : return changed;
1471 :
1472 20299907 : 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 20299907 : if (code == ADDR_EXPR)
1478 : {
1479 966361 : tree addr, addr_base;
1480 966361 : poly_int64 addr_offset;
1481 :
1482 966361 : addr = gimple_assign_rhs1 (def_stmt);
1483 966361 : 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 966361 : if (!addr_base
1490 286774 : && *i_p == ops->length () - 1
1491 143387 : && 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 1052731 : && default_vn_walk_kind == VN_WALKREWRITE)
1496 : {
1497 86280 : auto_vec<vn_reference_op_s, 32> tem;
1498 86280 : 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 86280 : if (tem.length () >= 2
1503 86280 : && tem[tem.length () - 2].opcode == MEM_REF)
1504 : {
1505 86265 : vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
1506 86265 : new_mem_op->op0
1507 86265 : = wide_int_to_tree (TREE_TYPE (mem_op->op0),
1508 172530 : 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 86280 : ops->pop ();
1516 86280 : ops->pop ();
1517 86280 : ops->safe_splice (tem);
1518 86280 : --*i_p;
1519 86280 : return true;
1520 86280 : }
1521 880081 : if (!addr_base
1522 822974 : || TREE_CODE (addr_base) != MEM_REF
1523 1701226 : || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
1524 819284 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
1525 : 0))))
1526 : return changed;
1527 :
1528 821145 : off += addr_offset;
1529 821145 : off += mem_ref_offset (addr_base);
1530 821145 : op->op0 = TREE_OPERAND (addr_base, 0);
1531 : }
1532 : else
1533 : {
1534 19333546 : tree ptr, ptroff;
1535 19333546 : ptr = gimple_assign_rhs1 (def_stmt);
1536 19333546 : ptroff = gimple_assign_rhs2 (def_stmt);
1537 19333546 : if (TREE_CODE (ptr) != SSA_NAME
1538 17604155 : || 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 17602758 : || SSA_VAL (ptr) == op->op0
1543 36936304 : || !poly_int_tree_p (ptroff))
1544 : return changed;
1545 :
1546 6654486 : off += wi::to_poly_offset (ptroff);
1547 6654486 : op->op0 = ptr;
1548 : }
1549 :
1550 7475631 : mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1551 7475631 : if (tree_fits_shwi_p (mem_op->op0))
1552 7164993 : mem_op->off = tree_to_shwi (mem_op->op0);
1553 : else
1554 : mem_op->off = -1;
1555 : /* ??? Can end up with endless recursion here!?
1556 : gcc.c-torture/execute/strcmp-1.c */
1557 7475631 : if (TREE_CODE (op->op0) == SSA_NAME)
1558 7473770 : op->op0 = SSA_VAL (op->op0);
1559 7475631 : if (TREE_CODE (op->op0) != SSA_NAME)
1560 1951 : op->opcode = TREE_CODE (op->op0);
1561 :
1562 7475631 : changed = true;
1563 : }
1564 : /* Tail-recurse. */
1565 7475631 : 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 111977111 : fully_constant_vn_reference_p (vn_reference_t ref)
1579 : {
1580 111977111 : vec<vn_reference_op_s> operands = ref->operands;
1581 111977111 : 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 111977111 : op = &operands[0];
1586 111977111 : if (op->opcode == CALL_EXPR
1587 90872 : && (!op->op0
1588 83348 : || (TREE_CODE (op->op0) == ADDR_EXPR
1589 83348 : && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
1590 83348 : && fndecl_built_in_p (TREE_OPERAND (op->op0, 0),
1591 : BUILT_IN_NORMAL)))
1592 73185 : && operands.length () >= 2
1593 112050264 : && operands.length () <= 3)
1594 : {
1595 34114 : vn_reference_op_t arg0, arg1 = NULL;
1596 34114 : bool anyconst = false;
1597 34114 : arg0 = &operands[1];
1598 34114 : if (operands.length () > 2)
1599 5601 : arg1 = &operands[2];
1600 34114 : if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
1601 34114 : || (arg0->opcode == ADDR_EXPR
1602 13836 : && is_gimple_min_invariant (arg0->op0)))
1603 : anyconst = true;
1604 34114 : if (arg1
1605 34114 : && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
1606 4110 : || (arg1->opcode == ADDR_EXPR
1607 587 : && is_gimple_min_invariant (arg1->op0))))
1608 : anyconst = true;
1609 32036 : if (anyconst)
1610 : {
1611 22424 : combined_fn fn;
1612 22424 : if (op->op0)
1613 21469 : fn = as_combined_fn (DECL_FUNCTION_CODE
1614 21469 : (TREE_OPERAND (op->op0, 0)));
1615 : else
1616 955 : fn = as_combined_fn ((internal_fn) op->clique);
1617 22424 : tree folded;
1618 22424 : if (arg1)
1619 2714 : folded = fold_const_call (fn, ref->type, arg0->op0, arg1->op0);
1620 : else
1621 19710 : folded = fold_const_call (fn, ref->type, arg0->op0);
1622 22424 : if (folded
1623 22424 : && is_gimple_min_invariant (folded))
1624 1042 : return folded;
1625 : }
1626 : }
1627 :
1628 : /* Simplify reads from constants or constant initializers. */
1629 111942997 : else if (BITS_PER_UNIT == 8
1630 111942997 : && ref->type
1631 111942997 : && COMPLETE_TYPE_P (ref->type)
1632 223885952 : && is_gimple_reg_type (ref->type))
1633 : {
1634 107554246 : poly_int64 off = 0;
1635 107554246 : HOST_WIDE_INT size;
1636 107554246 : if (INTEGRAL_TYPE_P (ref->type))
1637 54669537 : size = TYPE_PRECISION (ref->type);
1638 52884709 : else if (tree_fits_shwi_p (TYPE_SIZE (ref->type)))
1639 52884709 : size = tree_to_shwi (TYPE_SIZE (ref->type));
1640 : else
1641 : return NULL_TREE;
1642 107554246 : if (size % BITS_PER_UNIT != 0
1643 105739796 : || size > MAX_BITSIZE_MODE_ANY_MODE)
1644 : return NULL_TREE;
1645 105738469 : size /= BITS_PER_UNIT;
1646 105738469 : unsigned i;
1647 195965964 : for (i = 0; i < operands.length (); ++i)
1648 : {
1649 195965964 : if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant)
1650 : {
1651 309 : ++i;
1652 309 : break;
1653 : }
1654 195965655 : if (operands[i].reverse)
1655 : return NULL_TREE;
1656 195957220 : if (known_eq (operands[i].off, -1))
1657 : return NULL_TREE;
1658 181986707 : off += operands[i].off;
1659 181986707 : if (operands[i].opcode == MEM_REF)
1660 : {
1661 91759212 : ++i;
1662 91759212 : break;
1663 : }
1664 : }
1665 91759521 : vn_reference_op_t base = &operands[--i];
1666 91759521 : tree ctor = error_mark_node;
1667 91759521 : tree decl = NULL_TREE;
1668 91759521 : if (TREE_CODE_CLASS (base->opcode) == tcc_constant)
1669 309 : ctor = base->op0;
1670 91759212 : else if (base->opcode == MEM_REF
1671 91759212 : && base[1].opcode == ADDR_EXPR
1672 150708526 : && (VAR_P (TREE_OPERAND (base[1].op0, 0))
1673 3590878 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL
1674 3590818 : || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST))
1675 : {
1676 55364601 : decl = TREE_OPERAND (base[1].op0, 0);
1677 55364601 : if (TREE_CODE (decl) == STRING_CST)
1678 : ctor = decl;
1679 : else
1680 55358496 : ctor = ctor_for_folding (decl);
1681 : }
1682 91753416 : if (ctor == NULL_TREE)
1683 386 : return build_zero_cst (ref->type);
1684 91759135 : else if (ctor != error_mark_node)
1685 : {
1686 104243 : HOST_WIDE_INT const_off;
1687 104243 : if (decl)
1688 : {
1689 207868 : tree res = fold_ctor_reference (ref->type, ctor,
1690 103934 : off * BITS_PER_UNIT,
1691 103934 : size * BITS_PER_UNIT, decl);
1692 103934 : if (res)
1693 : {
1694 59568 : STRIP_USELESS_TYPE_CONVERSION (res);
1695 59568 : if (is_gimple_min_invariant (res))
1696 59436 : 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 60471697 : contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
1716 : {
1717 60471697 : vn_reference_op_t op;
1718 60471697 : unsigned i;
1719 :
1720 237031454 : FOR_EACH_VEC_ELT (ops, i, op)
1721 176559757 : 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 60479974 : reverse_storage_order_for_component_p (vec<vn_reference_op_s> ops)
1731 : {
1732 60479974 : unsigned i = 0;
1733 60479974 : if (ops[i].opcode == REALPART_EXPR || ops[i].opcode == IMAGPART_EXPR)
1734 : ++i;
1735 60479974 : switch (ops[i].opcode)
1736 : {
1737 58398328 : case ARRAY_REF:
1738 58398328 : case COMPONENT_REF:
1739 58398328 : case BIT_FIELD_REF:
1740 58398328 : case MEM_REF:
1741 58398328 : 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 223972366 : valueize_refs_1 (vec<vn_reference_op_s> *orig, bool *valueized_anything,
1754 : bool with_avail = false)
1755 : {
1756 223972366 : *valueized_anything = false;
1757 :
1758 904371959 : for (unsigned i = 0; i < orig->length (); ++i)
1759 : {
1760 680399593 : re_valueize:
1761 684373226 : vn_reference_op_t vro = &(*orig)[i];
1762 684373226 : if (vro->opcode == SSA_NAME
1763 584798061 : || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
1764 : {
1765 124281910 : tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0);
1766 124281910 : if (tem != vro->op0)
1767 : {
1768 18539991 : *valueized_anything = true;
1769 18539991 : vro->op0 = tem;
1770 : }
1771 : /* If it transforms from an SSA_NAME to a constant, update
1772 : the opcode. */
1773 124281910 : if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
1774 2171693 : vro->opcode = TREE_CODE (vro->op0);
1775 : }
1776 684373226 : if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
1777 : {
1778 26272 : tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1);
1779 26272 : if (tem != vro->op1)
1780 : {
1781 595 : *valueized_anything = true;
1782 595 : vro->op1 = tem;
1783 : }
1784 : }
1785 684373226 : if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
1786 : {
1787 206317 : tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2);
1788 206317 : if (tem != vro->op2)
1789 : {
1790 119775 : *valueized_anything = true;
1791 119775 : vro->op2 = tem;
1792 : }
1793 : }
1794 : /* If it transforms from an SSA_NAME to an address, fold with
1795 : a preceding indirect reference. */
1796 684373226 : if (i > 0
1797 460321140 : && vro->op0
1798 456793888 : && TREE_CODE (vro->op0) == ADDR_EXPR
1799 819597628 : && (*orig)[i - 1].opcode == MEM_REF)
1800 : {
1801 129245747 : if (vn_reference_fold_indirect (orig, &i))
1802 686433 : *valueized_anything = true;
1803 : }
1804 555127479 : else if (i > 0
1805 331075393 : && vro->opcode == SSA_NAME
1806 652530951 : && (*orig)[i - 1].opcode == MEM_REF)
1807 : {
1808 87430296 : if (vn_reference_maybe_forwprop_address (orig, &i))
1809 : {
1810 3973633 : *valueized_anything = true;
1811 : /* Re-valueize the current operand. */
1812 3973633 : goto re_valueize;
1813 : }
1814 : }
1815 : /* If it transforms a non-constant ARRAY_REF into a constant
1816 : one, adjust the constant offset. */
1817 467697183 : else if ((vro->opcode == ARRAY_REF
1818 467697183 : || vro->opcode == ARRAY_RANGE_REF)
1819 40110970 : && known_eq (vro->off, -1)
1820 17393234 : && poly_int_tree_p (vro->op0)
1821 5009816 : && poly_int_tree_p (vro->op1)
1822 472706999 : && 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 4875268 : if (!(cfun->curr_properties & PROP_objsz)
1829 6115183 : && (*orig)[0].opcode == ADDR_EXPR)
1830 : {
1831 36546 : tree dom = TYPE_DOMAIN ((*orig)[i + 1].type);
1832 55955 : if (!dom
1833 36396 : || !TYPE_MAX_VALUE (dom)
1834 26418 : || !poly_int_tree_p (TYPE_MAX_VALUE (dom))
1835 53759 : || integer_minus_onep (TYPE_MAX_VALUE (dom)))
1836 20216 : 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 9710104 : poly_offset_int off = ((wi::to_poly_offset (vro->op0)
1843 14565156 : - wi::to_poly_offset (vro->op1))
1844 9710104 : * wi::to_offset (vro->op2)
1845 4855052 : * vn_ref_op_align_unit (vro));
1846 4855052 : off.to_shwi (&vro->off);
1847 : }
1848 : }
1849 223972366 : }
1850 :
1851 : static void
1852 12905644 : valueize_refs (vec<vn_reference_op_s> *orig)
1853 : {
1854 12905644 : 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 184418313 : valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
1867 : {
1868 184418313 : if (!ref)
1869 0 : return vNULL;
1870 184418313 : shared_lookup_references.truncate (0);
1871 184418313 : copy_reference_ops_from_ref (ref, &shared_lookup_references);
1872 184418313 : valueize_refs_1 (&shared_lookup_references, valueized_anything);
1873 184418313 : 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 9390191 : valueize_shared_reference_ops_from_call (gcall *call)
1882 : {
1883 9390191 : if (!call)
1884 0 : return vNULL;
1885 9390191 : shared_lookup_references.truncate (0);
1886 9390191 : copy_reference_ops_from_call (call, &shared_lookup_references);
1887 9390191 : valueize_refs (&shared_lookup_references);
1888 9390191 : 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 66736474 : vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
1898 : {
1899 66736474 : vn_reference_s **slot;
1900 66736474 : hashval_t hash;
1901 :
1902 66736474 : hash = vr->hashcode;
1903 66736474 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
1904 66736474 : if (slot)
1905 : {
1906 8361849 : if (vnresult)
1907 8361849 : *vnresult = (vn_reference_t)*slot;
1908 8361849 : 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 62541978 : 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 62541978 : : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
1940 62541978 : mask (mask_), masked_result (NULL_TREE), same_val (NULL_TREE),
1941 62541978 : vn_walk_kind (vn_walk_kind_),
1942 62541978 : tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_),
1943 125083956 : saved_operands (vNULL), first_range (), first_set (-2),
1944 125083956 : first_base_set (-2)
1945 : {
1946 62541978 : if (!last_vuse_ptr)
1947 28972759 : last_vuse_ptr = &last_vuse;
1948 62541978 : ao_ref_init (&orig_ref, orig_ref_);
1949 62541978 : if (mask)
1950 : {
1951 306553 : wide_int w = wi::to_wide (mask);
1952 306553 : unsigned int pos = 0, prec = w.get_precision ();
1953 306553 : pd_data pd;
1954 306553 : pd.rhs = build_constructor (NULL_TREE, NULL);
1955 306553 : 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 657179 : while (pos < prec)
1964 : {
1965 636703 : int tz = wi::ctz (w);
1966 636703 : if (pos + tz > prec)
1967 286077 : tz = prec - pos;
1968 636703 : if (tz)
1969 : {
1970 484700 : if (BYTES_BIG_ENDIAN)
1971 : pd.offset = prec - pos - tz;
1972 : else
1973 484700 : pd.offset = pos;
1974 484700 : pd.size = tz;
1975 484700 : void *r = push_partial_def (pd, 0, 0, 0, prec);
1976 484700 : gcc_assert (r == NULL_TREE);
1977 : }
1978 636703 : pos += tz;
1979 636703 : if (pos == prec)
1980 : break;
1981 350626 : w = wi::lrshift (w, tz);
1982 350626 : tz = wi::ctz (wi::bit_not (w));
1983 350626 : if (pos + tz > prec)
1984 0 : tz = prec - pos;
1985 350626 : pos += tz;
1986 350626 : w = wi::lrshift (w, tz);
1987 : }
1988 306553 : }
1989 62541978 : }
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 62541978 : vn_walk_cb_data::~vn_walk_cb_data ()
2020 : {
2021 62541978 : if (known_ranges)
2022 173771 : obstack_free (&ranges_obstack, NULL);
2023 62541978 : saved_operands.release ();
2024 62541978 : }
2025 :
2026 : void *
2027 1590563 : vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
2028 : {
2029 1590563 : if (first_set != -2)
2030 : {
2031 454257 : set = first_set;
2032 454257 : base_set = first_base_set;
2033 : }
2034 1590563 : if (mask)
2035 : {
2036 459 : masked_result = val;
2037 459 : return (void *) -1;
2038 : }
2039 1590104 : if (same_val && !operand_equal_p (val, same_val))
2040 : return (void *) -1;
2041 1586322 : vec<vn_reference_op_s> &operands
2042 1586322 : = saved_operands.exists () ? saved_operands : vr->operands;
2043 1586322 : return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
2044 : vr->offset, vr->max_size,
2045 1586322 : 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 569907 : 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 569907 : 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 569832 : 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 569832 : if (!CONSTANT_CLASS_P (pd.rhs))
2075 : {
2076 528619 : 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 528619 : if (pd.size > maxsizei)
2084 7763 : pd.size = maxsizei + ((pd.size - maxsizei) % BITS_PER_UNIT);
2085 : }
2086 :
2087 569832 : pd.offset -= offseti;
2088 :
2089 1139664 : bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
2090 569832 : || CONSTANT_CLASS_P (pd.rhs));
2091 569832 : pd_range *r;
2092 569832 : if (partial_defs.is_empty ())
2093 : {
2094 : /* If we get a clobber upfront, fail. */
2095 364487 : if (TREE_CLOBBER_P (pd.rhs))
2096 : return (void *)-1;
2097 364132 : if (!pd_constant_p)
2098 : return (void *)-1;
2099 331426 : partial_defs.safe_push (pd);
2100 331426 : first_range.offset = pd.offset;
2101 331426 : first_range.size = pd.size;
2102 331426 : first_set = set;
2103 331426 : first_base_set = base_set;
2104 331426 : last_vuse_ptr = NULL;
2105 331426 : 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 205345 : if (!known_ranges)
2112 : {
2113 : /* ??? Optimize the case where the 2nd partial def completes
2114 : things. */
2115 173771 : gcc_obstack_init (&ranges_obstack);
2116 173771 : known_ranges.insert_max_node (&first_range);
2117 : }
2118 : /* Lookup the offset and see if we need to merge. */
2119 205345 : int comparison = known_ranges.lookup_le
2120 414980 : ([&] (pd_range *r) { return pd.offset < r->offset; },
2121 184466 : [&] (pd_range *r) { return pd.offset > r->offset; });
2122 205345 : r = known_ranges.root ();
2123 205345 : if (comparison >= 0
2124 205345 : && 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 5907 : if (known_subrange_p (pd.offset, pd.size, r->offset, r->size))
2130 : return NULL;
2131 5012 : 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 199438 : void *addr = XOBNEW (&ranges_obstack, pd_range);
2137 199438 : r = new (addr) pd_range { pd.offset, pd.size, {} };
2138 199438 : 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 204450 : if (known_ranges.splay_next_node ())
2143 22986 : do
2144 : {
2145 22986 : pd_range *rafter = known_ranges.root ();
2146 22986 : if (!ranges_known_overlap_p (r->offset, r->size + 1,
2147 22986 : rafter->offset, rafter->size))
2148 : break;
2149 22716 : r->size = MAX (r->offset + r->size,
2150 22716 : rafter->offset + rafter->size) - r->offset;
2151 : }
2152 22716 : while (known_ranges.remove_root_and_splay_next ());
2153 : /* If we get a clobber, fail. */
2154 204450 : 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 202253 : if (!pd_constant_p)
2158 : return (void *)-1;
2159 195771 : 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 527197 : 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 8939 : unsigned ndefs = partial_defs.length ();
2171 : /* We support up to 512-bit values (for V8DFmode). */
2172 8939 : unsigned char buffer[bufsize + 1];
2173 8939 : unsigned char this_buffer[bufsize + 1];
2174 8939 : int len;
2175 :
2176 8939 : memset (buffer, 0, bufsize + 1);
2177 8939 : unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
2178 35034 : while (!partial_defs.is_empty ())
2179 : {
2180 26095 : pd_data pd = partial_defs.pop ();
2181 26095 : unsigned int amnt;
2182 26095 : if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
2183 : {
2184 : /* Empty CONSTRUCTOR. */
2185 2200 : if (pd.size >= needed_len * BITS_PER_UNIT)
2186 2200 : len = needed_len;
2187 : else
2188 1843 : len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
2189 2200 : memset (this_buffer, 0, len);
2190 : }
2191 23895 : else if (pd.rhs_off >= 0)
2192 : {
2193 47790 : len = native_encode_expr (pd.rhs, this_buffer, bufsize,
2194 23895 : (MAX (0, -pd.offset)
2195 23895 : + pd.rhs_off) / BITS_PER_UNIT);
2196 23895 : if (len <= 0
2197 23895 : || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
2198 23895 : - 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 569907 : 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 : return (void *)-1;
2222 : }
2223 : }
2224 :
2225 26095 : unsigned char *p = buffer;
2226 26095 : HOST_WIDE_INT size = pd.size;
2227 26095 : if (pd.offset < 0)
2228 318 : size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
2229 26095 : this_buffer[len] = 0;
2230 26095 : 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 26095 : if (pd.offset >= 0)
2300 : {
2301 : /* LSB of this_buffer[0] byte should be at pd.offset bits
2302 : in buffer. */
2303 25777 : unsigned int msk;
2304 25777 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2305 25777 : amnt = pd.offset % BITS_PER_UNIT;
2306 25777 : if (amnt)
2307 1517 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2308 25777 : unsigned int off = pd.offset / BITS_PER_UNIT;
2309 25777 : gcc_assert (off < needed_len);
2310 25777 : size = MIN (size,
2311 : (HOST_WIDE_INT) (needed_len - off) * BITS_PER_UNIT);
2312 25777 : p = buffer + off;
2313 25777 : 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 1090 : msk = ((1 << size) - 1) << amnt;
2319 1090 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2320 1090 : size = 0;
2321 : }
2322 24687 : else if (amnt)
2323 : {
2324 1141 : msk = -1U << amnt;
2325 1141 : *p = (*p & ~msk) | (this_buffer[0] & msk);
2326 1141 : p++;
2327 1141 : size -= (BITS_PER_UNIT - amnt);
2328 : }
2329 : }
2330 : else
2331 : {
2332 318 : amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
2333 318 : if (amnt)
2334 17 : size -= BITS_PER_UNIT - amnt;
2335 318 : size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2336 318 : if (amnt)
2337 17 : shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2338 : }
2339 26095 : memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
2340 26095 : p += size / BITS_PER_UNIT;
2341 26095 : if (size % BITS_PER_UNIT)
2342 : {
2343 627 : unsigned int msk = -1U << (size % BITS_PER_UNIT);
2344 627 : *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
2345 627 : & ~msk) | (*p & msk);
2346 : }
2347 : }
2348 : }
2349 :
2350 8939 : tree type = vr->type;
2351 : /* Make sure to interpret in a type that has a range covering the whole
2352 : access size. */
2353 8939 : 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 8939 : tree val;
2362 8939 : 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 8939 : 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 8939 : 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 8935 : if (val)
2398 : {
2399 8935 : 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 8935 : 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 : 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 1098912548 : vn_reference_lookup_2 (ao_ref *op, tree vuse, void *data_)
2420 : {
2421 1098912548 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2422 1098912548 : vn_reference_t vr = data->vr;
2423 1098912548 : vn_reference_s **slot;
2424 1098912548 : hashval_t hash;
2425 :
2426 : /* If we have partial definitions recorded we have to go through
2427 : vn_reference_lookup_3. */
2428 1098912548 : if (!data->partial_defs.is_empty ())
2429 : return NULL;
2430 :
2431 1098122380 : if (data->last_vuse_ptr)
2432 : {
2433 1076788183 : *data->last_vuse_ptr = vuse;
2434 1076788183 : data->last_vuse = vuse;
2435 : }
2436 :
2437 : /* Fixup vuse and hash. */
2438 1098122380 : if (vr->vuse)
2439 1098122380 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2440 1098122380 : vr->vuse = vuse_ssa_val (vuse);
2441 1098122380 : if (vr->vuse)
2442 1098122380 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2443 :
2444 1098122380 : hash = vr->hashcode;
2445 1098122380 : slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
2446 1098122380 : if (slot)
2447 : {
2448 8069506 : if ((*slot)->result && data->saved_operands.exists ())
2449 439512 : return data->finish (vr->set, vr->base_set, (*slot)->result);
2450 : return *slot;
2451 : }
2452 :
2453 1090052874 : if (SSA_NAME_IS_DEFAULT_DEF (vuse))
2454 : {
2455 18474028 : HOST_WIDE_INT op_offset, op_size;
2456 18474028 : tree v = NULL_TREE;
2457 18474028 : tree base = ao_ref_base (op);
2458 :
2459 18474028 : if (base
2460 18474028 : && op->offset.is_constant (&op_offset)
2461 18474028 : && op->size.is_constant (&op_size)
2462 18474028 : && op->max_size_known_p ()
2463 36489692 : && known_eq (op->size, op->max_size))
2464 : {
2465 17712474 : if (TREE_CODE (base) == PARM_DECL)
2466 678794 : v = ipcp_get_aggregate_const (cfun, base, false, op_offset,
2467 : op_size);
2468 17033680 : else if (TREE_CODE (base) == MEM_REF
2469 7095845 : && integer_zerop (TREE_OPERAND (base, 1))
2470 5703383 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
2471 5698180 : && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0))
2472 20831538 : && (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (base, 0)))
2473 : == PARM_DECL))
2474 3743722 : v = ipcp_get_aggregate_const (cfun,
2475 3743722 : SSA_NAME_VAR (TREE_OPERAND (base, 0)),
2476 : true, op_offset, op_size);
2477 : }
2478 4422516 : 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 1586322 : 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 1586322 : vn_reference_s vr1;
2501 1586322 : vn_reference_t result;
2502 1586322 : unsigned value_id;
2503 1586322 : vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
2504 1586322 : vr1.operands = operands;
2505 1586322 : vr1.type = type;
2506 1586322 : vr1.set = set;
2507 1586322 : vr1.base_set = base_set;
2508 1586322 : vr1.offset = offset;
2509 1586322 : vr1.max_size = max_size;
2510 1586322 : vr1.hashcode = vn_reference_compute_hash (&vr1);
2511 1586322 : if (vn_reference_lookup_1 (&vr1, &result))
2512 8307 : return result;
2513 :
2514 1578015 : if (TREE_CODE (value) == SSA_NAME)
2515 367008 : value_id = VN_INFO (value)->value_id;
2516 : else
2517 1211007 : value_id = get_or_alloc_constant_value_id (value);
2518 1578015 : return vn_reference_insert_pieces (vuse, set, base_set, offset, max_size,
2519 1578015 : 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 18890458 : vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
2529 : bool simplify)
2530 : {
2531 18890458 : 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 18890458 : unsigned i = 0;
2538 18890458 : if (simplify)
2539 43836703 : for (i = 0; i < res_op->num_ops; ++i)
2540 24951954 : if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
2541 : {
2542 16012699 : tree tem = vn_valueize (res_op->ops[i]);
2543 16012699 : if (!tem)
2544 : break;
2545 16012699 : res_op->ops[i] = tem;
2546 : }
2547 : /* If valueization of an operand fails (it is not available), skip
2548 : simplification. */
2549 18890458 : bool res = false;
2550 18890458 : 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 18884749 : if (rpo_avail)
2555 11317398 : mprts_hook = vn_lookup_simplify_result;
2556 18884749 : res = res_op->resimplify (NULL, vn_valueize);
2557 18884749 : mprts_hook = NULL;
2558 : }
2559 32556852 : gimple *new_stmt = NULL;
2560 18884749 : if (res
2561 18884749 : && gimple_simplified_result_is_gimple_val (res_op))
2562 : {
2563 : /* The expression is already available. */
2564 5218355 : result = res_op->ops[0];
2565 : /* Valueize it, simplification returns sth in AVAIL only. */
2566 5218355 : if (TREE_CODE (result) == SSA_NAME)
2567 292671 : result = SSA_VAL (result);
2568 : }
2569 : else
2570 : {
2571 13672103 : 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 13672103 : if (!val && insert && res_op->code.is_tree_code ())
2576 : {
2577 147120 : gimple_seq stmts = NULL;
2578 147120 : result = maybe_push_res_to_seq (res_op, &stmts);
2579 147120 : if (result)
2580 : {
2581 147114 : gcc_assert (gimple_seq_singleton_p (stmts));
2582 147114 : new_stmt = gimple_seq_first_stmt (stmts);
2583 : }
2584 : }
2585 : else
2586 : /* The expression is already available. */
2587 : result = val;
2588 : }
2589 292677 : 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 147114 : vn_ssa_aux_t result_info = VN_INFO (result);
2595 147114 : result_info->valnum = result;
2596 147114 : result_info->value_id = get_next_value_id ();
2597 147114 : result_info->visited = 1;
2598 147114 : gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
2599 : new_stmt);
2600 147114 : 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 147114 : vn_nary_op_t nary = NULL;
2605 147114 : vn_nary_op_lookup_stmt (new_stmt, &nary);
2606 147114 : 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 147114 : unsigned int length = vn_nary_length_from_stmt (new_stmt);
2621 147114 : vn_nary_op_t vno1
2622 147114 : = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack);
2623 147114 : vno1->value_id = result_info->value_id;
2624 147114 : vno1->length = length;
2625 147114 : vno1->predicated_values = 0;
2626 147114 : vno1->u.result = result;
2627 147114 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (new_stmt));
2628 147114 : vn_nary_op_insert_into (vno1, valid_info->nary);
2629 : /* Also do not link it into the undo chain. */
2630 147114 : last_inserted_nary = vno1->next;
2631 147114 : vno1->next = (vn_nary_op_t)(void *)-1;
2632 : }
2633 147114 : 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 18890458 : 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 194342 : 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 7564131 : vn_nary_simplify (vn_nary_op_t nary)
2660 : {
2661 7564131 : 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 7563585 : || nary->opcode == CONSTRUCTOR)
2665 : return NULL_TREE;
2666 7561092 : gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
2667 7561092 : nary->type, nary->length);
2668 7561092 : memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
2669 7561092 : 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 27395126 : for (unsigned i = 0; i < op.num_ops; ++i)
2673 12273024 : if (TREE_CODE (op.ops[i]) == SSA_NAME
2674 12273024 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op.ops[i]))
2675 : return res;
2676 7561010 : if (op.code.is_tree_code ()
2677 7561010 : && op.num_ops <= nary->length
2678 15121220 : && (tree_code) op.code != CONSTRUCTOR)
2679 : {
2680 7560209 : nary->opcode = (tree_code) op.code;
2681 7560209 : nary->length = op.num_ops;
2682 19831514 : for (unsigned i = 0; i < op.num_ops; ++i)
2683 12271305 : 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 12623766 : class rpo_elim : public eliminate_dom_walker
2731 : {
2732 : public:
2733 6311883 : rpo_elim(basic_block entry_)
2734 6311883 : : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
2735 12623766 : 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 6986959 : adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
2753 : tree base2, poly_int64 *offset2)
2754 : {
2755 6986959 : poly_int64 soff;
2756 6986959 : if (TREE_CODE (base1) == MEM_REF
2757 3183077 : && TREE_CODE (base2) == MEM_REF)
2758 : {
2759 2554848 : if (mem_ref_offset (base1).to_shwi (&soff))
2760 : {
2761 2554848 : base1 = TREE_OPERAND (base1, 0);
2762 2554848 : *offset1 += soff * BITS_PER_UNIT;
2763 : }
2764 2554848 : if (mem_ref_offset (base2).to_shwi (&soff))
2765 : {
2766 2554848 : base2 = TREE_OPERAND (base2, 0);
2767 2554848 : *offset2 += soff * BITS_PER_UNIT;
2768 : }
2769 2554848 : return operand_equal_p (base1, base2, 0);
2770 : }
2771 4432111 : 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 43316195 : vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
2783 : translate_flags *disambiguate_only)
2784 : {
2785 43316195 : vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2786 43316195 : vn_reference_t vr = data->vr;
2787 43316195 : gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
2788 43316195 : tree base = ao_ref_base (ref);
2789 43316195 : HOST_WIDE_INT offseti = 0, maxsizei, sizei = 0;
2790 43316195 : static vec<vn_reference_op_s> lhs_ops;
2791 43316195 : ao_ref lhs_ref;
2792 43316195 : bool lhs_ref_ok = false;
2793 43316195 : poly_int64 copy_size;
2794 :
2795 : /* First try to disambiguate after value-replacing in the definitions LHS. */
2796 43316195 : if (is_gimple_assign (def_stmt))
2797 : {
2798 21221137 : tree lhs = gimple_assign_lhs (def_stmt);
2799 21221137 : bool valueized_anything = false;
2800 : /* Avoid re-allocation overhead. */
2801 21221137 : lhs_ops.truncate (0);
2802 21221137 : basic_block saved_rpo_bb = vn_context_bb;
2803 21221137 : vn_context_bb = gimple_bb (def_stmt);
2804 21221137 : if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE)
2805 : {
2806 13870599 : copy_reference_ops_from_ref (lhs, &lhs_ops);
2807 13870599 : valueize_refs_1 (&lhs_ops, &valueized_anything, true);
2808 : }
2809 21221137 : vn_context_bb = saved_rpo_bb;
2810 21221137 : ao_ref_init (&lhs_ref, lhs);
2811 21221137 : lhs_ref_ok = true;
2812 21221137 : if (valueized_anything
2813 2033477 : && ao_ref_init_from_vn_reference
2814 2033477 : (&lhs_ref, ao_ref_alias_set (&lhs_ref),
2815 2033477 : ao_ref_base_alias_set (&lhs_ref), TREE_TYPE (lhs), lhs_ops)
2816 23254614 : && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
2817 : {
2818 1737471 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2819 6675015 : 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 19483666 : if (!data->redundant_store_removal_p
2828 10709972 : && gimple_clobber_p (def_stmt)
2829 20002637 : && !operand_equal_p (ao_ref_base (&lhs_ref), base, OEP_ADDRESS_OF))
2830 : {
2831 492686 : *disambiguate_only = TR_DISAMBIGUATE;
2832 492686 : 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 18990980 : if (!ref->ref
2838 : && lhs_ref_ok
2839 2733328 : && data->orig_ref.ref)
2840 : {
2841 : /* We want to use the non-valueized LHS for this, but avoid redundant
2842 : work. */
2843 1902661 : ao_ref *lref = &lhs_ref;
2844 1902661 : ao_ref lref_alt;
2845 1902661 : if (valueized_anything)
2846 : {
2847 115359 : ao_ref_init (&lref_alt, lhs);
2848 115359 : lref = &lref_alt;
2849 : }
2850 1902661 : if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
2851 : {
2852 313356 : *disambiguate_only = (valueized_anything
2853 156678 : ? TR_VALUEIZE_AND_DISAMBIGUATE
2854 : : TR_DISAMBIGUATE);
2855 156678 : 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 18834302 : if (!gimple_has_volatile_ops (def_stmt)
2864 17419250 : && ((is_gimple_reg_type (TREE_TYPE (lhs))
2865 12800140 : && types_compatible_p (TREE_TYPE (lhs), vr->type)
2866 9936063 : && !storage_order_barrier_p (lhs)
2867 9936063 : && !reverse_storage_order_for_component_p (lhs))
2868 7483191 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == CONSTRUCTOR)
2869 11015945 : && (ref->ref || data->orig_ref.ref)
2870 10541171 : && !data->mask
2871 10518600 : && data->partial_defs.is_empty ()
2872 10516245 : && multiple_p (get_object_alignment
2873 : (ref->ref ? ref->ref : data->orig_ref.ref),
2874 : ref->size)
2875 42087284 : && multiple_p (get_object_alignment (lhs), ref->size))
2876 : {
2877 10121912 : HOST_WIDE_INT offset2i, size2i;
2878 10121912 : poly_int64 offset = ref->offset;
2879 10121912 : poly_int64 maxsize = ref->max_size;
2880 :
2881 10121912 : gcc_assert (lhs_ref_ok);
2882 10121912 : tree base2 = ao_ref_base (&lhs_ref);
2883 10121912 : poly_int64 offset2 = lhs_ref.offset;
2884 10121912 : poly_int64 size2 = lhs_ref.size;
2885 10121912 : poly_int64 maxsize2 = lhs_ref.max_size;
2886 :
2887 10121912 : tree rhs = gimple_assign_rhs1 (def_stmt);
2888 10121912 : if (TREE_CODE (rhs) == CONSTRUCTOR)
2889 1050275 : 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 10121912 : if (data->same_val
2898 10121912 : && !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 9839003 : else if (!(*disambiguate_only > TR_TRANSLATE)
2903 3380349 : && base2
2904 3380349 : && known_eq (maxsize2, size2)
2905 2386670 : && adjust_offsets_for_equal_base_address (base, &offset,
2906 : base2, &offset2)
2907 1166137 : && offset2.is_constant (&offset2i)
2908 1166137 : && size2.is_constant (&size2i)
2909 1166137 : && maxsize.is_constant (&maxsizei)
2910 1166137 : && offset.is_constant (&offseti)
2911 11005140 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
2912 : size2i))
2913 : ;
2914 8768628 : else if (CONSTANT_CLASS_P (rhs))
2915 : {
2916 4222554 : if (dump_file && (dump_flags & TDF_DETAILS))
2917 : {
2918 2218 : fprintf (dump_file,
2919 : "Skipping possible redundant definition ");
2920 2218 : 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 4222554 : data->last_vuse_ptr = NULL;
2925 4222554 : data->same_val = rhs;
2926 4288180 : return NULL;
2927 : }
2928 : else
2929 : {
2930 4546074 : tree saved_vuse = vr->vuse;
2931 4546074 : hashval_t saved_hashcode = vr->hashcode;
2932 4546074 : if (vr->vuse)
2933 4546074 : vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2934 9092148 : vr->vuse = vuse_ssa_val (gimple_vuse (def_stmt));
2935 4546074 : if (vr->vuse)
2936 4546074 : vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2937 4546074 : 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 4546074 : vn_reference_lookup_1 (vr, &vnresult);
2943 : /* Need to restore vr->vuse and vr->hashcode. */
2944 4546074 : vr->vuse = saved_vuse;
2945 4546074 : vr->hashcode = saved_hashcode;
2946 4546074 : if (vnresult)
2947 : {
2948 249822 : if (TREE_CODE (rhs) == SSA_NAME)
2949 248301 : rhs = SSA_VAL (rhs);
2950 249822 : if (vnresult->result
2951 249822 : && operand_equal_p (vnresult->result, rhs, 0))
2952 65626 : return vnresult;
2953 : }
2954 : }
2955 : }
2956 : }
2957 22095058 : else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE
2958 19862970 : && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
2959 24214905 : && 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 5011634 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2970 : {
2971 3453010 : oldargs[i] = gimple_call_arg (def_stmt, i);
2972 3453010 : tree val = vn_valueize (oldargs[i]);
2973 3453010 : if (val != oldargs[i])
2974 : {
2975 128795 : gimple_call_set_arg (def_stmt, i, val);
2976 128795 : valueized_anything = true;
2977 : }
2978 : }
2979 1558624 : if (valueized_anything)
2980 : {
2981 99996 : bool res = call_may_clobber_ref_p_1 (as_a <gcall *> (def_stmt),
2982 : ref, data->tbaa_p);
2983 464234 : for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2984 264242 : gimple_call_set_arg (def_stmt, i, oldargs[i]);
2985 99996 : if (!res)
2986 : {
2987 31403 : *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2988 31403 : return NULL;
2989 : }
2990 : }
2991 : }
2992 :
2993 36609777 : 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 24399323 : if (!ref->max_size_known_p ())
2999 : return (void *)-1;
3000 :
3001 23968486 : poly_int64 offset = ref->offset;
3002 23968486 : 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 23968486 : if (is_gimple_reg_type (vr->type)
3008 23962673 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
3009 23872982 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
3010 90225 : && (integer_zerop (gimple_call_arg (def_stmt, 1))
3011 32457 : || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
3012 8936 : || (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 31135 : && offset.is_constant (&offseti)
3017 31135 : && ref->size.is_constant (&sizei)
3018 31135 : && (offseti % BITS_PER_UNIT == 0
3019 39 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST)))
3020 88903 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
3021 36571 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3022 36571 : && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
3023 24021389 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3024 29748 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
3025 : {
3026 52862 : tree base2;
3027 52862 : poly_int64 offset2, size2, maxsize2;
3028 52862 : bool reverse;
3029 52862 : tree ref2 = gimple_call_arg (def_stmt, 0);
3030 52862 : if (TREE_CODE (ref2) == SSA_NAME)
3031 : {
3032 29707 : ref2 = SSA_VAL (ref2);
3033 29707 : if (TREE_CODE (ref2) == SSA_NAME
3034 29707 : && (TREE_CODE (base) != MEM_REF
3035 19076 : || TREE_OPERAND (base, 0) != ref2))
3036 : {
3037 23385 : gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
3038 23385 : if (gimple_assign_single_p (def_stmt)
3039 23385 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3040 818 : ref2 = gimple_assign_rhs1 (def_stmt);
3041 : }
3042 : }
3043 52862 : if (TREE_CODE (ref2) == ADDR_EXPR)
3044 : {
3045 26898 : ref2 = TREE_OPERAND (ref2, 0);
3046 26898 : base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
3047 : &reverse);
3048 26898 : if (!known_size_p (maxsize2)
3049 26858 : || !known_eq (maxsize2, size2)
3050 53688 : || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
3051 52499 : return (void *)-1;
3052 : }
3053 25964 : else if (TREE_CODE (ref2) == SSA_NAME)
3054 : {
3055 25964 : poly_int64 soff;
3056 25964 : if (TREE_CODE (base) != MEM_REF
3057 44438 : || !(mem_ref_offset (base)
3058 44438 : << LOG2_BITS_PER_UNIT).to_shwi (&soff))
3059 21942 : return (void *)-1;
3060 18474 : offset += soff;
3061 18474 : offset2 = 0;
3062 18474 : if (TREE_OPERAND (base, 0) != ref2)
3063 : {
3064 15077 : gimple *def = SSA_NAME_DEF_STMT (ref2);
3065 15077 : if (is_gimple_assign (def)
3066 13653 : && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
3067 11803 : && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
3068 15732 : && poly_int_tree_p (gimple_assign_rhs2 (def)))
3069 : {
3070 625 : tree rhs2 = gimple_assign_rhs2 (def);
3071 625 : if (!(poly_offset_int::from (wi::to_poly_wide (rhs2),
3072 : SIGNED)
3073 625 : << LOG2_BITS_PER_UNIT).to_shwi (&offset2))
3074 : return (void *)-1;
3075 625 : ref2 = gimple_assign_rhs1 (def);
3076 625 : if (TREE_CODE (ref2) == SSA_NAME)
3077 625 : ref2 = SSA_VAL (ref2);
3078 : }
3079 : else
3080 : return (void *)-1;
3081 : }
3082 : }
3083 : else
3084 : return (void *)-1;
3085 27041 : tree len = gimple_call_arg (def_stmt, 2);
3086 27041 : HOST_WIDE_INT leni, offset2i;
3087 27041 : 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 27041 : if (!ranges_maybe_overlap_p (offset, maxsize, offset2,
3092 54082 : (wi::to_poly_offset (len)
3093 27041 : << LOG2_BITS_PER_UNIT)))
3094 : return NULL;
3095 54024 : if (data->partial_defs.is_empty ()
3096 26983 : && known_subrange_p (offset, maxsize, offset2,
3097 26983 : wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
3098 : {
3099 26481 : tree val;
3100 26481 : if (integer_zerop (gimple_call_arg (def_stmt, 1)))
3101 21505 : val = build_zero_cst (vr->type);
3102 4976 : else if (INTEGRAL_TYPE_P (vr->type)
3103 3836 : && known_eq (ref->size, 8)
3104 7961 : && 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 1991 : unsigned buflen
3117 1991 : = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)) + 1;
3118 1991 : if (INTEGRAL_TYPE_P (vr->type)
3119 1991 : && TYPE_MODE (vr->type) != BLKmode)
3120 1700 : buflen = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (vr->type)) + 1;
3121 1991 : unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
3122 1991 : memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
3123 : buflen);
3124 1991 : 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 1991 : 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 1991 : val = native_interpret_expr (vr->type, buf, buflen);
3147 1991 : if (!val)
3148 : return (void *)-1;
3149 : }
3150 26481 : return data->finish (0, 0, val);
3151 : }
3152 : /* For now handle clearing memory with partial defs. */
3153 560 : else if (known_eq (ref->size, maxsize)
3154 484 : && integer_zerop (gimple_call_arg (def_stmt, 1))
3155 201 : && tree_fits_poly_int64_p (len)
3156 197 : && tree_to_poly_int64 (len).is_constant (&leni)
3157 197 : && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
3158 197 : && offset.is_constant (&offseti)
3159 197 : && offset2.is_constant (&offset2i)
3160 197 : && maxsize.is_constant (&maxsizei)
3161 560 : && ranges_known_overlap_p (offseti, maxsizei, offset2i,
3162 560 : leni << LOG2_BITS_PER_UNIT))
3163 : {
3164 197 : pd_data pd;
3165 197 : pd.rhs = build_constructor (NULL_TREE, NULL);
3166 197 : pd.rhs_off = 0;
3167 197 : pd.offset = offset2i;
3168 197 : pd.size = leni << LOG2_BITS_PER_UNIT;
3169 197 : return data->push_partial_def (pd, 0, 0, offseti, maxsizei);
3170 : }
3171 : }
3172 :
3173 : /* 2) Assignment from an empty CONSTRUCTOR. */
3174 23915624 : else if (is_gimple_reg_type (vr->type)
3175 23909811 : && gimple_assign_single_p (def_stmt)
3176 7891758 : && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
3177 2001458 : && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0
3178 25917082 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)))
3179 : {
3180 2001426 : tree base2;
3181 2001426 : poly_int64 offset2, size2, maxsize2;
3182 2001426 : HOST_WIDE_INT offset2i, size2i;
3183 2001426 : gcc_assert (lhs_ref_ok);
3184 2001426 : base2 = ao_ref_base (&lhs_ref);
3185 2001426 : offset2 = lhs_ref.offset;
3186 2001426 : size2 = lhs_ref.size;
3187 2001426 : maxsize2 = lhs_ref.max_size;
3188 2001426 : if (known_size_p (maxsize2)
3189 2001388 : && known_eq (maxsize2, size2)
3190 4002768 : && adjust_offsets_for_equal_base_address (base, &offset,
3191 : base2, &offset2))
3192 : {
3193 1973178 : if (data->partial_defs.is_empty ()
3194 1969602 : && known_subrange_p (offset, maxsize, offset2, size2))
3195 : {
3196 : /* While technically undefined behavior do not optimize
3197 : a full read from a clobber. */
3198 1968689 : if (gimple_clobber_p (def_stmt))
3199 1973128 : return (void *)-1;
3200 1000943 : tree val = build_zero_cst (vr->type);
3201 1000943 : return data->finish (ao_ref_alias_set (&lhs_ref),
3202 1000943 : ao_ref_base_alias_set (&lhs_ref), val);
3203 : }
3204 4489 : else if (known_eq (ref->size, maxsize)
3205 4439 : && maxsize.is_constant (&maxsizei)
3206 4439 : && offset.is_constant (&offseti)
3207 4439 : && offset2.is_constant (&offset2i)
3208 4439 : && size2.is_constant (&size2i)
3209 4489 : && 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 4439 : pd_data pd;
3216 4439 : pd.rhs = gimple_assign_rhs1 (def_stmt);
3217 4439 : pd.rhs_off = 0;
3218 4439 : pd.offset = offset2i;
3219 4439 : pd.size = size2i;
3220 4439 : 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 21914198 : else if (known_eq (ref->size, maxsize)
3230 21388684 : && is_gimple_reg_type (vr->type)
3231 21382871 : && !reverse_storage_order_for_component_p (vr->operands)
3232 21380112 : && !contains_storage_order_barrier_p (vr->operands)
3233 21380112 : && gimple_assign_single_p (def_stmt)
3234 5567184 : && !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 5564223 : && maxsize.is_constant (&maxsizei)
3241 5564223 : && offset.is_constant (&offseti)
3242 27478421 : && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
3243 4689680 : || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
3244 1902736 : && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
3245 : {
3246 891360 : tree lhs = gimple_assign_lhs (def_stmt);
3247 891360 : tree base2;
3248 891360 : poly_int64 offset2, size2, maxsize2;
3249 891360 : HOST_WIDE_INT offset2i, size2i;
3250 891360 : bool reverse;
3251 891360 : gcc_assert (lhs_ref_ok);
3252 891360 : base2 = ao_ref_base (&lhs_ref);
3253 891360 : offset2 = lhs_ref.offset;
3254 891360 : size2 = lhs_ref.size;
3255 891360 : maxsize2 = lhs_ref.max_size;
3256 891360 : reverse = reverse_storage_order_for_component_p (lhs);
3257 891360 : if (base2
3258 891360 : && !reverse
3259 890532 : && !storage_order_barrier_p (lhs)
3260 890532 : && known_eq (maxsize2, size2)
3261 857686 : && adjust_offsets_for_equal_base_address (base, &offset,
3262 : base2, &offset2)
3263 85883 : && offset.is_constant (&offseti)
3264 85883 : && offset2.is_constant (&offset2i)
3265 891360 : && size2.is_constant (&size2i))
3266 : {
3267 85883 : if (data->partial_defs.is_empty ()
3268 68804 : && known_subrange_p (offseti, maxsizei, offset2, size2))
3269 : {
3270 : /* We support up to 512-bit values (for V8DFmode). */
3271 44555 : unsigned char buffer[65];
3272 44555 : int len;
3273 :
3274 44555 : tree rhs = gimple_assign_rhs1 (def_stmt);
3275 44555 : if (TREE_CODE (rhs) == SSA_NAME)
3276 1783 : rhs = SSA_VAL (rhs);
3277 89110 : len = native_encode_expr (rhs,
3278 : buffer, sizeof (buffer) - 1,
3279 44555 : (offseti - offset2i) / BITS_PER_UNIT);
3280 44555 : if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
3281 : {
3282 41533 : tree type = vr->type;
3283 41533 : unsigned char *buf = buffer;
3284 41533 : unsigned int amnt = 0;
3285 : /* Make sure to interpret in a type that has a range
3286 : covering the whole access size. */
3287 41533 : if (INTEGRAL_TYPE_P (vr->type)
3288 41533 : && maxsizei != TYPE_PRECISION (vr->type))
3289 : {
3290 1009 : bool uns = TYPE_UNSIGNED (type);
3291 1008 : if (BITINT_TYPE_P (vr->type)
3292 1010 : && maxsizei > MAX_FIXED_MODE_SIZE)
3293 1 : type = build_bitint_type (maxsizei, uns);
3294 : else
3295 1008 : type = build_nonstandard_integer_type (maxsizei, uns);
3296 : }
3297 41533 : 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 41533 : amnt = ((unsigned HOST_WIDE_INT) offset2i
3347 41533 : - offseti) % BITS_PER_UNIT;
3348 41533 : 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 41533 : 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 41533 : if (val
3361 41531 : && type != vr->type)
3362 : {
3363 1009 : if (! int_fits_type_p (val, vr->type))
3364 : val = NULL_TREE;
3365 : else
3366 1009 : val = fold_convert (vr->type, val);
3367 : }
3368 :
3369 41531 : if (val)
3370 41531 : return data->finish (ao_ref_alias_set (&lhs_ref),
3371 41531 : ao_ref_base_alias_set (&lhs_ref), val);
3372 : }
3373 : }
3374 41328 : else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
3375 : size2i))
3376 : {
3377 41328 : pd_data pd;
3378 41328 : tree rhs = gimple_assign_rhs1 (def_stmt);
3379 41328 : if (TREE_CODE (rhs) == SSA_NAME)
3380 2230 : rhs = SSA_VAL (rhs);
3381 41328 : pd.rhs = rhs;
3382 41328 : pd.rhs_off = 0;
3383 41328 : pd.offset = offset2i;
3384 41328 : pd.size = size2i;
3385 41328 : 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 21022838 : else if (known_eq (ref->size, maxsize)
3395 20497324 : && is_gimple_reg_type (vr->type)
3396 20491511 : && !reverse_storage_order_for_component_p (vr->operands)
3397 20488752 : && !contains_storage_order_barrier_p (vr->operands)
3398 20488752 : && gimple_assign_single_p (def_stmt)
3399 4675824 : && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
3400 25695701 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
3401 : {
3402 1885919 : tree lhs = gimple_assign_lhs (def_stmt);
3403 1885919 : tree base2;
3404 1885919 : poly_int64 offset2, size2, maxsize2;
3405 1885919 : HOST_WIDE_INT offset2i, size2i, offseti;
3406 1885919 : bool reverse;
3407 1885919 : gcc_assert (lhs_ref_ok);
3408 1885919 : base2 = ao_ref_base (&lhs_ref);
3409 1885919 : offset2 = lhs_ref.offset;
3410 1885919 : size2 = lhs_ref.size;
3411 1885919 : maxsize2 = lhs_ref.max_size;
3412 1885919 : reverse = reverse_storage_order_for_component_p (lhs);
3413 1885919 : tree def_rhs = gimple_assign_rhs1 (def_stmt);
3414 1885919 : if (!reverse
3415 1885707 : && !storage_order_barrier_p (lhs)
3416 1885707 : && known_size_p (maxsize2)
3417 1860402 : && known_eq (maxsize2, size2)
3418 3627166 : && adjust_offsets_for_equal_base_address (base, &offset,
3419 : base2, &offset2))
3420 : {
3421 85967 : if (data->partial_defs.is_empty ()
3422 79472 : && 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 55301 : && (! INTEGRAL_TYPE_P (vr->type)
3428 41091 : || 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 51421 : || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
3434 : {
3435 91288 : 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 85874 : ao_ref_base_alias_set (&lhs_ref), val);
3454 : }
3455 39232 : else if (maxsize.is_constant (&maxsizei)
3456 39232 : && offset.is_constant (&offseti)
3457 39232 : && offset2.is_constant (&offset2i)
3458 39232 : && size2.is_constant (&size2i)
3459 39232 : && ranges_known_overlap_p (offset, maxsize, offset2, size2))
3460 : {
3461 39232 : pd_data pd;
3462 39232 : pd.rhs = SSA_VAL (def_rhs);
3463 39232 : pd.rhs_off = 0;
3464 39232 : pd.offset = offset2i;
3465 39232 : pd.size = size2i;
3466 39232 : 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 19136919 : else if (known_eq (ref->size, maxsize)
3477 18611405 : && is_gimple_reg_type (vr->type)
3478 18605592 : && !reverse_storage_order_for_component_p (vr->operands)
3479 18602833 : && !contains_storage_order_barrier_p (vr->operands)
3480 18602833 : && is_gimple_call (def_stmt)
3481 14972315 : && gimple_call_internal_p (def_stmt)
3482 19453026 : && 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 : return NULL;
3603 : }
3604 : }
3605 : }
3606 :
3607 : /* 5) For aggregate copies translate the reference through them if
3608 : the copy kills ref. */
3609 19136883 : else if (data->vn_walk_kind == VN_WALKREWRITE
3610 15457428 : && gimple_assign_single_p (def_stmt)
3611 2577242 : && !gimple_has_volatile_ops (def_stmt)
3612 21711827 : && (DECL_P (gimple_assign_rhs1 (def_stmt))
3613 1985708 : || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
3614 1572674 : || handled_component_p (gimple_assign_rhs1 (def_stmt))))
3615 : {
3616 2365896 : tree base2;
3617 2365896 : int i, j, k;
3618 2365896 : auto_vec<vn_reference_op_s> rhs;
3619 2365896 : vn_reference_op_t vro;
3620 2365896 : ao_ref r;
3621 :
3622 2365896 : gcc_assert (lhs_ref_ok);
3623 :
3624 : /* See if the assignment kills REF. */
3625 2365896 : base2 = ao_ref_base (&lhs_ref);
3626 2365896 : if (!lhs_ref.max_size_known_p ()
3627 2365321 : || (base != base2
3628 89321 : && (TREE_CODE (base) != MEM_REF
3629 73595 : || TREE_CODE (base2) != MEM_REF
3630 56268 : || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
3631 19424 : || !tree_int_cst_equal (TREE_OPERAND (base, 1),
3632 19424 : TREE_OPERAND (base2, 1))))
3633 4659653 : || !stmt_kills_ref_p (def_stmt, ref))
3634 : 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 1968630 : poly_int64 extra_off = 0;
3639 1968630 : i = vr->operands.length () - 1;
3640 1968630 : j = lhs_ops.length () - 1;
3641 :
3642 : /* The base should be always equal due to the above check. */
3643 1968630 : if (! vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3644 : return (void *)-1;
3645 1968370 : i--, j--;
3646 :
3647 : /* The 2nd component should always exist and be a MEM_REF. */
3648 1968370 : if (!(i >= 0 && j >= 0))
3649 : ;
3650 1968370 : else if (vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3651 933133 : i--, j--;
3652 1035237 : else if (vr->operands[i].opcode == MEM_REF
3653 1033733 : && lhs_ops[j].opcode == MEM_REF
3654 1033733 : && known_ne (lhs_ops[j].off, -1)
3655 2068970 : && known_ne (vr->operands[i].off, -1))
3656 : {
3657 1033733 : 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 1033733 : if (i > 0)
3663 : {
3664 114474 : int temi = i - 1;
3665 114474 : poly_int64 tem_extra_off = extra_off + vr->operands[i].off;
3666 114474 : while (temi >= 0
3667 249247 : && known_ne (vr->operands[temi].off, -1))
3668 : {
3669 136266 : if (vr->operands[temi].type
3670 136266 : && lhs_ops[j].type
3671 272532 : && (TYPE_MAIN_VARIANT (vr->operands[temi].type)
3672 136266 : == TYPE_MAIN_VARIANT (lhs_ops[j].type)))
3673 : {
3674 1493 : i = temi;
3675 : /* Strip the component that was type matched to
3676 : the MEM_REF. */
3677 1493 : extra_off = (tem_extra_off
3678 1493 : + vr->operands[i].off - lhs_ops[j].off);
3679 1493 : i--, j--;
3680 : /* Strip further equal components. */
3681 1493 : found = true;
3682 1493 : break;
3683 : }
3684 134773 : tem_extra_off += vr->operands[temi].off;
3685 134773 : temi--;
3686 : }
3687 : }
3688 1033733 : if (!found && j > 0)
3689 : {
3690 33318 : int temj = j - 1;
3691 33318 : poly_int64 tem_extra_off = extra_off - lhs_ops[j].off;
3692 33318 : while (temj >= 0
3693 63757 : && known_ne (lhs_ops[temj].off, -1))
3694 : {
3695 35571 : if (vr->operands[i].type
3696 35571 : && lhs_ops[temj].type
3697 71142 : && (TYPE_MAIN_VARIANT (vr->operands[i].type)
3698 35571 : == TYPE_MAIN_VARIANT (lhs_ops[temj].type)))
3699 : {
3700 5132 : j = temj;
3701 : /* Strip the component that was type matched to
3702 : the MEM_REF. */
3703 5132 : extra_off = (tem_extra_off
3704 5132 : + vr->operands[i].off - lhs_ops[j].off);
3705 5132 : i--, j--;
3706 : /* Strip further equal components. */
3707 5132 : found = true;
3708 5132 : break;
3709 : }
3710 30439 : tem_extra_off += -lhs_ops[temj].off;
3711 30439 : 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 1033733 : if (!found)
3718 : {
3719 : while (j >= 0
3720 2084269 : && known_ne (lhs_ops[j].off, -1))
3721 : {
3722 1057161 : extra_off += -lhs_ops[j].off;
3723 1057161 : j--;
3724 : }
3725 1027108 : if (j != -1)
3726 : return (void *)-1;
3727 : while (i >= 0
3728 2181634 : && known_ne (vr->operands[i].off, -1))
3729 : {
3730 : /* Punt if the additional ops contain a storage order
3731 : barrier. */
3732 1154526 : if (vr->operands[i].opcode == VIEW_CONVERT_EXPR
3733 1154526 : && vr->operands[i].reverse)
3734 : break;
3735 1154526 : extra_off += vr->operands[i].off;
3736 1154526 : i--;
3737 : }
3738 1027108 : 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 1966072 : while (j >= 0 && i >= 0
3753 1966072 : && vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3754 : {
3755 25666 : i--;
3756 25666 : 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 1940406 : if (j != -1)
3764 : return (void *)-1;
3765 :
3766 : /* Punt if the additional ops contain a storage order barrier. */
3767 3033500 : for (k = i; k >= 0; k--)
3768 : {
3769 1096044 : vro = &vr->operands[k];
3770 1096044 : 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 1937456 : tree rhs1 = gimple_assign_rhs1 (def_stmt);
3776 1937456 : copy_reference_ops_from_ref (rhs1, &rhs);
3777 :
3778 : /* Apply an extra offset to the inner MEM_REF of the RHS. */
3779 1937456 : bool force_no_tbaa = false;
3780 1937456 : if (maybe_ne (extra_off, 0))
3781 : {
3782 740021 : if (rhs.length () < 2)
3783 : return (void *)-1;
3784 740021 : int ix = rhs.length () - 2;
3785 740021 : if (rhs[ix].opcode != MEM_REF
3786 740021 : || known_eq (rhs[ix].off, -1))
3787 : return (void *)-1;
3788 740003 : rhs[ix].off += extra_off;
3789 740003 : rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
3790 740003 : 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 740003 : 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 1937438 : if (!data->saved_operands.exists ())
3801 1824541 : data->saved_operands = vr->operands.copy ();
3802 :
3803 : /* We need to pre-pend vr->operands[0..i] to rhs. */
3804 1937438 : vec<vn_reference_op_s> old = vr->operands;
3805 5812314 : if (i + 1 + rhs.length () > vr->operands.length ())
3806 1146684 : vr->operands.safe_grow (i + 1 + rhs.length (), true);
3807 : else
3808 790754 : vr->operands.truncate (i + 1 + rhs.length ());
3809 7009351 : FOR_EACH_VEC_ELT (rhs, j, vro)
3810 5071913 : vr->operands[i + 1 + j] = *vro;
3811 1937438 : valueize_refs (&vr->operands);
3812 3874876 : if (old == shared_lookup_references)
3813 1937438 : shared_lookup_references = vr->operands;
3814 1937438 : vr->hashcode = vn_reference_compute_hash (vr);
3815 :
3816 : /* Try folding the new reference to a constant. */
3817 1937438 : tree val = fully_constant_vn_reference_p (vr);
3818 1937438 : if (val)
3819 : {
3820 22159 : if (data->partial_defs.is_empty ())
3821 22150 : return data->finish (ao_ref_alias_set (&lhs_ref),
3822 22150 : 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 4281175 : if (!data->partial_defs.is_empty ())
3844 : return (void *)-1;
3845 :
3846 : /* Adjust *ref from the new operands. */
3847 1909445 : ao_ref rhs1_ref;
3848 1909445 : ao_ref_init (&rhs1_ref, rhs1);
3849 3093512 : if (!ao_ref_init_from_vn_reference (&r,
3850 : force_no_tbaa ? 0
3851 1184067 : : ao_ref_alias_set (&rhs1_ref),
3852 : force_no_tbaa ? 0
3853 1184067 : : ao_ref_base_alias_set (&rhs1_ref),
3854 : vr->type, vr->operands))
3855 : return (void *)-1;
3856 : /* This can happen with bitfields. */
3857 1909445 : 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 1909445 : *ref = r;
3870 1909445 : vr->offset = r.offset;
3871 1909445 : vr->max_size = r.max_size;
3872 :
3873 : /* Do not update last seen VUSE after translating. */
3874 1909445 : data->last_vuse_ptr = NULL;
3875 : /* Invalidate the original access path since it now contains
3876 : the wrong base. */
3877 1909445 : data->orig_ref.ref = NULL_TREE;
3878 : /* Use the alias-set of this LHS for recording an eventual result. */
3879 1909445 : if (data->first_set == -2)
3880 : {
3881 1798052 : data->first_set = ao_ref_alias_set (&lhs_ref);
3882 1798052 : data->first_base_set = ao_ref_base_alias_set (&lhs_ref);
3883 : }
3884 :
3885 : /* Keep looking for the adjusted *REF / VR pair. */
3886 : return NULL;
3887 2365896 : }
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 16770987 : else if (data->vn_walk_kind == VN_WALKREWRITE
3894 13091532 : && is_gimple_reg_type (vr->type)
3895 : /* ??? Handle BCOPY as well. */
3896 13085719 : && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
3897 13016048 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
3898 13015625 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
3899 13014449 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
3900 13014207 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
3901 12988310 : || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
3902 97737 : && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3903 85599 : || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
3904 97701 : && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
3905 69258 : || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
3906 97686 : && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), ©_size)
3907 55860 : || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3908 55860 : && 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 16815414 : && data->partial_defs.is_empty ())
3912 : {
3913 43729 : tree lhs, rhs;
3914 43729 : ao_ref r;
3915 43729 : poly_int64 rhs_offset, lhs_offset;
3916 43729 : vn_reference_op_s op;
3917 43729 : poly_uint64 mem_offset;
3918 43729 : poly_int64 at, byte_maxsize;
3919 :
3920 : /* Only handle non-variable, addressable refs. */
3921 43729 : if (maybe_ne (ref->size, maxsize)
3922 43198 : || !multiple_p (offset, BITS_PER_UNIT, &at)
3923 86991 : || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize))
3924 : return (void *)-1;
3925 :
3926 : /* Extract a pointer base and an offset for the destination. */
3927 43198 : lhs = gimple_call_arg (def_stmt, 0);
3928 43198 : lhs_offset = 0;
3929 43198 : if (TREE_CODE (lhs) == SSA_NAME)
3930 : {
3931 32776 : lhs = vn_valueize (lhs);
3932 32776 : if (TREE_CODE (lhs) == SSA_NAME)
3933 : {
3934 32439 : gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
3935 32439 : if (gimple_assign_single_p (def_stmt)
3936 32439 : && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3937 2490 : lhs = gimple_assign_rhs1 (def_stmt);
3938 : }
3939 : }
3940 43198 : if (TREE_CODE (lhs) == ADDR_EXPR)
3941 : {
3942 18644 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
3943 18347 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (lhs))))
3944 : return (void *)-1;
3945 13109 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0),
3946 : &lhs_offset);
3947 13109 : if (!tem)
3948 : return (void *)-1;
3949 12397 : if (TREE_CODE (tem) == MEM_REF
3950 12397 : && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3951 : {
3952 1778 : lhs = TREE_OPERAND (tem, 0);
3953 1778 : if (TREE_CODE (lhs) == SSA_NAME)
3954 1778 : lhs = vn_valueize (lhs);
3955 1778 : lhs_offset += mem_offset;
3956 : }
3957 10619 : else if (DECL_P (tem))
3958 10619 : lhs = build_fold_addr_expr (tem);
3959 : else
3960 : return (void *)-1;
3961 : }
3962 42346 : if (TREE_CODE (lhs) != SSA_NAME
3963 10620 : && TREE_CODE (lhs) != ADDR_EXPR)
3964 : return (void *)-1;
3965 :
3966 : /* Extract a pointer base and an offset for the source. */
3967 42346 : rhs = gimple_call_arg (def_stmt, 1);
3968 42346 : rhs_offset = 0;
3969 42346 : if (TREE_CODE (rhs) == SSA_NAME)
3970 19830 : rhs = vn_valueize (rhs);
3971 42346 : if (TREE_CODE (rhs) == ADDR_EXPR)
3972 : {
3973 35347 : if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (rhs)))
3974 24771 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_TYPE (rhs))))
3975 : return (void *)-1;
3976 24143 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0),
3977 : &rhs_offset);
3978 24143 : if (!tem)
3979 : return (void *)-1;
3980 24143 : if (TREE_CODE (tem) == MEM_REF
3981 24143 : && 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 24143 : else if (DECL_P (tem)
3987 17686 : || TREE_CODE (tem) == STRING_CST)
3988 24143 : rhs = build_fold_addr_expr (tem);
3989 : else
3990 : return (void *)-1;
3991 : }
3992 42346 : if (TREE_CODE (rhs) == SSA_NAME)
3993 18203 : rhs = SSA_VAL (rhs);
3994 24143 : 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 42346 : if (TREE_CODE (base) == MEM_REF)
3999 : {
4000 15855 : if (TREE_OPERAND (base, 0) != lhs
4001 15855 : || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset))
4002 : return (void *) -1;
4003 13133 : at += mem_offset;
4004 : }
4005 26491 : else if (!DECL_P (base)
4006 25543 : || TREE_CODE (lhs) != ADDR_EXPR
4007 35922 : || 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 13133 : 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 13100 : 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 12481 : if (!data->saved_operands.exists ())
4021 12048 : data->saved_operands = vr->operands.copy ();
4022 :
4023 : /* Make room for 2 operands in the new reference. */
4024 12481 : 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 12481 : vr->operands.truncate (2);
4033 :
4034 : /* The looked-through reference is a simple MEM_REF. */
4035 12481 : memset (&op, 0, sizeof (op));
4036 12481 : op.type = vr->type;
4037 12481 : op.opcode = MEM_REF;
4038 12481 : op.op0 = build_int_cst (ptr_type_node, at - lhs_offset + rhs_offset);
4039 12481 : op.off = at - lhs_offset + rhs_offset;
4040 12481 : vr->operands[0] = op;
4041 12481 : op.type = TREE_TYPE (rhs);
4042 12481 : op.opcode = TREE_CODE (rhs);
4043 12481 : op.op0 = rhs;
4044 12481 : op.off = -1;
4045 12481 : vr->operands[1] = op;
4046 12481 : vr->hashcode = vn_reference_compute_hash (vr);
4047 :
4048 : /* Try folding the new reference to a constant. */
4049 12481 : tree val = fully_constant_vn_reference_p (vr);
4050 12481 : if (val)
4051 3193 : return data->finish (0, 0, val);
4052 :
4053 : /* Adjust *ref from the new operands. */
4054 9288 : 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 9288 : if (maybe_ne (ref->size, r.size))
4058 : return (void *)-1;
4059 9288 : *ref = r;
4060 9288 : vr->offset = r.offset;
4061 9288 : vr->max_size = r.max_size;
4062 :
4063 : /* Do not update last seen VUSE after translating. */
4064 9288 : data->last_vuse_ptr = NULL;
4065 : /* Invalidate the original access path since it now contains
4066 : the wrong base. */
4067 9288 : data->orig_ref.ref = NULL_TREE;
4068 : /* Use the alias-set of this stmt for recording an eventual result. */
4069 9288 : if (data->first_set == -2)
4070 : {
4071 8906 : data->first_set = 0;
4072 8906 : data->first_base_set = 0;
4073 : }
4074 :
4075 : /* Keep looking for the adjusted *REF / VR pair. */
4076 : 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 124589417 : vn_is_backedge (edge e, void *)
4087 : {
4088 : /* During PRE elimination we no longer have access to this info. */
4089 124589417 : return (!vn_bb_to_rpo
4090 124589417 : || 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 4855276 : vn_reference_operands_for_lookup (tree op)
4099 : {
4100 4855276 : bool valueized;
4101 4855276 : 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 7950521 : 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 7950521 : struct vn_reference_s vr1;
4116 7950521 : vn_reference_t tmp;
4117 7950521 : tree cst;
4118 :
4119 7950521 : if (!vnresult)
4120 0 : vnresult = &tmp;
4121 7950521 : *vnresult = NULL;
4122 :
4123 7950521 : vr1.vuse = vuse_ssa_val (vuse);
4124 7950521 : shared_lookup_references.truncate (0);
4125 15901042 : shared_lookup_references.safe_grow (operands.length (), true);
4126 7950521 : memcpy (shared_lookup_references.address (),
4127 7950521 : operands.address (),
4128 : sizeof (vn_reference_op_s)
4129 7950521 : * operands.length ());
4130 7950521 : bool valueized_p;
4131 7950521 : valueize_refs_1 (&shared_lookup_references, &valueized_p);
4132 7950521 : vr1.operands = shared_lookup_references;
4133 7950521 : vr1.type = type;
4134 7950521 : vr1.set = set;
4135 7950521 : 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 7950521 : vr1.offset = 0;
4139 7950521 : vr1.max_size = -1;
4140 7950521 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4141 7950521 : if ((cst = fully_constant_vn_reference_p (&vr1)))
4142 : return cst;
4143 :
4144 7930675 : vn_reference_lookup_1 (&vr1, vnresult);
4145 7930675 : if (!*vnresult
4146 3061860 : && kind != VN_NOWALK
4147 3061860 : && vr1.vuse)
4148 : {
4149 3032013 : ao_ref r;
4150 3032013 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4151 3032013 : vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE,
4152 3032013 : false);
4153 3032013 : vec<vn_reference_op_s> ops_for_ref;
4154 3032013 : if (!valueized_p)
4155 2936778 : 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 190470 : ops_for_ref.create (operands.length ());
4162 190470 : ops_for_ref.quick_grow (operands.length ());
4163 95235 : memcpy (ops_for_ref.address (),
4164 95235 : operands.address (),
4165 : sizeof (vn_reference_op_s)
4166 95235 : * operands.length ());
4167 95235 : valueize_refs_1 (&ops_for_ref, &valueized_p, true);
4168 : }
4169 3032013 : if (ao_ref_init_from_vn_reference (&r, set, base_set, type,
4170 : ops_for_ref))
4171 2961089 : *vnresult
4172 2961089 : = ((vn_reference_t)
4173 2961089 : 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 6064026 : if (ops_for_ref != shared_lookup_references)
4177 95235 : ops_for_ref.release ();
4178 6064026 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4179 3032013 : if (*vnresult
4180 438098 : && data.same_val
4181 3032013 : && (!(*vnresult)->result
4182 0 : || !operand_equal_p ((*vnresult)->result, data.same_val)))
4183 : {
4184 0 : *vnresult = NULL;
4185 0 : return NULL_TREE;
4186 : }
4187 3032013 : }
4188 :
4189 7930675 : if (*vnresult)
4190 5306913 : 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 2277378 : vn_pp_nary_for_addr (const vec<vn_reference_op_s>& operands, tree ops[2])
4200 : {
4201 4554756 : 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 7390439 : for (i = 1; operands.iterate (i, &vro); ++i)
4207 : {
4208 7390439 : if (vro->opcode == SSA_NAME)
4209 : break;
4210 5164024 : else if (known_eq (vro->off, -1))
4211 : break;
4212 5113061 : off += vro->off;
4213 : }
4214 2277378 : if (i == operands.length () - 1
4215 2226415 : && 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 3753665 : && (off.coeffs[0]
4220 1476287 : == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
4221 : {
4222 1475747 : gcc_assert (operands[i-1].opcode == MEM_REF);
4223 1475747 : ops[0] = operands[i].op0;
4224 1475747 : ops[1] = wide_int_to_tree (sizetype, off);
4225 1475747 : 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 103102645 : 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 103102645 : vec<vn_reference_op_s> operands;
4250 103102645 : struct vn_reference_s vr1;
4251 103102645 : bool valueized_anything;
4252 :
4253 103102645 : if (vnresult)
4254 102700934 : *vnresult = NULL;
4255 :
4256 103102645 : vr1.vuse = vuse_ssa_val (vuse);
4257 206205290 : vr1.operands = operands
4258 103102645 : = 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 103102645 : if ((cfun->curr_properties & PROP_objsz)
4263 74817915 : && operands[0].opcode == ADDR_EXPR
4264 104245964 : && operands.last ().opcode == SSA_NAME)
4265 : {
4266 1108767 : tree ops[2];
4267 1108767 : if (vn_pp_nary_for_addr (operands, ops))
4268 : {
4269 719421 : tree res = vn_nary_op_lookup_pieces (2, POINTER_PLUS_EXPR,
4270 719421 : TREE_TYPE (op), ops, NULL);
4271 719421 : if (res)
4272 719421 : return res;
4273 719421 : return NULL_TREE;
4274 : }
4275 : }
4276 :
4277 102383224 : vr1.type = TREE_TYPE (op);
4278 102383224 : ao_ref op_ref;
4279 102383224 : ao_ref_init (&op_ref, op);
4280 102383224 : vr1.set = ao_ref_alias_set (&op_ref);
4281 102383224 : vr1.base_set = ao_ref_base_alias_set (&op_ref);
4282 102383224 : vr1.offset = 0;
4283 102383224 : vr1.max_size = -1;
4284 102383224 : vr1.hashcode = vn_reference_compute_hash (&vr1);
4285 102383224 : if (mask == NULL_TREE)
4286 102076671 : if (tree cst = fully_constant_vn_reference_p (&vr1))
4287 : return cst;
4288 :
4289 102367419 : if (kind != VN_NOWALK && vr1.vuse)
4290 : {
4291 59509965 : vn_reference_t wvnresult;
4292 59509965 : ao_ref r;
4293 59509965 : unsigned limit = param_sccvn_max_alias_queries_per_access;
4294 59509965 : auto_vec<vn_reference_op_s> ops_for_ref;
4295 59509965 : if (valueized_anything)
4296 : {
4297 4732054 : copy_reference_ops_from_ref (op, &ops_for_ref);
4298 4732054 : bool tem;
4299 4732054 : 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 59509965 : if (!valueized_anything
4304 59509965 : || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
4305 : vr1.type, ops_for_ref))
4306 : {
4307 54777911 : ao_ref_init (&r, op);
4308 : /* Record the extra info we're getting from the full ref. */
4309 54777911 : ao_ref_base (&r);
4310 54777911 : vr1.offset = r.offset;
4311 54777911 : vr1.max_size = r.max_size;
4312 : }
4313 59509965 : vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
4314 : last_vuse_ptr, kind, tbaa_p, mask,
4315 114287876 : redundant_store_removal_p);
4316 :
4317 59509965 : wvnresult
4318 : = ((vn_reference_t)
4319 59509965 : 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 119019930 : gcc_checking_assert (vr1.operands == shared_lookup_references);
4323 59509965 : if (wvnresult)
4324 : {
4325 8839448 : gcc_assert (mask == NULL_TREE);
4326 8839448 : if (data.same_val
4327 8839448 : && (!wvnresult->result
4328 67115 : || !operand_equal_p (wvnresult->result, data.same_val)))
4329 : return NULL_TREE;
4330 8792415 : if (vnresult)
4331 8789804 : *vnresult = wvnresult;
4332 8792415 : return wvnresult->result;
4333 : }
4334 50670517 : else if (mask)
4335 306553 : return data.masked_result;
4336 :
4337 : return NULL_TREE;
4338 59509965 : }
4339 :
4340 42857454 : if (last_vuse_ptr)
4341 1482850 : *last_vuse_ptr = vr1.vuse;
4342 42857454 : if (mask)
4343 : return NULL_TREE;
4344 42857454 : 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 9390191 : vn_reference_lookup_call (gcall *call, vn_reference_t *vnresult,
4352 : vn_reference_t vr)
4353 : {
4354 9390191 : if (vnresult)
4355 9390191 : *vnresult = NULL;
4356 :
4357 9390191 : tree vuse = gimple_vuse (call);
4358 :
4359 9390191 : vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
4360 9390191 : vr->operands = valueize_shared_reference_ops_from_call (call);
4361 9390191 : tree lhs = gimple_call_lhs (call);
4362 : /* For non-SSA return values the reference ops contain the LHS. */
4363 5092223 : vr->type = ((lhs && TREE_CODE (lhs) == SSA_NAME)
4364 14031052 : ? TREE_TYPE (lhs) : NULL_TREE);
4365 9390191 : vr->punned = false;
4366 9390191 : vr->set = 0;
4367 9390191 : vr->base_set = 0;
4368 9390191 : vr->offset = 0;
4369 9390191 : vr->max_size = -1;
4370 9390191 : vr->hashcode = vn_reference_compute_hash (vr);
4371 9390191 : vn_reference_lookup_1 (vr, vnresult);
4372 9390191 : }
4373 :
4374 : /* Insert OP into the current hash table with a value number of RESULT. */
4375 :
4376 : static void
4377 76460392 : vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
4378 : {
4379 76460392 : vn_reference_s **slot;
4380 76460392 : vn_reference_t vr1;
4381 76460392 : bool tem;
4382 :
4383 76460392 : vec<vn_reference_op_s> operands
4384 76460392 : = 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 76460392 : if ((cfun->curr_properties & PROP_objsz)
4388 57395605 : && operands[0].opcode == ADDR_EXPR
4389 77395563 : && operands.last ().opcode == SSA_NAME)
4390 : {
4391 903098 : tree ops[2];
4392 903098 : if (vn_pp_nary_for_addr (operands, ops))
4393 : {
4394 578874 : vn_nary_op_insert_pieces (2, POINTER_PLUS_EXPR,
4395 578874 : TREE_TYPE (op), ops, result,
4396 578874 : VN_INFO (result)->value_id);
4397 578874 : return;
4398 : }
4399 : }
4400 :
4401 75881518 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4402 75881518 : if (TREE_CODE (result) == SSA_NAME)
4403 52463568 : vr1->value_id = VN_INFO (result)->value_id;
4404 : else
4405 23417950 : vr1->value_id = get_or_alloc_constant_value_id (result);
4406 75881518 : vr1->vuse = vuse_ssa_val (vuse);
4407 75881518 : vr1->operands = operands.copy ();
4408 75881518 : vr1->type = TREE_TYPE (op);
4409 75881518 : vr1->punned = false;
4410 75881518 : ao_ref op_ref;
4411 75881518 : ao_ref_init (&op_ref, op);
4412 75881518 : vr1->set = ao_ref_alias_set (&op_ref);
4413 75881518 : 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 75881518 : vr1->offset = 0;
4417 75881518 : vr1->max_size = -1;
4418 75881518 : vr1->hashcode = vn_reference_compute_hash (vr1);
4419 75881518 : vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
4420 75881518 : vr1->result_vdef = vdef;
4421 :
4422 75881518 : 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 75881518 : 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 : return;
4447 : }
4448 :
4449 75881518 : *slot = vr1;
4450 75881518 : vr1->next = last_inserted_ref;
4451 75881518 : 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 1578015 : 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 1578015 : vn_reference_s **slot;
4467 1578015 : vn_reference_t vr1;
4468 :
4469 1578015 : vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4470 1578015 : vr1->value_id = value_id;
4471 1578015 : vr1->vuse = vuse_ssa_val (vuse);
4472 1578015 : vr1->operands = operands;
4473 1578015 : valueize_refs (&vr1->operands);
4474 1578015 : vr1->type = type;
4475 1578015 : vr1->punned = false;
4476 1578015 : vr1->set = set;
4477 1578015 : vr1->base_set = base_set;
4478 1578015 : vr1->offset = offset;
4479 1578015 : vr1->max_size = max_size;
4480 1578015 : vr1->hashcode = vn_reference_compute_hash (vr1);
4481 1578015 : if (result && TREE_CODE (result) == SSA_NAME)
4482 367008 : result = SSA_VAL (result);
4483 1578015 : vr1->result = result;
4484 1578015 : vr1->result_vdef = NULL_TREE;
4485 :
4486 1578015 : 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 1578015 : gcc_assert (!*slot);
4493 :
4494 1578015 : *slot = vr1;
4495 1578015 : vr1->next = last_inserted_ref;
4496 1578015 : last_inserted_ref = vr1;
4497 1578015 : return vr1;
4498 : }
4499 :
4500 : /* Compute and return the hash value for nary operation VBO1. */
4501 :
4502 : hashval_t
4503 310027639 : vn_nary_op_compute_hash (const vn_nary_op_t vno1)
4504 : {
4505 310027639 : inchash::hash hstate;
4506 310027639 : unsigned i;
4507 :
4508 310027639 : if (((vno1->length == 2
4509 260889445 : && commutative_tree_code (vno1->opcode))
4510 142040350 : || (vno1->length == 3
4511 1715459 : && commutative_ternary_tree_code (vno1->opcode)))
4512 478017119 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4513 2493958 : std::swap (vno1->op[0], vno1->op[1]);
4514 307533681 : else if (TREE_CODE_CLASS (vno1->opcode) == tcc_comparison
4515 307533681 : && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
4516 : {
4517 474254 : std::swap (vno1->op[0], vno1->op[1]);
4518 474254 : vno1->opcode = swap_tree_comparison (vno1->opcode);
4519 : }
4520 :
4521 310027639 : hstate.add_int (vno1->opcode);
4522 885173900 : for (i = 0; i < vno1->length; ++i)
4523 575146261 : inchash::add_expr (vno1->op[i], hstate);
4524 :
4525 310027639 : return hstate.end ();
4526 : }
4527 :
4528 : /* Compare nary operations VNO1 and VNO2 and return true if they are
4529 : equivalent. */
4530 :
4531 : bool
4532 977639644 : vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
4533 : {
4534 977639644 : unsigned i;
4535 :
4536 977639644 : if (vno1->hashcode != vno2->hashcode)
4537 : return false;
4538 :
4539 51387814 : if (vno1->length != vno2->length)
4540 : return false;
4541 :
4542 51387814 : if (vno1->opcode != vno2->opcode
4543 51387814 : || !types_compatible_p (vno1->type, vno2->type))
4544 : return false;
4545 :
4546 145161018 : for (i = 0; i < vno1->length; ++i)
4547 95039521 : 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 50121497 : if (vno1->opcode == BIT_INSERT_EXPR
4553 595 : && TREE_CODE (vno1->op[1]) == INTEGER_CST
4554 50121629 : && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
4555 132 : != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
4556 0 : return false;
4557 :
4558 : return true;
4559 : }
4560 :
4561 : /* Initialize VNO from the pieces provided. */
4562 :
4563 : static void
4564 192164919 : 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 192164919 : vno->opcode = code;
4568 192164919 : vno->length = length;
4569 192164919 : vno->type = type;
4570 4831920 : 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 111733879 : vn_nary_length_from_stmt (gimple *stmt)
4577 : {
4578 111733879 : 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 698261 : case BIT_FIELD_REF:
4586 698261 : return 3;
4587 :
4588 548604 : case CONSTRUCTOR:
4589 548604 : return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4590 :
4591 106776197 : default:
4592 106776197 : return gimple_num_ops (stmt) - 1;
4593 : }
4594 : }
4595 :
4596 : /* Initialize VNO from STMT. */
4597 :
4598 : void
4599 111733879 : init_vn_nary_op_from_stmt (vn_nary_op_t vno, gassign *stmt)
4600 : {
4601 111733879 : unsigned i;
4602 :
4603 111733879 : vno->opcode = gimple_assign_rhs_code (stmt);
4604 111733879 : vno->type = TREE_TYPE (gimple_assign_lhs (stmt));
4605 111733879 : switch (vno->opcode)
4606 : {
4607 3710817 : case REALPART_EXPR:
4608 3710817 : case IMAGPART_EXPR:
4609 3710817 : case VIEW_CONVERT_EXPR:
4610 3710817 : vno->length = 1;
4611 3710817 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4612 3710817 : break;
4613 :
4614 698261 : case BIT_FIELD_REF:
4615 698261 : vno->length = 3;
4616 698261 : vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
4617 698261 : vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
4618 698261 : vno->op[2] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
4619 698261 : break;
4620 :
4621 548604 : case CONSTRUCTOR:
4622 548604 : vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
4623 2174885 : for (i = 0; i < vno->length; ++i)
4624 1626281 : vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
4625 : break;
4626 :
4627 106776197 : default:
4628 106776197 : gcc_checking_assert (!gimple_assign_single_p (stmt));
4629 106776197 : vno->length = gimple_num_ops (stmt) - 1;
4630 292610524 : for (i = 0; i < vno->length; ++i)
4631 185834327 : vno->op[i] = gimple_op (stmt, i + 1);
4632 : }
4633 111733879 : }
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 134568722 : vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
4643 : {
4644 134568722 : vn_nary_op_s **slot;
4645 :
4646 134568722 : if (vnresult)
4647 126647858 : *vnresult = NULL;
4648 :
4649 374270382 : for (unsigned i = 0; i < vno->length; ++i)
4650 239701660 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4651 169524563 : vno->op[i] = SSA_VAL (vno->op[i]);
4652 :
4653 134568722 : vno->hashcode = vn_nary_op_compute_hash (vno);
4654 134568722 : slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
4655 134568722 : if (!slot)
4656 : return NULL_TREE;
4657 18130073 : if (vnresult)
4658 17668202 : *vnresult = *slot;
4659 18130073 : 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 76731125 : vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
4670 : tree type, tree *ops, vn_nary_op_t *vnresult)
4671 : {
4672 76731125 : vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
4673 : sizeof_vn_nary_op (length));
4674 76731125 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4675 76731125 : 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 57837597 : vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
4685 : {
4686 57837597 : vn_nary_op_t vno1
4687 57837597 : = XALLOCAVAR (struct vn_nary_op_s,
4688 : sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
4689 57837597 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
4690 57837597 : 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 174485233 : alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
4697 : {
4698 174485233 : 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 156773249 : 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 156773249 : vno1->value_id = value_id;
4710 156773249 : vno1->length = length;
4711 156773249 : vno1->predicated_values = 0;
4712 156773249 : vno1->u.result = result;
4713 :
4714 156773249 : return vno1;
4715 : }
4716 :
4717 : /* Insert VNO into TABLE. */
4718 :
4719 : static vn_nary_op_t
4720 161752283 : vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table)
4721 : {
4722 161752283 : vn_nary_op_s **slot;
4723 :
4724 161752283 : gcc_assert (! vno->predicated_values
4725 : || (! vno->u.values->next
4726 : && vno->u.values->n == 1));
4727 :
4728 473329818 : for (unsigned i = 0; i < vno->length; ++i)
4729 311577535 : if (TREE_CODE (vno->op[i]) == SSA_NAME)
4730 202790128 : vno->op[i] = SSA_VAL (vno->op[i]);
4731 :
4732 161752283 : vno->hashcode = vn_nary_op_compute_hash (vno);
4733 161752283 : slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT);
4734 161752283 : vno->unwind_to = *slot;
4735 161752283 : 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 31017740 : if ((*slot)->predicated_values
4742 30245857 : && ! 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 87146 : *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 87146 : vno->next = last_inserted_nary;
4762 87146 : last_inserted_nary = vno;
4763 87146 : return vno;
4764 : }
4765 30930594 : else if (vno->predicated_values
4766 30930242 : && ! (*slot)->predicated_values)
4767 : return *slot;
4768 30159063 : else if (vno->predicated_values
4769 30158711 : && (*slot)->predicated_values)
4770 : {
4771 : /* ??? Factor this all into a insert_single_predicated_value
4772 : routine. */
4773 30158711 : gcc_assert (!vno->u.values->next && vno->u.values->n == 1);
4774 30158711 : basic_block vno_bb
4775 30158711 : = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]);
4776 30158711 : vn_pval *nval = vno->u.values;
4777 30158711 : vn_pval **next = &vno->u.values;
4778 30158711 : vn_pval *ins = NULL;
4779 30158711 : vn_pval *ins_at = NULL;
4780 : /* Find an existing value to append to. */
4781 56642479 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4782 : {
4783 31193984 : if (expressions_equal_p (val->result, nval->result))
4784 : {
4785 : /* Limit the number of places we register a predicate
4786 : as valid. */
4787 4710216 : if (val->n > 8)
4788 139638 : return *slot;
4789 11745654 : for (unsigned i = 0; i < val->n; ++i)
4790 : {
4791 7416380 : basic_block val_bb
4792 7416380 : = BASIC_BLOCK_FOR_FN (cfun,
4793 : val->valid_dominated_by_p[i]);
4794 7416380 : if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb))
4795 : /* Value registered with more generic predicate. */
4796 241304 : return *slot;
4797 7175076 : else if (flag_checking)
4798 : /* Shouldn't happen, we insert in RPO order. */
4799 7175076 : gcc_assert (!dominated_by_p (CDI_DOMINATORS,
4800 : val_bb, vno_bb));
4801 : }
4802 : /* Append the location. */
4803 4329274 : ins_at = val;
4804 4329274 : ins = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4805 : sizeof (vn_pval)
4806 : + val->n * sizeof (int));
4807 4329274 : ins->next = NULL;
4808 4329274 : ins->result = val->result;
4809 4329274 : ins->n = val->n + 1;
4810 4329274 : memcpy (ins->valid_dominated_by_p,
4811 4329274 : val->valid_dominated_by_p,
4812 4329274 : val->n * sizeof (int));
4813 4329274 : ins->valid_dominated_by_p[val->n] = vno_bb->index;
4814 4329274 : 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 61489607 : for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4821 : {
4822 31711838 : if (val == ins_at)
4823 : /* Replace the node we appended to. */
4824 4329274 : *next = ins;
4825 : else
4826 : {
4827 : /* Copy other predicated values. */
4828 27382564 : *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4829 : sizeof (vn_pval)
4830 : + ((val->n-1)
4831 : * sizeof (int)));
4832 27382564 : memcpy (*next, val,
4833 27382564 : sizeof (vn_pval) + (val->n-1) * sizeof (int));
4834 27382564 : (*next)->next = NULL;
4835 : }
4836 31711838 : next = &(*next)->next;
4837 : }
4838 : /* Append the value if we didn't find it. */
4839 29777769 : if (!ins_at)
4840 25448495 : *next = nval;
4841 29777769 : *slot = vno;
4842 29777769 : vno->next = last_inserted_nary;
4843 29777769 : last_inserted_nary = vno;
4844 29777769 : 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 130734543 : gcc_assert (!*slot);
4863 :
4864 130734543 : *slot = vno;
4865 130734543 : vno->next = last_inserted_nary;
4866 130734543 : last_inserted_nary = vno;
4867 130734543 : 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 578874 : 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 578874 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
4880 578874 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4881 578874 : 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 155282729 : 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 155282729 : if (single_pred_p (pred_e->dest))
4893 : return true;
4894 : /* Never record for backedges. */
4895 12313116 : 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 11619085 : edge_iterator ei;
4902 11619085 : edge e;
4903 19896209 : FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
4904 18009273 : 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 110023000 : 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 110023000 : if (flag_checking)
4916 110022180 : gcc_assert (can_track_predicate_on_edge (pred_e));
4917 :
4918 75424 : if (dump_file && (dump_flags & TDF_DETAILS)
4919 : /* ??? Fix dumping, but currently we only get comparisons. */
4920 110094322 : && TREE_CODE_CLASS (code) == tcc_comparison)
4921 : {
4922 71322 : fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index,
4923 71322 : pred_e->dest->index);
4924 71322 : print_generic_expr (dump_file, ops[0], TDF_SLIM);
4925 71322 : fprintf (dump_file, " %s ", get_tree_code_name (code));
4926 71322 : print_generic_expr (dump_file, ops[1], TDF_SLIM);
4927 106612 : fprintf (dump_file, " == %s\n",
4928 71322 : integer_zerop (result) ? "false" : "true");
4929 : }
4930 110023000 : vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id);
4931 110023000 : init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4932 110023000 : vno1->predicated_values = 1;
4933 110023000 : vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4934 : sizeof (vn_pval));
4935 110023000 : vno1->u.values->next = NULL;
4936 110023000 : vno1->u.values->result = result;
4937 110023000 : vno1->u.values->n = 1;
4938 110023000 : vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index;
4939 110023000 : 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 1800523 : vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb,
4947 : edge e = NULL)
4948 : {
4949 1800523 : if (! vno->predicated_values)
4950 0 : return vno->u.result;
4951 3753337 : for (vn_pval *val = vno->u.values; val; val = val->next)
4952 5779314 : for (unsigned i = 0; i < val->n; ++i)
4953 : {
4954 3826500 : basic_block cand
4955 3826500 : = 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 3826500 : if (e && (e->flags & EDGE_DFS_BACK))
4963 : {
4964 22468 : if (dominated_by_p (CDI_DOMINATORS, bb, cand))
4965 6859 : return val->result;
4966 : }
4967 3804032 : else if (dominated_by_p_w_unex (bb, cand, false))
4968 552045 : return val->result;
4969 : }
4970 : return NULL_TREE;
4971 : }
4972 :
4973 : static tree
4974 213858 : 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 46171375 : vn_nary_op_insert_stmt (gimple *stmt, tree result)
4984 : {
4985 46171375 : vn_nary_op_t vno1
4986 46171375 : = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
4987 46171375 : result, VN_INFO (result)->value_id);
4988 46171375 : init_vn_nary_op_from_stmt (vno1, as_a <gassign *> (stmt));
4989 46171375 : 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 50754174 : vn_phi_compute_hash (vn_phi_t vp1)
4996 : {
4997 50754174 : inchash::hash hstate;
4998 50754174 : tree phi1op;
4999 50754174 : tree type;
5000 50754174 : edge e;
5001 50754174 : edge_iterator ei;
5002 :
5003 101508348 : hstate.add_int (EDGE_COUNT (vp1->block->preds));
5004 50754174 : switch (EDGE_COUNT (vp1->block->preds))
5005 : {
5006 : case 1:
5007 : break;
5008 43683026 : case 2:
5009 : /* When this is a PHI node subject to CSE for different blocks
5010 : avoid hashing the block index. */
5011 43683026 : if (vp1->cclhs)
5012 : break;
5013 : /* Fallthru. */
5014 34052204 : default:
5015 34052204 : 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 50754174 : type = vp1->type;
5021 50754174 : hstate.merge_hash (vn_hash_type (type));
5022 :
5023 176758966 : 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 126004792 : if (e->flags & EDGE_DFS_BACK)
5028 27798760 : continue;
5029 :
5030 98206032 : phi1op = vp1->phiargs[e->dest_idx];
5031 98206032 : if (phi1op == VN_TOP)
5032 248815 : continue;
5033 97957217 : inchash::add_expr (phi1op, hstate);
5034 : }
5035 :
5036 50754174 : 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 3553619 : cond_stmts_equal_p (gcond *cond1, tree lhs1, tree rhs1,
5046 : gcond *cond2, tree lhs2, tree rhs2, bool *inverted_p)
5047 : {
5048 3553619 : enum tree_code code1 = gimple_cond_code (cond1);
5049 3553619 : enum tree_code code2 = gimple_cond_code (cond2);
5050 :
5051 3553619 : *inverted_p = false;
5052 3553619 : if (code1 == code2)
5053 : ;
5054 282187 : else if (code1 == swap_tree_comparison (code2))
5055 : std::swap (lhs2, rhs2);
5056 247266 : else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
5057 114832 : *inverted_p = true;
5058 132434 : else if (code1 == invert_tree_comparison
5059 132434 : (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
5060 : {
5061 10288 : std::swap (lhs2, rhs2);
5062 10288 : *inverted_p = true;
5063 : }
5064 : else
5065 : return false;
5066 :
5067 3431473 : return ((expressions_equal_p (lhs1, lhs2)
5068 109142 : && expressions_equal_p (rhs1, rhs2))
5069 3456718 : || (commutative_tree_code (code1)
5070 1771905 : && expressions_equal_p (lhs1, rhs2)
5071 2433 : && expressions_equal_p (rhs1, lhs2)));
5072 : }
5073 :
5074 : /* Compare two phi entries for equality, ignoring VN_TOP arguments. */
5075 :
5076 : static int
5077 40639371 : vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
5078 : {
5079 40639371 : if (vp1->hashcode != vp2->hashcode)
5080 : return false;
5081 :
5082 12502801 : if (vp1->block != vp2->block)
5083 : {
5084 10683930 : if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds))
5085 : return false;
5086 :
5087 3561310 : switch (EDGE_COUNT (vp1->block->preds))
5088 : {
5089 : case 1:
5090 : /* Single-arg PHIs are just copies. */
5091 : break;
5092 :
5093 3561310 : case 2:
5094 3561310 : {
5095 : /* Make sure both PHIs are classified as CSEable. */
5096 3561310 : if (! vp1->cclhs || ! vp2->cclhs)
5097 : return false;
5098 :
5099 : /* Rule out backedges into the PHI. */
5100 3561310 : 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 3561310 : 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 3553619 : basic_block idom1
5113 3553619 : = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5114 3553619 : basic_block idom2
5115 3553619 : = get_immediate_dominator (CDI_DOMINATORS, vp2->block);
5116 3553619 : gcc_checking_assert (EDGE_COUNT (idom1->succs) == 2
5117 : && EDGE_COUNT (idom2->succs) == 2);
5118 :
5119 : /* Verify the controlling stmt is the same. */
5120 7107238 : gcond *last1 = as_a <gcond *> (*gsi_last_bb (idom1));
5121 7107238 : gcond *last2 = as_a <gcond *> (*gsi_last_bb (idom2));
5122 3553619 : bool inverted_p;
5123 3553619 : if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
5124 3553619 : last2, vp2->cclhs, vp2->ccrhs,
5125 : &inverted_p))
5126 : return false;
5127 :
5128 : /* Get at true/false controlled edges into the PHI. */
5129 83993 : edge te1, te2, fe1, fe2;
5130 83993 : if (! extract_true_false_controlled_edges (idom1, vp1->block,
5131 : &te1, &fe1)
5132 83993 : || ! extract_true_false_controlled_edges (idom2, vp2->block,
5133 : &te2, &fe2))
5134 : return false;
5135 :
5136 : /* Swap edges if the second condition is the inverted of the
5137 : first. */
5138 47997 : if (inverted_p)
5139 2050 : 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 47997 : if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
5147 47997 : vp2->phiargs[te2->dest_idx], false)
5148 94181 : || ! expressions_equal_p (vp1->phiargs[fe1->dest_idx],
5149 46184 : 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 8941491 : 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 8940375 : unsigned nargs = EDGE_COUNT (vp1->block->preds);
5168 20598958 : for (unsigned i = 0; i < nargs; ++i)
5169 : {
5170 16496971 : tree phi1op = vp1->phiargs[i];
5171 16496971 : tree phi2op = vp2->phiargs[i];
5172 16496971 : if (phi1op == phi2op)
5173 11562014 : continue;
5174 4934957 : 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 27764231 : vn_phi_lookup (gimple *phi, bool backedges_varying_p)
5187 : {
5188 27764231 : vn_phi_s **slot;
5189 27764231 : struct vn_phi_s *vp1;
5190 27764231 : edge e;
5191 27764231 : edge_iterator ei;
5192 :
5193 27764231 : 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 95980679 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5199 : {
5200 68216448 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5201 68216448 : if (TREE_CODE (def) == SSA_NAME
5202 56817007 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5203 : {
5204 54262342 : if (!virtual_operand_p (def)
5205 54262342 : && ssa_undefined_value_p (def, false))
5206 138168 : def = VN_TOP;
5207 : else
5208 54124174 : def = SSA_VAL (def);
5209 : }
5210 68216448 : vp1->phiargs[e->dest_idx] = def;
5211 : }
5212 27764231 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5213 27764231 : vp1->block = gimple_bb (phi);
5214 : /* Extract values of the controlling condition. */
5215 27764231 : vp1->cclhs = NULL_TREE;
5216 27764231 : vp1->ccrhs = NULL_TREE;
5217 27764231 : if (EDGE_COUNT (vp1->block->preds) == 2
5218 27764231 : && vp1->block->loop_father->header != vp1->block)
5219 : {
5220 8821576 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5221 8821576 : if (EDGE_COUNT (idom1->succs) == 2)
5222 17544318 : 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 8535743 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5227 8535743 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5228 : }
5229 : }
5230 27764231 : vp1->hashcode = vn_phi_compute_hash (vp1);
5231 27764231 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
5232 27764231 : if (!slot)
5233 : return NULL_TREE;
5234 4148171 : 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 22989943 : vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
5242 : {
5243 22989943 : vn_phi_s **slot;
5244 22989943 : 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 22989943 : edge e;
5249 22989943 : edge_iterator ei;
5250 :
5251 : /* Canonicalize the SSA_NAME's to their value number. */
5252 80778287 : FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5253 : {
5254 57788344 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5255 57788344 : if (TREE_CODE (def) == SSA_NAME
5256 47452316 : && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
5257 : {
5258 44898086 : if (!virtual_operand_p (def)
5259 44898086 : && ssa_undefined_value_p (def, false))
5260 110891 : def = VN_TOP;
5261 : else
5262 44787195 : def = SSA_VAL (def);
5263 : }
5264 57788344 : vp1->phiargs[e->dest_idx] = def;
5265 : }
5266 22989943 : vp1->value_id = VN_INFO (result)->value_id;
5267 22989943 : vp1->type = TREE_TYPE (gimple_phi_result (phi));
5268 22989943 : vp1->block = gimple_bb (phi);
5269 : /* Extract values of the controlling condition. */
5270 22989943 : vp1->cclhs = NULL_TREE;
5271 22989943 : vp1->ccrhs = NULL_TREE;
5272 22989943 : if (EDGE_COUNT (vp1->block->preds) == 2
5273 22989943 : && vp1->block->loop_father->header != vp1->block)
5274 : {
5275 8446993 : basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
5276 8446993 : if (EDGE_COUNT (idom1->succs) == 2)
5277 16799348 : 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 8166227 : vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
5282 8166227 : vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
5283 : }
5284 : }
5285 22989943 : vp1->result = result;
5286 22989943 : vp1->hashcode = vn_phi_compute_hash (vp1);
5287 :
5288 22989943 : slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
5289 22989943 : gcc_assert (!*slot);
5290 :
5291 22989943 : *slot = vp1;
5292 22989943 : vp1->next = last_inserted_phi;
5293 22989943 : last_inserted_phi = vp1;
5294 22989943 : 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 77199289 : dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
5304 : {
5305 77199289 : edge_iterator ei;
5306 77199289 : edge e;
5307 :
5308 77199289 : 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 22149042 : if (EDGE_COUNT (bb1->preds) > 1)
5317 : {
5318 3094005 : edge prede = NULL;
5319 6783965 : FOR_EACH_EDGE (e, ei, bb1->preds)
5320 6311783 : if ((e->flags & EDGE_EXECUTABLE)
5321 676561 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5322 : {
5323 5715828 : if (prede)
5324 : {
5325 : prede = NULL;
5326 : break;
5327 : }
5328 : prede = e;
5329 : }
5330 3094005 : if (prede)
5331 : {
5332 472182 : bb1 = prede->src;
5333 :
5334 : /* Re-do the dominance check with changed bb1. */
5335 472182 : if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
5336 : return true;
5337 : }
5338 : }
5339 :
5340 : /* Iterate to the single executable bb2 successor. */
5341 21881871 : if (EDGE_COUNT (bb2->succs) > 1)
5342 : {
5343 6857565 : edge succe = NULL;
5344 13886685 : FOR_EACH_EDGE (e, ei, bb2->succs)
5345 13715379 : if ((e->flags & EDGE_EXECUTABLE)
5346 210576 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5347 : {
5348 13504845 : if (succe)
5349 : {
5350 : succe = NULL;
5351 : break;
5352 : }
5353 : succe = e;
5354 : }
5355 6857565 : 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 6857565 : && 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 131758 : if (EDGE_COUNT (succe->dest->preds) > 1)
5365 : {
5366 56190 : FOR_EACH_EDGE (e, ei, succe->dest->preds)
5367 43648 : if (e != succe
5368 28169 : && ((e->flags & EDGE_EXECUTABLE)
5369 18338 : || (!allow_back && (e->flags & EDGE_DFS_BACK))))
5370 : {
5371 : succe = NULL;
5372 : break;
5373 : }
5374 : }
5375 131758 : if (succe)
5376 : {
5377 121918 : bb2 = succe->dest;
5378 :
5379 : /* Re-do the dominance check with changed bb2. */
5380 121918 : 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 15024306 : else if (EDGE_COUNT (bb2->succs) == 1
5388 14449784 : && 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 29215407 : && EDGE_COUNT (single_succ (bb2)->preds) < 8)
5393 : {
5394 5215428 : edge prede = NULL;
5395 11808308 : FOR_EACH_EDGE (e, ei, single_succ (bb2)->preds)
5396 11190261 : if ((e->flags & EDGE_EXECUTABLE)
5397 1429966 : || (!allow_back && (e->flags & EDGE_DFS_BACK)))
5398 : {
5399 9764761 : 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 5215428 : if (prede && prede->src == bb2)
5409 : {
5410 555160 : bb2 = prede->dest;
5411 :
5412 : /* Re-do the dominance check with changed bb2. */
5413 555160 : 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 209713472 : set_ssa_val_to (tree from, tree to)
5427 : {
5428 209713472 : vn_ssa_aux_t from_info = VN_INFO (from);
5429 209713472 : tree currval = from_info->valnum; // SSA_VAL (from)
5430 209713472 : poly_int64 toff, coff;
5431 209713472 : bool curr_undefined = false;
5432 209713472 : 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 209713472 : 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 209713472 : 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 209713472 : if (from != to)
5462 : {
5463 33510662 : if (currval == from)
5464 : {
5465 14615 : 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 : return false;
5474 : }
5475 33496047 : curr_invariant = is_gimple_min_invariant (currval);
5476 66992094 : curr_undefined = (TREE_CODE (currval) == SSA_NAME
5477 3924852 : && !virtual_operand_p (currval)
5478 37190284 : && ssa_undefined_value_p (currval, false));
5479 33496047 : if (currval != VN_TOP
5480 : && !curr_invariant
5481 5468719 : && !curr_undefined
5482 37407569 : && 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 33495827 : else if (currval != VN_TOP
5498 5468499 : && !curr_undefined
5499 5455169 : && TREE_CODE (to) == SSA_NAME
5500 4598104 : && !virtual_operand_p (to)
5501 37863316 : && 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 33495821 : else if (TREE_CODE (to) == SSA_NAME
5517 33495821 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to))
5518 : to = from;
5519 : }
5520 :
5521 176202810 : set_and_exit:
5522 209698857 : if (dump_file && (dump_flags & TDF_DETAILS))
5523 : {
5524 398951 : fprintf (dump_file, "Setting value number of ");
5525 398951 : print_generic_expr (dump_file, from);
5526 398951 : fprintf (dump_file, " to ");
5527 398951 : print_generic_expr (dump_file, to);
5528 : }
5529 :
5530 209698857 : if (currval != to
5531 171563997 : && !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 171494424 : && !(curr_undefined
5535 3461 : && 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 381192641 : && !(TREE_CODE (currval) == ADDR_EXPR
5543 468196 : && 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 171493778 : if (to != from
5549 29056896 : && currval != VN_TOP
5550 1033181 : && !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 1033181 : && curr_invariant
5558 172180574 : && 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 171493778 : if (dump_file && (dump_flags & TDF_DETAILS))
5565 398635 : fprintf (dump_file, " (changed)\n");
5566 171493778 : from_info->valnum = to;
5567 171493778 : return true;
5568 : }
5569 38205079 : 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 310585161 : defs_to_varying (gimple *stmt)
5579 : {
5580 310585161 : bool changed = false;
5581 310585161 : ssa_op_iter iter;
5582 310585161 : def_operand_p defp;
5583 :
5584 341094601 : FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
5585 : {
5586 30509440 : tree def = DEF_FROM_PTR (defp);
5587 30509440 : changed |= set_ssa_val_to (def, def);
5588 : }
5589 310585161 : 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 8187562 : visit_copy (tree lhs, tree rhs)
5597 : {
5598 : /* Valueize. */
5599 8187562 : rhs = SSA_VAL (rhs);
5600 :
5601 8187562 : 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 2492158 : valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
5609 : {
5610 2492158 : if (TREE_CODE (op) == SSA_NAME)
5611 2186429 : op = vn_valueize (op);
5612 :
5613 : /* Either we have the op widened available. */
5614 2492158 : tree ops[3] = {};
5615 2492158 : ops[0] = op;
5616 2492158 : tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR,
5617 : wide_type, ops, NULL);
5618 2492158 : if (tem)
5619 : return tem;
5620 :
5621 : /* Or the op is truncated from some existing value. */
5622 2198500 : if (allow_truncate && TREE_CODE (op) == SSA_NAME)
5623 : {
5624 560634 : gimple *def = SSA_NAME_DEF_STMT (op);
5625 560634 : if (is_gimple_assign (def)
5626 560634 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5627 : {
5628 301732 : tem = gimple_assign_rhs1 (def);
5629 301732 : if (useless_type_conversion_p (wide_type, TREE_TYPE (tem)))
5630 : {
5631 203531 : if (TREE_CODE (tem) == SSA_NAME)
5632 203531 : tem = vn_valueize (tem);
5633 : return tem;
5634 : }
5635 : }
5636 : }
5637 :
5638 : /* For constants simply extend it. */
5639 1994969 : if (TREE_CODE (op) == INTEGER_CST)
5640 339176 : 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 21957 : vn_nary_result_avail_or_insertable_p (tree result)
5652 : {
5653 21957 : return (TYPE_OVERFLOW_WRAPS (TREE_TYPE (result))
5654 13768 : || (rpo_avail && vn_context_bb
5655 13768 : && 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 14282656 : ssa_integral_conversion_op (tree op)
5664 : {
5665 14282656 : if (TREE_CODE (op) != SSA_NAME)
5666 : return NULL_TREE;
5667 13954314 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
5668 11731672 : if (!def || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
5669 : return NULL_TREE;
5670 1554282 : const tree src = gimple_assign_rhs1 (def);
5671 1554282 : if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
5672 : return NULL_TREE;
5673 1296613 : 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 50002068 : visit_nary_op (tree lhs, gassign *stmt)
5681 : {
5682 50002068 : vn_nary_op_t vnresult;
5683 50002068 : tree result = vn_nary_op_lookup_stmt (stmt, &vnresult);
5684 50002068 : if (! result && vnresult)
5685 157065 : result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt));
5686 46243844 : if (result)
5687 3828143 : return set_ssa_val_to (lhs, result);
5688 :
5689 : /* Do some special pattern matching for redundancies of operations
5690 : in different types. */
5691 46173925 : enum tree_code code = gimple_assign_rhs_code (stmt);
5692 46173925 : tree type = TREE_TYPE (lhs);
5693 46173925 : tree rhs1 = gimple_assign_rhs1 (stmt);
5694 46173925 : switch (code)
5695 : {
5696 10236965 : 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 10236965 : if (INTEGRAL_TYPE_P (type)
5701 9170871 : && 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 19169821 : && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
5706 5375237 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5707 5374444 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5708 8204318 : && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
5709 6049845 : || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
5710 : {
5711 7802622 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5712 5688826 : if (def
5713 5688826 : && (gimple_assign_rhs_code (def) == PLUS_EXPR
5714 4448668 : || gimple_assign_rhs_code (def) == MINUS_EXPR
5715 4293681 : || gimple_assign_rhs_code (def) == MULT_EXPR))
5716 : {
5717 2006978 : 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 2006978 : bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
5721 : /* Either we have the op widened available. */
5722 2006978 : ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
5723 : allow_truncate);
5724 2006978 : if (ops[0])
5725 970360 : ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
5726 : allow_truncate);
5727 2006978 : if (ops[0] && ops[1])
5728 : {
5729 351185 : ops[0] = vn_nary_op_lookup_pieces
5730 351185 : (2, gimple_assign_rhs_code (def), type, ops, NULL);
5731 : /* We have wider operation available. */
5732 351185 : if (ops[0] && vn_nary_result_avail_or_insertable_p (ops[0]))
5733 : {
5734 8109 : unsigned lhs_prec = TYPE_PRECISION (type);
5735 8109 : unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
5736 8109 : if (lhs_prec == rhs_prec
5737 8109 : || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
5738 809 : && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
5739 : {
5740 7472 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5741 7472 : NOP_EXPR, type, ops[0]);
5742 7472 : result = vn_nary_build_or_lookup (&match_op);
5743 7472 : if (result)
5744 : {
5745 7472 : bool changed = set_ssa_val_to (lhs, result);
5746 7472 : if (TREE_CODE (result) == SSA_NAME)
5747 7472 : vn_nary_op_insert_stmt (stmt, result);
5748 7472 : return changed;
5749 : }
5750 : }
5751 : else
5752 : {
5753 637 : tree mask = wide_int_to_tree
5754 637 : (type, wi::mask (rhs_prec, false, lhs_prec));
5755 637 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5756 637 : BIT_AND_EXPR,
5757 637 : TREE_TYPE (lhs),
5758 637 : ops[0], mask);
5759 637 : result = vn_nary_build_or_lookup (&match_op);
5760 637 : if (result)
5761 : {
5762 637 : bool changed = set_ssa_val_to (lhs, result);
5763 637 : if (TREE_CODE (result) == SSA_NAME)
5764 637 : vn_nary_op_insert_stmt (stmt, result);
5765 637 : return changed;
5766 : }
5767 : }
5768 : }
5769 : }
5770 : }
5771 : }
5772 : break;
5773 13897286 : case PLUS_EXPR:
5774 13897286 : case MINUS_EXPR:
5775 13897286 : {
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 13897286 : const tree narrow1 = ssa_integral_conversion_op (vn_valueize (rhs1));
5785 13897286 : if (!INTEGRAL_TYPE_P (type) || !narrow1)
5786 : break;
5787 1121539 : 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 1121539 : const bool sign_change_p
5791 1121539 : = TYPE_PRECISION (ntype) == TYPE_PRECISION (type);
5792 1121539 : const bool nowrap_widening_p
5793 1121539 : = (TYPE_PRECISION (ntype) < TYPE_PRECISION (type)
5794 1121539 : && TYPE_OVERFLOW_UNDEFINED (ntype));
5795 1121539 : 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 858036 : const tree rhs2 = gimple_assign_rhs2 (stmt);
5801 858036 : tree narrow2 = NULL_TREE;
5802 858036 : if (TREE_CODE (rhs2) == INTEGER_CST)
5803 : {
5804 472666 : const widest_int cst = wi::to_widest (rhs2);
5805 472666 : const widest_int narrowed
5806 472666 : = wi::ext (cst, TYPE_PRECISION (ntype), TYPE_SIGN (ntype));
5807 472666 : const widest_int extended
5808 472666 : = wi::ext (narrowed, TYPE_PRECISION (type), TYPE_SIGN (type));
5809 472666 : if (cst == extended)
5810 469898 : narrow2 = fold_convert (ntype, rhs2);
5811 472672 : }
5812 385370 : else if (TREE_CODE (rhs2) == SSA_NAME)
5813 : {
5814 385370 : const tree op = ssa_integral_conversion_op (vn_valueize (rhs2));
5815 385370 : if (op && types_compatible_p (TREE_TYPE (op), ntype))
5816 : narrow2 = op;
5817 : }
5818 636935 : if (!narrow2)
5819 : break;
5820 634167 : tree ops[3] = { narrow1, narrow2 };
5821 634167 : const tree narrow_val
5822 634167 : = vn_nary_op_lookup_pieces (2, code, ntype, ops, NULL);
5823 : /* We have a narrower or sign-changed operation available. */
5824 634167 : if (narrow_val && vn_nary_result_avail_or_insertable_p (narrow_val))
5825 : {
5826 11398 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5827 11398 : NOP_EXPR, type, narrow_val);
5828 11398 : result = vn_nary_build_or_lookup (&match_op);
5829 11398 : if (result)
5830 : {
5831 11398 : const bool changed = set_ssa_val_to (lhs, result);
5832 11398 : if (TREE_CODE (result) == SSA_NAME)
5833 11398 : vn_nary_op_insert_stmt (stmt, result);
5834 11398 : return changed;
5835 : }
5836 : }
5837 : }
5838 622769 : break;
5839 1534516 : case BIT_AND_EXPR:
5840 1534516 : if (INTEGRAL_TYPE_P (type)
5841 1493211 : && TREE_CODE (rhs1) == SSA_NAME
5842 1493211 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
5843 909928 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)
5844 909808 : && default_vn_walk_kind != VN_NOWALK
5845 : && CHAR_BIT == 8
5846 : && BITS_PER_UNIT == 8
5847 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
5848 909599 : && TYPE_PRECISION (type) <= vn_walk_cb_data::bufsize * BITS_PER_UNIT
5849 909597 : && !integer_all_onesp (gimple_assign_rhs2 (stmt))
5850 2444113 : && !integer_zerop (gimple_assign_rhs2 (stmt)))
5851 : {
5852 909597 : gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
5853 664754 : if (ass
5854 664754 : && !gimple_has_volatile_ops (ass)
5855 663176 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5856 : {
5857 306553 : tree last_vuse = gimple_vuse (ass);
5858 306553 : tree op = gimple_assign_rhs1 (ass);
5859 919659 : 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 306553 : if (result
5864 307012 : && 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 284978 : case BIT_FIELD_REF:
5871 284978 : if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
5872 : {
5873 284950 : tree op0 = vn_valueize (TREE_OPERAND (rhs1, 0));
5874 284950 : gassign *ass;
5875 284950 : if (TREE_CODE (op0) == SSA_NAME
5876 284950 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)))
5877 239649 : && !gimple_has_volatile_ops (ass)
5878 524516 : && vn_get_stmt_kind (ass) == VN_REFERENCE)
5879 : {
5880 102990 : tree last_vuse = gimple_vuse (ass);
5881 102990 : tree op = gimple_assign_rhs1 (ass);
5882 : /* Avoid building invalid and unexpected refs. */
5883 102990 : 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 95158 : tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1),
5889 : gimple_assign_rhs1 (ass),
5890 95158 : TREE_OPERAND (rhs1, 1),
5891 95158 : TREE_OPERAND (rhs1, 2));
5892 190316 : tree result = vn_reference_lookup (op, gimple_vuse (ass),
5893 : default_vn_walk_kind,
5894 : NULL, true, &last_vuse);
5895 95158 : if (result
5896 95158 : && useless_type_conversion_p (type, TREE_TYPE (result)))
5897 2611 : return set_ssa_val_to (lhs, result);
5898 93080 : else if (result
5899 533 : && TYPE_SIZE (type)
5900 533 : && TYPE_SIZE (TREE_TYPE (result))
5901 93613 : && operand_equal_p (TYPE_SIZE (type),
5902 533 : TYPE_SIZE (TREE_TYPE (result))))
5903 : {
5904 533 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5905 533 : VIEW_CONVERT_EXPR,
5906 533 : type, result);
5907 533 : result = vn_nary_build_or_lookup (&match_op);
5908 533 : if (result)
5909 : {
5910 533 : bool changed = set_ssa_val_to (lhs, result);
5911 533 : if (TREE_CODE (result) == SSA_NAME)
5912 521 : vn_nary_op_insert_stmt (stmt, result);
5913 533 : return changed;
5914 : }
5915 : }
5916 : }
5917 : }
5918 : }
5919 : break;
5920 346808 : case TRUNC_DIV_EXPR:
5921 346808 : if (TYPE_UNSIGNED (type))
5922 : break;
5923 : /* Fallthru. */
5924 5566149 : case RDIV_EXPR:
5925 5566149 : case MULT_EXPR:
5926 : /* Match up ([-]a){/,*}([-])b with v=a{/,*}b, replacing it with -v. */
5927 5566149 : if (! HONOR_SIGN_DEPENDENT_ROUNDING (type))
5928 : {
5929 5565235 : tree rhs[2];
5930 5565235 : rhs[0] = rhs1;
5931 5565235 : rhs[1] = gimple_assign_rhs2 (stmt);
5932 16688841 : for (unsigned i = 0; i <= 1; ++i)
5933 : {
5934 11129315 : unsigned j = i == 0 ? 1 : 0;
5935 11129315 : tree ops[2];
5936 11129315 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5937 11129315 : NEGATE_EXPR, type, rhs[i]);
5938 11129315 : ops[i] = vn_nary_build_or_lookup_1 (&match_op, false, true);
5939 11129315 : ops[j] = rhs[j];
5940 11129315 : if (ops[i]
5941 11129315 : && (ops[0] = vn_nary_op_lookup_pieces (2, code,
5942 : type, ops, NULL)))
5943 : {
5944 5709 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5945 5709 : NEGATE_EXPR, type, ops[0]);
5946 5709 : result = vn_nary_build_or_lookup_1 (&match_op, true, false);
5947 5709 : if (result)
5948 : {
5949 5709 : bool changed = set_ssa_val_to (lhs, result);
5950 5709 : if (TREE_CODE (result) == SSA_NAME)
5951 5709 : vn_nary_op_insert_stmt (stmt, result);
5952 5709 : return changed;
5953 : }
5954 : }
5955 : }
5956 : }
5957 : break;
5958 371410 : case LSHIFT_EXPR:
5959 : /* For X << C, use the value number of X * (1 << C). */
5960 371410 : if (INTEGRAL_TYPE_P (type)
5961 355464 : && TYPE_OVERFLOW_WRAPS (type)
5962 561158 : && !TYPE_SATURATING (type))
5963 : {
5964 189748 : tree rhs2 = gimple_assign_rhs2 (stmt);
5965 189748 : if (TREE_CODE (rhs2) == INTEGER_CST
5966 110294 : && tree_fits_uhwi_p (rhs2)
5967 300042 : && tree_to_uhwi (rhs2) < TYPE_PRECISION (type))
5968 : {
5969 220588 : wide_int w = wi::set_bit_in_zero (tree_to_uhwi (rhs2),
5970 110294 : TYPE_PRECISION (type));
5971 220588 : gimple_match_op match_op (gimple_match_cond::UNCOND,
5972 110294 : MULT_EXPR, type, rhs1,
5973 110294 : wide_int_to_tree (type, w));
5974 110294 : result = vn_nary_build_or_lookup (&match_op);
5975 110294 : if (result)
5976 : {
5977 110294 : bool changed = set_ssa_val_to (lhs, result);
5978 110294 : if (TREE_CODE (result) == SSA_NAME)
5979 110293 : vn_nary_op_insert_stmt (stmt, result);
5980 110294 : return changed;
5981 : }
5982 110294 : }
5983 : }
5984 : break;
5985 : default:
5986 : break;
5987 : }
5988 :
5989 46035345 : bool changed = set_ssa_val_to (lhs, lhs);
5990 46035345 : vn_nary_op_insert_stmt (stmt, lhs);
5991 46035345 : 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 8824351 : visit_reference_op_call (tree lhs, gcall *stmt)
5999 : {
6000 8824351 : bool changed = false;
6001 8824351 : struct vn_reference_s vr1;
6002 8824351 : vn_reference_t vnresult = NULL;
6003 8824351 : tree vdef = gimple_vdef (stmt);
6004 8824351 : modref_summary *summary;
6005 :
6006 : /* Non-ssa lhs is handled in copy_reference_ops_from_call. */
6007 8824351 : if (lhs && TREE_CODE (lhs) != SSA_NAME)
6008 4718448 : lhs = NULL_TREE;
6009 :
6010 8824351 : 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 8824351 : const unsigned accesses_limit = 8;
6015 8824351 : if (!vnresult
6016 8125693 : && !vdef
6017 8125693 : && lhs
6018 2846383 : && gimple_vuse (stmt)
6019 10418893 : && (((summary = get_modref_function_summary (stmt, NULL))
6020 231235 : && !summary->global_memory_read
6021 95726 : && summary->load_accesses < accesses_limit)
6022 1499175 : || 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 96090 : bool unknown_memory_access = false;
6027 96090 : auto_vec<ao_ref, accesses_limit> accesses;
6028 96090 : unsigned load_accesses = summary ? summary->load_accesses : 0;
6029 96090 : 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 284390 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
6034 : {
6035 188308 : tree arg = gimple_call_arg (stmt, i);
6036 188308 : if (TREE_CODE (arg) != SSA_NAME
6037 188308 : && !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 96090 : if (summary && !unknown_memory_access)
6049 : {
6050 : /* Add loads as analyzed by IPA modref. */
6051 330173 : for (auto base_node : summary->loads->bases)
6052 82997 : if (unknown_memory_access)
6053 : break;
6054 338376 : else for (auto ref_node : base_node->refs)
6055 90336 : if (unknown_memory_access)
6056 : break;
6057 379575 : else for (auto access_node : ref_node->accesses)
6058 : {
6059 252784 : accesses.quick_grow (accesses.length () + 1);
6060 126392 : ao_ref *r = &accesses.last ();
6061 126392 : if (!access_node.get_ao_ref (stmt, r))
6062 : {
6063 : /* Initialize a ref based on the argument and
6064 : unknown offset if possible. */
6065 17789 : tree arg = access_node.get_call_arg (stmt);
6066 17789 : if (arg && TREE_CODE (arg) == SSA_NAME)
6067 4322 : arg = SSA_VAL (arg);
6068 4322 : if (arg
6069 17779 : && TREE_CODE (arg) == ADDR_EXPR
6070 13463 : && (arg = get_base_address (arg))
6071 17785 : && 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 108603 : r->base_alias_set = base_node->base;
6084 108603 : 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 96090 : unsigned limit = (unknown_memory_access
6091 96090 : ? 0
6092 78293 : : (param_sccvn_max_alias_queries_per_access
6093 78293 : / (accesses.length () + 1)));
6094 96090 : tree saved_vuse = vr1.vuse;
6095 96090 : hashval_t saved_hashcode = vr1.hashcode;
6096 521848 : while (limit > 0 && !vnresult && !SSA_NAME_IS_DEFAULT_DEF (vr1.vuse))
6097 : {
6098 454986 : vr1.hashcode = vr1.hashcode - SSA_NAME_VERSION (vr1.vuse);
6099 454986 : 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 454986 : if (is_a <gphi *> (def))
6103 : break;
6104 851516 : vr1.vuse = vuse_ssa_val (gimple_vuse (def));
6105 425758 : vr1.hashcode = vr1.hashcode + SSA_NAME_VERSION (vr1.vuse);
6106 425758 : vn_reference_lookup_1 (&vr1, &vnresult);
6107 425758 : limit--;
6108 : }
6109 :
6110 : /* If we found a candidate to CSE to verify it is valid. */
6111 96090 : if (vnresult && !accesses.is_empty ())
6112 : {
6113 1985 : tree vuse = vuse_ssa_val (gimple_vuse (stmt));
6114 7463 : while (vnresult && vuse != vr1.vuse)
6115 : {
6116 3493 : gimple *def = SSA_NAME_DEF_STMT (vuse);
6117 18765 : 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 10051 : if (stmt_may_clobber_ref_p_1 (def, &ref, true))
6122 : {
6123 1765 : vnresult = NULL;
6124 1765 : break;
6125 : }
6126 : }
6127 6986 : vuse = vuse_ssa_val (gimple_vuse (def));
6128 : }
6129 : }
6130 96090 : vr1.vuse = saved_vuse;
6131 96090 : vr1.hashcode = saved_hashcode;
6132 96090 : }
6133 :
6134 8824351 : if (vnresult)
6135 : {
6136 698906 : if (vdef)
6137 : {
6138 175588 : if (vnresult->result_vdef)
6139 175588 : 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 698906 : if (!vnresult->result && lhs)
6152 0 : vnresult->result = lhs;
6153 :
6154 698906 : if (vnresult->result && lhs)
6155 124571 : changed |= set_ssa_val_to (lhs, vnresult->result);
6156 : }
6157 : else
6158 : {
6159 8125445 : vn_reference_t vr2;
6160 8125445 : vn_reference_s **slot;
6161 8125445 : tree vdef_val = vdef;
6162 8125445 : 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 4951144 : tree fn = gimple_call_fn (stmt);
6168 4951144 : if (fn && TREE_CODE (fn) == SSA_NAME)
6169 : {
6170 130180 : fn = SSA_VAL (fn);
6171 130180 : 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 131553 : && (lhs || gimple_call_lhs (stmt) == NULL_TREE))
6179 2604 : vdef_val = vuse_ssa_val (gimple_vuse (stmt));
6180 : }
6181 4951144 : changed |= set_ssa_val_to (vdef, vdef_val);
6182 : }
6183 8125445 : if (lhs)
6184 3981332 : changed |= set_ssa_val_to (lhs, lhs);
6185 8125445 : vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s);
6186 8125445 : 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 8125445 : vr2->operands = vr1.operands.copy ();
6191 8125445 : vr2->type = vr1.type;
6192 8125445 : vr2->punned = vr1.punned;
6193 8125445 : vr2->set = vr1.set;
6194 8125445 : vr2->offset = vr1.offset;
6195 8125445 : vr2->max_size = vr1.max_size;
6196 8125445 : vr2->base_set = vr1.base_set;
6197 8125445 : vr2->hashcode = vr1.hashcode;
6198 8125445 : vr2->result = lhs;
6199 8125445 : vr2->result_vdef = vdef_val;
6200 8125445 : vr2->value_id = 0;
6201 8125445 : slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
6202 : INSERT);
6203 8125445 : gcc_assert (!*slot);
6204 8125445 : *slot = vr2;
6205 8125445 : vr2->next = last_inserted_ref;
6206 8125445 : last_inserted_ref = vr2;
6207 : }
6208 :
6209 8824351 : 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 35385259 : visit_reference_op_load (tree lhs, tree op, gimple *stmt)
6217 : {
6218 35385259 : bool changed = false;
6219 35385259 : tree result;
6220 35385259 : vn_reference_t res;
6221 :
6222 35385259 : tree vuse = gimple_vuse (stmt);
6223 35385259 : tree last_vuse = vuse;
6224 35385259 : 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 35385259 : if (result
6230 35385259 : && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
6231 : {
6232 18595 : 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 14362 : gimple_match_op res_op (gimple_match_cond::UNCOND,
6241 14362 : VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
6242 14362 : result = vn_nary_build_or_lookup (&res_op);
6243 14362 : if (result
6244 14356 : && TREE_CODE (result) == SSA_NAME
6245 27060 : && 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 11432 : res->punned = true;
6250 : }
6251 :
6252 : /* When building the conversion fails avoid inserting the reference
6253 : again. */
6254 18595 : if (!result)
6255 6 : return set_ssa_val_to (lhs, lhs);
6256 : }
6257 :
6258 35366664 : if (result)
6259 5734273 : changed = set_ssa_val_to (lhs, result);
6260 : else
6261 : {
6262 29650980 : changed = set_ssa_val_to (lhs, lhs);
6263 29650980 : vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
6264 29650980 : if (vuse && SSA_VAL (last_vuse) != SSA_VAL (vuse))
6265 : {
6266 9188982 : 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 9188982 : 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 33737966 : visit_reference_op_store (tree lhs, tree op, gimple *stmt)
6285 : {
6286 33737966 : bool changed = false;
6287 33737966 : vn_reference_t vnresult = NULL;
6288 33737966 : tree assign;
6289 33737966 : bool resultsame = false;
6290 33737966 : tree vuse = gimple_vuse (stmt);
6291 33737966 : tree vdef = gimple_vdef (stmt);
6292 :
6293 33737966 : if (TREE_CODE (op) == SSA_NAME)
6294 15342042 : 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 33737966 : vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
6313 33737966 : if (vnresult
6314 1709905 : && vnresult->result)
6315 : {
6316 1709905 : tree result = vnresult->result;
6317 1709905 : gcc_checking_assert (TREE_CODE (result) != SSA_NAME
6318 : || result == SSA_VAL (result));
6319 1709905 : resultsame = expressions_equal_p (result, op);
6320 1709905 : if (resultsame)
6321 : {
6322 : /* If the TBAA state isn't compatible for downstream reads
6323 : we cannot value-number the VDEFs the same. */
6324 53777 : ao_ref lhs_ref;
6325 53777 : ao_ref_init (&lhs_ref, lhs);
6326 53777 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
6327 53777 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
6328 53777 : if ((vnresult->set != set
6329 938 : && ! alias_set_subset_of (set, vnresult->set))
6330 54386 : || (vnresult->base_set != base_set
6331 8204 : && ! alias_set_subset_of (base_set, vnresult->base_set)))
6332 2713 : resultsame = false;
6333 : }
6334 : }
6335 :
6336 2713 : if (!resultsame)
6337 : {
6338 33686902 : if (dump_file && (dump_flags & TDF_DETAILS))
6339 : {
6340 20385 : fprintf (dump_file, "No store match\n");
6341 20385 : fprintf (dump_file, "Value numbering store ");
6342 20385 : print_generic_expr (dump_file, lhs);
6343 20385 : fprintf (dump_file, " to ");
6344 20385 : print_generic_expr (dump_file, op);
6345 20385 : 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 33686902 : if (vdef)
6350 33686902 : changed |= set_ssa_val_to (vdef, vdef);
6351 :
6352 : /* Do not insert structure copies into the tables. */
6353 33686902 : if (is_gimple_min_invariant (op)
6354 33686902 : || is_gimple_reg (op))
6355 30025609 : vn_reference_insert (lhs, op, vdef, NULL);
6356 :
6357 : /* Only perform the following when being called from PRE
6358 : which embeds tail merging. */
6359 33686902 : if (default_vn_walk_kind == VN_WALK)
6360 : {
6361 7636811 : assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
6362 7636811 : vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
6363 7636811 : if (!vnresult)
6364 7594821 : 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 51064 : 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 51064 : changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
6377 : }
6378 :
6379 33737966 : 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 34806588 : visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
6390 : {
6391 34806588 : tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
6392 34806588 : bool seen_undef_visited = false;
6393 34806588 : tree backedge_val = NULL_TREE;
6394 34806588 : bool seen_non_backedge = false;
6395 34806588 : tree sameval_base = NULL_TREE;
6396 34806588 : poly_int64 soff, doff;
6397 34806588 : unsigned n_executable = 0;
6398 34806588 : edge sameval_e = NULL;
6399 :
6400 : /* TODO: We could check for this in initialization, and replace this
6401 : with a gcc_assert. */
6402 34806588 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
6403 30854 : 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 34775734 : if (!inserted)
6409 27212342 : gimple_set_plf (phi, GF_PLF_1, false);
6410 :
6411 34775734 : 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 34775734 : auto_vec<edge, 2> preds;
6416 69551468 : preds.reserve_exact (EDGE_COUNT (bb->preds));
6417 34775734 : bool seen_nonconstant = false;
6418 149783575 : for (unsigned i = 0; i < EDGE_COUNT (bb->preds); ++i)
6419 : {
6420 80232107 : edge e = EDGE_PRED (bb, i);
6421 80232107 : preds.quick_push (e);
6422 80232107 : if (!seen_nonconstant)
6423 : {
6424 42596208 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6425 42596208 : if (TREE_CODE (def) == SSA_NAME)
6426 : {
6427 33024452 : seen_nonconstant = true;
6428 33024452 : if (i != 0)
6429 5819604 : 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 146387038 : for (edge e : preds)
6437 69055092 : if (e->flags & EDGE_EXECUTABLE)
6438 : {
6439 63987051 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
6440 :
6441 63987051 : if (def == PHI_RESULT (phi))
6442 335892 : continue;
6443 63676432 : ++n_executable;
6444 63676432 : bool visited = true;
6445 63676432 : if (TREE_CODE (def) == SSA_NAME)
6446 : {
6447 51388956 : tree val = SSA_VAL (def, &visited);
6448 51388956 : if (SSA_NAME_IS_DEFAULT_DEF (def))
6449 2713399 : visited = true;
6450 51388956 : if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
6451 48841509 : def = val;
6452 51388956 : if (e->flags & EDGE_DFS_BACK)
6453 15444506 : backedge_val = def;
6454 : }
6455 63676432 : if (!(e->flags & EDGE_DFS_BACK))
6456 48089444 : seen_non_backedge = true;
6457 63676432 : if (def == VN_TOP)
6458 : ;
6459 : /* Ignore undefined defs for sameval but record one. */
6460 63676432 : else if (TREE_CODE (def) == SSA_NAME
6461 47946960 : && ! virtual_operand_p (def)
6462 88003069 : && ssa_undefined_value_p (def, false))
6463 : {
6464 235963 : 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 200813 : seen_undef = def;
6470 200813 : seen_undef_visited = visited;
6471 : }
6472 : }
6473 63440469 : else if (sameval == VN_TOP)
6474 : {
6475 : sameval = def;
6476 : sameval_e = e;
6477 : }
6478 28712404 : else if (expressions_equal_p (def, sameval))
6479 : sameval_e = NULL;
6480 45141657 : else if (virtual_operand_p (def))
6481 : {
6482 : sameval = NULL_TREE;
6483 26995256 : 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 16829711 : if (TREE_CODE (def) == ADDR_EXPR
6491 393172 : && TREE_CODE (sameval) == ADDR_EXPR
6492 108250 : && sameval_base != (void *)-1)
6493 : {
6494 108250 : if (!sameval_base)
6495 108248 : sameval_base = get_addr_base_and_unit_offset
6496 108248 : (TREE_OPERAND (sameval, 0), &soff);
6497 108248 : if (!sameval_base)
6498 : sameval_base = (tree)(void *)-1;
6499 108255 : else if ((get_addr_base_and_unit_offset
6500 108250 : (TREE_OPERAND (def, 0), &doff) == sameval_base)
6501 108250 : && known_eq (soff, doff))
6502 5 : continue;
6503 : }
6504 : /* There's also the possibility to use equivalences. */
6505 32567409 : 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 15632184 : && (TREE_CODE (sameval) != SSA_NAME
6509 12312321 : || SSA_VAL (sameval) == sameval)
6510 32461827 : && (TREE_CODE (def) != SSA_NAME || SSA_VAL (def) == def))
6511 : {
6512 15632109 : vn_nary_op_t vnresult;
6513 15632109 : tree ops[2];
6514 15632109 : ops[0] = def;
6515 15632109 : ops[1] = sameval;
6516 : /* Canonicalize the operands order for eq below. */
6517 15632109 : if (tree_swap_operands_p (ops[0], ops[1]))
6518 9380926 : std::swap (ops[0], ops[1]);
6519 15632109 : tree val = vn_nary_op_lookup_pieces (2, EQ_EXPR,
6520 : boolean_type_node,
6521 : ops, &vnresult);
6522 15632109 : if (! val && vnresult && vnresult->predicated_values)
6523 : {
6524 213858 : val = vn_nary_op_get_predicated_value (vnresult, e);
6525 120039 : if (val && integer_truep (val)
6526 239246 : && !(sameval_e && (sameval_e->flags & EDGE_DFS_BACK)))
6527 : {
6528 25268 : 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 25268 : 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 34775734 : bool visited_p;
6554 34775734 : if ((backedge_val
6555 34775734 : && !seen_non_backedge
6556 1857 : && TREE_CODE (backedge_val) == SSA_NAME
6557 1590 : && sameval == backedge_val
6558 313 : && (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 34777318 : || (sameval
6563 7780205 : && TREE_CODE (sameval) == SSA_NAME
6564 4619063 : && !SSA_NAME_IS_DEFAULT_DEF (sameval)
6565 3902096 : && SSA_NAME_IS_VIRTUAL_OPERAND (sameval)
6566 1961900 : && (SSA_VAL (sameval, &visited_p), !visited_p)))
6567 : /* Note this just drops to VARYING without inserting the PHI into
6568 : the hashes. */
6569 300556 : 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 34475178 : else if (n_executable <= 1)
6573 6705421 : result = seen_undef ? seen_undef : sameval;
6574 : /* If we saw only undefined values and VN_TOP use one of the
6575 : undefined values. */
6576 27769757 : else if (sameval == VN_TOP)
6577 5526 : 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 27764231 : else if ((result = vn_phi_lookup (phi, backedges_varying_p)))
6581 : {
6582 4148171 : if (!inserted
6583 70851 : && TREE_CODE (result) == SSA_NAME
6584 4219022 : && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI)
6585 : {
6586 70851 : gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true);
6587 70851 : 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 23616060 : else if (sameval
6600 23616060 : && (! seen_undef || is_gimple_min_invariant (sameval)))
6601 : result = sameval;
6602 : else
6603 : {
6604 22989943 : 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 22989943 : vn_phi_insert (phi, result, backedges_varying_p);
6609 22989943 : if (inserted)
6610 3328930 : *inserted = true;
6611 : }
6612 :
6613 34775734 : return set_ssa_val_to (PHI_RESULT (phi), result);
6614 34775734 : }
6615 :
6616 : /* Try to simplify RHS using equivalences and constant folding. */
6617 :
6618 : static tree
6619 130055654 : try_to_simplify (gassign *stmt)
6620 : {
6621 130055654 : enum tree_code code = gimple_assign_rhs_code (stmt);
6622 130055654 : 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 130055654 : if (code == SSA_NAME)
6627 : return NULL_TREE;
6628 :
6629 : /* First try constant folding based on our current lattice. */
6630 114713284 : mprts_hook = vn_lookup_simplify_result;
6631 114713284 : tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
6632 114713284 : mprts_hook = NULL;
6633 114713284 : if (tem
6634 114713284 : && (TREE_CODE (tem) == SSA_NAME
6635 25516640 : || is_gimple_min_invariant (tem)))
6636 25559941 : 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 481807064 : visit_stmt (gimple *stmt, bool backedges_varying_p = false)
6646 : {
6647 481807064 : bool changed = false;
6648 :
6649 481807064 : if (dump_file && (dump_flags & TDF_DETAILS))
6650 : {
6651 411413 : fprintf (dump_file, "Value numbering stmt = ");
6652 411413 : print_gimple_stmt (dump_file, stmt, 0);
6653 : }
6654 :
6655 481807064 : if (gimple_code (stmt) == GIMPLE_PHI)
6656 27233483 : changed = visit_phi (stmt, NULL, backedges_varying_p);
6657 630265464 : else if (gimple_has_volatile_ops (stmt))
6658 9246002 : changed = defs_to_varying (stmt);
6659 445327579 : else if (gassign *ass = dyn_cast <gassign *> (stmt))
6660 : {
6661 135213155 : enum tree_code code = gimple_assign_rhs_code (ass);
6662 135213155 : tree lhs = gimple_assign_lhs (ass);
6663 135213155 : tree rhs1 = gimple_assign_rhs1 (ass);
6664 135213155 : tree simplified;
6665 :
6666 : /* Shortcut for copies. Simplifying copies is pointless,
6667 : since we copy the expression and value they represent. */
6668 135213155 : if (code == SSA_NAME
6669 20499871 : && TREE_CODE (lhs) == SSA_NAME)
6670 : {
6671 5157501 : changed = visit_copy (lhs, rhs1);
6672 5157501 : goto done;
6673 : }
6674 130055654 : simplified = try_to_simplify (ass);
6675 130055654 : if (simplified)
6676 : {
6677 25559941 : if (dump_file && (dump_flags & TDF_DETAILS))
6678 : {
6679 14767 : fprintf (dump_file, "RHS ");
6680 14767 : print_gimple_expr (dump_file, ass, 0);
6681 14767 : fprintf (dump_file, " simplified to ");
6682 14767 : print_generic_expr (dump_file, simplified);
6683 14767 : 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 25559941 : if (simplified
6691 25559941 : && is_gimple_min_invariant (simplified)
6692 22530189 : && TREE_CODE (lhs) == SSA_NAME)
6693 : {
6694 7789712 : changed = set_ssa_val_to (lhs, simplified);
6695 7789712 : goto done;
6696 : }
6697 122265942 : else if (simplified
6698 17770229 : && TREE_CODE (simplified) == SSA_NAME
6699 3029752 : && TREE_CODE (lhs) == SSA_NAME)
6700 : {
6701 3029752 : changed = visit_copy (lhs, simplified);
6702 3029752 : goto done;
6703 : }
6704 :
6705 119236190 : if ((TREE_CODE (lhs) == SSA_NAME
6706 : /* We can substitute SSA_NAMEs that are live over
6707 : abnormal edges with their constant value. */
6708 85497922 : && !(gimple_assign_copy_p (ass)
6709 26 : && is_gimple_min_invariant (rhs1))
6710 85497896 : && !(simplified
6711 0 : && is_gimple_min_invariant (simplified))
6712 85497896 : && 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 204732773 : || (code == SSA_NAME
6716 15342370 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
6717 1641 : changed = defs_to_varying (ass);
6718 119234549 : else if (REFERENCE_CLASS_P (lhs)
6719 119234549 : || DECL_P (lhs))
6720 33737966 : changed = visit_reference_op_store (lhs, rhs1, ass);
6721 85496583 : else if (TREE_CODE (lhs) == SSA_NAME)
6722 : {
6723 85496583 : if ((gimple_assign_copy_p (ass)
6724 26 : && is_gimple_min_invariant (rhs1))
6725 85496609 : || (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 85496583 : switch (vn_get_stmt_kind (ass))
6737 : {
6738 50002068 : case VN_NARY:
6739 50002068 : changed = visit_nary_op (lhs, ass);
6740 50002068 : break;
6741 35385259 : case VN_REFERENCE:
6742 35385259 : changed = visit_reference_op_load (lhs, rhs1, ass);
6743 35385259 : break;
6744 109256 : default:
6745 109256 : changed = defs_to_varying (ass);
6746 109256 : break;
6747 : }
6748 : }
6749 : }
6750 : else
6751 0 : changed = defs_to_varying (ass);
6752 : }
6753 310114424 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
6754 : {
6755 25419828 : tree lhs = gimple_call_lhs (call_stmt);
6756 25419828 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
6757 : {
6758 : /* Try constant folding based on our current lattice. */
6759 8522232 : tree simplified = gimple_fold_stmt_to_constant_1 (call_stmt,
6760 : vn_valueize);
6761 8522232 : if (simplified)
6762 : {
6763 68014 : 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 68014 : if (simplified
6777 68014 : && is_gimple_min_invariant (simplified))
6778 : {
6779 61502 : changed = set_ssa_val_to (lhs, simplified);
6780 123004 : if (gimple_vdef (call_stmt))
6781 740 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6782 : SSA_VAL (gimple_vuse (call_stmt)));
6783 61502 : goto done;
6784 : }
6785 8460730 : else if (simplified
6786 6512 : && TREE_CODE (simplified) == SSA_NAME)
6787 : {
6788 309 : changed = visit_copy (lhs, simplified);
6789 618 : if (gimple_vdef (call_stmt))
6790 0 : changed |= set_ssa_val_to (gimple_vdef (call_stmt),
6791 : SSA_VAL (gimple_vuse (call_stmt)));
6792 309 : goto done;
6793 : }
6794 8460421 : 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 25357603 : tree fn = gimple_call_fn (stmt);
6803 25357603 : int extra_fnflags = 0;
6804 25357603 : if (fn && TREE_CODE (fn) == SSA_NAME)
6805 : {
6806 540645 : fn = SSA_VAL (fn);
6807 540645 : if (TREE_CODE (fn) == ADDR_EXPR
6808 540645 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
6809 5326 : extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
6810 : }
6811 25357603 : 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 25357603 : ((gimple_call_flags (call_stmt) | extra_fnflags)
6815 25357603 : & (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 21319591 : || (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 21284817 : && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
6829 : /* Only perform the following when being called from PRE
6830 : which embeds tail merging. */
6831 20714091 : && default_vn_walk_kind == VN_WALK))
6832 : /* Do not process .DEFERRED_INIT since that confuses uninit
6833 : analysis. */
6834 30420140 : && !gimple_call_internal_p (call_stmt, IFN_DEFERRED_INIT))
6835 8824351 : changed = visit_reference_op_call (lhs, call_stmt);
6836 : else
6837 16533252 : changed = defs_to_varying (call_stmt);
6838 : }
6839 : else
6840 284694596 : changed = defs_to_varying (stmt);
6841 481807064 : done:
6842 481807064 : return changed;
6843 : }
6844 :
6845 :
6846 : /* Allocate a value number table. */
6847 :
6848 : static void
6849 6311883 : allocate_vn_table (vn_tables_t table, unsigned size)
6850 : {
6851 6311883 : table->phis = new vn_phi_table_type (size);
6852 6311883 : table->nary = new vn_nary_op_table_type (size);
6853 6311883 : table->references = new vn_reference_table_type (size);
6854 6311883 : }
6855 :
6856 : /* Free a value number table. */
6857 :
6858 : static void
6859 6311883 : free_vn_table (vn_tables_t table)
6860 : {
6861 : /* Walk over elements and release vectors. */
6862 6311883 : vn_reference_iterator_type hir;
6863 6311883 : vn_reference_t vr;
6864 78370530 : FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir)
6865 72058647 : vr->operands.release ();
6866 6311883 : delete table->phis;
6867 6311883 : table->phis = NULL;
6868 6311883 : delete table->nary;
6869 6311883 : table->nary = NULL;
6870 6311883 : delete table->references;
6871 6311883 : table->references = NULL;
6872 6311883 : }
6873 :
6874 : /* Set *ID according to RESULT. */
6875 :
6876 : static void
6877 35276735 : set_value_id_for_result (tree result, unsigned int *id)
6878 : {
6879 35276735 : if (result && TREE_CODE (result) == SSA_NAME)
6880 21963175 : *id = VN_INFO (result)->value_id;
6881 9959764 : else if (result && is_gimple_min_invariant (result))
6882 3765920 : *id = get_or_alloc_constant_value_id (result);
6883 : else
6884 9547640 : *id = get_next_value_id ();
6885 35276735 : }
6886 :
6887 : /* Set the value ids in the valid hash tables. */
6888 :
6889 : static void
6890 981527 : set_hashtable_value_ids (void)
6891 : {
6892 981527 : vn_nary_op_iterator_type hin;
6893 981527 : vn_phi_iterator_type hip;
6894 981527 : vn_reference_iterator_type hir;
6895 981527 : vn_nary_op_t vno;
6896 981527 : vn_reference_t vr;
6897 981527 : vn_phi_t vp;
6898 :
6899 : /* Now set the value ids of the things we had put in the hash
6900 : table. */
6901 :
6902 25365841 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin)
6903 24384314 : if (! vno->predicated_values)
6904 7953368 : set_value_id_for_result (vno->u.result, &vno->value_id);
6905 :
6906 5072487 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip)
6907 4090960 : set_value_id_for_result (vp->result, &vp->value_id);
6908 :
6909 24213934 : FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t,
6910 : hir)
6911 23232407 : set_value_id_for_result (vr->result, &vr->value_id);
6912 981527 : }
6913 :
6914 : /* Return the maximum value id we have ever seen. */
6915 :
6916 : unsigned int
6917 1963054 : get_max_value_id (void)
6918 : {
6919 1963054 : return next_value_id;
6920 : }
6921 :
6922 : /* Return the maximum constant value id we have ever seen. */
6923 :
6924 : unsigned int
6925 1963054 : get_max_constant_value_id (void)
6926 : {
6927 1963054 : return -next_constant_value_id;
6928 : }
6929 :
6930 : /* Return the next unique value id. */
6931 :
6932 : unsigned int
6933 50174385 : get_next_value_id (void)
6934 : {
6935 50174385 : gcc_checking_assert ((int)next_value_id > 0);
6936 50174385 : return next_value_id++;
6937 : }
6938 :
6939 : /* Return the next unique value id for constants. */
6940 :
6941 : unsigned int
6942 2575531 : get_next_constant_value_id (void)
6943 : {
6944 2575531 : gcc_checking_assert (next_constant_value_id < 0);
6945 2575531 : 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 251884604 : expressions_equal_p (tree e1, tree e2, bool match_vn_top_optimistically)
6955 : {
6956 : /* The obvious case. */
6957 251884604 : if (e1 == e2)
6958 : return true;
6959 :
6960 : /* If either one is VN_TOP consider them equal. */
6961 71532829 : if (match_vn_top_optimistically
6962 66594250 : && (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 71532829 : if (!e1 || !e2)
6970 : return false;
6971 :
6972 : /* SSA_NAME compare pointer equal. */
6973 71532829 : if (TREE_CODE (e1) == SSA_NAME || TREE_CODE (e2) == SSA_NAME)
6974 : return false;
6975 :
6976 : /* Now perform the actual comparison. */
6977 35917713 : if (TREE_CODE (e1) == TREE_CODE (e2)
6978 35917713 : && 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 5719149 : vn_nary_may_trap (vn_nary_op_t nary)
6990 : {
6991 5719149 : tree type;
6992 5719149 : tree rhs2 = NULL_TREE;
6993 5719149 : bool honor_nans = false;
6994 5719149 : bool honor_snans = false;
6995 5719149 : bool fp_operation = false;
6996 5719149 : bool honor_trapv = false;
6997 5719149 : bool handled, ret;
6998 5719149 : unsigned i;
6999 :
7000 5719149 : if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
7001 : || TREE_CODE_CLASS (nary->opcode) == tcc_unary
7002 5719149 : || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
7003 : {
7004 5598701 : type = nary->type;
7005 5598701 : fp_operation = FLOAT_TYPE_P (type);
7006 5478249 : if (fp_operation)
7007 : {
7008 120452 : honor_nans = flag_trapping_math && !flag_finite_math_only;
7009 120452 : honor_snans = flag_signaling_nans != 0;
7010 : }
7011 5478249 : else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
7012 : honor_trapv = true;
7013 : }
7014 5719149 : if (nary->length >= 2)
7015 2302596 : rhs2 = nary->op[1];
7016 5719149 : ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
7017 : honor_trapv, honor_nans, honor_snans,
7018 : rhs2, &handled);
7019 5719149 : if (handled && ret)
7020 : return true;
7021 :
7022 13433850 : for (i = 0; i < nary->length; ++i)
7023 7834484 : 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 943359 : vn_reference_may_trap (vn_reference_t ref)
7033 : {
7034 943359 : 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 2600375 : FOR_EACH_VEC_ELT (ref->operands, i, op)
7049 : {
7050 2600120 : switch (op->opcode)
7051 : {
7052 : case WITH_SIZE_EXPR:
7053 : case TARGET_MEM_REF:
7054 : /* Always variable. */
7055 : return true;
7056 729482 : case COMPONENT_REF:
7057 729482 : 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 204715 : case ARRAY_REF:
7065 204715 : {
7066 204715 : if (TREE_CODE (op->op0) != INTEGER_CST)
7067 : return true;
7068 :
7069 : /* !in_array_bounds */
7070 184245 : tree domain_type = TYPE_DOMAIN (ref->operands[i+1].type);
7071 184245 : if (!domain_type)
7072 : return true;
7073 :
7074 184199 : tree min = op->op1;
7075 184199 : tree max = TYPE_MAX_VALUE (domain_type);
7076 184199 : if (!min
7077 184199 : || !max
7078 171266 : || TREE_CODE (min) != INTEGER_CST
7079 171266 : || TREE_CODE (max) != INTEGER_CST)
7080 : return true;
7081 :
7082 168582 : if (tree_int_cst_lt (op->op0, min)
7083 168582 : || tree_int_cst_lt (max, op->op0))
7084 : 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 535405 : case ADDR_EXPR:
7095 535405 : if (op->op0)
7096 535405 : return tree_could_trap_p (TREE_OPERAND (op->op0, 0));
7097 : return false;
7098 1743199 : default:;
7099 : }
7100 : }
7101 : return false;
7102 : }
7103 :
7104 10708821 : eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction,
7105 : bitmap inserted_exprs_)
7106 10708821 : : dom_walker (direction), do_pre (inserted_exprs_ != NULL),
7107 10708821 : el_todo (0), eliminations (0), insertions (0),
7108 10708821 : inserted_exprs (inserted_exprs_)
7109 : {
7110 10708821 : need_eh_cleanup = BITMAP_ALLOC (NULL);
7111 10708821 : need_ab_cleanup = BITMAP_ALLOC (NULL);
7112 10708821 : }
7113 :
7114 10708821 : eliminate_dom_walker::~eliminate_dom_walker ()
7115 : {
7116 10708821 : BITMAP_FREE (need_eh_cleanup);
7117 10708821 : BITMAP_FREE (need_ab_cleanup);
7118 10708821 : }
7119 :
7120 : /* Return a leader for OP that is available at the current point of the
7121 : eliminate domwalk. */
7122 :
7123 : tree
7124 187133968 : eliminate_dom_walker::eliminate_avail (basic_block, tree op)
7125 : {
7126 187133968 : tree valnum = VN_INFO (op)->valnum;
7127 187133968 : if (TREE_CODE (valnum) == SSA_NAME)
7128 : {
7129 181939053 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
7130 : return valnum;
7131 316678299 : if (avail.length () > SSA_NAME_VERSION (valnum))
7132 : {
7133 142616893 : 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 142616893 : gassign *ass;
7139 250948427 : if (av && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (av))))
7140 77075575 : if (gimple_assign_rhs_class (ass) == GIMPLE_SINGLE_RHS)
7141 : {
7142 40826742 : tree rhs1 = gimple_assign_rhs1 (ass);
7143 40826742 : if (CONSTANT_CLASS_P (rhs1)
7144 40826742 : || (TREE_CODE (rhs1) == SSA_NAME
7145 35173 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
7146 : av = rhs1;
7147 : }
7148 : return av;
7149 : }
7150 : }
7151 5194915 : else if (is_gimple_min_invariant (valnum))
7152 5194915 : return valnum;
7153 : return NULL_TREE;
7154 : }
7155 :
7156 : /* At the current point of the eliminate domwalk make OP available. */
7157 :
7158 : void
7159 51389509 : eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
7160 : {
7161 51389509 : tree valnum = VN_INFO (op)->valnum;
7162 51389509 : if (TREE_CODE (valnum) == SSA_NAME)
7163 : {
7164 99309573 : if (avail.length () <= SSA_NAME_VERSION (valnum))
7165 17472515 : avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1, true);
7166 51389509 : tree pushop = op;
7167 51389509 : if (avail[SSA_NAME_VERSION (valnum)])
7168 45312 : pushop = avail[SSA_NAME_VERSION (valnum)];
7169 51389509 : avail_stack.safe_push (pushop);
7170 51389509 : avail[SSA_NAME_VERSION (valnum)] = op;
7171 : }
7172 51389509 : }
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 137519 : 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 137519 : gimple_seq stmts = VN_INFO (val)->expr;
7183 137519 : if (!gimple_seq_singleton_p (stmts))
7184 : return NULL_TREE;
7185 137519 : gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts));
7186 137519 : if (!stmt
7187 137519 : || (!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 106 : || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)))
7193 : return NULL_TREE;
7194 :
7195 44295 : tree op = gimple_assign_rhs1 (stmt);
7196 44295 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
7197 44295 : || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7198 20420 : op = TREE_OPERAND (op, 0);
7199 44295 : tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op;
7200 44249 : if (!leader)
7201 : return NULL_TREE;
7202 :
7203 34091 : tree res;
7204 34091 : stmts = NULL;
7205 53517 : if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
7206 34446 : res = gimple_build (&stmts, BIT_FIELD_REF,
7207 17223 : TREE_TYPE (val), leader,
7208 17223 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
7209 17223 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
7210 16868 : else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
7211 204 : res = gimple_build (&stmts, BIT_AND_EXPR,
7212 102 : TREE_TYPE (val), leader, gimple_assign_rhs2 (stmt));
7213 : else
7214 16766 : res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
7215 16766 : TREE_TYPE (val), leader);
7216 34091 : if (TREE_CODE (res) != SSA_NAME
7217 34090 : || SSA_NAME_IS_DEFAULT_DEF (res)
7218 68181 : || 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 : return NULL_TREE;
7243 : }
7244 : else
7245 : {
7246 34087 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
7247 34087 : vn_ssa_aux_t vn_info = VN_INFO (res);
7248 34087 : vn_info->valnum = val;
7249 34087 : vn_info->visited = true;
7250 : }
7251 :
7252 34087 : insertions++;
7253 34087 : 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 374710740 : eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
7264 : {
7265 374710740 : tree sprime = NULL_TREE;
7266 374710740 : gimple *stmt = gsi_stmt (*gsi);
7267 374710740 : tree lhs = gimple_get_lhs (stmt);
7268 123697447 : if (lhs && TREE_CODE (lhs) == SSA_NAME
7269 170961526 : && !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 459124132 : && !(gimple_assign_single_p (stmt)
7278 36515882 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
7279 2494250 : && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
7280 4184 : && is_global_var (gimple_assign_rhs1 (stmt)))))
7281 : {
7282 84413148 : sprime = eliminate_avail (b, lhs);
7283 84413148 : 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 70979658 : tree val = VN_INFO (lhs)->valnum;
7289 70979658 : vn_ssa_aux_t vn_info;
7290 70979658 : if (val != VN_TOP
7291 70979658 : && TREE_CODE (val) == SSA_NAME
7292 70979658 : && (vn_info = VN_INFO (val), true)
7293 70979658 : && vn_info->needs_insertion
7294 335473 : && vn_info->expr != NULL
7295 71117177 : && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE)
7296 34087 : 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 70979658 : if (sprime
7303 13467577 : && TREE_CODE (sprime) == SSA_NAME)
7304 9258001 : 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 9258001 : if (sprime
7312 13467577 : && TREE_CODE (sprime) == SSA_NAME
7313 9258001 : && do_pre
7314 948013 : && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1)
7315 929241 : && loop_outer (b->loop_father)
7316 402177 : && has_zero_uses (sprime)
7317 197279 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
7318 197071 : && gimple_assign_load_p (stmt))
7319 : {
7320 107125 : gimple *def_stmt = SSA_NAME_DEF_STMT (sprime);
7321 107125 : basic_block def_bb = gimple_bb (def_stmt);
7322 107125 : if (gimple_code (def_stmt) == GIMPLE_PHI
7323 107125 : && def_bb->loop_father->header == def_bb)
7324 : {
7325 67207 : loop_p loop = def_bb->loop_father;
7326 67207 : ssa_op_iter iter;
7327 67207 : tree op;
7328 67207 : bool found = false;
7329 85438 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
7330 : {
7331 63499 : affine_iv iv;
7332 63499 : def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
7333 63499 : if (def_bb
7334 57283 : && flow_bb_inside_loop_p (loop, def_bb)
7335 115542 : && simple_iv (loop, loop, op, &iv, true))
7336 : {
7337 45268 : found = true;
7338 45268 : break;
7339 : }
7340 : }
7341 21939 : if (found)
7342 : {
7343 45268 : 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 : sprime = NULL_TREE;
7355 : }
7356 : }
7357 : }
7358 :
7359 84413148 : 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 13422309 : if (may_propagate_copy (lhs, sprime))
7364 : {
7365 : /* Mark it for removal. */
7366 13420368 : to_remove.safe_push (stmt);
7367 :
7368 : /* ??? Don't count copy/constant propagations. */
7369 13420368 : if (gimple_assign_single_p (stmt)
7370 13420368 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7371 4707104 : || gimple_assign_rhs1 (stmt) == sprime))
7372 14279851 : return;
7373 :
7374 8167428 : if (dump_file && (dump_flags & TDF_DETAILS))
7375 : {
7376 19016 : fprintf (dump_file, "Replaced ");
7377 19016 : print_gimple_expr (dump_file, stmt, 0);
7378 19016 : fprintf (dump_file, " with ");
7379 19016 : print_generic_expr (dump_file, sprime);
7380 19016 : fprintf (dump_file, " in all uses of ");
7381 19016 : print_gimple_stmt (dump_file, stmt, 0);
7382 : }
7383 :
7384 8167428 : eliminations++;
7385 8167428 : 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 1941 : 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 1942 : && 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 : 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 361288431 : if (gimple_assign_single_p (stmt)
7469 130846708 : && !gimple_has_volatile_ops (stmt)
7470 56841589 : && !is_gimple_reg (gimple_assign_lhs (stmt))
7471 29210107 : && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
7472 2849543 : || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
7473 390494529 : && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
7474 16656944 : || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
7475 : {
7476 26073630 : tree rhs = gimple_assign_rhs1 (stmt);
7477 26073630 : 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 26073630 : tree lookup_lhs = lhs;
7484 51877883 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
7485 13609248 : && (TREE_CODE (lhs) != COMPONENT_REF
7486 8234374 : || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
7487 39480180 : && !type_has_mode_precision_p (TREE_TYPE (lhs)))
7488 : {
7489 842208 : if (BITINT_TYPE_P (TREE_TYPE (lhs))
7490 437523 : && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE)
7491 : lookup_lhs = NULL_TREE;
7492 419284 : else if (TREE_CODE (lhs) == COMPONENT_REF
7493 419284 : || TREE_CODE (lhs) == MEM_REF)
7494 : {
7495 293841 : tree ltype = build_nonstandard_integer_type
7496 293841 : (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhs))),
7497 293841 : TYPE_UNSIGNED (TREE_TYPE (lhs)));
7498 293841 : if (TREE_CODE (lhs) == COMPONENT_REF)
7499 : {
7500 225248 : tree foff = component_ref_field_offset (lhs);
7501 225248 : tree f = TREE_OPERAND (lhs, 1);
7502 225248 : if (!poly_int_tree_p (foff))
7503 : lookup_lhs = NULL_TREE;
7504 : else
7505 450496 : lookup_lhs = build3 (BIT_FIELD_REF, ltype,
7506 225248 : TREE_OPERAND (lhs, 0),
7507 225248 : TYPE_SIZE (TREE_TYPE (lhs)),
7508 : bit_from_pos
7509 225248 : (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 25940898 : tree val = NULL_TREE, tem;
7520 25940898 : if (lookup_lhs)
7521 51881796 : val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
7522 : VN_WALKREWRITE, &vnresult, false,
7523 : NULL, NULL_TREE, true);
7524 26073630 : if (TREE_CODE (rhs) == SSA_NAME)
7525 12549154 : rhs = VN_INFO (rhs)->valnum;
7526 26073630 : gassign *ass;
7527 26073630 : if (val
7528 26073630 : && (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 3200587 : || (TREE_CODE (val) == SSA_NAME
7533 1955197 : && gimple_assign_single_p (SSA_NAME_DEF_STMT (val))
7534 1776838 : && (tem = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val)))
7535 1776838 : && TREE_CODE (tem) == VIEW_CONVERT_EXPR
7536 3538 : && TREE_OPERAND (tem, 0) == rhs)
7537 3200585 : || (TREE_CODE (rhs) == SSA_NAME
7538 26554152 : && (ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs)))
7539 1522237 : && gimple_assign_rhs1 (ass) == val
7540 708828 : && 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 252077 : ao_ref lhs_ref;
7547 252077 : ao_ref_init (&lhs_ref, lhs);
7548 252077 : alias_set_type set = ao_ref_alias_set (&lhs_ref);
7549 252077 : alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
7550 252077 : if (! vnresult
7551 252077 : || ((vnresult->set == set
7552 54531 : || alias_set_subset_of (set, vnresult->set))
7553 233285 : && (vnresult->base_set == base_set
7554 25747 : || alias_set_subset_of (base_set, vnresult->base_set))))
7555 : {
7556 228306 : 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 228306 : to_remove.safe_push (stmt);
7564 228306 : 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 361060125 : if (gcond *cond = dyn_cast <gcond *> (stmt))
7573 : {
7574 19494731 : if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
7575 19494731 : ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
7576 : {
7577 629236 : 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 629236 : if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
7583 629236 : == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
7584 250664 : gimple_cond_make_true (cond);
7585 : else
7586 378572 : gimple_cond_make_false (cond);
7587 629236 : update_stmt (cond);
7588 629236 : el_todo |= TODO_cleanup_cfg;
7589 629236 : return;
7590 : }
7591 : }
7592 :
7593 360430889 : bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
7594 360430889 : bool was_noreturn = (is_gimple_call (stmt)
7595 360430889 : && gimple_call_noreturn_p (stmt));
7596 360430889 : tree vdef = gimple_vdef (stmt);
7597 360430889 : 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 360430889 : bool modified = false;
7603 360430889 : use_operand_p use_p;
7604 360430889 : ssa_op_iter iter;
7605 531042599 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
7606 : {
7607 170611710 : tree use = USE_FROM_PTR (use_p);
7608 : /* ??? The call code above leaves stmt operands un-updated. */
7609 170611710 : if (TREE_CODE (use) != SSA_NAME)
7610 0 : continue;
7611 170611710 : tree sprime;
7612 170611710 : 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 27333384 : 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 143278326 : sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use);
7624 170611710 : if (sprime && sprime != use
7625 13560675 : && 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 184171668 : && (!inserted_exprs
7631 1222319 : || TREE_CODE (sprime) != SSA_NAME
7632 1204486 : || !is_gimple_debug (stmt)
7633 383578 : || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
7634 : {
7635 13210858 : propagate_value (use_p, sprime);
7636 13210858 : 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 360430889 : gimple *old_stmt = stmt;
7643 360430889 : 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 12296153 : if (gimple_assign_single_p (stmt)
7648 12296153 : && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
7649 244756 : recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
7650 12296153 : gimple_stmt_iterator prev = *gsi;
7651 12296153 : gsi_prev (&prev);
7652 12296153 : 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 1037671 : if (gsi_end_p (prev))
7660 225544 : prev = gsi_start_bb (b);
7661 : else
7662 924899 : gsi_next (&prev);
7663 1037671 : if (gsi_stmt (prev) != gsi_stmt (*gsi))
7664 108938 : do
7665 : {
7666 68662 : tree def;
7667 68662 : ssa_op_iter dit;
7668 133080 : 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 64418 : if (! has_VN_INFO (def))
7673 : {
7674 40174 : vn_ssa_aux_t vn_info = VN_INFO (def);
7675 40174 : vn_info->valnum = def;
7676 40174 : vn_info->visited = true;
7677 : }
7678 68662 : if (gsi_stmt (prev) == gsi_stmt (*gsi))
7679 : break;
7680 40276 : gsi_next (&prev);
7681 40276 : }
7682 : while (1);
7683 : }
7684 12296153 : stmt = gsi_stmt (*gsi);
7685 : /* In case we folded the stmt away schedule the NOP for removal. */
7686 12296153 : if (gimple_nop_p (stmt))
7687 844 : 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 360430889 : if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
7695 : {
7696 22918214 : tree fn = gimple_call_fn (call_stmt);
7697 22918214 : if (fn
7698 22096929 : && flag_devirtualize
7699 44268450 : && virtual_method_call_p (fn))
7700 : {
7701 186796 : tree otr_type = obj_type_ref_class (fn);
7702 186796 : unsigned HOST_WIDE_INT otr_tok
7703 186796 : = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));
7704 186796 : tree instance;
7705 186796 : ipa_polymorphic_call_context context (current_function_decl,
7706 186796 : fn, stmt, &instance);
7707 186796 : context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),
7708 : otr_type, stmt, NULL);
7709 186796 : bool final;
7710 186796 : vec <cgraph_node *> targets
7711 186796 : = possible_polymorphic_call_targets (obj_type_ref_class (fn),
7712 : otr_tok, context, &final);
7713 186796 : if (dump_file)
7714 22 : dump_possible_polymorphic_call_targets (dump_file,
7715 : obj_type_ref_class (fn),
7716 : otr_tok, context);
7717 187091 : 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 360430889 : if (modified)
7748 : {
7749 : /* When changing a call into a noreturn call, cfg cleanup
7750 : is needed to fix up the noreturn call. */
7751 12296174 : if (!was_noreturn
7752 12296174 : && 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 12296174 : if ((gimple_code (stmt) == GIMPLE_COND
7757 1557576 : && (gimple_cond_true_p (as_a <gcond *> (stmt))
7758 1551936 : || gimple_cond_false_p (as_a <gcond *> (stmt))))
7759 13845233 : || (gimple_code (stmt) == GIMPLE_SWITCH
7760 7700 : && TREE_CODE (gimple_switch_index
7761 : (as_a <gswitch *> (stmt))) == INTEGER_CST))
7762 10322 : el_todo |= TODO_cleanup_cfg;
7763 : /* If we removed EH side-effects from the statement, clean
7764 : its EH information. */
7765 12296174 : if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
7766 : {
7767 1961 : bitmap_set_bit (need_eh_cleanup,
7768 1961 : gimple_bb (stmt)->index);
7769 1961 : 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 12296174 : if (can_make_abnormal_goto
7774 12296174 : && !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 12296174 : 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 15642374 : if (vdef && SSA_NAME_IN_FREE_LIST (vdef))
7786 2164 : 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 360430889 : tree def;
7793 432757603 : FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
7794 72326714 : if (! has_zero_uses (def)
7795 72326714 : || (inserted_exprs
7796 216774 : && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (def))))
7797 70869389 : eliminate_push_avail (b, def);
7798 : }
7799 :
7800 : /* Perform elimination for the basic-block B during the domwalk. */
7801 :
7802 : edge
7803 42354972 : eliminate_dom_walker::before_dom_children (basic_block b)
7804 : {
7805 : /* Mark new bb. */
7806 42354972 : avail_stack.safe_push (NULL_TREE);
7807 :
7808 : /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */
7809 42354972 : if (!(b->flags & BB_EXECUTABLE))
7810 : return NULL;
7811 :
7812 37406223 : vn_context_bb = b;
7813 :
7814 49128511 : for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
7815 : {
7816 11722288 : gphi *phi = gsi.phi ();
7817 11722288 : tree res = PHI_RESULT (phi);
7818 :
7819 23444576 : if (virtual_operand_p (res))
7820 : {
7821 5405626 : gsi_next (&gsi);
7822 5405626 : continue;
7823 : }
7824 :
7825 6316662 : tree sprime = eliminate_avail (b, res);
7826 6316662 : if (sprime
7827 6316662 : && sprime != res)
7828 : {
7829 445886 : 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 445886 : if (! inserted_exprs
7840 568355 : || ! bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
7841 418041 : eliminations++;
7842 :
7843 : /* If we will propagate into all uses don't bother to do
7844 : anything. */
7845 445886 : if (may_propagate_copy (res, sprime))
7846 : {
7847 : /* Mark the PHI for removal. */
7848 445886 : to_remove.safe_push (phi);
7849 445886 : gsi_next (&gsi);
7850 445886 : 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 5870776 : eliminate_push_avail (b, res);
7864 5870776 : gsi_next (&gsi);
7865 : }
7866 :
7867 74812446 : for (gimple_stmt_iterator gsi = gsi_start_bb (b);
7868 297959345 : !gsi_end_p (gsi);
7869 260553122 : gsi_next (&gsi))
7870 260553122 : eliminate_stmt (b, &gsi);
7871 :
7872 : /* Replace destination PHI arguments. */
7873 37406223 : edge_iterator ei;
7874 37406223 : edge e;
7875 88272495 : FOR_EACH_EDGE (e, ei, b->succs)
7876 50866272 : if (e->flags & EDGE_EXECUTABLE)
7877 50303163 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
7878 80462059 : !gsi_end_p (gsi);
7879 30158896 : gsi_next (&gsi))
7880 : {
7881 30158896 : gphi *phi = gsi.phi ();
7882 30158896 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
7883 30158896 : tree arg = USE_FROM_PTR (use_p);
7884 49878344 : if (TREE_CODE (arg) != SSA_NAME
7885 30158896 : || virtual_operand_p (arg))
7886 19719448 : continue;
7887 10439448 : tree sprime = eliminate_avail (b, arg);
7888 20878896 : if (sprime && may_propagate_copy (arg, sprime,
7889 10439448 : !(e->flags & EDGE_ABNORMAL)))
7890 10427364 : propagate_value (use_p, sprime);
7891 : }
7892 :
7893 37406223 : vn_context_bb = NULL;
7894 :
7895 37406223 : return NULL;
7896 : }
7897 :
7898 : /* Make no longer available leaders no longer available. */
7899 :
7900 : void
7901 42354972 : eliminate_dom_walker::after_dom_children (basic_block)
7902 : {
7903 42354972 : tree entry;
7904 93744481 : while ((entry = avail_stack.pop ()) != NULL_TREE)
7905 : {
7906 51389509 : tree valnum = VN_INFO (entry)->valnum;
7907 51389509 : tree old = avail[SSA_NAME_VERSION (valnum)];
7908 51389509 : if (old == entry)
7909 : avail[SSA_NAME_VERSION (valnum)] = NULL_TREE;
7910 : else
7911 45312 : avail[SSA_NAME_VERSION (valnum)] = entry;
7912 : }
7913 42354972 : }
7914 :
7915 : /* Remove queued stmts and perform delayed cleanups. */
7916 :
7917 : unsigned
7918 6292280 : eliminate_dom_walker::eliminate_cleanup (bool region_p)
7919 : {
7920 6292280 : statistics_counter_event (cfun, "Eliminated", eliminations);
7921 6292280 : 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 34303369 : while (!to_remove.is_empty ())
7928 : {
7929 15426473 : bool do_release_defs = true;
7930 15426473 : 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 15426473 : if (region_p)
7940 : {
7941 1810206 : if (gphi *phi = dyn_cast <gphi *> (stmt))
7942 : {
7943 1127317 : tree lhs = gimple_phi_result (phi);
7944 1127317 : if (!has_zero_uses (lhs))
7945 : {
7946 23972 : 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 23972 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7950 23972 : gimple *copy = gimple_build_assign (lhs, sprime);
7951 23972 : gimple_stmt_iterator gsi
7952 23972 : = gsi_after_labels (gimple_bb (stmt));
7953 23972 : gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
7954 23972 : do_release_defs = false;
7955 : }
7956 : }
7957 682889 : else if (tree lhs = gimple_get_lhs (stmt))
7958 682889 : if (TREE_CODE (lhs) == SSA_NAME
7959 682889 : && !has_zero_uses (lhs))
7960 : {
7961 2057 : 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 2057 : tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
7965 2057 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7966 2057 : if (is_gimple_assign (stmt))
7967 : {
7968 2057 : gimple_assign_set_rhs_from_tree (&gsi, sprime);
7969 2057 : stmt = gsi_stmt (gsi);
7970 2057 : update_stmt (stmt);
7971 2057 : if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
7972 0 : bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
7973 2057 : 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 15424416 : if (dump_file && (dump_flags & TDF_DETAILS))
7985 : {
7986 21753 : fprintf (dump_file, "Removing dead stmt ");
7987 21753 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
7988 : }
7989 :
7990 15424416 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7991 15424416 : if (gimple_code (stmt) == GIMPLE_PHI)
7992 1776955 : remove_phi_node (&gsi, do_release_defs);
7993 : else
7994 : {
7995 13647461 : basic_block bb = gimple_bb (stmt);
7996 13647461 : unlink_stmt_vdef (stmt);
7997 13647461 : if (gsi_remove (&gsi, true))
7998 26546 : bitmap_set_bit (need_eh_cleanup, bb->index);
7999 13647461 : if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt))
8000 2 : bitmap_set_bit (need_ab_cleanup, bb->index);
8001 13647461 : if (do_release_defs)
8002 13647461 : release_defs (stmt);
8003 : }
8004 :
8005 : /* Removing a stmt may expose a forwarder block. */
8006 15424416 : 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 6292336 : 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 6292280 : bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
8028 6292280 : bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
8029 :
8030 6292280 : if (do_eh_cleanup)
8031 10722 : gimple_purge_all_dead_eh_edges (need_eh_cleanup);
8032 :
8033 6292280 : if (do_ab_cleanup)
8034 2 : gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
8035 :
8036 6292280 : if (do_eh_cleanup || do_ab_cleanup)
8037 10724 : el_todo |= TODO_cleanup_cfg;
8038 :
8039 6292280 : return el_todo;
8040 : }
8041 :
8042 : /* Eliminate fully redundant computations. */
8043 :
8044 : unsigned
8045 4396938 : eliminate_with_rpo_vn (bitmap inserted_exprs)
8046 : {
8047 4396938 : eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);
8048 :
8049 4396938 : eliminate_dom_walker *saved_rpo_avail = rpo_avail;
8050 4396938 : rpo_avail = &walker;
8051 4396938 : walker.walk (cfun->cfg->x_entry_block_ptr);
8052 4396938 : rpo_avail = saved_rpo_avail;
8053 :
8054 4396938 : return walker.eliminate_cleanup ();
8055 4396938 : }
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 981527 : run_rpo_vn (vn_lookup_kind kind)
8064 : {
8065 981527 : do_rpo_vn_1 (cfun, NULL, NULL, true, false, false, kind);
8066 :
8067 : /* ??? Prune requirement of these. */
8068 981527 : 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 981527 : tree name;
8073 981527 : unsigned i;
8074 48316657 : FOR_EACH_SSA_NAME (i, name, cfun)
8075 : {
8076 34374963 : vn_ssa_aux_t info = VN_INFO (name);
8077 34374963 : if (!info->visited
8078 34297619 : || info->valnum == VN_TOP)
8079 77344 : info->valnum = name;
8080 34374963 : if (info->valnum == name)
8081 33197813 : info->value_id = get_next_value_id ();
8082 1177150 : else if (is_gimple_min_invariant (info->valnum))
8083 41879 : info->value_id = get_or_alloc_constant_value_id (info->valnum);
8084 : }
8085 :
8086 : /* Propagate. */
8087 48316657 : FOR_EACH_SSA_NAME (i, name, cfun)
8088 : {
8089 34374963 : vn_ssa_aux_t info = VN_INFO (name);
8090 34374963 : if (TREE_CODE (info->valnum) == SSA_NAME
8091 34333084 : && info->valnum != name
8092 35510234 : && info->value_id != VN_INFO (info->valnum)->value_id)
8093 1135271 : info->value_id = VN_INFO (info->valnum)->value_id;
8094 : }
8095 :
8096 981527 : set_hashtable_value_ids ();
8097 :
8098 981527 : 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 981527 : }
8114 :
8115 : /* Free VN associated data structures. */
8116 :
8117 : void
8118 6311883 : free_rpo_vn (void)
8119 : {
8120 6311883 : free_vn_table (valid_info);
8121 6311883 : XDELETE (valid_info);
8122 6311883 : obstack_free (&vn_tables_obstack, NULL);
8123 6311883 : obstack_free (&vn_tables_insert_obstack, NULL);
8124 :
8125 6311883 : vn_ssa_aux_iterator_type it;
8126 6311883 : vn_ssa_aux_t info;
8127 183335236 : FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it)
8128 177023353 : if (info->needs_insertion)
8129 4205514 : release_ssa_name (info->name);
8130 6311883 : obstack_free (&vn_ssa_aux_obstack, NULL);
8131 6311883 : delete vn_ssa_aux_hash;
8132 :
8133 6311883 : delete constant_to_value_id;
8134 6311883 : constant_to_value_id = NULL;
8135 6311883 : }
8136 :
8137 : /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
8138 :
8139 : static tree
8140 23518194 : vn_lookup_simplify_result (gimple_match_op *res_op)
8141 : {
8142 23518194 : if (!res_op->code.is_tree_code ())
8143 : return NULL_TREE;
8144 23515022 : tree *ops = res_op->ops;
8145 23515022 : unsigned int length = res_op->num_ops;
8146 23515022 : 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 23515022 : && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR)
8150 : {
8151 1058 : length = CONSTRUCTOR_NELTS (res_op->ops[0]);
8152 1058 : ops = XALLOCAVEC (tree, length);
8153 4774 : for (unsigned i = 0; i < length; ++i)
8154 3716 : ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value;
8155 : }
8156 23515022 : vn_nary_op_t vnresult = NULL;
8157 23515022 : 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 23515022 : if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail)
8162 2297884 : 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 282666738 : rpo_elim::eliminate_avail (basic_block bb, tree op)
8170 : {
8171 282666738 : bool visited;
8172 282666738 : 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 282666738 : if (!visited)
8176 : return op;
8177 280450027 : if (TREE_CODE (valnum) == SSA_NAME)
8178 : {
8179 265893787 : if (SSA_NAME_IS_DEFAULT_DEF (valnum))
8180 : return valnum;
8181 258928348 : vn_ssa_aux_t valnum_info = VN_INFO (valnum);
8182 258928348 : vn_avail *av = valnum_info->avail;
8183 258928348 : 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 85595357 : if (!valnum_info->visited)
8188 : return valnum;
8189 84712262 : return NULL_TREE;
8190 : }
8191 173332991 : if (av->location == bb->index)
8192 : /* On tramp3d 90% of the cases are here. */
8193 114273744 : return ssa_name (av->leader);
8194 73395257 : do
8195 : {
8196 73395257 : 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 73395257 : if (dominated_by_p_w_unex (bb, abb, true))
8209 : {
8210 55005882 : tree leader = ssa_name (av->leader);
8211 : /* Prevent eliminations that break loop-closed SSA. */
8212 55005882 : if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
8213 3673489 : && ! SSA_NAME_IS_DEFAULT_DEF (leader)
8214 58679371 : && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT
8215 3673489 : (leader))->loop_father,
8216 : bb))
8217 : return NULL_TREE;
8218 54928791 : if (dump_file && (dump_flags & TDF_DETAILS))
8219 : {
8220 3814 : print_generic_expr (dump_file, leader);
8221 3814 : fprintf (dump_file, " is available for ");
8222 3814 : print_generic_expr (dump_file, valnum);
8223 3814 : fprintf (dump_file, "\n");
8224 : }
8225 : /* On tramp3d 99% of the _remaining_ cases succeed at
8226 : the first enty. */
8227 : 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 18389375 : av = av->next;
8233 : }
8234 18389375 : 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 4053365 : if (!valnum_info->visited)
8239 2 : return valnum;
8240 : }
8241 14556240 : else if (valnum != VN_TOP)
8242 : /* valnum is is_gimple_min_invariant. */
8243 14556240 : return valnum;
8244 : return NULL_TREE;
8245 : }
8246 :
8247 : /* Make LEADER a leader for its value at BB. */
8248 :
8249 : void
8250 99204319 : rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
8251 : {
8252 99204319 : tree valnum = VN_INFO (leader)->valnum;
8253 99204319 : if (valnum == VN_TOP
8254 99204319 : || is_gimple_min_invariant (valnum))
8255 : return;
8256 99204319 : if (dump_file && (dump_flags & TDF_DETAILS))
8257 : {
8258 324997 : fprintf (dump_file, "Making available beyond BB%d ", bb->index);
8259 324997 : print_generic_expr (dump_file, leader);
8260 324997 : fprintf (dump_file, " for value ");
8261 324997 : print_generic_expr (dump_file, valnum);
8262 324997 : fprintf (dump_file, "\n");
8263 : }
8264 99204319 : vn_ssa_aux_t value = VN_INFO (valnum);
8265 99204319 : vn_avail *av;
8266 99204319 : if (m_avail_freelist)
8267 : {
8268 18855602 : av = m_avail_freelist;
8269 18855602 : m_avail_freelist = m_avail_freelist->next;
8270 : }
8271 : else
8272 80348717 : av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
8273 99204319 : av->location = bb->index;
8274 99204319 : av->leader = SSA_NAME_VERSION (leader);
8275 99204319 : av->next = value->avail;
8276 99204319 : av->next_undo = last_pushed_avail;
8277 99204319 : last_pushed_avail = value;
8278 99204319 : value->avail = av;
8279 : }
8280 :
8281 : /* Valueization hook for RPO VN plus required state. */
8282 :
8283 : tree
8284 2256931422 : rpo_vn_valueize (tree name)
8285 : {
8286 2256931422 : if (TREE_CODE (name) == SSA_NAME)
8287 : {
8288 2209661482 : vn_ssa_aux_t val = VN_INFO (name);
8289 2209661482 : if (val)
8290 : {
8291 2209661482 : tree tem = val->valnum;
8292 2209661482 : if (tem != VN_TOP && tem != name)
8293 : {
8294 118919549 : 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 101174664 : tem = rpo_avail->eliminate_avail (vn_context_bb, tem);
8299 101174664 : if (tem)
8300 100980547 : 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 27962091 : insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e)
8312 : {
8313 27962091 : switch (code)
8314 : {
8315 1384621 : case LT_EXPR:
8316 : /* a < b -> a {!,<}= b */
8317 1384621 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8318 : ops, boolean_true_node, 0, pred_e);
8319 1384621 : 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 1384621 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8323 : ops, boolean_false_node, 0, pred_e);
8324 1384621 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8325 : ops, boolean_false_node, 0, pred_e);
8326 1384621 : break;
8327 3541344 : case GT_EXPR:
8328 : /* a > b -> a {!,>}= b */
8329 3541344 : vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
8330 : ops, boolean_true_node, 0, pred_e);
8331 3541344 : 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 3541344 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8335 : ops, boolean_false_node, 0, pred_e);
8336 3541344 : vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
8337 : ops, boolean_false_node, 0, pred_e);
8338 3541344 : break;
8339 9580097 : case EQ_EXPR:
8340 : /* a == b -> ! a {<,>} b */
8341 9580097 : vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
8342 : ops, boolean_false_node, 0, pred_e);
8343 9580097 : vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
8344 : ops, boolean_false_node, 0, pred_e);
8345 9580097 : break;
8346 : case LE_EXPR:
8347 : case GE_EXPR:
8348 : case NE_EXPR:
8349 : /* Nothing besides inverted condition. */
8350 : break;
8351 27962091 : default:;
8352 : }
8353 27962091 : }
8354 :
8355 : /* Insert on the TRUE_E true and FALSE_E false predicates
8356 : derived from LHS CODE RHS. */
8357 :
8358 : static void
8359 23928236 : 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 23928236 : if (!true_e && !false_e)
8364 1367796 : return;
8365 :
8366 : /* Canonicalize the comparison if needed, putting
8367 : the constant in the rhs. */
8368 22563932 : if (tree_swap_operands_p (lhs, rhs))
8369 : {
8370 16860 : std::swap (lhs, rhs);
8371 16860 : code = swap_tree_comparison (code);
8372 : }
8373 :
8374 : /* If the lhs is not a ssa name, don't record anything. */
8375 22563932 : if (TREE_CODE (lhs) != SSA_NAME)
8376 : return;
8377 :
8378 22560440 : tree_code icode = invert_tree_comparison (code, HONOR_NANS (lhs));
8379 22560440 : tree ops[2];
8380 22560440 : ops[0] = lhs;
8381 22560440 : ops[1] = rhs;
8382 22560440 : if (true_e)
8383 18421375 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8384 : boolean_true_node, 0, true_e);
8385 22560440 : if (false_e)
8386 17339120 : vn_nary_op_insert_pieces_predicated (2, code, boolean_type_node, ops,
8387 : boolean_false_node, 0, false_e);
8388 22560440 : if (icode != ERROR_MARK)
8389 : {
8390 22307285 : if (true_e)
8391 18264049 : vn_nary_op_insert_pieces_predicated (2, icode, boolean_type_node, ops,
8392 : boolean_false_node, 0, true_e);
8393 22307285 : if (false_e)
8394 17134402 : 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 22560440 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
8400 : {
8401 17642635 : if (true_e)
8402 14470140 : insert_related_predicates_on_edge (code, ops, true_e);
8403 17642635 : if (false_e)
8404 13491951 : insert_related_predicates_on_edge (icode, ops, false_e);
8405 : }
8406 22560440 : if (integer_zerop (rhs)
8407 22560440 : && (code == NE_EXPR || code == EQ_EXPR))
8408 : {
8409 9412142 : 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 9412142 : if (is_gimple_assign (def_stmt)
8413 9412142 : && TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
8414 : {
8415 440632 : tree_code nc = gimple_assign_rhs_code (def_stmt);
8416 440632 : tree nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
8417 440632 : tree nrhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8418 440632 : edge nt = true_e;
8419 440632 : edge nf = false_e;
8420 440632 : if (code == EQ_EXPR)
8421 313862 : std::swap (nt, nf);
8422 440632 : if (lhs != nlhs)
8423 440632 : 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 9412142 : if (is_gimple_assign (def_stmt)
8430 9412142 : && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
8431 : {
8432 263545 : edge e = code == EQ_EXPR ? true_e : false_e;
8433 263545 : tree nlhs;
8434 :
8435 263545 : 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 263545 : if (nlhs != lhs)
8439 263545 : 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 263545 : nlhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
8444 263545 : if (nlhs != lhs)
8445 263545 : 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 62865086 : 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 62865086 : unsigned todo = 0;
8458 62865086 : edge_iterator ei;
8459 62865086 : edge e;
8460 :
8461 62865086 : 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 62865086 : bool lc_phi_nodes = false;
8466 62865086 : if (!skip_phis
8467 62865086 : && loops_state_satisfies_p (LOOP_CLOSED_SSA))
8468 3838871 : FOR_EACH_EDGE (e, ei, bb->preds)
8469 2320479 : if (e->src->loop_father != e->dest->loop_father
8470 2320479 : && 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 62865086 : if (!iterate && eliminate && bb->loop_father->header == bb)
8479 : {
8480 : /* Keep fields in sync with substitute_in_loop_info. */
8481 952192 : if (bb->loop_father->nb_iterations)
8482 155276 : bb->loop_father->nb_iterations
8483 155276 : = 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 62865086 : if (!skip_phis)
8489 90069138 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8490 27233483 : gsi_next (&gsi))
8491 : {
8492 27233483 : gphi *phi = gsi.phi ();
8493 27233483 : tree res = PHI_RESULT (phi);
8494 27233483 : vn_ssa_aux_t res_info = VN_INFO (res);
8495 27233483 : if (!bb_visited)
8496 : {
8497 19321901 : gcc_assert (!res_info->visited);
8498 19321901 : res_info->valnum = VN_TOP;
8499 19321901 : res_info->visited = true;
8500 : }
8501 :
8502 : /* When not iterating force backedge values to varying. */
8503 27233483 : visit_stmt (phi, !iterate_phis);
8504 54466966 : if (virtual_operand_p (res))
8505 10839587 : 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 16393896 : tree val = res_info->valnum;
8512 16393896 : if (res != val && !iterate && eliminate)
8513 : {
8514 1449942 : if (tree leader = avail.eliminate_avail (bb, res))
8515 : {
8516 1331600 : if (leader != res
8517 : /* Preserve loop-closed SSA form. */
8518 1331600 : && (! lc_phi_nodes
8519 5554 : || is_gimple_min_invariant (leader)))
8520 : {
8521 1331069 : if (dump_file && (dump_flags & TDF_DETAILS))
8522 : {
8523 213 : fprintf (dump_file, "Replaced redundant PHI node "
8524 : "defining ");
8525 213 : print_generic_expr (dump_file, res);
8526 213 : fprintf (dump_file, " with ");
8527 213 : print_generic_expr (dump_file, leader);
8528 213 : fprintf (dump_file, "\n");
8529 : }
8530 1331069 : avail.eliminations++;
8531 :
8532 1331069 : if (may_propagate_copy (res, leader))
8533 : {
8534 : /* Schedule for removal. */
8535 1331069 : avail.to_remove.safe_push (phi);
8536 1331069 : 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 15062827 : if (lc_phi_nodes
8546 15062827 : || res == val
8547 15062827 : || ! avail.eliminate_avail (bb, res))
8548 11511967 : 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 125730172 : if (gsi_end_p (gsi_start_bb (bb)))
8556 : {
8557 14045532 : FOR_EACH_EDGE (e, ei, bb->succs)
8558 : {
8559 7022766 : if (!(e->flags & EDGE_EXECUTABLE))
8560 : {
8561 4827850 : if (dump_file && (dump_flags & TDF_DETAILS))
8562 6236 : fprintf (dump_file,
8563 : "marking outgoing edge %d -> %d executable\n",
8564 6236 : e->src->index, e->dest->index);
8565 4827850 : e->flags |= EDGE_EXECUTABLE;
8566 4827850 : e->dest->flags |= BB_EXECUTABLE;
8567 : }
8568 2194916 : 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 125730172 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
8579 517438667 : !gsi_end_p (gsi); gsi_next (&gsi))
8580 : {
8581 454573581 : ssa_op_iter i;
8582 454573581 : tree op;
8583 454573581 : if (!bb_visited)
8584 : {
8585 516025694 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
8586 : {
8587 141666445 : vn_ssa_aux_t op_info = VN_INFO (op);
8588 141666445 : gcc_assert (!op_info->visited);
8589 141666445 : op_info->valnum = VN_TOP;
8590 141666445 : 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 454573581 : visit_stmt (gsi_stmt (gsi));
8601 :
8602 454573581 : gimple *last = gsi_stmt (gsi);
8603 454573581 : e = NULL;
8604 454573581 : switch (gimple_code (last))
8605 : {
8606 116509 : case GIMPLE_SWITCH:
8607 116509 : e = find_taken_edge (bb, vn_valueize (gimple_switch_index
8608 116509 : (as_a <gswitch *> (last))));
8609 116509 : break;
8610 25223411 : case GIMPLE_COND:
8611 25223411 : {
8612 25223411 : tree lhs = vn_valueize (gimple_cond_lhs (last));
8613 25223411 : tree rhs = vn_valueize (gimple_cond_rhs (last));
8614 25223411 : tree_code cmpcode = gimple_cond_code (last);
8615 : /* Canonicalize the comparison if needed, putting
8616 : the constant in the rhs. */
8617 25223411 : if (tree_swap_operands_p (lhs, rhs))
8618 : {
8619 850552 : std::swap (lhs, rhs);
8620 850552 : cmpcode = swap_tree_comparison (cmpcode);
8621 : }
8622 25223411 : 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 25223411 : if (! val || TREE_CODE (val) != INTEGER_CST)
8628 : {
8629 23329486 : vn_nary_op_t vnresult;
8630 23329486 : tree ops[2];
8631 23329486 : ops[0] = lhs;
8632 23329486 : ops[1] = rhs;
8633 23329486 : 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 23329486 : if (val && TREE_CODE (val) == SSA_NAME)
8639 : {
8640 174935 : ops[0] = val;
8641 174935 : ops[1] = build_zero_cst (TREE_TYPE (val));
8642 174935 : 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 23329460 : if (! val && vnresult && vnresult->predicated_values)
8648 : {
8649 1429600 : val = vn_nary_op_get_predicated_value (vnresult, bb);
8650 1429600 : 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 23329486 : if (val)
8660 2262897 : e = find_taken_edge (bb, val);
8661 25223411 : 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 22960514 : edge true_e, false_e;
8669 22960514 : extract_true_false_edges_from_block (bb, &true_e, &false_e);
8670 555936 : if ((do_region && bitmap_bit_p (exit_bbs, true_e->dest->index))
8671 23199225 : || !can_track_predicate_on_edge (true_e))
8672 5062391 : true_e = NULL;
8673 555936 : if ((do_region && bitmap_bit_p (exit_bbs, false_e->dest->index))
8674 23173196 : || !can_track_predicate_on_edge (false_e))
8675 6024268 : false_e = NULL;
8676 22960514 : insert_predicates_for_cond (cmpcode, lhs, rhs, true_e, false_e);
8677 : }
8678 : break;
8679 : }
8680 1400 : case GIMPLE_GOTO:
8681 1400 : e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last)));
8682 1400 : break;
8683 : default:
8684 : e = NULL;
8685 : }
8686 454573581 : if (e)
8687 : {
8688 2266531 : todo = TODO_cleanup_cfg;
8689 2266531 : if (!(e->flags & EDGE_EXECUTABLE))
8690 : {
8691 1791997 : 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 1791997 : e->flags |= EDGE_EXECUTABLE;
8697 1791997 : e->dest->flags |= BB_EXECUTABLE;
8698 : }
8699 474534 : else if (!(e->dest->flags & BB_EXECUTABLE))
8700 : {
8701 27387 : if (dump_file && (dump_flags & TDF_DETAILS))
8702 1 : fprintf (dump_file,
8703 : "marking destination block %d reachable\n",
8704 : e->dest->index);
8705 27387 : e->dest->flags |= BB_EXECUTABLE;
8706 : }
8707 : }
8708 452307050 : else if (gsi_one_before_end_p (gsi))
8709 : {
8710 131372346 : FOR_EACH_EDGE (e, ei, bb->succs)
8711 : {
8712 77796557 : if (!(e->flags & EDGE_EXECUTABLE))
8713 : {
8714 57168062 : if (dump_file && (dump_flags & TDF_DETAILS))
8715 18523 : fprintf (dump_file,
8716 : "marking outgoing edge %d -> %d executable\n",
8717 18523 : e->src->index, e->dest->index);
8718 57168062 : e->flags |= EDGE_EXECUTABLE;
8719 57168062 : e->dest->flags |= BB_EXECUTABLE;
8720 : }
8721 20628495 : else if (!(e->dest->flags & BB_EXECUTABLE))
8722 : {
8723 2633048 : if (dump_file && (dump_flags & TDF_DETAILS))
8724 6009 : fprintf (dump_file,
8725 : "marking destination block %d reachable\n",
8726 : e->dest->index);
8727 2633048 : e->dest->flags |= BB_EXECUTABLE;
8728 : }
8729 : }
8730 : }
8731 :
8732 : /* Eliminate. That also pushes to avail. */
8733 454573581 : if (eliminate && ! iterate)
8734 114157618 : 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 422285549 : FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF)
8739 81869586 : if (! has_zero_uses (op)
8740 81869586 : && ! avail.eliminate_avail (bb, op))
8741 62307609 : 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 62865086 : if (!iterate && eliminate)
8748 33707096 : FOR_EACH_EDGE (e, ei, bb->succs)
8749 20079783 : for (gphi_iterator gsi = gsi_start_phis (e->dest);
8750 38946728 : !gsi_end_p (gsi); gsi_next (&gsi))
8751 : {
8752 18866945 : gphi *phi = gsi.phi ();
8753 18866945 : use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
8754 18866945 : tree arg = USE_FROM_PTR (use_p);
8755 28671280 : if (TREE_CODE (arg) != SSA_NAME
8756 18866945 : || virtual_operand_p (arg))
8757 9804335 : continue;
8758 9062610 : tree sprime;
8759 9062610 : if (SSA_NAME_IS_DEFAULT_DEF (arg))
8760 : {
8761 118828 : sprime = SSA_VAL (arg);
8762 118828 : 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 8943782 : sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)),
8772 : arg);
8773 9062610 : if (sprime
8774 9062610 : && sprime != arg
8775 9062610 : && may_propagate_copy (arg, sprime, !(e->flags & EDGE_ABNORMAL)))
8776 1559823 : propagate_value (use_p, sprime);
8777 : }
8778 :
8779 62865086 : vn_context_bb = NULL;
8780 62865086 : 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 1928235 : do_unwind (unwind_state *to, rpo_elim &avail)
8806 : {
8807 1928235 : gcc_assert (to->iterate);
8808 35177417 : for (; last_inserted_nary != to->nary_top;
8809 33249182 : last_inserted_nary = last_inserted_nary->next)
8810 : {
8811 33249182 : vn_nary_op_t *slot;
8812 33249182 : slot = valid_info->nary->find_slot_with_hash
8813 33249182 : (last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT);
8814 : /* Predication causes the need to restore previous state. */
8815 33249182 : if ((*slot)->unwind_to)
8816 6769910 : *slot = (*slot)->unwind_to;
8817 : else
8818 26479272 : valid_info->nary->clear_slot (slot);
8819 : }
8820 7514949 : for (; last_inserted_phi != to->phi_top;
8821 5586714 : last_inserted_phi = last_inserted_phi->next)
8822 : {
8823 5586714 : vn_phi_t *slot;
8824 5586714 : slot = valid_info->phis->find_slot_with_hash
8825 5586714 : (last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT);
8826 5586714 : valid_info->phis->clear_slot (slot);
8827 : }
8828 15454566 : for (; last_inserted_ref != to->ref_top;
8829 13526331 : last_inserted_ref = last_inserted_ref->next)
8830 : {
8831 13526331 : vn_reference_t *slot;
8832 13526331 : slot = valid_info->references->find_slot_with_hash
8833 13526331 : (last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT);
8834 13526331 : (*slot)->operands.release ();
8835 13526331 : valid_info->references->clear_slot (slot);
8836 : }
8837 1928235 : obstack_free (&vn_tables_obstack, to->ob_top);
8838 :
8839 : /* Prune [rpo_idx, ] from avail. */
8840 20783837 : for (; last_pushed_avail && last_pushed_avail->avail != to->avail_top;)
8841 : {
8842 18855602 : vn_ssa_aux_t val = last_pushed_avail;
8843 18855602 : vn_avail *av = val->avail;
8844 18855602 : val->avail = av->next;
8845 18855602 : last_pushed_avail = av->next_undo;
8846 18855602 : av->next = avail.m_avail_freelist;
8847 18855602 : avail.m_avail_freelist = av;
8848 : }
8849 1928235 : }
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 6311883 : 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 6311883 : unsigned todo = 0;
8863 6311883 : default_vn_walk_kind = kind;
8864 :
8865 : /* We currently do not support region-based iteration when
8866 : elimination is requested. */
8867 6311883 : gcc_assert (!entry || !iterate || !eliminate);
8868 : /* When iterating we need loop info up-to-date. */
8869 6311883 : gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP));
8870 :
8871 6311883 : bool do_region = entry != NULL;
8872 6311883 : if (!do_region)
8873 : {
8874 5616917 : entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn));
8875 5616917 : exit_bbs = BITMAP_ALLOC (NULL);
8876 5616917 : 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 6311883 : edge_iterator ei;
8882 6311883 : edge e;
8883 12684734 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8884 6372851 : e->flags &= ~EDGE_DFS_BACK;
8885 :
8886 6311883 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS);
8887 6311883 : auto_vec<std::pair<int, int> > toplevel_scc_extents;
8888 6311883 : int n = rev_post_order_and_mark_dfs_back_seme
8889 8226828 : (fn, entry, exit_bbs, true, rpo, !iterate ? &toplevel_scc_extents : NULL);
8890 :
8891 6311883 : if (!do_region)
8892 5616917 : 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 12684733 : FOR_EACH_EDGE (e, ei, entry->dest->preds)
8898 6372851 : if (e != entry
8899 60968 : && !(e->flags & EDGE_DFS_BACK))
8900 : break;
8901 6311883 : 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 6311883 : skip_entry_phis |= e != NULL;
8905 :
8906 6311883 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
8907 64372695 : for (int i = 0; i < n; ++i)
8908 51748929 : bb_to_rpo[rpo[i]] = i;
8909 6311883 : vn_bb_to_rpo = bb_to_rpo;
8910 :
8911 6311883 : unwind_state *rpo_state = XNEWVEC (unwind_state, n);
8912 :
8913 6311883 : rpo_elim avail (entry->dest);
8914 6311883 : rpo_avail = &avail;
8915 :
8916 : /* Verify we have no extra entries into the region. */
8917 6311883 : if (flag_checking && do_region)
8918 : {
8919 694960 : auto_bb_flag bb_in_region (fn);
8920 2825736 : for (int i = 0; i < n; ++i)
8921 : {
8922 1435816 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8923 1435816 : 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 2130776 : for (int i = 0; i < n; ++i)
8931 : {
8932 1435816 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8933 1435816 : edge e;
8934 1435816 : edge_iterator ei;
8935 3143295 : FOR_EACH_EDGE (e, ei, bb->preds)
8936 1707479 : gcc_assert (e == entry
8937 : || (skip_entry_phis && bb == entry->dest)
8938 : || (e->src->flags & bb_in_region));
8939 : }
8940 2130776 : for (int i = 0; i < n; ++i)
8941 : {
8942 1435816 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8943 1435816 : bb->flags &= ~bb_in_region;
8944 : }
8945 694960 : }
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 6311883 : unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names)
8950 6311883 : / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS));
8951 6311883 : VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
8952 6311883 : next_value_id = 1;
8953 6311883 : next_constant_value_id = -1;
8954 :
8955 6311883 : vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2);
8956 6311883 : gcc_obstack_init (&vn_ssa_aux_obstack);
8957 :
8958 6311883 : gcc_obstack_init (&vn_tables_obstack);
8959 6311883 : gcc_obstack_init (&vn_tables_insert_obstack);
8960 6311883 : valid_info = XCNEW (struct vn_tables_s);
8961 6311883 : allocate_vn_table (valid_info, region_size);
8962 6311883 : last_inserted_ref = NULL;
8963 6311883 : last_inserted_phi = NULL;
8964 6311883 : last_inserted_nary = NULL;
8965 6311883 : last_pushed_avail = NULL;
8966 :
8967 6311883 : vn_valueize = rpo_vn_valueize;
8968 :
8969 : /* Initialize the unwind state and edge/BB executable state. */
8970 6311883 : unsigned curr_scc = 0;
8971 58060812 : for (int i = 0; i < n; ++i)
8972 : {
8973 51748929 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
8974 51748929 : rpo_state[i].visited = 0;
8975 51748929 : rpo_state[i].max_rpo = i;
8976 60433558 : if (!iterate && curr_scc < toplevel_scc_extents.length ())
8977 : {
8978 7247399 : if (i >= toplevel_scc_extents[curr_scc].first
8979 7247399 : && i <= toplevel_scc_extents[curr_scc].second)
8980 3946632 : rpo_state[i].max_rpo = toplevel_scc_extents[curr_scc].second;
8981 7247399 : if (i == toplevel_scc_extents[curr_scc].second)
8982 739203 : curr_scc++;
8983 : }
8984 51748929 : bb->flags &= ~BB_EXECUTABLE;
8985 51748929 : bool has_backedges = false;
8986 51748929 : edge e;
8987 51748929 : edge_iterator ei;
8988 122770335 : FOR_EACH_EDGE (e, ei, bb->preds)
8989 : {
8990 71021406 : if (e->flags & EDGE_DFS_BACK)
8991 2876849 : has_backedges = true;
8992 71021406 : e->flags &= ~EDGE_EXECUTABLE;
8993 71021406 : if (iterate || e == entry || (skip_entry_phis && bb == entry->dest))
8994 71021406 : continue;
8995 : }
8996 51748929 : rpo_state[i].iterate = iterate && has_backedges;
8997 : }
8998 6311883 : entry->flags |= EDGE_EXECUTABLE;
8999 6311883 : 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 6311883 : if (iterate)
9004 : {
9005 4396938 : unsigned max_depth = param_rpo_vn_max_loop_depth;
9006 14763441 : for (auto loop : loops_list (cfun, LI_ONLY_INNERMOST))
9007 1575045 : if (loop_depth (loop) > max_depth)
9008 2108 : for (unsigned i = 2;
9009 9052 : 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 4396938 : }
9035 : }
9036 :
9037 6311883 : uint64_t nblk = 0;
9038 6311883 : int idx = 0;
9039 4396938 : if (iterate)
9040 : /* Go and process all blocks, iterating as necessary. */
9041 50105233 : do
9042 : {
9043 50105233 : 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 50105233 : if (rpo_state[idx].iterate)
9053 : {
9054 4428346 : rpo_state[idx].ob_top = obstack_alloc (&vn_tables_obstack, 0);
9055 4428346 : rpo_state[idx].ref_top = last_inserted_ref;
9056 4428346 : rpo_state[idx].phi_top = last_inserted_phi;
9057 4428346 : rpo_state[idx].nary_top = last_inserted_nary;
9058 4428346 : rpo_state[idx].avail_top
9059 4428346 : = last_pushed_avail ? last_pushed_avail->avail : NULL;
9060 : }
9061 :
9062 50105233 : if (!(bb->flags & BB_EXECUTABLE))
9063 : {
9064 976524 : 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 976524 : idx++;
9068 2904759 : continue;
9069 : }
9070 :
9071 49128709 : if (dump_file && (dump_flags & TDF_DETAILS))
9072 334 : fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
9073 49128709 : nblk++;
9074 98257418 : todo |= process_bb (avail, bb,
9075 49128709 : rpo_state[idx].visited != 0,
9076 : rpo_state[idx].iterate,
9077 : iterate, eliminate, do_region, exit_bbs, false);
9078 49128709 : 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 49128709 : int iterate_to = -1;
9085 49128709 : edge_iterator ei;
9086 49128709 : edge e;
9087 118283771 : FOR_EACH_EDGE (e, ei, bb->succs)
9088 69155062 : if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE))
9089 : == (EDGE_DFS_BACK|EDGE_EXECUTABLE)
9090 4433186 : && rpo_state[bb_to_rpo[e->dest->index]].iterate)
9091 : {
9092 4430420 : int destidx = bb_to_rpo[e->dest->index];
9093 4430420 : 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 4430286 : 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 4430286 : vn_context_bb = e->dest;
9107 4430286 : gphi_iterator gsi;
9108 4430286 : for (gsi = gsi_start_phis (e->dest);
9109 10074353 : !gsi_end_p (gsi); gsi_next (&gsi))
9110 : {
9111 7573105 : 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 7573105 : bool phival_changed;
9120 7573105 : if ((phival_changed = visit_phi (gsi.phi (),
9121 : &inserted, false))
9122 8977669 : || (inserted && gimple_plf (gsi.phi (), GF_PLF_1)))
9123 : {
9124 1929038 : if (!phival_changed
9125 1929038 : && dump_file && (dump_flags & TDF_DETAILS))
9126 0 : fprintf (dump_file, "PHI was CSEd and hashtable "
9127 : "state (changed)\n");
9128 1929038 : if (iterate_to == -1 || destidx < iterate_to)
9129 1928953 : iterate_to = destidx;
9130 1929038 : break;
9131 : }
9132 : }
9133 4430286 : vn_context_bb = NULL;
9134 : }
9135 49128709 : if (iterate_to != -1)
9136 : {
9137 1928235 : do_unwind (&rpo_state[iterate_to], avail);
9138 1928235 : idx = iterate_to;
9139 1928235 : 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 1928235 : continue;
9143 : }
9144 :
9145 47200474 : idx++;
9146 : }
9147 50105233 : 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 1914945 : auto_bitmap worklist;
9154 1914945 : bitmap_set_bit (worklist, 0);
9155 17566267 : while (!bitmap_empty_p (worklist))
9156 : {
9157 13736377 : int idx = bitmap_clear_first_set_bit (worklist);
9158 13736377 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
9159 13736377 : gcc_assert ((bb->flags & BB_EXECUTABLE)
9160 : && !rpo_state[idx].visited);
9161 :
9162 13736377 : if (dump_file && (dump_flags & TDF_DETAILS))
9163 35271 : 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 13736377 : edge_iterator ei;
9171 13736377 : edge e;
9172 33302397 : FOR_EACH_EDGE (e, ei, bb->preds)
9173 19566020 : if (!(e->flags & EDGE_EXECUTABLE)
9174 1030837 : && (bb == entry->dest
9175 973207 : || (!rpo_state[bb_to_rpo[e->src->index]].visited
9176 935333 : && (rpo_state[bb_to_rpo[e->src->index]].max_rpo
9177 : >= (int)idx))))
9178 : {
9179 969420 : if (dump_file && (dump_flags & TDF_DETAILS))
9180 11332 : fprintf (dump_file, "Cannot trust state of predecessor "
9181 : "edge %d -> %d, marking executable\n",
9182 11332 : e->src->index, e->dest->index);
9183 969420 : e->flags |= EDGE_EXECUTABLE;
9184 : }
9185 :
9186 13736377 : nblk++;
9187 27472754 : todo |= process_bb (avail, bb, false, false, false, eliminate,
9188 : do_region, exit_bbs,
9189 59478 : skip_entry_phis && bb == entry->dest);
9190 13736377 : rpo_state[idx].visited++;
9191 :
9192 33948820 : FOR_EACH_EDGE (e, ei, bb->succs)
9193 20212443 : if ((e->flags & EDGE_EXECUTABLE)
9194 20133325 : && e->dest->index != EXIT_BLOCK
9195 18943247 : && (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index))
9196 37796634 : && !rpo_state[bb_to_rpo[e->dest->index]].visited)
9197 16620238 : bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]);
9198 : }
9199 1914945 : }
9200 :
9201 : /* If statistics or dump file active. */
9202 6311883 : int nex = 0;
9203 6311883 : unsigned max_visited = 1;
9204 58060812 : for (int i = 0; i < n; ++i)
9205 : {
9206 51748929 : basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
9207 51748929 : if (bb->flags & BB_EXECUTABLE)
9208 51131048 : nex++;
9209 51748929 : statistics_histogram_event (cfun, "RPO block visited times",
9210 51748929 : rpo_state[i].visited);
9211 51748929 : if (rpo_state[i].visited > max_visited)
9212 : max_visited = rpo_state[i].visited;
9213 : }
9214 6311883 : unsigned nvalues = 0, navail = 0;
9215 174413305 : for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
9216 174413305 : i != vn_ssa_aux_hash->end (); ++i)
9217 : {
9218 168101422 : nvalues++;
9219 168101422 : vn_avail *av = (*i)->avail;
9220 248450139 : while (av)
9221 : {
9222 80348717 : navail++;
9223 80348717 : av = av->next;
9224 : }
9225 : }
9226 6311883 : statistics_counter_event (cfun, "RPO blocks", n);
9227 6311883 : statistics_counter_event (cfun, "RPO blocks visited", nblk);
9228 6311883 : statistics_counter_event (cfun, "RPO blocks executable", nex);
9229 6311883 : statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex);
9230 6311883 : statistics_histogram_event (cfun, "RPO num values", nvalues);
9231 6311883 : statistics_histogram_event (cfun, "RPO num avail", navail);
9232 6311883 : statistics_histogram_event (cfun, "RPO num lattice",
9233 6311883 : vn_ssa_aux_hash->elements ());
9234 6311883 : if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS)))
9235 : {
9236 11237 : 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 11237 : (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10),
9241 : max_visited);
9242 11237 : fprintf (dump_file, "RPO tracked %d values available at %d locations "
9243 : "and %" PRIu64 " lattice elements\n",
9244 11237 : nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ());
9245 : }
9246 :
9247 6311883 : if (eliminate)
9248 : {
9249 : /* When !iterate we already performed elimination during the RPO
9250 : walk. */
9251 5310753 : if (iterate)
9252 : {
9253 : /* Elimination for region-based VN needs to be done within the
9254 : RPO walk. */
9255 3415411 : 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 3415411 : todo |= eliminate_with_rpo_vn (NULL);
9260 : }
9261 : else
9262 1895342 : todo |= avail.eliminate_cleanup (do_region);
9263 : }
9264 :
9265 6311883 : vn_valueize = NULL;
9266 6311883 : rpo_avail = NULL;
9267 6311883 : vn_bb_to_rpo = NULL;
9268 :
9269 6311883 : XDELETEVEC (bb_to_rpo);
9270 6311883 : XDELETEVEC (rpo);
9271 6311883 : XDELETEVEC (rpo_state);
9272 :
9273 6311883 : return todo;
9274 6311883 : }
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 714569 : 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 714569 : auto_timevar tv (TV_TREE_RPO_VN);
9292 714569 : unsigned todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate,
9293 : skip_entry_phis, kind);
9294 714569 : free_rpo_vn ();
9295 1429138 : return todo;
9296 714569 : }
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 1470980 : pass_fre (gcc::context *ctxt)
9318 2941960 : : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
9319 : {}
9320 :
9321 : /* opt_pass methods: */
9322 1176784 : opt_pass * clone () final override { return new pass_fre (m_ctxt); }
9323 1470980 : void set_pass_param (unsigned int n, bool param) final override
9324 : {
9325 1470980 : gcc_assert (n == 0);
9326 1470980 : may_iterate = param;
9327 1470980 : }
9328 4696126 : bool gate (function *) final override
9329 : {
9330 4696126 : 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 4615787 : pass_fre::execute (function *fun)
9340 : {
9341 4615787 : unsigned todo = 0;
9342 :
9343 : /* At -O[1g] use the cheap non-iterating mode. */
9344 4615787 : bool iterate_p = may_iterate && (optimize > 1);
9345 4615787 : calculate_dominance_info (CDI_DOMINATORS);
9346 4615787 : if (iterate_p)
9347 3415411 : loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
9348 :
9349 4615787 : todo = do_rpo_vn_1 (fun, NULL, NULL, iterate_p, true, false, VN_WALKREWRITE);
9350 4615787 : free_rpo_vn ();
9351 :
9352 4615787 : if (iterate_p)
9353 3415411 : loop_optimizer_finalize ();
9354 :
9355 4615787 : if (scev_initialized_p ())
9356 32415 : 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 4615787 : if (!may_iterate)
9361 1013720 : todo |= TODO_update_address_taken;
9362 :
9363 4615787 : return todo;
9364 : }
9365 :
9366 : } // anon namespace
9367 :
9368 : gimple_opt_pass *
9369 294196 : make_pass_fre (gcc::context *ctxt)
9370 : {
9371 294196 : return new pass_fre (ctxt);
9372 : }
9373 :
9374 : #undef BB_EXECUTABLE
|