1 /* SCC value numbering for trees
2    Copyright (C) 2006-2020 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 "splay-tree.h"
25 #include "backend.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "ssa.h"
30 #include "expmed.h"
31 #include "insn-config.h"
32 #include "memmodel.h"
33 #include "emit-rtl.h"
34 #include "cgraph.h"
35 #include "gimple-pretty-print.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-fold.h"
43 #include "tree-eh.h"
44 #include "gimplify.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-iterator.h"
60 #include "gimple-match.h"
61 #include "stringpool.h"
62 #include "attribs.h"
63 #include "tree-pass.h"
64 #include "statistics.h"
65 #include "langhooks.h"
66 #include "ipa-utils.h"
67 #include "dbgcnt.h"
68 #include "tree-cfgcleanup.h"
69 #include "tree-ssa-loop.h"
70 #include "tree-scalar-evolution.h"
71 #include "tree-ssa-loop-niter.h"
72 #include "builtins.h"
73 #include "tree-ssa-sccvn.h"
74 
75 /* This algorithm is based on the SCC algorithm presented by Keith
76    Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
77    (http://citeseer.ist.psu.edu/41805.html).  In
78    straight line code, it is equivalent to a regular hash based value
79    numbering that is performed in reverse postorder.
80 
81    For code with cycles, there are two alternatives, both of which
82    require keeping the hashtables separate from the actual list of
83    value numbers for SSA names.
84 
85    1. Iterate value numbering in an RPO walk of the blocks, removing
86    all the entries from the hashtable after each iteration (but
87    keeping the SSA name->value number mapping between iterations).
88    Iterate until it does not change.
89 
90    2. Perform value numbering as part of an SCC walk on the SSA graph,
91    iterating only the cycles in the SSA graph until they do not change
92    (using a separate, optimistic hashtable for value numbering the SCC
93    operands).
94 
95    The second is not just faster in practice (because most SSA graph
96    cycles do not involve all the variables in the graph), it also has
97    some nice properties.
98 
99    One of these nice properties is that when we pop an SCC off the
100    stack, we are guaranteed to have processed all the operands coming from
101    *outside of that SCC*, so we do not need to do anything special to
102    ensure they have value numbers.
103 
104    Another nice property is that the SCC walk is done as part of a DFS
105    of the SSA graph, which makes it easy to perform combining and
106    simplifying operations at the same time.
107 
108    The code below is deliberately written in a way that makes it easy
109    to separate the SCC walk from the other work it does.
110 
111    In order to propagate constants through the code, we track which
112    expressions contain constants, and use those while folding.  In
113    theory, we could also track expressions whose value numbers are
114    replaced, in case we end up folding based on expression
115    identities.
116 
117    In order to value number memory, we assign value numbers to vuses.
118    This enables us to note that, for example, stores to the same
119    address of the same value from the same starting memory states are
120    equivalent.
121    TODO:
122 
123    1. We can iterate only the changing portions of the SCC's, but
124    I have not seen an SCC big enough for this to be a win.
125    2. If you differentiate between phi nodes for loops and phi nodes
126    for if-then-else, you can properly consider phi nodes in different
127    blocks for equivalence.
128    3. We could value number vuses in more cases, particularly, whole
129    structure copies.
130 */
131 
132 /* There's no BB_EXECUTABLE but we can use BB_VISITED.  */
133 #define BB_EXECUTABLE BB_VISITED
134 
135 static vn_lookup_kind default_vn_walk_kind;
136 
137 /* vn_nary_op hashtable helpers.  */
138 
139 struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s>
140 {
141   typedef vn_nary_op_s *compare_type;
142   static inline hashval_t hash (const vn_nary_op_s *);
143   static inline bool equal (const vn_nary_op_s *, const vn_nary_op_s *);
144 };
145 
146 /* Return the computed hashcode for nary operation P1.  */
147 
148 inline hashval_t
hash(const vn_nary_op_s * vno1)149 vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
150 {
151   return vno1->hashcode;
152 }
153 
154 /* Compare nary operations P1 and P2 and return true if they are
155    equivalent.  */
156 
157 inline bool
equal(const vn_nary_op_s * vno1,const vn_nary_op_s * vno2)158 vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
159 {
160   return vno1 == vno2 || vn_nary_op_eq (vno1, vno2);
161 }
162 
163 typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type;
164 typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;
165 
166 
167 /* vn_phi hashtable helpers.  */
168 
169 static int
170 vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
171 
172 struct vn_phi_hasher : nofree_ptr_hash <vn_phi_s>
173 {
174   static inline hashval_t hash (const vn_phi_s *);
175   static inline bool equal (const vn_phi_s *, const vn_phi_s *);
176 };
177 
178 /* Return the computed hashcode for phi operation P1.  */
179 
180 inline hashval_t
hash(const vn_phi_s * vp1)181 vn_phi_hasher::hash (const vn_phi_s *vp1)
182 {
183   return vp1->hashcode;
184 }
185 
186 /* Compare two phi entries for equality, ignoring VN_TOP arguments.  */
187 
188 inline bool
equal(const vn_phi_s * vp1,const vn_phi_s * vp2)189 vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
190 {
191   return vp1 == vp2 || vn_phi_eq (vp1, vp2);
192 }
193 
194 typedef hash_table<vn_phi_hasher> vn_phi_table_type;
195 typedef vn_phi_table_type::iterator vn_phi_iterator_type;
196 
197 
198 /* Compare two reference operands P1 and P2 for equality.  Return true if
199    they are equal, and false otherwise.  */
200 
201 static int
vn_reference_op_eq(const void * p1,const void * p2)202 vn_reference_op_eq (const void *p1, const void *p2)
203 {
204   const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
205   const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
206 
207   return (vro1->opcode == vro2->opcode
208 	  /* We do not care for differences in type qualification.  */
209 	  && (vro1->type == vro2->type
210 	      || (vro1->type && vro2->type
211 		  && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
212 					 TYPE_MAIN_VARIANT (vro2->type))))
213 	  && expressions_equal_p (vro1->op0, vro2->op0)
214 	  && expressions_equal_p (vro1->op1, vro2->op1)
215 	  && expressions_equal_p (vro1->op2, vro2->op2));
216 }
217 
218 /* Free a reference operation structure VP.  */
219 
220 static inline void
free_reference(vn_reference_s * vr)221 free_reference (vn_reference_s *vr)
222 {
223   vr->operands.release ();
224 }
225 
226 
227 /* vn_reference hashtable helpers.  */
228 
229 struct vn_reference_hasher : nofree_ptr_hash <vn_reference_s>
230 {
231   static inline hashval_t hash (const vn_reference_s *);
232   static inline bool equal (const vn_reference_s *, const vn_reference_s *);
233 };
234 
235 /* Return the hashcode for a given reference operation P1.  */
236 
237 inline hashval_t
hash(const vn_reference_s * vr1)238 vn_reference_hasher::hash (const vn_reference_s *vr1)
239 {
240   return vr1->hashcode;
241 }
242 
243 inline bool
equal(const vn_reference_s * v,const vn_reference_s * c)244 vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
245 {
246   return v == c || vn_reference_eq (v, c);
247 }
248 
249 typedef hash_table<vn_reference_hasher> vn_reference_table_type;
250 typedef vn_reference_table_type::iterator vn_reference_iterator_type;
251 
252 
253 /* The set of VN hashtables.  */
254 
255 typedef struct vn_tables_s
256 {
257   vn_nary_op_table_type *nary;
258   vn_phi_table_type *phis;
259   vn_reference_table_type *references;
260 } *vn_tables_t;
261 
262 
263 /* vn_constant hashtable helpers.  */
264 
265 struct vn_constant_hasher : free_ptr_hash <vn_constant_s>
266 {
267   static inline hashval_t hash (const vn_constant_s *);
268   static inline bool equal (const vn_constant_s *, const vn_constant_s *);
269 };
270 
271 /* Hash table hash function for vn_constant_t.  */
272 
273 inline hashval_t
hash(const vn_constant_s * vc1)274 vn_constant_hasher::hash (const vn_constant_s *vc1)
275 {
276   return vc1->hashcode;
277 }
278 
279 /* Hash table equality function for vn_constant_t.  */
280 
281 inline bool
equal(const vn_constant_s * vc1,const vn_constant_s * vc2)282 vn_constant_hasher::equal (const vn_constant_s *vc1, const vn_constant_s *vc2)
283 {
284   if (vc1->hashcode != vc2->hashcode)
285     return false;
286 
287   return vn_constant_eq_with_type (vc1->constant, vc2->constant);
288 }
289 
290 static hash_table<vn_constant_hasher> *constant_to_value_id;
291 static bitmap constant_value_ids;
292 
293 
294 /* Obstack we allocate the vn-tables elements from.  */
295 static obstack vn_tables_obstack;
296 /* Special obstack we never unwind.  */
297 static obstack vn_tables_insert_obstack;
298 
299 static vn_reference_t last_inserted_ref;
300 static vn_phi_t last_inserted_phi;
301 static vn_nary_op_t last_inserted_nary;
302 
303 /* Valid hashtables storing information we have proven to be
304    correct.  */
305 static vn_tables_t valid_info;
306 
307 
308 /* Valueization hook.  Valueize NAME if it is an SSA name, otherwise
309    just return it.  */
310 tree (*vn_valueize) (tree);
vn_valueize_wrapper(tree t,void * context ATTRIBUTE_UNUSED)311 tree vn_valueize_wrapper (tree t, void* context ATTRIBUTE_UNUSED)
312 {
313   return vn_valueize (t);
314 }
315 
316 
317 /* This represents the top of the VN lattice, which is the universal
318    value.  */
319 
320 tree VN_TOP;
321 
322 /* Unique counter for our value ids.  */
323 
324 static unsigned int next_value_id;
325 
326 
327 /* Table of vn_ssa_aux_t's, one per ssa_name.  The vn_ssa_aux_t objects
328    are allocated on an obstack for locality reasons, and to free them
329    without looping over the vec.  */
330 
331 struct vn_ssa_aux_hasher : typed_noop_remove <vn_ssa_aux_t>
332 {
333   typedef vn_ssa_aux_t value_type;
334   typedef tree compare_type;
335   static inline hashval_t hash (const value_type &);
336   static inline bool equal (const value_type &, const compare_type &);
mark_deletedvn_ssa_aux_hasher337   static inline void mark_deleted (value_type &) {}
338   static const bool empty_zero_p = true;
mark_emptyvn_ssa_aux_hasher339   static inline void mark_empty (value_type &e) { e = NULL; }
is_deletedvn_ssa_aux_hasher340   static inline bool is_deleted (value_type &) { return false; }
is_emptyvn_ssa_aux_hasher341   static inline bool is_empty (value_type &e) { return e == NULL; }
342 };
343 
344 hashval_t
hash(const value_type & entry)345 vn_ssa_aux_hasher::hash (const value_type &entry)
346 {
347   return SSA_NAME_VERSION (entry->name);
348 }
349 
350 bool
equal(const value_type & entry,const compare_type & name)351 vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name)
352 {
353   return name == entry->name;
354 }
355 
356 static hash_table<vn_ssa_aux_hasher> *vn_ssa_aux_hash;
357 typedef hash_table<vn_ssa_aux_hasher>::iterator vn_ssa_aux_iterator_type;
358 static struct obstack vn_ssa_aux_obstack;
359 
360 static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree);
361 static unsigned int vn_nary_length_from_stmt (gimple *);
362 static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *);
363 static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t,
364 					    vn_nary_op_table_type *, bool);
365 static void init_vn_nary_op_from_stmt (vn_nary_op_t, gimple *);
366 static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
367 					 enum tree_code, tree, tree *);
368 static tree vn_lookup_simplify_result (gimple_match_op *);
369 static vn_reference_t vn_reference_lookup_or_insert_for_pieces
370 	  (tree, alias_set_type, alias_set_type, tree,
371 	   vec<vn_reference_op_s, va_heap>, tree);
372 
373 /* Return whether there is value numbering information for a given SSA name.  */
374 
375 bool
has_VN_INFO(tree name)376 has_VN_INFO (tree name)
377 {
378   return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name));
379 }
380 
381 vn_ssa_aux_t
VN_INFO(tree name)382 VN_INFO (tree name)
383 {
384   vn_ssa_aux_t *res
385     = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name),
386 					    INSERT);
387   if (*res != NULL)
388     return *res;
389 
390   vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
391   memset (newinfo, 0, sizeof (struct vn_ssa_aux));
392   newinfo->name = name;
393   newinfo->valnum = VN_TOP;
394   /* We are using the visited flag to handle uses with defs not within the
395      region being value-numbered.  */
396   newinfo->visited = false;
397 
398   /* Given we create the VN_INFOs on-demand now we have to do initialization
399      different than VN_TOP here.  */
400   if (SSA_NAME_IS_DEFAULT_DEF (name))
401     switch (TREE_CODE (SSA_NAME_VAR (name)))
402       {
403       case VAR_DECL:
404         /* All undefined vars are VARYING.  */
405         newinfo->valnum = name;
406 	newinfo->visited = true;
407 	break;
408 
409       case PARM_DECL:
410 	/* Parameters are VARYING but we can record a condition
411 	   if we know it is a non-NULL pointer.  */
412 	newinfo->visited = true;
413 	newinfo->valnum = name;
414 	if (POINTER_TYPE_P (TREE_TYPE (name))
415 	    && nonnull_arg_p (SSA_NAME_VAR (name)))
416 	  {
417 	    tree ops[2];
418 	    ops[0] = name;
419 	    ops[1] = build_int_cst (TREE_TYPE (name), 0);
420 	    vn_nary_op_t nary;
421 	    /* Allocate from non-unwinding stack.  */
422 	    nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
423 	    init_vn_nary_op_from_pieces (nary, 2, NE_EXPR,
424 					 boolean_type_node, ops);
425 	    nary->predicated_values = 0;
426 	    nary->u.result = boolean_true_node;
427 	    vn_nary_op_insert_into (nary, valid_info->nary, true);
428 	    gcc_assert (nary->unwind_to == NULL);
429 	    /* Also do not link it into the undo chain.  */
430 	    last_inserted_nary = nary->next;
431 	    nary->next = (vn_nary_op_t)(void *)-1;
432 	    nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
433 	    init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR,
434 					 boolean_type_node, ops);
435 	    nary->predicated_values = 0;
436 	    nary->u.result = boolean_false_node;
437 	    vn_nary_op_insert_into (nary, valid_info->nary, true);
438 	    gcc_assert (nary->unwind_to == NULL);
439 	    last_inserted_nary = nary->next;
440 	    nary->next = (vn_nary_op_t)(void *)-1;
441 	    if (dump_file && (dump_flags & TDF_DETAILS))
442 	      {
443 		fprintf (dump_file, "Recording ");
444 		print_generic_expr (dump_file, name, TDF_SLIM);
445 		fprintf (dump_file, " != 0\n");
446 	      }
447 	  }
448 	break;
449 
450       case RESULT_DECL:
451 	/* If the result is passed by invisible reference the default
452 	   def is initialized, otherwise it's uninitialized.  Still
453 	   undefined is varying.  */
454 	newinfo->visited = true;
455 	newinfo->valnum = name;
456 	break;
457 
458       default:
459 	gcc_unreachable ();
460       }
461   return newinfo;
462 }
463 
464 /* Return the SSA value of X.  */
465 
466 inline tree
467 SSA_VAL (tree x, bool *visited = NULL)
468 {
469   vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
470   if (visited)
471     *visited = tem && tem->visited;
472   return tem && tem->visited ? tem->valnum : x;
473 }
474 
475 /* Return the SSA value of the VUSE x, supporting released VDEFs
476    during elimination which will value-number the VDEF to the
477    associated VUSE (but not substitute in the whole lattice).  */
478 
479 static inline tree
vuse_ssa_val(tree x)480 vuse_ssa_val (tree x)
481 {
482   if (!x)
483     return NULL_TREE;
484 
485   do
486     {
487       x = SSA_VAL (x);
488       gcc_assert (x != VN_TOP);
489     }
490   while (SSA_NAME_IN_FREE_LIST (x));
491 
492   return x;
493 }
494 
495 /* Similar to the above but used as callback for walk_non_aliased_vuses
496    and thus should stop at unvisited VUSE to not walk across region
497    boundaries.  */
498 
499 static tree
vuse_valueize(tree vuse)500 vuse_valueize (tree vuse)
501 {
502   do
503     {
504       bool visited;
505       vuse = SSA_VAL (vuse, &visited);
506       if (!visited)
507 	return NULL_TREE;
508       gcc_assert (vuse != VN_TOP);
509     }
510   while (SSA_NAME_IN_FREE_LIST (vuse));
511   return vuse;
512 }
513 
514 
515 /* Return the vn_kind the expression computed by the stmt should be
516    associated with.  */
517 
518 enum vn_kind
vn_get_stmt_kind(gimple * stmt)519 vn_get_stmt_kind (gimple *stmt)
520 {
521   switch (gimple_code (stmt))
522     {
523     case GIMPLE_CALL:
524       return VN_REFERENCE;
525     case GIMPLE_PHI:
526       return VN_PHI;
527     case GIMPLE_ASSIGN:
528       {
529 	enum tree_code code = gimple_assign_rhs_code (stmt);
530 	tree rhs1 = gimple_assign_rhs1 (stmt);
531 	switch (get_gimple_rhs_class (code))
532 	  {
533 	  case GIMPLE_UNARY_RHS:
534 	  case GIMPLE_BINARY_RHS:
535 	  case GIMPLE_TERNARY_RHS:
536 	    return VN_NARY;
537 	  case GIMPLE_SINGLE_RHS:
538 	    switch (TREE_CODE_CLASS (code))
539 	      {
540 	      case tcc_reference:
541 		/* VOP-less references can go through unary case.  */
542 		if ((code == REALPART_EXPR
543 		     || code == IMAGPART_EXPR
544 		     || code == VIEW_CONVERT_EXPR
545 		     || code == BIT_FIELD_REF)
546 		    && (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
547 			|| is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
548 		  return VN_NARY;
549 
550 		/* Fallthrough.  */
551 	      case tcc_declaration:
552 		return VN_REFERENCE;
553 
554 	      case tcc_constant:
555 		return VN_CONSTANT;
556 
557 	      default:
558 		if (code == ADDR_EXPR)
559 		  return (is_gimple_min_invariant (rhs1)
560 			  ? VN_CONSTANT : VN_REFERENCE);
561 		else if (code == CONSTRUCTOR)
562 		  return VN_NARY;
563 		return VN_NONE;
564 	      }
565 	  default:
566 	    return VN_NONE;
567 	  }
568       }
569     default:
570       return VN_NONE;
571     }
572 }
573 
574 /* Lookup a value id for CONSTANT and return it.  If it does not
575    exist returns 0.  */
576 
577 unsigned int
get_constant_value_id(tree constant)578 get_constant_value_id (tree constant)
579 {
580   vn_constant_s **slot;
581   struct vn_constant_s vc;
582 
583   vc.hashcode = vn_hash_constant_with_type (constant);
584   vc.constant = constant;
585   slot = constant_to_value_id->find_slot (&vc, NO_INSERT);
586   if (slot)
587     return (*slot)->value_id;
588   return 0;
589 }
590 
591 /* Lookup a value id for CONSTANT, and if it does not exist, create a
592    new one and return it.  If it does exist, return it.  */
593 
594 unsigned int
get_or_alloc_constant_value_id(tree constant)595 get_or_alloc_constant_value_id (tree constant)
596 {
597   vn_constant_s **slot;
598   struct vn_constant_s vc;
599   vn_constant_t vcp;
600 
601   /* If the hashtable isn't initialized we're not running from PRE and thus
602      do not need value-ids.  */
603   if (!constant_to_value_id)
604     return 0;
605 
606   vc.hashcode = vn_hash_constant_with_type (constant);
607   vc.constant = constant;
608   slot = constant_to_value_id->find_slot (&vc, INSERT);
609   if (*slot)
610     return (*slot)->value_id;
611 
612   vcp = XNEW (struct vn_constant_s);
613   vcp->hashcode = vc.hashcode;
614   vcp->constant = constant;
615   vcp->value_id = get_next_value_id ();
616   *slot = vcp;
617   bitmap_set_bit (constant_value_ids, vcp->value_id);
618   return vcp->value_id;
619 }
620 
621 /* Return true if V is a value id for a constant.  */
622 
623 bool
value_id_constant_p(unsigned int v)624 value_id_constant_p (unsigned int v)
625 {
626   return bitmap_bit_p (constant_value_ids, v);
627 }
628 
629 /* Compute the hash for a reference operand VRO1.  */
630 
631 static void
vn_reference_op_compute_hash(const vn_reference_op_t vro1,inchash::hash & hstate)632 vn_reference_op_compute_hash (const vn_reference_op_t vro1, inchash::hash &hstate)
633 {
634   hstate.add_int (vro1->opcode);
635   if (vro1->op0)
636     inchash::add_expr (vro1->op0, hstate);
637   if (vro1->op1)
638     inchash::add_expr (vro1->op1, hstate);
639   if (vro1->op2)
640     inchash::add_expr (vro1->op2, hstate);
641 }
642 
643 /* Compute a hash for the reference operation VR1 and return it.  */
644 
645 static hashval_t
vn_reference_compute_hash(const vn_reference_t vr1)646 vn_reference_compute_hash (const vn_reference_t vr1)
647 {
648   inchash::hash hstate;
649   hashval_t result;
650   int i;
651   vn_reference_op_t vro;
652   poly_int64 off = -1;
653   bool deref = false;
654 
655   FOR_EACH_VEC_ELT (vr1->operands, i, vro)
656     {
657       if (vro->opcode == MEM_REF)
658 	deref = true;
659       else if (vro->opcode != ADDR_EXPR)
660 	deref = false;
661       if (maybe_ne (vro->off, -1))
662 	{
663 	  if (known_eq (off, -1))
664 	    off = 0;
665 	  off += vro->off;
666 	}
667       else
668 	{
669 	  if (maybe_ne (off, -1)
670 	      && maybe_ne (off, 0))
671 	    hstate.add_poly_int (off);
672 	  off = -1;
673 	  if (deref
674 	      && vro->opcode == ADDR_EXPR)
675 	    {
676 	      if (vro->op0)
677 		{
678 		  tree op = TREE_OPERAND (vro->op0, 0);
679 		  hstate.add_int (TREE_CODE (op));
680 		  inchash::add_expr (op, hstate);
681 		}
682 	    }
683 	  else
684 	    vn_reference_op_compute_hash (vro, hstate);
685 	}
686     }
687   result = hstate.end ();
688   /* ??? We would ICE later if we hash instead of adding that in. */
689   if (vr1->vuse)
690     result += SSA_NAME_VERSION (vr1->vuse);
691 
692   return result;
693 }
694 
695 /* Return true if reference operations VR1 and VR2 are equivalent.  This
696    means they have the same set of operands and vuses.  */
697 
698 bool
vn_reference_eq(const_vn_reference_t const vr1,const_vn_reference_t const vr2)699 vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
700 {
701   unsigned i, j;
702 
703   /* Early out if this is not a hash collision.  */
704   if (vr1->hashcode != vr2->hashcode)
705     return false;
706 
707   /* The VOP needs to be the same.  */
708   if (vr1->vuse != vr2->vuse)
709     return false;
710 
711   /* If the operands are the same we are done.  */
712   if (vr1->operands == vr2->operands)
713     return true;
714 
715   if (!expressions_equal_p (TYPE_SIZE (vr1->type), TYPE_SIZE (vr2->type)))
716     return false;
717 
718   if (INTEGRAL_TYPE_P (vr1->type)
719       && INTEGRAL_TYPE_P (vr2->type))
720     {
721       if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
722 	return false;
723     }
724   else if (INTEGRAL_TYPE_P (vr1->type)
725 	   && (TYPE_PRECISION (vr1->type)
726 	       != TREE_INT_CST_LOW (TYPE_SIZE (vr1->type))))
727     return false;
728   else if (INTEGRAL_TYPE_P (vr2->type)
729 	   && (TYPE_PRECISION (vr2->type)
730 	       != TREE_INT_CST_LOW (TYPE_SIZE (vr2->type))))
731     return false;
732 
733   i = 0;
734   j = 0;
735   do
736     {
737       poly_int64 off1 = 0, off2 = 0;
738       vn_reference_op_t vro1, vro2;
739       vn_reference_op_s tem1, tem2;
740       bool deref1 = false, deref2 = false;
741       bool reverse1 = false, reverse2 = false;
742       for (; vr1->operands.iterate (i, &vro1); i++)
743 	{
744 	  if (vro1->opcode == MEM_REF)
745 	    deref1 = true;
746 	  /* Do not look through a storage order barrier.  */
747 	  else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
748 	    return false;
749 	  reverse1 |= vro1->reverse;
750 	  if (known_eq (vro1->off, -1))
751 	    break;
752 	  off1 += vro1->off;
753 	}
754       for (; vr2->operands.iterate (j, &vro2); j++)
755 	{
756 	  if (vro2->opcode == MEM_REF)
757 	    deref2 = true;
758 	  /* Do not look through a storage order barrier.  */
759 	  else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
760 	    return false;
761 	  reverse2 |= vro2->reverse;
762 	  if (known_eq (vro2->off, -1))
763 	    break;
764 	  off2 += vro2->off;
765 	}
766       if (maybe_ne (off1, off2) || reverse1 != reverse2)
767 	return false;
768       if (deref1 && vro1->opcode == ADDR_EXPR)
769 	{
770 	  memset (&tem1, 0, sizeof (tem1));
771 	  tem1.op0 = TREE_OPERAND (vro1->op0, 0);
772 	  tem1.type = TREE_TYPE (tem1.op0);
773 	  tem1.opcode = TREE_CODE (tem1.op0);
774 	  vro1 = &tem1;
775 	  deref1 = false;
776 	}
777       if (deref2 && vro2->opcode == ADDR_EXPR)
778 	{
779 	  memset (&tem2, 0, sizeof (tem2));
780 	  tem2.op0 = TREE_OPERAND (vro2->op0, 0);
781 	  tem2.type = TREE_TYPE (tem2.op0);
782 	  tem2.opcode = TREE_CODE (tem2.op0);
783 	  vro2 = &tem2;
784 	  deref2 = false;
785 	}
786       if (deref1 != deref2)
787 	return false;
788       if (!vn_reference_op_eq (vro1, vro2))
789 	return false;
790       ++j;
791       ++i;
792     }
793   while (vr1->operands.length () != i
794 	 || vr2->operands.length () != j);
795 
796   return true;
797 }
798 
799 /* Copy the operations present in load/store REF into RESULT, a vector of
800    vn_reference_op_s's.  */
801 
802 static void
copy_reference_ops_from_ref(tree ref,vec<vn_reference_op_s> * result)803 copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
804 {
805   /* For non-calls, store the information that makes up the address.  */
806   tree orig = ref;
807   while (ref)
808     {
809       vn_reference_op_s temp;
810 
811       memset (&temp, 0, sizeof (temp));
812       temp.type = TREE_TYPE (ref);
813       temp.opcode = TREE_CODE (ref);
814       temp.off = -1;
815 
816       switch (temp.opcode)
817 	{
818 	case MODIFY_EXPR:
819 	  temp.op0 = TREE_OPERAND (ref, 1);
820 	  break;
821 	case WITH_SIZE_EXPR:
822 	  temp.op0 = TREE_OPERAND (ref, 1);
823 	  temp.off = 0;
824 	  break;
825 	case MEM_REF:
826 	  /* The base address gets its own vn_reference_op_s structure.  */
827 	  temp.op0 = TREE_OPERAND (ref, 1);
828 	  if (!mem_ref_offset (ref).to_shwi (&temp.off))
829 	    temp.off = -1;
830 	  temp.clique = MR_DEPENDENCE_CLIQUE (ref);
831 	  temp.base = MR_DEPENDENCE_BASE (ref);
832 	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
833 	  break;
834 	case TARGET_MEM_REF:
835 	  /* The base address gets its own vn_reference_op_s structure.  */
836 	  temp.op0 = TMR_INDEX (ref);
837 	  temp.op1 = TMR_STEP (ref);
838 	  temp.op2 = TMR_OFFSET (ref);
839 	  temp.clique = MR_DEPENDENCE_CLIQUE (ref);
840 	  temp.base = MR_DEPENDENCE_BASE (ref);
841 	  result->safe_push (temp);
842 	  memset (&temp, 0, sizeof (temp));
843 	  temp.type = NULL_TREE;
844 	  temp.opcode = ERROR_MARK;
845 	  temp.op0 = TMR_INDEX2 (ref);
846 	  temp.off = -1;
847 	  break;
848 	case BIT_FIELD_REF:
849 	  /* Record bits, position and storage order.  */
850 	  temp.op0 = TREE_OPERAND (ref, 1);
851 	  temp.op1 = TREE_OPERAND (ref, 2);
852 	  if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
853 	    temp.off = -1;
854 	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
855 	  break;
856 	case COMPONENT_REF:
857 	  /* The field decl is enough to unambiguously specify the field,
858 	     a matching type is not necessary and a mismatching type
859 	     is always a spurious difference.  */
860 	  temp.type = NULL_TREE;
861 	  temp.op0 = TREE_OPERAND (ref, 1);
862 	  temp.op1 = TREE_OPERAND (ref, 2);
863 	  temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
864 			  && TYPE_REVERSE_STORAGE_ORDER
865 			       (TREE_TYPE (TREE_OPERAND (ref, 0))));
866 	  {
867 	    tree this_offset = component_ref_field_offset (ref);
868 	    if (this_offset
869 		&& poly_int_tree_p (this_offset))
870 	      {
871 		tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1));
872 		if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0)
873 		  {
874 		    poly_offset_int off
875 		      = (wi::to_poly_offset (this_offset)
876 			 + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT));
877 		    /* Probibit value-numbering zero offset components
878 		       of addresses the same before the pass folding
879 		       __builtin_object_size had a chance to run
880 		       (checking cfun->after_inlining does the
881 		       trick here).  */
882 		    if (TREE_CODE (orig) != ADDR_EXPR
883 			|| maybe_ne (off, 0)
884 			|| cfun->after_inlining)
885 		      off.to_shwi (&temp.off);
886 		  }
887 	      }
888 	  }
889 	  break;
890 	case ARRAY_RANGE_REF:
891 	case ARRAY_REF:
892 	  {
893 	    tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
894 	    /* Record index as operand.  */
895 	    temp.op0 = TREE_OPERAND (ref, 1);
896 	    /* Always record lower bounds and element size.  */
897 	    temp.op1 = array_ref_low_bound (ref);
898 	    /* But record element size in units of the type alignment.  */
899 	    temp.op2 = TREE_OPERAND (ref, 3);
900 	    temp.align = eltype->type_common.align;
901 	    if (! temp.op2)
902 	      temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
903 				     size_int (TYPE_ALIGN_UNIT (eltype)));
904 	    if (poly_int_tree_p (temp.op0)
905 		&& poly_int_tree_p (temp.op1)
906 		&& TREE_CODE (temp.op2) == INTEGER_CST)
907 	      {
908 		poly_offset_int off = ((wi::to_poly_offset (temp.op0)
909 					- wi::to_poly_offset (temp.op1))
910 				       * wi::to_offset (temp.op2)
911 				       * vn_ref_op_align_unit (&temp));
912 		off.to_shwi (&temp.off);
913 	      }
914 	    temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
915 			    && TYPE_REVERSE_STORAGE_ORDER
916 				 (TREE_TYPE (TREE_OPERAND (ref, 0))));
917 	  }
918 	  break;
919 	case VAR_DECL:
920 	  if (DECL_HARD_REGISTER (ref))
921 	    {
922 	      temp.op0 = ref;
923 	      break;
924 	    }
925 	  /* Fallthru.  */
926 	case PARM_DECL:
927 	case CONST_DECL:
928 	case RESULT_DECL:
929 	  /* Canonicalize decls to MEM[&decl] which is what we end up with
930 	     when valueizing MEM[ptr] with ptr = &decl.  */
931 	  temp.opcode = MEM_REF;
932 	  temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
933 	  temp.off = 0;
934 	  result->safe_push (temp);
935 	  temp.opcode = ADDR_EXPR;
936 	  temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
937 	  temp.type = TREE_TYPE (temp.op0);
938 	  temp.off = -1;
939 	  break;
940 	case STRING_CST:
941 	case INTEGER_CST:
942 	case POLY_INT_CST:
943 	case COMPLEX_CST:
944 	case VECTOR_CST:
945 	case REAL_CST:
946 	case FIXED_CST:
947 	case CONSTRUCTOR:
948 	case SSA_NAME:
949 	  temp.op0 = ref;
950 	  break;
951 	case ADDR_EXPR:
952 	  if (is_gimple_min_invariant (ref))
953 	    {
954 	      temp.op0 = ref;
955 	      break;
956 	    }
957 	  break;
958 	  /* These are only interesting for their operands, their
959 	     existence, and their type.  They will never be the last
960 	     ref in the chain of references (IE they require an
961 	     operand), so we don't have to put anything
962 	     for op* as it will be handled by the iteration  */
963 	case REALPART_EXPR:
964 	  temp.off = 0;
965 	  break;
966 	case VIEW_CONVERT_EXPR:
967 	  temp.off = 0;
968 	  temp.reverse = storage_order_barrier_p (ref);
969 	  break;
970 	case IMAGPART_EXPR:
971 	  /* This is only interesting for its constant offset.  */
972 	  temp.off = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (ref)));
973 	  break;
974 	default:
975 	  gcc_unreachable ();
976 	}
977       result->safe_push (temp);
978 
979       if (REFERENCE_CLASS_P (ref)
980 	  || TREE_CODE (ref) == MODIFY_EXPR
981 	  || TREE_CODE (ref) == WITH_SIZE_EXPR
982 	  || (TREE_CODE (ref) == ADDR_EXPR
983 	      && !is_gimple_min_invariant (ref)))
984 	ref = TREE_OPERAND (ref, 0);
985       else
986 	ref = NULL_TREE;
987     }
988 }
989 
990 /* Build a alias-oracle reference abstraction in *REF from the vn_reference
991    operands in *OPS, the reference alias set SET and the reference type TYPE.
992    Return true if something useful was produced.  */
993 
994 bool
ao_ref_init_from_vn_reference(ao_ref * ref,alias_set_type set,alias_set_type base_set,tree type,vec<vn_reference_op_s> ops)995 ao_ref_init_from_vn_reference (ao_ref *ref,
996 			       alias_set_type set, alias_set_type base_set,
997 			       tree type, vec<vn_reference_op_s> ops)
998 {
999   vn_reference_op_t op;
1000   unsigned i;
1001   tree base = NULL_TREE;
1002   tree *op0_p = &base;
1003   poly_offset_int offset = 0;
1004   poly_offset_int max_size;
1005   poly_offset_int size = -1;
1006   tree size_tree = NULL_TREE;
1007 
1008   machine_mode mode = TYPE_MODE (type);
1009   if (mode == BLKmode)
1010     size_tree = TYPE_SIZE (type);
1011   else
1012     size = GET_MODE_BITSIZE (mode);
1013   if (size_tree != NULL_TREE
1014       && poly_int_tree_p (size_tree))
1015     size = wi::to_poly_offset (size_tree);
1016 
1017   /* Lower the final access size from the outermost expression.  */
1018   op = &ops[0];
1019   size_tree = NULL_TREE;
1020   if (op->opcode == COMPONENT_REF)
1021     size_tree = DECL_SIZE (op->op0);
1022   else if (op->opcode == BIT_FIELD_REF)
1023     size_tree = op->op0;
1024   if (size_tree != NULL_TREE
1025       && poly_int_tree_p (size_tree)
1026       && (!known_size_p (size)
1027 	  || known_lt (wi::to_poly_offset (size_tree), size)))
1028     size = wi::to_poly_offset (size_tree);
1029 
1030   /* Initially, maxsize is the same as the accessed element size.
1031      In the following it will only grow (or become -1).  */
1032   max_size = size;
1033 
1034   /* Compute cumulative bit-offset for nested component-refs and array-refs,
1035      and find the ultimate containing object.  */
1036   FOR_EACH_VEC_ELT (ops, i, op)
1037     {
1038       switch (op->opcode)
1039 	{
1040 	/* These may be in the reference ops, but we cannot do anything
1041 	   sensible with them here.  */
1042 	case ADDR_EXPR:
1043 	  /* Apart from ADDR_EXPR arguments to MEM_REF.  */
1044 	  if (base != NULL_TREE
1045 	      && TREE_CODE (base) == MEM_REF
1046 	      && op->op0
1047 	      && DECL_P (TREE_OPERAND (op->op0, 0)))
1048 	    {
1049 	      vn_reference_op_t pop = &ops[i-1];
1050 	      base = TREE_OPERAND (op->op0, 0);
1051 	      if (known_eq (pop->off, -1))
1052 		{
1053 		  max_size = -1;
1054 		  offset = 0;
1055 		}
1056 	      else
1057 		offset += pop->off * BITS_PER_UNIT;
1058 	      op0_p = NULL;
1059 	      break;
1060 	    }
1061 	  /* Fallthru.  */
1062 	case CALL_EXPR:
1063 	  return false;
1064 
1065 	/* Record the base objects.  */
1066 	case MEM_REF:
1067 	  *op0_p = build2 (MEM_REF, op->type,
1068 			   NULL_TREE, op->op0);
1069 	  MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
1070 	  MR_DEPENDENCE_BASE (*op0_p) = op->base;
1071 	  op0_p = &TREE_OPERAND (*op0_p, 0);
1072 	  break;
1073 
1074 	case VAR_DECL:
1075 	case PARM_DECL:
1076 	case RESULT_DECL:
1077 	case SSA_NAME:
1078 	  *op0_p = op->op0;
1079 	  op0_p = NULL;
1080 	  break;
1081 
1082 	/* And now the usual component-reference style ops.  */
1083 	case BIT_FIELD_REF:
1084 	  offset += wi::to_poly_offset (op->op1);
1085 	  break;
1086 
1087 	case COMPONENT_REF:
1088 	  {
1089 	    tree field = op->op0;
1090 	    /* We do not have a complete COMPONENT_REF tree here so we
1091 	       cannot use component_ref_field_offset.  Do the interesting
1092 	       parts manually.  */
1093 	    tree this_offset = DECL_FIELD_OFFSET (field);
1094 
1095 	    if (op->op1 || !poly_int_tree_p (this_offset))
1096 	      max_size = -1;
1097 	    else
1098 	      {
1099 		poly_offset_int woffset = (wi::to_poly_offset (this_offset)
1100 					   << LOG2_BITS_PER_UNIT);
1101 		woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
1102 		offset += woffset;
1103 	      }
1104 	    break;
1105 	  }
1106 
1107 	case ARRAY_RANGE_REF:
1108 	case ARRAY_REF:
1109 	  /* We recorded the lower bound and the element size.  */
1110 	  if (!poly_int_tree_p (op->op0)
1111 	      || !poly_int_tree_p (op->op1)
1112 	      || TREE_CODE (op->op2) != INTEGER_CST)
1113 	    max_size = -1;
1114 	  else
1115 	    {
1116 	      poly_offset_int woffset
1117 		= wi::sext (wi::to_poly_offset (op->op0)
1118 			    - wi::to_poly_offset (op->op1),
1119 			    TYPE_PRECISION (sizetype));
1120 	      woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op);
1121 	      woffset <<= LOG2_BITS_PER_UNIT;
1122 	      offset += woffset;
1123 	    }
1124 	  break;
1125 
1126 	case REALPART_EXPR:
1127 	  break;
1128 
1129 	case IMAGPART_EXPR:
1130 	  offset += size;
1131 	  break;
1132 
1133 	case VIEW_CONVERT_EXPR:
1134 	  break;
1135 
1136 	case STRING_CST:
1137 	case INTEGER_CST:
1138 	case COMPLEX_CST:
1139 	case VECTOR_CST:
1140 	case REAL_CST:
1141 	case CONSTRUCTOR:
1142 	case CONST_DECL:
1143 	  return false;
1144 
1145 	default:
1146 	  return false;
1147 	}
1148     }
1149 
1150   if (base == NULL_TREE)
1151     return false;
1152 
1153   ref->ref = NULL_TREE;
1154   ref->base = base;
1155   ref->ref_alias_set = set;
1156   ref->base_alias_set = base_set;
1157   /* We discount volatiles from value-numbering elsewhere.  */
1158   ref->volatile_p = false;
1159 
1160   if (!size.to_shwi (&ref->size) || maybe_lt (ref->size, 0))
1161     {
1162       ref->offset = 0;
1163       ref->size = -1;
1164       ref->max_size = -1;
1165       return true;
1166     }
1167 
1168   if (!offset.to_shwi (&ref->offset))
1169     {
1170       ref->offset = 0;
1171       ref->max_size = -1;
1172       return true;
1173     }
1174 
1175   if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0))
1176     ref->max_size = -1;
1177 
1178   return true;
1179 }
1180 
1181 /* Copy the operations present in load/store/call REF into RESULT, a vector of
1182    vn_reference_op_s's.  */
1183 
1184 static void
copy_reference_ops_from_call(gcall * call,vec<vn_reference_op_s> * result)1185 copy_reference_ops_from_call (gcall *call,
1186 			      vec<vn_reference_op_s> *result)
1187 {
1188   vn_reference_op_s temp;
1189   unsigned i;
1190   tree lhs = gimple_call_lhs (call);
1191   int lr;
1192 
1193   /* If 2 calls have a different non-ssa lhs, vdef value numbers should be
1194      different.  By adding the lhs here in the vector, we ensure that the
1195      hashcode is different, guaranteeing a different value number.  */
1196   if (lhs && TREE_CODE (lhs) != SSA_NAME)
1197     {
1198       memset (&temp, 0, sizeof (temp));
1199       temp.opcode = MODIFY_EXPR;
1200       temp.type = TREE_TYPE (lhs);
1201       temp.op0 = lhs;
1202       temp.off = -1;
1203       result->safe_push (temp);
1204     }
1205 
1206   /* Copy the type, opcode, function, static chain and EH region, if any.  */
1207   memset (&temp, 0, sizeof (temp));
1208   temp.type = gimple_call_fntype (call);
1209   temp.opcode = CALL_EXPR;
1210   temp.op0 = gimple_call_fn (call);
1211   temp.op1 = gimple_call_chain (call);
1212   if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0)
1213     temp.op2 = size_int (lr);
1214   temp.off = -1;
1215   result->safe_push (temp);
1216 
1217   /* Copy the call arguments.  As they can be references as well,
1218      just chain them together.  */
1219   for (i = 0; i < gimple_call_num_args (call); ++i)
1220     {
1221       tree callarg = gimple_call_arg (call, i);
1222       copy_reference_ops_from_ref (callarg, result);
1223     }
1224 }
1225 
1226 /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
1227    *I_P to point to the last element of the replacement.  */
1228 static bool
vn_reference_fold_indirect(vec<vn_reference_op_s> * ops,unsigned int * i_p)1229 vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
1230 			    unsigned int *i_p)
1231 {
1232   unsigned int i = *i_p;
1233   vn_reference_op_t op = &(*ops)[i];
1234   vn_reference_op_t mem_op = &(*ops)[i - 1];
1235   tree addr_base;
1236   poly_int64 addr_offset = 0;
1237 
1238   /* The only thing we have to do is from &OBJ.foo.bar add the offset
1239      from .foo.bar to the preceding MEM_REF offset and replace the
1240      address with &OBJ.  */
1241   addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 0),
1242 					     &addr_offset);
1243   gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
1244   if (addr_base != TREE_OPERAND (op->op0, 0))
1245     {
1246       poly_offset_int off
1247 	= (poly_offset_int::from (wi::to_poly_wide (mem_op->op0),
1248 				  SIGNED)
1249 	   + addr_offset);
1250       mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1251       op->op0 = build_fold_addr_expr (addr_base);
1252       if (tree_fits_shwi_p (mem_op->op0))
1253 	mem_op->off = tree_to_shwi (mem_op->op0);
1254       else
1255 	mem_op->off = -1;
1256       return true;
1257     }
1258   return false;
1259 }
1260 
1261 /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
1262    *I_P to point to the last element of the replacement.  */
1263 static bool
vn_reference_maybe_forwprop_address(vec<vn_reference_op_s> * ops,unsigned int * i_p)1264 vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
1265 				     unsigned int *i_p)
1266 {
1267   bool changed = false;
1268   vn_reference_op_t op;
1269 
1270   do
1271     {
1272       unsigned int i = *i_p;
1273       op = &(*ops)[i];
1274       vn_reference_op_t mem_op = &(*ops)[i - 1];
1275       gimple *def_stmt;
1276       enum tree_code code;
1277       poly_offset_int off;
1278 
1279       def_stmt = SSA_NAME_DEF_STMT (op->op0);
1280       if (!is_gimple_assign (def_stmt))
1281 	return changed;
1282 
1283       code = gimple_assign_rhs_code (def_stmt);
1284       if (code != ADDR_EXPR
1285 	  && code != POINTER_PLUS_EXPR)
1286 	return changed;
1287 
1288       off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);
1289 
1290       /* The only thing we have to do is from &OBJ.foo.bar add the offset
1291 	 from .foo.bar to the preceding MEM_REF offset and replace the
1292 	 address with &OBJ.  */
1293       if (code == ADDR_EXPR)
1294 	{
1295 	  tree addr, addr_base;
1296 	  poly_int64 addr_offset;
1297 
1298 	  addr = gimple_assign_rhs1 (def_stmt);
1299 	  addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
1300 						     &addr_offset);
1301 	  /* If that didn't work because the address isn't invariant propagate
1302 	     the reference tree from the address operation in case the current
1303 	     dereference isn't offsetted.  */
1304 	  if (!addr_base
1305 	      && *i_p == ops->length () - 1
1306 	      && known_eq (off, 0)
1307 	      /* This makes us disable this transform for PRE where the
1308 		 reference ops might be also used for code insertion which
1309 		 is invalid.  */
1310 	      && default_vn_walk_kind == VN_WALKREWRITE)
1311 	    {
1312 	      auto_vec<vn_reference_op_s, 32> tem;
1313 	      copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
1314 	      /* Make sure to preserve TBAA info.  The only objects not
1315 		 wrapped in MEM_REFs that can have their address taken are
1316 		 STRING_CSTs.  */
1317 	      if (tem.length () >= 2
1318 		  && tem[tem.length () - 2].opcode == MEM_REF)
1319 		{
1320 		  vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
1321 		  new_mem_op->op0
1322 		      = wide_int_to_tree (TREE_TYPE (mem_op->op0),
1323 					  wi::to_poly_wide (new_mem_op->op0));
1324 		}
1325 	      else
1326 		gcc_assert (tem.last ().opcode == STRING_CST);
1327 	      ops->pop ();
1328 	      ops->pop ();
1329 	      ops->safe_splice (tem);
1330 	      --*i_p;
1331 	      return true;
1332 	    }
1333 	  if (!addr_base
1334 	      || TREE_CODE (addr_base) != MEM_REF
1335 	      || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
1336 		  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
1337 								    0))))
1338 	    return changed;
1339 
1340 	  off += addr_offset;
1341 	  off += mem_ref_offset (addr_base);
1342 	  op->op0 = TREE_OPERAND (addr_base, 0);
1343 	}
1344       else
1345 	{
1346 	  tree ptr, ptroff;
1347 	  ptr = gimple_assign_rhs1 (def_stmt);
1348 	  ptroff = gimple_assign_rhs2 (def_stmt);
1349 	  if (TREE_CODE (ptr) != SSA_NAME
1350 	      || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
1351 	      /* Make sure to not endlessly recurse.
1352 		 See gcc.dg/tree-ssa/20040408-1.c for an example.  Can easily
1353 		 happen when we value-number a PHI to its backedge value.  */
1354 	      || SSA_VAL (ptr) == op->op0
1355 	      || !poly_int_tree_p (ptroff))
1356 	    return changed;
1357 
1358 	  off += wi::to_poly_offset (ptroff);
1359 	  op->op0 = ptr;
1360 	}
1361 
1362       mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
1363       if (tree_fits_shwi_p (mem_op->op0))
1364 	mem_op->off = tree_to_shwi (mem_op->op0);
1365       else
1366 	mem_op->off = -1;
1367       /* ???  Can end up with endless recursion here!?
1368 	 gcc.c-torture/execute/strcmp-1.c  */
1369       if (TREE_CODE (op->op0) == SSA_NAME)
1370 	op->op0 = SSA_VAL (op->op0);
1371       if (TREE_CODE (op->op0) != SSA_NAME)
1372 	op->opcode = TREE_CODE (op->op0);
1373 
1374       changed = true;
1375     }
1376   /* Tail-recurse.  */
1377   while (TREE_CODE (op->op0) == SSA_NAME);
1378 
1379   /* Fold a remaining *&.  */
1380   if (TREE_CODE (op->op0) == ADDR_EXPR)
1381     vn_reference_fold_indirect (ops, i_p);
1382 
1383   return changed;
1384 }
1385 
1386 /* Optimize the reference REF to a constant if possible or return
1387    NULL_TREE if not.  */
1388 
1389 tree
fully_constant_vn_reference_p(vn_reference_t ref)1390 fully_constant_vn_reference_p (vn_reference_t ref)
1391 {
1392   vec<vn_reference_op_s> operands = ref->operands;
1393   vn_reference_op_t op;
1394 
1395   /* Try to simplify the translated expression if it is
1396      a call to a builtin function with at most two arguments.  */
1397   op = &operands[0];
1398   if (op->opcode == CALL_EXPR
1399       && TREE_CODE (op->op0) == ADDR_EXPR
1400       && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
1401       && fndecl_built_in_p (TREE_OPERAND (op->op0, 0))
1402       && operands.length () >= 2
1403       && operands.length () <= 3)
1404     {
1405       vn_reference_op_t arg0, arg1 = NULL;
1406       bool anyconst = false;
1407       arg0 = &operands[1];
1408       if (operands.length () > 2)
1409 	arg1 = &operands[2];
1410       if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
1411 	  || (arg0->opcode == ADDR_EXPR
1412 	      && is_gimple_min_invariant (arg0->op0)))
1413 	anyconst = true;
1414       if (arg1
1415 	  && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
1416 	      || (arg1->opcode == ADDR_EXPR
1417 		  && is_gimple_min_invariant (arg1->op0))))
1418 	anyconst = true;
1419       if (anyconst)
1420 	{
1421 	  tree folded = build_call_expr (TREE_OPERAND (op->op0, 0),
1422 					 arg1 ? 2 : 1,
1423 					 arg0->op0,
1424 					 arg1 ? arg1->op0 : NULL);
1425 	  if (folded
1426 	      && TREE_CODE (folded) == NOP_EXPR)
1427 	    folded = TREE_OPERAND (folded, 0);
1428 	  if (folded
1429 	      && is_gimple_min_invariant (folded))
1430 	    return folded;
1431 	}
1432     }
1433 
1434   /* Simplify reads from constants or constant initializers.  */
1435   else if (BITS_PER_UNIT == 8
1436 	   && COMPLETE_TYPE_P (ref->type)
1437 	   && is_gimple_reg_type (ref->type))
1438     {
1439       poly_int64 off = 0;
1440       HOST_WIDE_INT size;
1441       if (INTEGRAL_TYPE_P (ref->type))
1442 	size = TYPE_PRECISION (ref->type);
1443       else if (tree_fits_shwi_p (TYPE_SIZE (ref->type)))
1444 	size = tree_to_shwi (TYPE_SIZE (ref->type));
1445       else
1446 	return NULL_TREE;
1447       if (size % BITS_PER_UNIT != 0
1448 	  || size > MAX_BITSIZE_MODE_ANY_MODE)
1449 	return NULL_TREE;
1450       size /= BITS_PER_UNIT;
1451       unsigned i;
1452       for (i = 0; i < operands.length (); ++i)
1453 	{
1454 	  if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant)
1455 	    {
1456 	      ++i;
1457 	      break;
1458 	    }
1459 	  if (known_eq (operands[i].off, -1))
1460 	    return NULL_TREE;
1461 	  off += operands[i].off;
1462 	  if (operands[i].opcode == MEM_REF)
1463 	    {
1464 	      ++i;
1465 	      break;
1466 	    }
1467 	}
1468       vn_reference_op_t base = &operands[--i];
1469       tree ctor = error_mark_node;
1470       tree decl = NULL_TREE;
1471       if (TREE_CODE_CLASS (base->opcode) == tcc_constant)
1472 	ctor = base->op0;
1473       else if (base->opcode == MEM_REF
1474 	       && base[1].opcode == ADDR_EXPR
1475 	       && (TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == VAR_DECL
1476 		   || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL
1477 		   || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST))
1478 	{
1479 	  decl = TREE_OPERAND (base[1].op0, 0);
1480 	  if (TREE_CODE (decl) == STRING_CST)
1481 	    ctor = decl;
1482 	  else
1483 	    ctor = ctor_for_folding (decl);
1484 	}
1485       if (ctor == NULL_TREE)
1486 	return build_zero_cst (ref->type);
1487       else if (ctor != error_mark_node)
1488 	{
1489 	  HOST_WIDE_INT const_off;
1490 	  if (decl)
1491 	    {
1492 	      tree res = fold_ctor_reference (ref->type, ctor,
1493 					      off * BITS_PER_UNIT,
1494 					      size * BITS_PER_UNIT, decl);
1495 	      if (res)
1496 		{
1497 		  STRIP_USELESS_TYPE_CONVERSION (res);
1498 		  if (is_gimple_min_invariant (res))
1499 		    return res;
1500 		}
1501 	    }
1502 	  else if (off.is_constant (&const_off))
1503 	    {
1504 	      unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
1505 	      int len = native_encode_expr (ctor, buf, size, const_off);
1506 	      if (len > 0)
1507 		return native_interpret_expr (ref->type, buf, len);
1508 	    }
1509 	}
1510     }
1511 
1512   return NULL_TREE;
1513 }
1514 
1515 /* Return true if OPS contain a storage order barrier.  */
1516 
1517 static bool
contains_storage_order_barrier_p(vec<vn_reference_op_s> ops)1518 contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
1519 {
1520   vn_reference_op_t op;
1521   unsigned i;
1522 
1523   FOR_EACH_VEC_ELT (ops, i, op)
1524     if (op->opcode == VIEW_CONVERT_EXPR && op->reverse)
1525       return true;
1526 
1527   return false;
1528 }
1529 
1530 /* Return true if OPS represent an access with reverse storage order.  */
1531 
1532 static bool
reverse_storage_order_for_component_p(vec<vn_reference_op_s> ops)1533 reverse_storage_order_for_component_p (vec<vn_reference_op_s> ops)
1534 {
1535   unsigned i = 0;
1536   if (ops[i].opcode == REALPART_EXPR || ops[i].opcode == IMAGPART_EXPR)
1537     ++i;
1538   switch (ops[i].opcode)
1539     {
1540     case ARRAY_REF:
1541     case COMPONENT_REF:
1542     case BIT_FIELD_REF:
1543     case MEM_REF:
1544       return ops[i].reverse;
1545     default:
1546       return false;
1547     }
1548 }
1549 
1550 /* Transform any SSA_NAME's in a vector of vn_reference_op_s
1551    structures into their value numbers.  This is done in-place, and
1552    the vector passed in is returned.  *VALUEIZED_ANYTHING will specify
1553    whether any operands were valueized.  */
1554 
1555 static void
1556 valueize_refs_1 (vec<vn_reference_op_s> *orig, bool *valueized_anything,
1557 		 bool with_avail = false)
1558 {
1559   vn_reference_op_t vro;
1560   unsigned int i;
1561 
1562   *valueized_anything = false;
1563 
1564   FOR_EACH_VEC_ELT (*orig, i, vro)
1565     {
1566       if (vro->opcode == SSA_NAME
1567 	  || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
1568 	{
1569 	  tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0);
1570 	  if (tem != vro->op0)
1571 	    {
1572 	      *valueized_anything = true;
1573 	      vro->op0 = tem;
1574 	    }
1575 	  /* If it transforms from an SSA_NAME to a constant, update
1576 	     the opcode.  */
1577 	  if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
1578 	    vro->opcode = TREE_CODE (vro->op0);
1579 	}
1580       if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
1581 	{
1582 	  tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1);
1583 	  if (tem != vro->op1)
1584 	    {
1585 	      *valueized_anything = true;
1586 	      vro->op1 = tem;
1587 	    }
1588 	}
1589       if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
1590 	{
1591 	  tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2);
1592 	  if (tem != vro->op2)
1593 	    {
1594 	      *valueized_anything = true;
1595 	      vro->op2 = tem;
1596 	    }
1597 	}
1598       /* If it transforms from an SSA_NAME to an address, fold with
1599 	 a preceding indirect reference.  */
1600       if (i > 0
1601 	  && vro->op0
1602 	  && TREE_CODE (vro->op0) == ADDR_EXPR
1603 	  && (*orig)[i - 1].opcode == MEM_REF)
1604 	{
1605 	  if (vn_reference_fold_indirect (orig, &i))
1606 	    *valueized_anything = true;
1607 	}
1608       else if (i > 0
1609 	       && vro->opcode == SSA_NAME
1610 	       && (*orig)[i - 1].opcode == MEM_REF)
1611 	{
1612 	  if (vn_reference_maybe_forwprop_address (orig, &i))
1613 	    *valueized_anything = true;
1614 	}
1615       /* If it transforms a non-constant ARRAY_REF into a constant
1616 	 one, adjust the constant offset.  */
1617       else if (vro->opcode == ARRAY_REF
1618 	       && known_eq (vro->off, -1)
1619 	       && poly_int_tree_p (vro->op0)
1620 	       && poly_int_tree_p (vro->op1)
1621 	       && TREE_CODE (vro->op2) == INTEGER_CST)
1622 	{
1623 	  poly_offset_int off = ((wi::to_poly_offset (vro->op0)
1624 				  - wi::to_poly_offset (vro->op1))
1625 				 * wi::to_offset (vro->op2)
1626 				 * vn_ref_op_align_unit (vro));
1627 	  off.to_shwi (&vro->off);
1628 	}
1629     }
1630 }
1631 
1632 static void
valueize_refs(vec<vn_reference_op_s> * orig)1633 valueize_refs (vec<vn_reference_op_s> *orig)
1634 {
1635   bool tem;
1636   valueize_refs_1 (orig, &tem);
1637 }
1638 
1639 static vec<vn_reference_op_s> shared_lookup_references;
1640 
1641 /* Create a vector of vn_reference_op_s structures from REF, a
1642    REFERENCE_CLASS_P tree.  The vector is shared among all callers of
1643    this function.  *VALUEIZED_ANYTHING will specify whether any
1644    operands were valueized.  */
1645 
1646 static vec<vn_reference_op_s>
valueize_shared_reference_ops_from_ref(tree ref,bool * valueized_anything)1647 valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
1648 {
1649   if (!ref)
1650     return vNULL;
1651   shared_lookup_references.truncate (0);
1652   copy_reference_ops_from_ref (ref, &shared_lookup_references);
1653   valueize_refs_1 (&shared_lookup_references, valueized_anything);
1654   return shared_lookup_references;
1655 }
1656 
1657 /* Create a vector of vn_reference_op_s structures from CALL, a
1658    call statement.  The vector is shared among all callers of
1659    this function.  */
1660 
1661 static vec<vn_reference_op_s>
valueize_shared_reference_ops_from_call(gcall * call)1662 valueize_shared_reference_ops_from_call (gcall *call)
1663 {
1664   if (!call)
1665     return vNULL;
1666   shared_lookup_references.truncate (0);
1667   copy_reference_ops_from_call (call, &shared_lookup_references);
1668   valueize_refs (&shared_lookup_references);
1669   return shared_lookup_references;
1670 }
1671 
1672 /* Lookup a SCCVN reference operation VR in the current hash table.
1673    Returns the resulting value number if it exists in the hash table,
1674    NULL_TREE otherwise.  VNRESULT will be filled in with the actual
1675    vn_reference_t stored in the hashtable if something is found.  */
1676 
1677 static tree
vn_reference_lookup_1(vn_reference_t vr,vn_reference_t * vnresult)1678 vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
1679 {
1680   vn_reference_s **slot;
1681   hashval_t hash;
1682 
1683   hash = vr->hashcode;
1684   slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
1685   if (slot)
1686     {
1687       if (vnresult)
1688 	*vnresult = (vn_reference_t)*slot;
1689       return ((vn_reference_t)*slot)->result;
1690     }
1691 
1692   return NULL_TREE;
1693 }
1694 
1695 
1696 /* Partial definition tracking support.  */
1697 
1698 struct pd_range
1699 {
1700   HOST_WIDE_INT offset;
1701   HOST_WIDE_INT size;
1702 };
1703 
1704 struct pd_data
1705 {
1706   tree rhs;
1707   HOST_WIDE_INT offset;
1708   HOST_WIDE_INT size;
1709 };
1710 
1711 /* Context for alias walking.  */
1712 
1713 struct vn_walk_cb_data
1714 {
vn_walk_cb_datavn_walk_cb_data1715   vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
1716 		   vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_)
1717     : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
1718       mask (mask_), masked_result (NULL_TREE), vn_walk_kind (vn_walk_kind_),
1719       tbaa_p (tbaa_p_), saved_operands (vNULL), first_set (-2),
1720       first_base_set (-2), known_ranges (NULL)
1721   {
1722     if (!last_vuse_ptr)
1723       last_vuse_ptr = &last_vuse;
1724     ao_ref_init (&orig_ref, orig_ref_);
1725     if (mask)
1726       {
1727 	wide_int w = wi::to_wide (mask);
1728 	unsigned int pos = 0, prec = w.get_precision ();
1729 	pd_data pd;
1730 	pd.rhs = build_constructor (NULL_TREE, NULL);
1731 	/* When bitwise and with a constant is done on a memory load,
1732 	   we don't really need all the bits to be defined or defined
1733 	   to constants, we don't really care what is in the position
1734 	   corresponding to 0 bits in the mask.
1735 	   So, push the ranges of those 0 bits in the mask as artificial
1736 	   zero stores and let the partial def handling code do the
1737 	   rest.  */
1738 	while (pos < prec)
1739 	  {
1740 	    int tz = wi::ctz (w);
1741 	    if (pos + tz > prec)
1742 	      tz = prec - pos;
1743 	    if (tz)
1744 	      {
1745 		if (BYTES_BIG_ENDIAN)
1746 		  pd.offset = prec - pos - tz;
1747 		else
1748 		  pd.offset = pos;
1749 		pd.size = tz;
1750 		void *r = push_partial_def (pd, 0, 0, 0, prec);
1751 		gcc_assert (r == NULL_TREE);
1752 	      }
1753 	    pos += tz;
1754 	    if (pos == prec)
1755 	      break;
1756 	    w = wi::lrshift (w, tz);
1757 	    tz = wi::ctz (wi::bit_not (w));
1758 	    if (pos + tz > prec)
1759 	      tz = prec - pos;
1760 	    pos += tz;
1761 	    w = wi::lrshift (w, tz);
1762 	  }
1763       }
1764   }
1765   ~vn_walk_cb_data ();
1766   void *finish (alias_set_type, alias_set_type, tree);
1767   void *push_partial_def (pd_data pd,
1768 			  alias_set_type, alias_set_type, HOST_WIDE_INT,
1769 			  HOST_WIDE_INT);
1770 
1771   vn_reference_t vr;
1772   ao_ref orig_ref;
1773   tree *last_vuse_ptr;
1774   tree last_vuse;
1775   tree mask;
1776   tree masked_result;
1777   vn_lookup_kind vn_walk_kind;
1778   bool tbaa_p;
1779   vec<vn_reference_op_s> saved_operands;
1780 
1781   /* The VDEFs of partial defs we come along.  */
1782   auto_vec<pd_data, 2> partial_defs;
1783   /* The first defs range to avoid splay tree setup in most cases.  */
1784   pd_range first_range;
1785   alias_set_type first_set;
1786   alias_set_type first_base_set;
1787   splay_tree known_ranges;
1788   obstack ranges_obstack;
1789 };
1790 
~vn_walk_cb_data()1791 vn_walk_cb_data::~vn_walk_cb_data ()
1792 {
1793   if (known_ranges)
1794     {
1795       splay_tree_delete (known_ranges);
1796       obstack_free (&ranges_obstack, NULL);
1797     }
1798   saved_operands.release ();
1799 }
1800 
1801 void *
finish(alias_set_type set,alias_set_type base_set,tree val)1802 vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
1803 {
1804   if (first_set != -2)
1805     {
1806       set = first_set;
1807       base_set = first_base_set;
1808     }
1809   if (mask)
1810     {
1811       masked_result = val;
1812       return (void *) -1;
1813     }
1814   vec<vn_reference_op_s> &operands
1815     = saved_operands.exists () ? saved_operands : vr->operands;
1816   return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
1817 						   vr->type, operands, val);
1818 }
1819 
1820 /* pd_range splay-tree helpers.  */
1821 
1822 static int
pd_range_compare(splay_tree_key offset1p,splay_tree_key offset2p)1823 pd_range_compare (splay_tree_key offset1p, splay_tree_key offset2p)
1824 {
1825   HOST_WIDE_INT offset1 = *(HOST_WIDE_INT *)offset1p;
1826   HOST_WIDE_INT offset2 = *(HOST_WIDE_INT *)offset2p;
1827   if (offset1 < offset2)
1828     return -1;
1829   else if (offset1 > offset2)
1830     return 1;
1831   return 0;
1832 }
1833 
1834 static void *
pd_tree_alloc(int size,void * data_)1835 pd_tree_alloc (int size, void *data_)
1836 {
1837   vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
1838   return obstack_alloc (&data->ranges_obstack, size);
1839 }
1840 
1841 static void
pd_tree_dealloc(void *,void *)1842 pd_tree_dealloc (void *, void *)
1843 {
1844 }
1845 
1846 /* Push PD to the vector of partial definitions returning a
1847    value when we are ready to combine things with VUSE, SET and MAXSIZEI,
1848    NULL when we want to continue looking for partial defs or -1
1849    on failure.  */
1850 
1851 void *
push_partial_def(pd_data pd,alias_set_type set,alias_set_type base_set,HOST_WIDE_INT offseti,HOST_WIDE_INT maxsizei)1852 vn_walk_cb_data::push_partial_def (pd_data pd,
1853 				   alias_set_type set, alias_set_type base_set,
1854 				   HOST_WIDE_INT offseti,
1855 				   HOST_WIDE_INT maxsizei)
1856 {
1857   const HOST_WIDE_INT bufsize = 64;
1858   /* We're using a fixed buffer for encoding so fail early if the object
1859      we want to interpret is bigger.  */
1860   if (maxsizei > bufsize * BITS_PER_UNIT
1861       || CHAR_BIT != 8
1862       || BITS_PER_UNIT != 8
1863       /* Not prepared to handle PDP endian.  */
1864       || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
1865     return (void *)-1;
1866 
1867   /* Turn too large constant stores into non-constant stores.  */
1868   if (CONSTANT_CLASS_P (pd.rhs) && pd.size > bufsize * BITS_PER_UNIT)
1869     pd.rhs = error_mark_node;
1870 
1871   /* And for non-constant or CONSTRUCTOR stores shrink them to only keep at
1872      most a partial byte before and/or after the region.  */
1873   if (!CONSTANT_CLASS_P (pd.rhs))
1874     {
1875       if (pd.offset < offseti)
1876 	{
1877 	  HOST_WIDE_INT o = ROUND_DOWN (offseti - pd.offset, BITS_PER_UNIT);
1878 	  gcc_assert (pd.size > o);
1879 	  pd.size -= o;
1880 	  pd.offset += o;
1881 	}
1882       if (pd.size > maxsizei)
1883 	pd.size = maxsizei + ((pd.size - maxsizei) % BITS_PER_UNIT);
1884     }
1885 
1886   pd.offset -= offseti;
1887 
1888   bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
1889 			|| CONSTANT_CLASS_P (pd.rhs));
1890   if (partial_defs.is_empty ())
1891     {
1892       /* If we get a clobber upfront, fail.  */
1893       if (TREE_CLOBBER_P (pd.rhs))
1894 	return (void *)-1;
1895       if (!pd_constant_p)
1896 	return (void *)-1;
1897       partial_defs.safe_push (pd);
1898       first_range.offset = pd.offset;
1899       first_range.size = pd.size;
1900       first_set = set;
1901       first_base_set = base_set;
1902       last_vuse_ptr = NULL;
1903       /* Continue looking for partial defs.  */
1904       return NULL;
1905     }
1906 
1907   if (!known_ranges)
1908     {
1909       /* ???  Optimize the case where the 2nd partial def completes things.  */
1910       gcc_obstack_init (&ranges_obstack);
1911       known_ranges = splay_tree_new_with_allocator (pd_range_compare, 0, 0,
1912 						    pd_tree_alloc,
1913 						    pd_tree_dealloc, this);
1914       splay_tree_insert (known_ranges,
1915 			 (splay_tree_key)&first_range.offset,
1916 			 (splay_tree_value)&first_range);
1917     }
1918 
1919   pd_range newr = { pd.offset, pd.size };
1920   splay_tree_node n;
1921   pd_range *r;
1922   /* Lookup the predecessor of offset + 1 and see if we need to merge.  */
1923   HOST_WIDE_INT loffset = newr.offset + 1;
1924   if ((n = splay_tree_predecessor (known_ranges, (splay_tree_key)&loffset))
1925       && ((r = (pd_range *)n->value), true)
1926       && ranges_known_overlap_p (r->offset, r->size + 1,
1927 				 newr.offset, newr.size))
1928     {
1929       /* Ignore partial defs already covered.  Here we also drop shadowed
1930          clobbers arriving here at the floor.  */
1931       if (known_subrange_p (newr.offset, newr.size, r->offset, r->size))
1932 	return NULL;
1933       r->size = MAX (r->offset + r->size, newr.offset + newr.size) - r->offset;
1934     }
1935   else
1936     {
1937       /* newr.offset wasn't covered yet, insert the range.  */
1938       r = XOBNEW (&ranges_obstack, pd_range);
1939       *r = newr;
1940       splay_tree_insert (known_ranges, (splay_tree_key)&r->offset,
1941 			 (splay_tree_value)r);
1942     }
1943   /* Merge r which now contains newr and is a member of the splay tree with
1944      adjacent overlapping ranges.  */
1945   pd_range *rafter;
1946   while ((n = splay_tree_successor (known_ranges, (splay_tree_key)&r->offset))
1947 	 && ((rafter = (pd_range *)n->value), true)
1948 	 && ranges_known_overlap_p (r->offset, r->size + 1,
1949 				    rafter->offset, rafter->size))
1950     {
1951       r->size = MAX (r->offset + r->size,
1952 		     rafter->offset + rafter->size) - r->offset;
1953       splay_tree_remove (known_ranges, (splay_tree_key)&rafter->offset);
1954     }
1955   /* If we get a clobber, fail.  */
1956   if (TREE_CLOBBER_P (pd.rhs))
1957     return (void *)-1;
1958   /* Non-constants are OK as long as they are shadowed by a constant.  */
1959   if (!pd_constant_p)
1960     return (void *)-1;
1961   partial_defs.safe_push (pd);
1962 
1963   /* Now we have merged newr into the range tree.  When we have covered
1964      [offseti, sizei] then the tree will contain exactly one node which has
1965      the desired properties and it will be 'r'.  */
1966   if (!known_subrange_p (0, maxsizei, r->offset, r->size))
1967     /* Continue looking for partial defs.  */
1968     return NULL;
1969 
1970   /* Now simply native encode all partial defs in reverse order.  */
1971   unsigned ndefs = partial_defs.length ();
1972   /* We support up to 512-bit values (for V8DFmode).  */
1973   unsigned char buffer[bufsize + 1];
1974   unsigned char this_buffer[bufsize + 1];
1975   int len;
1976 
1977   memset (buffer, 0, bufsize + 1);
1978   unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
1979   while (!partial_defs.is_empty ())
1980     {
1981       pd_data pd = partial_defs.pop ();
1982       unsigned int amnt;
1983       if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
1984 	{
1985 	  /* Empty CONSTRUCTOR.  */
1986 	  if (pd.size >= needed_len * BITS_PER_UNIT)
1987 	    len = needed_len;
1988 	  else
1989 	    len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
1990 	  memset (this_buffer, 0, len);
1991 	}
1992       else
1993 	{
1994 	  len = native_encode_expr (pd.rhs, this_buffer, bufsize,
1995 				    MAX (0, -pd.offset) / BITS_PER_UNIT);
1996 	  if (len <= 0
1997 	      || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
1998 			- MAX (0, -pd.offset) / BITS_PER_UNIT))
1999 	    {
2000 	      if (dump_file && (dump_flags & TDF_DETAILS))
2001 		fprintf (dump_file, "Failed to encode %u "
2002 			 "partial definitions\n", ndefs);
2003 	      return (void *)-1;
2004 	    }
2005 	}
2006 
2007       unsigned char *p = buffer;
2008       HOST_WIDE_INT size = pd.size;
2009       if (pd.offset < 0)
2010 	size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
2011       this_buffer[len] = 0;
2012       if (BYTES_BIG_ENDIAN)
2013 	{
2014 	  /* LSB of this_buffer[len - 1] byte should be at
2015 	     pd.offset + pd.size - 1 bits in buffer.  */
2016 	  amnt = ((unsigned HOST_WIDE_INT) pd.offset
2017 		  + pd.size) % BITS_PER_UNIT;
2018 	  if (amnt)
2019 	    shift_bytes_in_array_right (this_buffer, len + 1, amnt);
2020 	  unsigned char *q = this_buffer;
2021 	  unsigned int off = 0;
2022 	  if (pd.offset >= 0)
2023 	    {
2024 	      unsigned int msk;
2025 	      off = pd.offset / BITS_PER_UNIT;
2026 	      gcc_assert (off < needed_len);
2027 	      p = buffer + off;
2028 	      if (size <= amnt)
2029 		{
2030 		  msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
2031 		  *p = (*p & ~msk) | (this_buffer[len] & msk);
2032 		  size = 0;
2033 		}
2034 	      else
2035 		{
2036 		  if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2037 		    q = (this_buffer + len
2038 			 - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2039 			    / BITS_PER_UNIT));
2040 		  if (pd.offset % BITS_PER_UNIT)
2041 		    {
2042 		      msk = -1U << (BITS_PER_UNIT
2043 				    - (pd.offset % BITS_PER_UNIT));
2044 		      *p = (*p & msk) | (*q & ~msk);
2045 		      p++;
2046 		      q++;
2047 		      off++;
2048 		      size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
2049 		      gcc_assert (size >= 0);
2050 		    }
2051 		}
2052 	    }
2053 	  else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
2054 	    {
2055 	      q = (this_buffer + len
2056 		   - (ROUND_UP (size - amnt, BITS_PER_UNIT)
2057 		      / BITS_PER_UNIT));
2058 	      if (pd.offset % BITS_PER_UNIT)
2059 		{
2060 		  q++;
2061 		  size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
2062 					   % BITS_PER_UNIT);
2063 		  gcc_assert (size >= 0);
2064 		}
2065 	    }
2066 	  if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
2067 	      > needed_len)
2068 	    size = (needed_len - off) * BITS_PER_UNIT;
2069 	  memcpy (p, q, size / BITS_PER_UNIT);
2070 	  if (size % BITS_PER_UNIT)
2071 	    {
2072 	      unsigned int msk
2073 		= -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
2074 	      p += size / BITS_PER_UNIT;
2075 	      q += size / BITS_PER_UNIT;
2076 	      *p = (*q & msk) | (*p & ~msk);
2077 	    }
2078 	}
2079       else
2080 	{
2081 	  if (pd.offset >= 0)
2082 	    {
2083 	      /* LSB of this_buffer[0] byte should be at pd.offset bits
2084 		 in buffer.  */
2085 	      unsigned int msk;
2086 	      size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2087 	      amnt = pd.offset % BITS_PER_UNIT;
2088 	      if (amnt)
2089 		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2090 	      unsigned int off = pd.offset / BITS_PER_UNIT;
2091 	      gcc_assert (off < needed_len);
2092 	      size = MIN (size,
2093 			  (HOST_WIDE_INT) (needed_len - off) * BITS_PER_UNIT);
2094 	      p = buffer + off;
2095 	      if (amnt + size < BITS_PER_UNIT)
2096 		{
2097 		  /* Low amnt bits come from *p, then size bits
2098 		     from this_buffer[0] and the remaining again from
2099 		     *p.  */
2100 		  msk = ((1 << size) - 1) << amnt;
2101 		  *p = (*p & ~msk) | (this_buffer[0] & msk);
2102 		  size = 0;
2103 		}
2104 	      else if (amnt)
2105 		{
2106 		  msk = -1U << amnt;
2107 		  *p = (*p & ~msk) | (this_buffer[0] & msk);
2108 		  p++;
2109 		  size -= (BITS_PER_UNIT - amnt);
2110 		}
2111 	    }
2112 	  else
2113 	    {
2114 	      amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
2115 	      if (amnt)
2116 		size -= BITS_PER_UNIT - amnt;
2117 	      size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
2118 	      if (amnt)
2119 		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
2120 	    }
2121 	  memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
2122 	  p += size / BITS_PER_UNIT;
2123 	  if (size % BITS_PER_UNIT)
2124 	    {
2125 	      unsigned int msk = -1U << (size % BITS_PER_UNIT);
2126 	      *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
2127 		    & ~msk) | (*p & msk);
2128 	    }
2129 	}
2130     }
2131 
2132   tree type = vr->type;
2133   /* Make sure to interpret in a type that has a range covering the whole
2134      access size.  */
2135   if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
2136     type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
2137   tree val;
2138   if (BYTES_BIG_ENDIAN)
2139     {
2140       unsigned sz = needed_len;
2141       if (maxsizei % BITS_PER_UNIT)
2142 	shift_bytes_in_array_right (buffer, needed_len,
2143 				    BITS_PER_UNIT
2144 				    - (maxsizei % BITS_PER_UNIT));
2145       if (INTEGRAL_TYPE_P (type))
2146 	sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
2147       if (sz > needed_len)
2148 	{
2149 	  memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
2150 	  val = native_interpret_expr (type, this_buffer, sz);
2151 	}
2152       else
2153 	val = native_interpret_expr (type, buffer, needed_len);
2154     }
2155   else
2156     val = native_interpret_expr (type, buffer, bufsize);
2157   /* If we chop off bits because the types precision doesn't match the memory
2158      access size this is ok when optimizing reads but not when called from
2159      the DSE code during elimination.  */
2160   if (val && type != vr->type)
2161     {
2162       if (! int_fits_type_p (val, vr->type))
2163 	val = NULL_TREE;
2164       else
2165 	val = fold_convert (vr->type, val);
2166     }
2167 
2168   if (val)
2169     {
2170       if (dump_file && (dump_flags & TDF_DETAILS))
2171 	fprintf (dump_file,
2172 		 "Successfully combined %u partial definitions\n", ndefs);
2173       /* We are using the alias-set of the first store we encounter which
2174 	 should be appropriate here.  */
2175       return finish (first_set, first_base_set, val);
2176     }
2177   else
2178     {
2179       if (dump_file && (dump_flags & TDF_DETAILS))
2180 	fprintf (dump_file,
2181 		 "Failed to interpret %u encoded partial definitions\n", ndefs);
2182       return (void *)-1;
2183     }
2184 }
2185 
2186 /* Callback for walk_non_aliased_vuses.  Adjusts the vn_reference_t VR_
2187    with the current VUSE and performs the expression lookup.  */
2188 
2189 static void *
vn_reference_lookup_2(ao_ref * op ATTRIBUTE_UNUSED,tree vuse,void * data_)2190 vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *data_)
2191 {
2192   vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2193   vn_reference_t vr = data->vr;
2194   vn_reference_s **slot;
2195   hashval_t hash;
2196 
2197   /* If we have partial definitions recorded we have to go through
2198      vn_reference_lookup_3.  */
2199   if (!data->partial_defs.is_empty ())
2200     return NULL;
2201 
2202   if (data->last_vuse_ptr)
2203     {
2204       *data->last_vuse_ptr = vuse;
2205       data->last_vuse = vuse;
2206     }
2207 
2208   /* Fixup vuse and hash.  */
2209   if (vr->vuse)
2210     vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
2211   vr->vuse = vuse_ssa_val (vuse);
2212   if (vr->vuse)
2213     vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
2214 
2215   hash = vr->hashcode;
2216   slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
2217   if (slot)
2218     {
2219       if ((*slot)->result && data->saved_operands.exists ())
2220 	return data->finish (vr->set, vr->base_set, (*slot)->result);
2221       return *slot;
2222     }
2223 
2224   return NULL;
2225 }
2226 
2227 /* Lookup an existing or insert a new vn_reference entry into the
2228    value table for the VUSE, SET, TYPE, OPERANDS reference which
2229    has the value VALUE which is either a constant or an SSA name.  */
2230 
2231 static vn_reference_t
vn_reference_lookup_or_insert_for_pieces(tree vuse,alias_set_type set,alias_set_type base_set,tree type,vec<vn_reference_op_s,va_heap> operands,tree value)2232 vn_reference_lookup_or_insert_for_pieces (tree vuse,
2233 					  alias_set_type set,
2234 					  alias_set_type base_set,
2235 					  tree type,
2236 					  vec<vn_reference_op_s,
2237 					        va_heap> operands,
2238 					  tree value)
2239 {
2240   vn_reference_s vr1;
2241   vn_reference_t result;
2242   unsigned value_id;
2243   vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
2244   vr1.operands = operands;
2245   vr1.type = type;
2246   vr1.set = set;
2247   vr1.base_set = base_set;
2248   vr1.hashcode = vn_reference_compute_hash (&vr1);
2249   if (vn_reference_lookup_1 (&vr1, &result))
2250     return result;
2251   if (TREE_CODE (value) == SSA_NAME)
2252     value_id = VN_INFO (value)->value_id;
2253   else
2254     value_id = get_or_alloc_constant_value_id (value);
2255   return vn_reference_insert_pieces (vuse, set, base_set, type,
2256 				     operands.copy (), value, value_id);
2257 }
2258 
2259 /* Return a value-number for RCODE OPS... either by looking up an existing
2260    value-number for the simplified result or by inserting the operation if
2261    INSERT is true.  */
2262 
2263 static tree
vn_nary_build_or_lookup_1(gimple_match_op * res_op,bool insert)2264 vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
2265 {
2266   tree result = NULL_TREE;
2267   /* We will be creating a value number for
2268        RCODE (OPS...).
2269      So first simplify and lookup this expression to see if it
2270      is already available.  */
2271   /* For simplification valueize.  */
2272   unsigned i;
2273   for (i = 0; i < res_op->num_ops; ++i)
2274     if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
2275       {
2276 	tree tem = vn_valueize (res_op->ops[i]);
2277 	if (!tem)
2278 	  break;
2279 	res_op->ops[i] = tem;
2280       }
2281   /* If valueization of an operand fails (it is not available), skip
2282      simplification.  */
2283   bool res = false;
2284   if (i == res_op->num_ops)
2285     {
2286       mprts_hook = vn_lookup_simplify_result;
2287       res = res_op->resimplify (NULL, vn_valueize);
2288       mprts_hook = NULL;
2289     }
2290   gimple *new_stmt = NULL;
2291   if (res
2292       && gimple_simplified_result_is_gimple_val (res_op))
2293     {
2294       /* The expression is already available.  */
2295       result = res_op->ops[0];
2296       /* Valueize it, simplification returns sth in AVAIL only.  */
2297       if (TREE_CODE (result) == SSA_NAME)
2298 	result = SSA_VAL (result);
2299     }
2300   else
2301     {
2302       tree val = vn_lookup_simplify_result (res_op);
2303       if (!val && insert)
2304 	{
2305 	  gimple_seq stmts = NULL;
2306 	  result = maybe_push_res_to_seq (res_op, &stmts);
2307 	  if (result)
2308 	    {
2309 	      gcc_assert (gimple_seq_singleton_p (stmts));
2310 	      new_stmt = gimple_seq_first_stmt (stmts);
2311 	    }
2312 	}
2313       else
2314 	/* The expression is already available.  */
2315 	result = val;
2316     }
2317   if (new_stmt)
2318     {
2319       /* The expression is not yet available, value-number lhs to
2320 	 the new SSA_NAME we created.  */
2321       /* Initialize value-number information properly.  */
2322       vn_ssa_aux_t result_info = VN_INFO (result);
2323       result_info->valnum = result;
2324       result_info->value_id = get_next_value_id ();
2325       result_info->visited = 1;
2326       gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
2327 					  new_stmt);
2328       result_info->needs_insertion = true;
2329       /* ???  PRE phi-translation inserts NARYs without corresponding
2330          SSA name result.  Re-use those but set their result according
2331 	 to the stmt we just built.  */
2332       vn_nary_op_t nary = NULL;
2333       vn_nary_op_lookup_stmt (new_stmt, &nary);
2334       if (nary)
2335 	{
2336 	  gcc_assert (! nary->predicated_values && nary->u.result == NULL_TREE);
2337 	  nary->u.result = gimple_assign_lhs (new_stmt);
2338 	}
2339       /* As all "inserted" statements are singleton SCCs, insert
2340 	 to the valid table.  This is strictly needed to
2341 	 avoid re-generating new value SSA_NAMEs for the same
2342 	 expression during SCC iteration over and over (the
2343 	 optimistic table gets cleared after each iteration).
2344 	 We do not need to insert into the optimistic table, as
2345 	 lookups there will fall back to the valid table.  */
2346       else
2347 	{
2348 	  unsigned int length = vn_nary_length_from_stmt (new_stmt);
2349 	  vn_nary_op_t vno1
2350 	    = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack);
2351 	  vno1->value_id = result_info->value_id;
2352 	  vno1->length = length;
2353 	  vno1->predicated_values = 0;
2354 	  vno1->u.result = result;
2355 	  init_vn_nary_op_from_stmt (vno1, new_stmt);
2356 	  vn_nary_op_insert_into (vno1, valid_info->nary, true);
2357 	  /* Also do not link it into the undo chain.  */
2358 	  last_inserted_nary = vno1->next;
2359 	  vno1->next = (vn_nary_op_t)(void *)-1;
2360 	}
2361       if (dump_file && (dump_flags & TDF_DETAILS))
2362 	{
2363 	  fprintf (dump_file, "Inserting name ");
2364 	  print_generic_expr (dump_file, result);
2365 	  fprintf (dump_file, " for expression ");
2366 	  print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
2367 	  fprintf (dump_file, "\n");
2368 	}
2369     }
2370   return result;
2371 }
2372 
2373 /* Return a value-number for RCODE OPS... either by looking up an existing
2374    value-number for the simplified result or by inserting the operation.  */
2375 
2376 static tree
vn_nary_build_or_lookup(gimple_match_op * res_op)2377 vn_nary_build_or_lookup (gimple_match_op *res_op)
2378 {
2379   return vn_nary_build_or_lookup_1 (res_op, true);
2380 }
2381 
2382 /* Try to simplify the expression RCODE OPS... of type TYPE and return
2383    its value if present.  */
2384 
2385 tree
vn_nary_simplify(vn_nary_op_t nary)2386 vn_nary_simplify (vn_nary_op_t nary)
2387 {
2388   if (nary->length > gimple_match_op::MAX_NUM_OPS)
2389     return NULL_TREE;
2390   gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
2391 		      nary->type, nary->length);
2392   memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
2393   return vn_nary_build_or_lookup_1 (&op, false);
2394 }
2395 
2396 /* Elimination engine.  */
2397 
2398 class eliminate_dom_walker : public dom_walker
2399 {
2400 public:
2401   eliminate_dom_walker (cdi_direction, bitmap);
2402   ~eliminate_dom_walker ();
2403 
2404   virtual edge before_dom_children (basic_block);
2405   virtual void after_dom_children (basic_block);
2406 
2407   virtual tree eliminate_avail (basic_block, tree op);
2408   virtual void eliminate_push_avail (basic_block, tree op);
2409   tree eliminate_insert (basic_block, gimple_stmt_iterator *gsi, tree val);
2410 
2411   void eliminate_stmt (basic_block, gimple_stmt_iterator *);
2412 
2413   unsigned eliminate_cleanup (bool region_p = false);
2414 
2415   bool do_pre;
2416   unsigned int el_todo;
2417   unsigned int eliminations;
2418   unsigned int insertions;
2419 
2420   /* SSA names that had their defs inserted by PRE if do_pre.  */
2421   bitmap inserted_exprs;
2422 
2423   /* Blocks with statements that have had their EH properties changed.  */
2424   bitmap need_eh_cleanup;
2425 
2426   /* Blocks with statements that have had their AB properties changed.  */
2427   bitmap need_ab_cleanup;
2428 
2429   /* Local state for the eliminate domwalk.  */
2430   auto_vec<gimple *> to_remove;
2431   auto_vec<gimple *> to_fixup;
2432   auto_vec<tree> avail;
2433   auto_vec<tree> avail_stack;
2434 };
2435 
2436 /* Adaptor to the elimination engine using RPO availability.  */
2437 
2438 class rpo_elim : public eliminate_dom_walker
2439 {
2440 public:
rpo_elim(basic_block entry_)2441   rpo_elim(basic_block entry_)
2442     : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
2443       m_avail_freelist (NULL) {}
2444 
2445   virtual tree eliminate_avail (basic_block, tree op);
2446 
2447   virtual void eliminate_push_avail (basic_block, tree);
2448 
2449   basic_block entry;
2450   /* Freelist of avail entries which are allocated from the vn_ssa_aux
2451      obstack.  */
2452   vn_avail *m_avail_freelist;
2453 };
2454 
2455 /* Global RPO state for access from hooks.  */
2456 static rpo_elim *rpo_avail;
2457 basic_block vn_context_bb;
2458 
2459 /* Return true if BASE1 and BASE2 can be adjusted so they have the
2460    same address and adjust *OFFSET1 and *OFFSET2 accordingly.
2461    Otherwise return false.  */
2462 
2463 static bool
adjust_offsets_for_equal_base_address(tree base1,poly_int64 * offset1,tree base2,poly_int64 * offset2)2464 adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
2465 				       tree base2, poly_int64 *offset2)
2466 {
2467   poly_int64 soff;
2468   if (TREE_CODE (base1) == MEM_REF
2469       && TREE_CODE (base2) == MEM_REF)
2470     {
2471       if (mem_ref_offset (base1).to_shwi (&soff))
2472 	{
2473 	  base1 = TREE_OPERAND (base1, 0);
2474 	  *offset1 += soff * BITS_PER_UNIT;
2475 	}
2476       if (mem_ref_offset (base2).to_shwi (&soff))
2477 	{
2478 	  base2 = TREE_OPERAND (base2, 0);
2479 	  *offset2 += soff * BITS_PER_UNIT;
2480 	}
2481       return operand_equal_p (base1, base2, 0);
2482     }
2483   return operand_equal_p (base1, base2, OEP_ADDRESS_OF);
2484 }
2485 
2486 /* Callback for walk_non_aliased_vuses.  Tries to perform a lookup
2487    from the statement defining VUSE and if not successful tries to
2488    translate *REFP and VR_ through an aggregate copy at the definition
2489    of VUSE.  If *DISAMBIGUATE_ONLY is true then do not perform translation
2490    of *REF and *VR.  If only disambiguation was performed then
2491    *DISAMBIGUATE_ONLY is set to true.  */
2492 
2493 static void *
vn_reference_lookup_3(ao_ref * ref,tree vuse,void * data_,translate_flags * disambiguate_only)2494 vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
2495 		       translate_flags *disambiguate_only)
2496 {
2497   vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
2498   vn_reference_t vr = data->vr;
2499   gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
2500   tree base = ao_ref_base (ref);
2501   HOST_WIDE_INT offseti = 0, maxsizei, sizei = 0;
2502   static vec<vn_reference_op_s> lhs_ops;
2503   ao_ref lhs_ref;
2504   bool lhs_ref_ok = false;
2505   poly_int64 copy_size;
2506 
2507   /* First try to disambiguate after value-replacing in the definitions LHS.  */
2508   if (is_gimple_assign (def_stmt))
2509     {
2510       tree lhs = gimple_assign_lhs (def_stmt);
2511       bool valueized_anything = false;
2512       /* Avoid re-allocation overhead.  */
2513       lhs_ops.truncate (0);
2514       basic_block saved_rpo_bb = vn_context_bb;
2515       vn_context_bb = gimple_bb (def_stmt);
2516       if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE)
2517 	{
2518 	  copy_reference_ops_from_ref (lhs, &lhs_ops);
2519 	  valueize_refs_1 (&lhs_ops, &valueized_anything, true);
2520 	}
2521       vn_context_bb = saved_rpo_bb;
2522       ao_ref_init (&lhs_ref, lhs);
2523       lhs_ref_ok = true;
2524       if (valueized_anything
2525 	  && ao_ref_init_from_vn_reference
2526 	       (&lhs_ref, ao_ref_alias_set (&lhs_ref),
2527 		ao_ref_base_alias_set (&lhs_ref), TREE_TYPE (lhs), lhs_ops)
2528 	  && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
2529 	{
2530 	  *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2531 	  return NULL;
2532 	}
2533 
2534       /* Besides valueizing the LHS we can also use access-path based
2535          disambiguation on the original non-valueized ref.  */
2536       if (!ref->ref
2537 	  && lhs_ref_ok
2538 	  && data->orig_ref.ref)
2539 	{
2540 	  /* We want to use the non-valueized LHS for this, but avoid redundant
2541 	     work.  */
2542 	  ao_ref *lref = &lhs_ref;
2543 	  ao_ref lref_alt;
2544 	  if (valueized_anything)
2545 	    {
2546 	      ao_ref_init (&lref_alt, lhs);
2547 	      lref = &lref_alt;
2548 	    }
2549 	  if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
2550 	    {
2551 	      *disambiguate_only = (valueized_anything
2552 				    ? TR_VALUEIZE_AND_DISAMBIGUATE
2553 				    : TR_DISAMBIGUATE);
2554 	      return NULL;
2555 	    }
2556 	}
2557 
2558       /* If we reach a clobbering statement try to skip it and see if
2559          we find a VN result with exactly the same value as the
2560 	 possible clobber.  In this case we can ignore the clobber
2561 	 and return the found value.  */
2562       if (is_gimple_reg_type (TREE_TYPE (lhs))
2563 	  && types_compatible_p (TREE_TYPE (lhs), vr->type)
2564 	  && ref->ref)
2565 	{
2566 	  tree *saved_last_vuse_ptr = data->last_vuse_ptr;
2567 	  /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */
2568 	  data->last_vuse_ptr = NULL;
2569 	  tree saved_vuse = vr->vuse;
2570 	  hashval_t saved_hashcode = vr->hashcode;
2571 	  void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), data);
2572 	  /* Need to restore vr->vuse and vr->hashcode.  */
2573 	  vr->vuse = saved_vuse;
2574 	  vr->hashcode = saved_hashcode;
2575 	  data->last_vuse_ptr = saved_last_vuse_ptr;
2576 	  if (res && res != (void *)-1)
2577 	    {
2578 	      vn_reference_t vnresult = (vn_reference_t) res;
2579 	      tree rhs = gimple_assign_rhs1 (def_stmt);
2580 	      if (TREE_CODE (rhs) == SSA_NAME)
2581 		rhs = SSA_VAL (rhs);
2582 	      if (vnresult->result
2583 		  && operand_equal_p (vnresult->result, rhs, 0)
2584 		  /* We have to honor our promise about union type punning
2585 		     and also support arbitrary overlaps with
2586 		     -fno-strict-aliasing.  So simply resort to alignment to
2587 		     rule out overlaps.  Do this check last because it is
2588 		     quite expensive compared to the hash-lookup above.  */
2589 		  && multiple_p (get_object_alignment (ref->ref), ref->size)
2590 		  && multiple_p (get_object_alignment (lhs), ref->size))
2591 		return res;
2592 	    }
2593 	}
2594     }
2595   else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE
2596 	   && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
2597 	   && gimple_call_num_args (def_stmt) <= 4)
2598     {
2599       /* For builtin calls valueize its arguments and call the
2600          alias oracle again.  Valueization may improve points-to
2601 	 info of pointers and constify size and position arguments.
2602 	 Originally this was motivated by PR61034 which has
2603 	 conditional calls to free falsely clobbering ref because
2604 	 of imprecise points-to info of the argument.  */
2605       tree oldargs[4];
2606       bool valueized_anything = false;
2607       for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2608 	{
2609 	  oldargs[i] = gimple_call_arg (def_stmt, i);
2610 	  tree val = vn_valueize (oldargs[i]);
2611 	  if (val != oldargs[i])
2612 	    {
2613 	      gimple_call_set_arg (def_stmt, i, val);
2614 	      valueized_anything = true;
2615 	    }
2616 	}
2617       if (valueized_anything)
2618 	{
2619 	  bool res = call_may_clobber_ref_p_1 (as_a <gcall *> (def_stmt),
2620 					       ref);
2621 	  for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
2622 	    gimple_call_set_arg (def_stmt, i, oldargs[i]);
2623 	  if (!res)
2624 	    {
2625 	      *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
2626 	      return NULL;
2627 	    }
2628 	}
2629     }
2630 
2631   if (*disambiguate_only > TR_TRANSLATE)
2632     return (void *)-1;
2633 
2634   /* If we cannot constrain the size of the reference we cannot
2635      test if anything kills it.  */
2636   if (!ref->max_size_known_p ())
2637     return (void *)-1;
2638 
2639   poly_int64 offset = ref->offset;
2640   poly_int64 maxsize = ref->max_size;
2641 
2642   /* def_stmt may-defs *ref.  See if we can derive a value for *ref
2643      from that definition.
2644      1) Memset.  */
2645   if (is_gimple_reg_type (vr->type)
2646       && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
2647 	  || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
2648       && (integer_zerop (gimple_call_arg (def_stmt, 1))
2649 	  || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
2650 	       || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
2651 	      && CHAR_BIT == 8
2652 	      && BITS_PER_UNIT == 8
2653 	      && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
2654 	      && offset.is_constant (&offseti)
2655 	      && ref->size.is_constant (&sizei)
2656 	      && (offseti % BITS_PER_UNIT == 0
2657 		  || TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST)))
2658       && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
2659 	  || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
2660 	      && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
2661       && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
2662 	  || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
2663     {
2664       tree base2;
2665       poly_int64 offset2, size2, maxsize2;
2666       bool reverse;
2667       tree ref2 = gimple_call_arg (def_stmt, 0);
2668       if (TREE_CODE (ref2) == SSA_NAME)
2669 	{
2670 	  ref2 = SSA_VAL (ref2);
2671 	  if (TREE_CODE (ref2) == SSA_NAME
2672 	      && (TREE_CODE (base) != MEM_REF
2673 		  || TREE_OPERAND (base, 0) != ref2))
2674 	    {
2675 	      gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
2676 	      if (gimple_assign_single_p (def_stmt)
2677 		  && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
2678 		ref2 = gimple_assign_rhs1 (def_stmt);
2679 	    }
2680 	}
2681       if (TREE_CODE (ref2) == ADDR_EXPR)
2682 	{
2683 	  ref2 = TREE_OPERAND (ref2, 0);
2684 	  base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
2685 					   &reverse);
2686 	  if (!known_size_p (maxsize2)
2687 	      || !known_eq (maxsize2, size2)
2688 	      || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
2689 	    return (void *)-1;
2690 	}
2691       else if (TREE_CODE (ref2) == SSA_NAME)
2692 	{
2693 	  poly_int64 soff;
2694 	  if (TREE_CODE (base) != MEM_REF
2695 	      || !(mem_ref_offset (base)
2696 		   << LOG2_BITS_PER_UNIT).to_shwi (&soff))
2697 	    return (void *)-1;
2698 	  offset += soff;
2699 	  offset2 = 0;
2700 	  if (TREE_OPERAND (base, 0) != ref2)
2701 	    {
2702 	      gimple *def = SSA_NAME_DEF_STMT (ref2);
2703 	      if (is_gimple_assign (def)
2704 		  && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
2705 		  && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
2706 		  && poly_int_tree_p (gimple_assign_rhs2 (def)))
2707 		{
2708 		  tree rhs2 = gimple_assign_rhs2 (def);
2709 		  if (!(poly_offset_int::from (wi::to_poly_wide (rhs2),
2710 					       SIGNED)
2711 			<< LOG2_BITS_PER_UNIT).to_shwi (&offset2))
2712 		    return (void *)-1;
2713 		  ref2 = gimple_assign_rhs1 (def);
2714 		  if (TREE_CODE (ref2) == SSA_NAME)
2715 		    ref2 = SSA_VAL (ref2);
2716 		}
2717 	      else
2718 		return (void *)-1;
2719 	    }
2720 	}
2721       else
2722 	return (void *)-1;
2723       tree len = gimple_call_arg (def_stmt, 2);
2724       HOST_WIDE_INT leni, offset2i;
2725       if (TREE_CODE (len) == SSA_NAME)
2726 	len = SSA_VAL (len);
2727       /* Sometimes the above trickery is smarter than alias analysis.  Take
2728          advantage of that.  */
2729       if (!ranges_maybe_overlap_p (offset, maxsize, offset2,
2730 				   (wi::to_poly_offset (len)
2731 				    << LOG2_BITS_PER_UNIT)))
2732 	return NULL;
2733       if (data->partial_defs.is_empty ()
2734 	  && known_subrange_p (offset, maxsize, offset2,
2735 			       wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
2736 	{
2737 	  tree val;
2738 	  if (integer_zerop (gimple_call_arg (def_stmt, 1)))
2739 	    val = build_zero_cst (vr->type);
2740 	  else if (INTEGRAL_TYPE_P (vr->type)
2741 		   && known_eq (ref->size, 8)
2742 		   && offseti % BITS_PER_UNIT == 0)
2743 	    {
2744 	      gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
2745 				      vr->type, gimple_call_arg (def_stmt, 1));
2746 	      val = vn_nary_build_or_lookup (&res_op);
2747 	      if (!val
2748 		  || (TREE_CODE (val) == SSA_NAME
2749 		      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
2750 		return (void *)-1;
2751 	    }
2752 	  else
2753 	    {
2754 	      unsigned buflen = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)) + 1;
2755 	      if (INTEGRAL_TYPE_P (vr->type))
2756 		buflen = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (vr->type)) + 1;
2757 	      unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
2758 	      memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
2759 		      buflen);
2760 	      if (BYTES_BIG_ENDIAN)
2761 		{
2762 		  unsigned int amnt
2763 		    = (((unsigned HOST_WIDE_INT) offseti + sizei)
2764 		       % BITS_PER_UNIT);
2765 		  if (amnt)
2766 		    {
2767 		      shift_bytes_in_array_right (buf, buflen,
2768 						  BITS_PER_UNIT - amnt);
2769 		      buf++;
2770 		      buflen--;
2771 		    }
2772 		}
2773 	      else if (offseti % BITS_PER_UNIT != 0)
2774 		{
2775 		  unsigned int amnt
2776 		    = BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) offseti
2777 				       % BITS_PER_UNIT);
2778 		  shift_bytes_in_array_left (buf, buflen, amnt);
2779 		  buf++;
2780 		  buflen--;
2781 		}
2782 	      val = native_interpret_expr (vr->type, buf, buflen);
2783 	      if (!val)
2784 		return (void *)-1;
2785 	    }
2786 	  return data->finish (0, 0, val);
2787 	}
2788       /* For now handle clearing memory with partial defs.  */
2789       else if (known_eq (ref->size, maxsize)
2790 	       && integer_zerop (gimple_call_arg (def_stmt, 1))
2791 	       && tree_fits_poly_int64_p (len)
2792 	       && tree_to_poly_int64 (len).is_constant (&leni)
2793 	       && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
2794 	       && offset.is_constant (&offseti)
2795 	       && offset2.is_constant (&offset2i)
2796 	       && maxsize.is_constant (&maxsizei)
2797 	       && ranges_known_overlap_p (offseti, maxsizei, offset2i,
2798 					  leni << LOG2_BITS_PER_UNIT))
2799 	{
2800 	  pd_data pd;
2801 	  pd.rhs = build_constructor (NULL_TREE, NULL);
2802 	  pd.offset = offset2i;
2803 	  pd.size = leni << LOG2_BITS_PER_UNIT;
2804 	  return data->push_partial_def (pd, 0, 0, offseti, maxsizei);
2805 	}
2806     }
2807 
2808   /* 2) Assignment from an empty CONSTRUCTOR.  */
2809   else if (is_gimple_reg_type (vr->type)
2810 	   && gimple_assign_single_p (def_stmt)
2811 	   && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
2812 	   && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
2813     {
2814       tree base2;
2815       poly_int64 offset2, size2, maxsize2;
2816       HOST_WIDE_INT offset2i, size2i;
2817       gcc_assert (lhs_ref_ok);
2818       base2 = ao_ref_base (&lhs_ref);
2819       offset2 = lhs_ref.offset;
2820       size2 = lhs_ref.size;
2821       maxsize2 = lhs_ref.max_size;
2822       if (known_size_p (maxsize2)
2823 	  && known_eq (maxsize2, size2)
2824 	  && adjust_offsets_for_equal_base_address (base, &offset,
2825 						    base2, &offset2))
2826 	{
2827 	  if (data->partial_defs.is_empty ()
2828 	      && known_subrange_p (offset, maxsize, offset2, size2))
2829 	    {
2830 	      /* While technically undefined behavior do not optimize
2831 	         a full read from a clobber.  */
2832 	      if (gimple_clobber_p (def_stmt))
2833 		return (void *)-1;
2834 	      tree val = build_zero_cst (vr->type);
2835 	      return data->finish (ao_ref_alias_set (&lhs_ref),
2836 				   ao_ref_base_alias_set (&lhs_ref), val);
2837 	    }
2838 	  else if (known_eq (ref->size, maxsize)
2839 		   && maxsize.is_constant (&maxsizei)
2840 		   && offset.is_constant (&offseti)
2841 		   && offset2.is_constant (&offset2i)
2842 		   && size2.is_constant (&size2i)
2843 		   && ranges_known_overlap_p (offseti, maxsizei,
2844 					      offset2i, size2i))
2845 	    {
2846 	      /* Let clobbers be consumed by the partial-def tracker
2847 	         which can choose to ignore them if they are shadowed
2848 		 by a later def.  */
2849 	      pd_data pd;
2850 	      pd.rhs = gimple_assign_rhs1 (def_stmt);
2851 	      pd.offset = offset2i;
2852 	      pd.size = size2i;
2853 	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
2854 					     ao_ref_base_alias_set (&lhs_ref),
2855 					     offseti, maxsizei);
2856 	    }
2857 	}
2858     }
2859 
2860   /* 3) Assignment from a constant.  We can use folds native encode/interpret
2861      routines to extract the assigned bits.  */
2862   else if (known_eq (ref->size, maxsize)
2863 	   && is_gimple_reg_type (vr->type)
2864 	   && !reverse_storage_order_for_component_p (vr->operands)
2865 	   && !contains_storage_order_barrier_p (vr->operands)
2866 	   && gimple_assign_single_p (def_stmt)
2867 	   && CHAR_BIT == 8
2868 	   && BITS_PER_UNIT == 8
2869 	   && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
2870 	   /* native_encode and native_decode operate on arrays of bytes
2871 	      and so fundamentally need a compile-time size and offset.  */
2872 	   && maxsize.is_constant (&maxsizei)
2873 	   && offset.is_constant (&offseti)
2874 	   && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
2875 	       || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
2876 		   && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
2877     {
2878       tree lhs = gimple_assign_lhs (def_stmt);
2879       tree base2;
2880       poly_int64 offset2, size2, maxsize2;
2881       HOST_WIDE_INT offset2i, size2i;
2882       bool reverse;
2883       gcc_assert (lhs_ref_ok);
2884       base2 = ao_ref_base (&lhs_ref);
2885       offset2 = lhs_ref.offset;
2886       size2 = lhs_ref.size;
2887       maxsize2 = lhs_ref.max_size;
2888       reverse = reverse_storage_order_for_component_p (lhs);
2889       if (base2
2890 	  && !reverse
2891 	  && !storage_order_barrier_p (lhs)
2892 	  && known_eq (maxsize2, size2)
2893 	  && adjust_offsets_for_equal_base_address (base, &offset,
2894 						    base2, &offset2)
2895 	  && offset.is_constant (&offseti)
2896 	  && offset2.is_constant (&offset2i)
2897 	  && size2.is_constant (&size2i))
2898 	{
2899 	  if (data->partial_defs.is_empty ()
2900 	      && known_subrange_p (offseti, maxsizei, offset2, size2))
2901 	    {
2902 	      /* We support up to 512-bit values (for V8DFmode).  */
2903 	      unsigned char buffer[65];
2904 	      int len;
2905 
2906 	      tree rhs = gimple_assign_rhs1 (def_stmt);
2907 	      if (TREE_CODE (rhs) == SSA_NAME)
2908 		rhs = SSA_VAL (rhs);
2909 	      len = native_encode_expr (rhs,
2910 					buffer, sizeof (buffer) - 1,
2911 					(offseti - offset2i) / BITS_PER_UNIT);
2912 	      if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
2913 		{
2914 		  tree type = vr->type;
2915 		  unsigned char *buf = buffer;
2916 		  unsigned int amnt = 0;
2917 		  /* Make sure to interpret in a type that has a range
2918 		     covering the whole access size.  */
2919 		  if (INTEGRAL_TYPE_P (vr->type)
2920 		      && maxsizei != TYPE_PRECISION (vr->type))
2921 		    type = build_nonstandard_integer_type (maxsizei,
2922 							   TYPE_UNSIGNED (type));
2923 		  if (BYTES_BIG_ENDIAN)
2924 		    {
2925 		      /* For big-endian native_encode_expr stored the rhs
2926 			 such that the LSB of it is the LSB of buffer[len - 1].
2927 			 That bit is stored into memory at position
2928 			 offset2 + size2 - 1, i.e. in byte
2929 			 base + (offset2 + size2 - 1) / BITS_PER_UNIT.
2930 			 E.g. for offset2 1 and size2 14, rhs -1 and memory
2931 			 previously cleared that is:
2932 			 0        1
2933 			 01111111|11111110
2934 			 Now, if we want to extract offset 2 and size 12 from
2935 			 it using native_interpret_expr (which actually works
2936 			 for integral bitfield types in terms of byte size of
2937 			 the mode), the native_encode_expr stored the value
2938 			 into buffer as
2939 			 XX111111|11111111
2940 			 and returned len 2 (the X bits are outside of
2941 			 precision).
2942 			 Let sz be maxsize / BITS_PER_UNIT if not extracting
2943 			 a bitfield, and GET_MODE_SIZE otherwise.
2944 			 We need to align the LSB of the value we want to
2945 			 extract as the LSB of buf[sz - 1].
2946 			 The LSB from memory we need to read is at position
2947 			 offset + maxsize - 1.  */
2948 		      HOST_WIDE_INT sz = maxsizei / BITS_PER_UNIT;
2949 		      if (INTEGRAL_TYPE_P (type))
2950 			sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
2951 		      amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
2952 			      - offseti - maxsizei) % BITS_PER_UNIT;
2953 		      if (amnt)
2954 			shift_bytes_in_array_right (buffer, len, amnt);
2955 		      amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
2956 			      - offseti - maxsizei - amnt) / BITS_PER_UNIT;
2957 		      if ((unsigned HOST_WIDE_INT) sz + amnt > (unsigned) len)
2958 			len = 0;
2959 		      else
2960 			{
2961 			  buf = buffer + len - sz - amnt;
2962 			  len -= (buf - buffer);
2963 			}
2964 		    }
2965 		  else
2966 		    {
2967 		      amnt = ((unsigned HOST_WIDE_INT) offset2i
2968 			      - offseti) % BITS_PER_UNIT;
2969 		      if (amnt)
2970 			{
2971 			  buffer[len] = 0;
2972 			  shift_bytes_in_array_left (buffer, len + 1, amnt);
2973 			  buf = buffer + 1;
2974 			}
2975 		    }
2976 		  tree val = native_interpret_expr (type, buf, len);
2977 		  /* If we chop off bits because the types precision doesn't
2978 		     match the memory access size this is ok when optimizing
2979 		     reads but not when called from the DSE code during
2980 		     elimination.  */
2981 		  if (val
2982 		      && type != vr->type)
2983 		    {
2984 		      if (! int_fits_type_p (val, vr->type))
2985 			val = NULL_TREE;
2986 		      else
2987 			val = fold_convert (vr->type, val);
2988 		    }
2989 
2990 		  if (val)
2991 		    return data->finish (ao_ref_alias_set (&lhs_ref),
2992 					 ao_ref_base_alias_set (&lhs_ref), val);
2993 		}
2994 	    }
2995 	  else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
2996 					   size2i))
2997 	    {
2998 	      pd_data pd;
2999 	      tree rhs = gimple_assign_rhs1 (def_stmt);
3000 	      if (TREE_CODE (rhs) == SSA_NAME)
3001 		rhs = SSA_VAL (rhs);
3002 	      pd.rhs = rhs;
3003 	      pd.offset = offset2i;
3004 	      pd.size = size2i;
3005 	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3006 					     ao_ref_base_alias_set (&lhs_ref),
3007 					     offseti, maxsizei);
3008 	    }
3009 	}
3010     }
3011 
3012   /* 4) Assignment from an SSA name which definition we may be able
3013      to access pieces from or we can combine to a larger entity.  */
3014   else if (known_eq (ref->size, maxsize)
3015 	   && is_gimple_reg_type (vr->type)
3016 	   && !reverse_storage_order_for_component_p (vr->operands)
3017 	   && !contains_storage_order_barrier_p (vr->operands)
3018 	   && gimple_assign_single_p (def_stmt)
3019 	   && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
3020     {
3021       tree lhs = gimple_assign_lhs (def_stmt);
3022       tree base2;
3023       poly_int64 offset2, size2, maxsize2;
3024       HOST_WIDE_INT offset2i, size2i, offseti;
3025       bool reverse;
3026       gcc_assert (lhs_ref_ok);
3027       base2 = ao_ref_base (&lhs_ref);
3028       offset2 = lhs_ref.offset;
3029       size2 = lhs_ref.size;
3030       maxsize2 = lhs_ref.max_size;
3031       reverse = reverse_storage_order_for_component_p (lhs);
3032       tree def_rhs = gimple_assign_rhs1 (def_stmt);
3033       if (!reverse
3034 	  && !storage_order_barrier_p (lhs)
3035 	  && known_size_p (maxsize2)
3036 	  && known_eq (maxsize2, size2)
3037 	  && adjust_offsets_for_equal_base_address (base, &offset,
3038 						    base2, &offset2))
3039 	{
3040 	  if (data->partial_defs.is_empty ()
3041 	      && known_subrange_p (offset, maxsize, offset2, size2)
3042 	      /* ???  We can't handle bitfield precision extracts without
3043 		 either using an alternate type for the BIT_FIELD_REF and
3044 		 then doing a conversion or possibly adjusting the offset
3045 		 according to endianness.  */
3046 	      && (! INTEGRAL_TYPE_P (vr->type)
3047 		  || known_eq (ref->size, TYPE_PRECISION (vr->type)))
3048 	      && multiple_p (ref->size, BITS_PER_UNIT))
3049 	    {
3050 	      tree val = NULL_TREE;
3051 	      if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs))
3052 		  || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
3053 		{
3054 		  gimple_match_op op (gimple_match_cond::UNCOND,
3055 				      BIT_FIELD_REF, vr->type,
3056 				      SSA_VAL (def_rhs),
3057 				      bitsize_int (ref->size),
3058 				      bitsize_int (offset - offset2));
3059 		  val = vn_nary_build_or_lookup (&op);
3060 		}
3061 	      else if (known_eq (ref->size, size2))
3062 		{
3063 		  gimple_match_op op (gimple_match_cond::UNCOND,
3064 				      VIEW_CONVERT_EXPR, vr->type,
3065 				      SSA_VAL (def_rhs));
3066 		  val = vn_nary_build_or_lookup (&op);
3067 		}
3068 	      if (val
3069 		  && (TREE_CODE (val) != SSA_NAME
3070 		      || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
3071 		return data->finish (ao_ref_alias_set (&lhs_ref),
3072 				     ao_ref_base_alias_set (&lhs_ref), val);
3073 	    }
3074 	  else if (maxsize.is_constant (&maxsizei)
3075 		   && offset.is_constant (&offseti)
3076 		   && offset2.is_constant (&offset2i)
3077 		   && size2.is_constant (&size2i)
3078 		   && ranges_known_overlap_p (offset, maxsize, offset2, size2))
3079 	    {
3080 	      pd_data pd;
3081 	      pd.rhs = SSA_VAL (def_rhs);
3082 	      pd.offset = offset2i;
3083 	      pd.size = size2i;
3084 	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3085 					     ao_ref_base_alias_set (&lhs_ref),
3086 					     offseti, maxsizei);
3087 	    }
3088 	}
3089     }
3090 
3091   /* 5) For aggregate copies translate the reference through them if
3092      the copy kills ref.  */
3093   else if (data->vn_walk_kind == VN_WALKREWRITE
3094 	   && gimple_assign_single_p (def_stmt)
3095 	   && (DECL_P (gimple_assign_rhs1 (def_stmt))
3096 	       || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
3097 	       || handled_component_p (gimple_assign_rhs1 (def_stmt))))
3098     {
3099       tree base2;
3100       int i, j, k;
3101       auto_vec<vn_reference_op_s> rhs;
3102       vn_reference_op_t vro;
3103       ao_ref r;
3104 
3105       gcc_assert (lhs_ref_ok);
3106 
3107       /* See if the assignment kills REF.  */
3108       base2 = ao_ref_base (&lhs_ref);
3109       if (!lhs_ref.max_size_known_p ()
3110 	  || (base != base2
3111 	      && (TREE_CODE (base) != MEM_REF
3112 		  || TREE_CODE (base2) != MEM_REF
3113 		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
3114 		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
3115 					  TREE_OPERAND (base2, 1))))
3116 	  || !stmt_kills_ref_p (def_stmt, ref))
3117 	return (void *)-1;
3118 
3119       /* Find the common base of ref and the lhs.  lhs_ops already
3120          contains valueized operands for the lhs.  */
3121       i = vr->operands.length () - 1;
3122       j = lhs_ops.length () - 1;
3123       while (j >= 0 && i >= 0
3124 	     && vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
3125 	{
3126 	  i--;
3127 	  j--;
3128 	}
3129 
3130       /* ???  The innermost op should always be a MEM_REF and we already
3131          checked that the assignment to the lhs kills vr.  Thus for
3132 	 aggregate copies using char[] types the vn_reference_op_eq
3133 	 may fail when comparing types for compatibility.  But we really
3134 	 don't care here - further lookups with the rewritten operands
3135 	 will simply fail if we messed up types too badly.  */
3136       poly_int64 extra_off = 0;
3137       if (j == 0 && i >= 0
3138 	  && lhs_ops[0].opcode == MEM_REF
3139 	  && known_ne (lhs_ops[0].off, -1))
3140 	{
3141 	  if (known_eq (lhs_ops[0].off, vr->operands[i].off))
3142 	    i--, j--;
3143 	  else if (vr->operands[i].opcode == MEM_REF
3144 		   && known_ne (vr->operands[i].off, -1))
3145 	    {
3146 	      extra_off = vr->operands[i].off - lhs_ops[0].off;
3147 	      i--, j--;
3148 	    }
3149 	}
3150 
3151       /* i now points to the first additional op.
3152 	 ???  LHS may not be completely contained in VR, one or more
3153 	 VIEW_CONVERT_EXPRs could be in its way.  We could at least
3154 	 try handling outermost VIEW_CONVERT_EXPRs.  */
3155       if (j != -1)
3156 	return (void *)-1;
3157 
3158       /* Punt if the additional ops contain a storage order barrier.  */
3159       for (k = i; k >= 0; k--)
3160 	{
3161 	  vro = &vr->operands[k];
3162 	  if (vro->opcode == VIEW_CONVERT_EXPR && vro->reverse)
3163 	    return (void *)-1;
3164 	}
3165 
3166       /* Now re-write REF to be based on the rhs of the assignment.  */
3167       tree rhs1 = gimple_assign_rhs1 (def_stmt);
3168       copy_reference_ops_from_ref (rhs1, &rhs);
3169 
3170       /* Apply an extra offset to the inner MEM_REF of the RHS.  */
3171       bool force_no_tbaa = false;
3172       if (maybe_ne (extra_off, 0))
3173 	{
3174 	  if (rhs.length () < 2)
3175 	    return (void *)-1;
3176 	  int ix = rhs.length () - 2;
3177 	  if (rhs[ix].opcode != MEM_REF
3178 	      || known_eq (rhs[ix].off, -1))
3179 	    return (void *)-1;
3180 	  rhs[ix].off += extra_off;
3181 	  rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
3182 					 build_int_cst (TREE_TYPE (rhs[ix].op0),
3183 							extra_off));
3184 	  /* When we have offsetted the RHS, reading only parts of it,
3185 	     we can no longer use the original TBAA type, force alias-set
3186 	     zero.  */
3187 	  force_no_tbaa = true;
3188 	}
3189 
3190       /* Save the operands since we need to use the original ones for
3191 	 the hash entry we use.  */
3192       if (!data->saved_operands.exists ())
3193 	data->saved_operands = vr->operands.copy ();
3194 
3195       /* We need to pre-pend vr->operands[0..i] to rhs.  */
3196       vec<vn_reference_op_s> old = vr->operands;
3197       if (i + 1 + rhs.length () > vr->operands.length ())
3198 	vr->operands.safe_grow (i + 1 + rhs.length ());
3199       else
3200 	vr->operands.truncate (i + 1 + rhs.length ());
3201       FOR_EACH_VEC_ELT (rhs, j, vro)
3202 	vr->operands[i + 1 + j] = *vro;
3203       valueize_refs (&vr->operands);
3204       if (old == shared_lookup_references)
3205 	shared_lookup_references = vr->operands;
3206       vr->hashcode = vn_reference_compute_hash (vr);
3207 
3208       /* Try folding the new reference to a constant.  */
3209       tree val = fully_constant_vn_reference_p (vr);
3210       if (val)
3211 	{
3212 	  if (data->partial_defs.is_empty ())
3213 	    return data->finish (ao_ref_alias_set (&lhs_ref),
3214 				 ao_ref_base_alias_set (&lhs_ref), val);
3215 	  /* This is the only interesting case for partial-def handling
3216 	     coming from targets that like to gimplify init-ctors as
3217 	     aggregate copies from constant data like aarch64 for
3218 	     PR83518.  */
3219 	  if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
3220 	    {
3221 	      pd_data pd;
3222 	      pd.rhs = val;
3223 	      pd.offset = 0;
3224 	      pd.size = maxsizei;
3225 	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
3226 					     ao_ref_base_alias_set (&lhs_ref),
3227 					     0, maxsizei);
3228 	    }
3229 	}
3230 
3231       /* Continuing with partial defs isn't easily possible here, we
3232          have to find a full def from further lookups from here.  Probably
3233 	 not worth the special-casing everywhere.  */
3234       if (!data->partial_defs.is_empty ())
3235 	return (void *)-1;
3236 
3237       /* Adjust *ref from the new operands.  */
3238       ao_ref rhs1_ref;
3239       ao_ref_init (&rhs1_ref, rhs1);
3240       if (!ao_ref_init_from_vn_reference (&r,
3241 					  force_no_tbaa ? 0
3242 					  : ao_ref_alias_set (&rhs1_ref),
3243 					  force_no_tbaa ? 0
3244 					  : ao_ref_base_alias_set (&rhs1_ref),
3245 					  vr->type, vr->operands))
3246 	return (void *)-1;
3247       /* This can happen with bitfields.  */
3248       if (maybe_ne (ref->size, r.size))
3249 	{
3250 	  /* If the access lacks some subsetting simply apply that by
3251 	     shortening it.  That in the end can only be successful
3252 	     if we can pun the lookup result which in turn requires
3253 	     exact offsets.  */
3254 	  if (known_eq (r.size, r.max_size)
3255 	      && known_lt (ref->size, r.size))
3256 	    r.size = r.max_size = ref->size;
3257 	  else
3258 	    return (void *)-1;
3259 	}
3260       *ref = r;
3261 
3262       /* Do not update last seen VUSE after translating.  */
3263       data->last_vuse_ptr = NULL;
3264       /* Invalidate the original access path since it now contains
3265          the wrong base.  */
3266       data->orig_ref.ref = NULL_TREE;
3267       /* Use the alias-set of this LHS for recording an eventual result.  */
3268       if (data->first_set == -2)
3269 	{
3270 	  data->first_set = ao_ref_alias_set (&lhs_ref);
3271 	  data->first_base_set = ao_ref_base_alias_set (&lhs_ref);
3272 	}
3273 
3274       /* Keep looking for the adjusted *REF / VR pair.  */
3275       return NULL;
3276     }
3277 
3278   /* 6) For memcpy copies translate the reference through them if
3279      the copy kills ref.  */
3280   else if (data->vn_walk_kind == VN_WALKREWRITE
3281 	   && is_gimple_reg_type (vr->type)
3282 	   /* ???  Handle BCOPY as well.  */
3283 	   && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
3284 	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
3285 	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
3286 	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
3287 	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
3288 	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
3289 	   && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
3290 	       || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
3291 	   && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
3292 	       || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
3293 	   && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size)
3294 	       || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
3295 		   && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)),
3296 				       &copy_size)))
3297 	   /* Handling this is more complicated, give up for now.  */
3298 	   && data->partial_defs.is_empty ())
3299     {
3300       tree lhs, rhs;
3301       ao_ref r;
3302       poly_int64 rhs_offset, lhs_offset;
3303       vn_reference_op_s op;
3304       poly_uint64 mem_offset;
3305       poly_int64 at, byte_maxsize;
3306 
3307       /* Only handle non-variable, addressable refs.  */
3308       if (maybe_ne (ref->size, maxsize)
3309 	  || !multiple_p (offset, BITS_PER_UNIT, &at)
3310 	  || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize))
3311 	return (void *)-1;
3312 
3313       /* Extract a pointer base and an offset for the destination.  */
3314       lhs = gimple_call_arg (def_stmt, 0);
3315       lhs_offset = 0;
3316       if (TREE_CODE (lhs) == SSA_NAME)
3317 	{
3318 	  lhs = vn_valueize (lhs);
3319 	  if (TREE_CODE (lhs) == SSA_NAME)
3320 	    {
3321 	      gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
3322 	      if (gimple_assign_single_p (def_stmt)
3323 		  && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3324 		lhs = gimple_assign_rhs1 (def_stmt);
3325 	    }
3326 	}
3327       if (TREE_CODE (lhs) == ADDR_EXPR)
3328 	{
3329 	  tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0),
3330 						    &lhs_offset);
3331 	  if (!tem)
3332 	    return (void *)-1;
3333 	  if (TREE_CODE (tem) == MEM_REF
3334 	      && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3335 	    {
3336 	      lhs = TREE_OPERAND (tem, 0);
3337 	      if (TREE_CODE (lhs) == SSA_NAME)
3338 		lhs = vn_valueize (lhs);
3339 	      lhs_offset += mem_offset;
3340 	    }
3341 	  else if (DECL_P (tem))
3342 	    lhs = build_fold_addr_expr (tem);
3343 	  else
3344 	    return (void *)-1;
3345 	}
3346       if (TREE_CODE (lhs) != SSA_NAME
3347 	  && TREE_CODE (lhs) != ADDR_EXPR)
3348 	return (void *)-1;
3349 
3350       /* Extract a pointer base and an offset for the source.  */
3351       rhs = gimple_call_arg (def_stmt, 1);
3352       rhs_offset = 0;
3353       if (TREE_CODE (rhs) == SSA_NAME)
3354 	rhs = vn_valueize (rhs);
3355       if (TREE_CODE (rhs) == ADDR_EXPR)
3356 	{
3357 	  tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0),
3358 						    &rhs_offset);
3359 	  if (!tem)
3360 	    return (void *)-1;
3361 	  if (TREE_CODE (tem) == MEM_REF
3362 	      && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
3363 	    {
3364 	      rhs = TREE_OPERAND (tem, 0);
3365 	      rhs_offset += mem_offset;
3366 	    }
3367 	  else if (DECL_P (tem)
3368 		   || TREE_CODE (tem) == STRING_CST)
3369 	    rhs = build_fold_addr_expr (tem);
3370 	  else
3371 	    return (void *)-1;
3372 	}
3373       if (TREE_CODE (rhs) == SSA_NAME)
3374 	rhs = SSA_VAL (rhs);
3375       else if (TREE_CODE (rhs) != ADDR_EXPR)
3376 	return (void *)-1;
3377 
3378       /* The bases of the destination and the references have to agree.  */
3379       if (TREE_CODE (base) == MEM_REF)
3380 	{
3381 	  if (TREE_OPERAND (base, 0) != lhs
3382 	      || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset))
3383 	    return (void *) -1;
3384 	  at += mem_offset;
3385 	}
3386       else if (!DECL_P (base)
3387 	       || TREE_CODE (lhs) != ADDR_EXPR
3388 	       || TREE_OPERAND (lhs, 0) != base)
3389 	return (void *)-1;
3390 
3391       /* If the access is completely outside of the memcpy destination
3392 	 area there is no aliasing.  */
3393       if (!ranges_maybe_overlap_p (lhs_offset, copy_size, at, byte_maxsize))
3394 	return NULL;
3395       /* And the access has to be contained within the memcpy destination.  */
3396       if (!known_subrange_p (at, byte_maxsize, lhs_offset, copy_size))
3397 	return (void *)-1;
3398 
3399       /* Save the operands since we need to use the original ones for
3400 	 the hash entry we use.  */
3401       if (!data->saved_operands.exists ())
3402 	data->saved_operands = vr->operands.copy ();
3403 
3404       /* Make room for 2 operands in the new reference.  */
3405       if (vr->operands.length () < 2)
3406 	{
3407 	  vec<vn_reference_op_s> old = vr->operands;
3408 	  vr->operands.safe_grow_cleared (2);
3409 	  if (old == shared_lookup_references)
3410 	    shared_lookup_references = vr->operands;
3411 	}
3412       else
3413 	vr->operands.truncate (2);
3414 
3415       /* The looked-through reference is a simple MEM_REF.  */
3416       memset (&op, 0, sizeof (op));
3417       op.type = vr->type;
3418       op.opcode = MEM_REF;
3419       op.op0 = build_int_cst (ptr_type_node, at - lhs_offset + rhs_offset);
3420       op.off = at - lhs_offset + rhs_offset;
3421       vr->operands[0] = op;
3422       op.type = TREE_TYPE (rhs);
3423       op.opcode = TREE_CODE (rhs);
3424       op.op0 = rhs;
3425       op.off = -1;
3426       vr->operands[1] = op;
3427       vr->hashcode = vn_reference_compute_hash (vr);
3428 
3429       /* Try folding the new reference to a constant.  */
3430       tree val = fully_constant_vn_reference_p (vr);
3431       if (val)
3432 	return data->finish (0, 0, val);
3433 
3434       /* Adjust *ref from the new operands.  */
3435       if (!ao_ref_init_from_vn_reference (&r, 0, 0, vr->type, vr->operands))
3436 	return (void *)-1;
3437       /* This can happen with bitfields.  */
3438       if (maybe_ne (ref->size, r.size))
3439 	return (void *)-1;
3440       *ref = r;
3441 
3442       /* Do not update last seen VUSE after translating.  */
3443       data->last_vuse_ptr = NULL;
3444       /* Invalidate the original access path since it now contains
3445          the wrong base.  */
3446       data->orig_ref.ref = NULL_TREE;
3447       /* Use the alias-set of this stmt for recording an eventual result.  */
3448       if (data->first_set == -2)
3449 	{
3450 	  data->first_set = 0;
3451 	  data->first_base_set = 0;
3452 	}
3453 
3454       /* Keep looking for the adjusted *REF / VR pair.  */
3455       return NULL;
3456     }
3457 
3458   /* Bail out and stop walking.  */
3459   return (void *)-1;
3460 }
3461 
3462 /* Return a reference op vector from OP that can be used for
3463    vn_reference_lookup_pieces.  The caller is responsible for releasing
3464    the vector.  */
3465 
3466 vec<vn_reference_op_s>
vn_reference_operands_for_lookup(tree op)3467 vn_reference_operands_for_lookup (tree op)
3468 {
3469   bool valueized;
3470   return valueize_shared_reference_ops_from_ref (op, &valueized).copy ();
3471 }
3472 
3473 /* Lookup a reference operation by it's parts, in the current hash table.
3474    Returns the resulting value number if it exists in the hash table,
3475    NULL_TREE otherwise.  VNRESULT will be filled in with the actual
3476    vn_reference_t stored in the hashtable if something is found.  */
3477 
3478 tree
vn_reference_lookup_pieces(tree vuse,alias_set_type set,alias_set_type base_set,tree type,vec<vn_reference_op_s> operands,vn_reference_t * vnresult,vn_lookup_kind kind)3479 vn_reference_lookup_pieces (tree vuse, alias_set_type set,
3480 			    alias_set_type base_set, tree type,
3481 			    vec<vn_reference_op_s> operands,
3482 			    vn_reference_t *vnresult, vn_lookup_kind kind)
3483 {
3484   struct vn_reference_s vr1;
3485   vn_reference_t tmp;
3486   tree cst;
3487 
3488   if (!vnresult)
3489     vnresult = &tmp;
3490   *vnresult = NULL;
3491 
3492   vr1.vuse = vuse_ssa_val (vuse);
3493   shared_lookup_references.truncate (0);
3494   shared_lookup_references.safe_grow (operands.length ());
3495   memcpy (shared_lookup_references.address (),
3496 	  operands.address (),
3497 	  sizeof (vn_reference_op_s)
3498 	  * operands.length ());
3499   bool valueized_p;
3500   valueize_refs_1 (&shared_lookup_references, &valueized_p);
3501   vr1.operands = shared_lookup_references;
3502   vr1.type = type;
3503   vr1.set = set;
3504   vr1.base_set = base_set;
3505   vr1.hashcode = vn_reference_compute_hash (&vr1);
3506   if ((cst = fully_constant_vn_reference_p (&vr1)))
3507     return cst;
3508 
3509   vn_reference_lookup_1 (&vr1, vnresult);
3510   if (!*vnresult
3511       && kind != VN_NOWALK
3512       && vr1.vuse)
3513     {
3514       ao_ref r;
3515       unsigned limit = param_sccvn_max_alias_queries_per_access;
3516       vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE);
3517       vec<vn_reference_op_s> ops_for_ref;
3518       if (!valueized_p)
3519 	ops_for_ref = vr1.operands;
3520       else
3521 	{
3522 	  /* For ao_ref_from_mem we have to ensure only available SSA names
3523 	     end up in base and the only convenient way to make this work
3524 	     for PRE is to re-valueize with that in mind.  */
3525 	  ops_for_ref.create (operands.length ());
3526 	  ops_for_ref.quick_grow (operands.length ());
3527 	  memcpy (ops_for_ref.address (),
3528 		  operands.address (),
3529 		  sizeof (vn_reference_op_s)
3530 		  * operands.length ());
3531 	  valueize_refs_1 (&ops_for_ref, &valueized_p, true);
3532 	}
3533       if (ao_ref_init_from_vn_reference (&r, set, base_set, type,
3534 					 ops_for_ref))
3535 	*vnresult
3536 	  = ((vn_reference_t)
3537 	     walk_non_aliased_vuses (&r, vr1.vuse, true, vn_reference_lookup_2,
3538 				     vn_reference_lookup_3, vuse_valueize,
3539 				     limit, &data));
3540       if (ops_for_ref != shared_lookup_references)
3541 	ops_for_ref.release ();
3542       gcc_checking_assert (vr1.operands == shared_lookup_references);
3543     }
3544 
3545   if (*vnresult)
3546      return (*vnresult)->result;
3547 
3548   return NULL_TREE;
3549 }
3550 
3551 /* Lookup OP in the current hash table, and return the resulting value
3552    number if it exists in the hash table.  Return NULL_TREE if it does
3553    not exist in the hash table or if the result field of the structure
3554    was NULL..  VNRESULT will be filled in with the vn_reference_t
3555    stored in the hashtable if one exists.  When TBAA_P is false assume
3556    we are looking up a store and treat it as having alias-set zero.
3557    *LAST_VUSE_PTR will be updated with the VUSE the value lookup succeeded.
3558    MASK is either NULL_TREE, or can be an INTEGER_CST if the result of the
3559    load is bitwise anded with MASK and so we are only interested in a subset
3560    of the bits and can ignore if the other bits are uninitialized or
3561    not initialized with constants.  */
3562 
3563 tree
vn_reference_lookup(tree op,tree vuse,vn_lookup_kind kind,vn_reference_t * vnresult,bool tbaa_p,tree * last_vuse_ptr,tree mask)3564 vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
3565 		     vn_reference_t *vnresult, bool tbaa_p,
3566 		     tree *last_vuse_ptr, tree mask)
3567 {
3568   vec<vn_reference_op_s> operands;
3569   struct vn_reference_s vr1;
3570   bool valueized_anything;
3571 
3572   if (vnresult)
3573     *vnresult = NULL;
3574 
3575   vr1.vuse = vuse_ssa_val (vuse);
3576   vr1.operands = operands
3577     = valueize_shared_reference_ops_from_ref (op, &valueized_anything);
3578   vr1.type = TREE_TYPE (op);
3579   ao_ref op_ref;
3580   ao_ref_init (&op_ref, op);
3581   vr1.set = ao_ref_alias_set (&op_ref);
3582   vr1.base_set = ao_ref_base_alias_set (&op_ref);
3583   vr1.hashcode = vn_reference_compute_hash (&vr1);
3584   if (mask == NULL_TREE)
3585     if (tree cst = fully_constant_vn_reference_p (&vr1))
3586       return cst;
3587 
3588   if (kind != VN_NOWALK && vr1.vuse)
3589     {
3590       vn_reference_t wvnresult;
3591       ao_ref r;
3592       unsigned limit = param_sccvn_max_alias_queries_per_access;
3593       auto_vec<vn_reference_op_s> ops_for_ref;
3594       if (valueized_anything)
3595 	{
3596 	  copy_reference_ops_from_ref (op, &ops_for_ref);
3597 	  bool tem;
3598 	  valueize_refs_1 (&ops_for_ref, &tem, true);
3599 	}
3600       /* Make sure to use a valueized reference if we valueized anything.
3601          Otherwise preserve the full reference for advanced TBAA.  */
3602       if (!valueized_anything
3603 	  || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
3604 					     vr1.type, ops_for_ref))
3605 	ao_ref_init (&r, op);
3606       vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
3607 			    last_vuse_ptr, kind, tbaa_p, mask);
3608 
3609       wvnresult
3610 	= ((vn_reference_t)
3611 	   walk_non_aliased_vuses (&r, vr1.vuse, tbaa_p, vn_reference_lookup_2,
3612 				   vn_reference_lookup_3, vuse_valueize, limit,
3613 				   &data));
3614       gcc_checking_assert (vr1.operands == shared_lookup_references);
3615       if (wvnresult)
3616 	{
3617 	  gcc_assert (mask == NULL_TREE);
3618 	  if (vnresult)
3619 	    *vnresult = wvnresult;
3620 	  return wvnresult->result;
3621 	}
3622       else if (mask)
3623 	return data.masked_result;
3624 
3625       return NULL_TREE;
3626     }
3627 
3628   if (last_vuse_ptr)
3629     *last_vuse_ptr = vr1.vuse;
3630   if (mask)
3631     return NULL_TREE;
3632   return vn_reference_lookup_1 (&vr1, vnresult);
3633 }
3634 
3635 /* Lookup CALL in the current hash table and return the entry in
3636    *VNRESULT if found.  Populates *VR for the hashtable lookup.  */
3637 
3638 void
vn_reference_lookup_call(gcall * call,vn_reference_t * vnresult,vn_reference_t vr)3639 vn_reference_lookup_call (gcall *call, vn_reference_t *vnresult,
3640 			  vn_reference_t vr)
3641 {
3642   if (vnresult)
3643     *vnresult = NULL;
3644 
3645   tree vuse = gimple_vuse (call);
3646 
3647   vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
3648   vr->operands = valueize_shared_reference_ops_from_call (call);
3649   vr->type = gimple_expr_type (call);
3650   vr->punned = false;
3651   vr->set = 0;
3652   vr->base_set = 0;
3653   vr->hashcode = vn_reference_compute_hash (vr);
3654   vn_reference_lookup_1 (vr, vnresult);
3655 }
3656 
3657 /* Insert OP into the current hash table with a value number of RESULT.  */
3658 
3659 static void
vn_reference_insert(tree op,tree result,tree vuse,tree vdef)3660 vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
3661 {
3662   vn_reference_s **slot;
3663   vn_reference_t vr1;
3664   bool tem;
3665 
3666   vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
3667   if (TREE_CODE (result) == SSA_NAME)
3668     vr1->value_id = VN_INFO (result)->value_id;
3669   else
3670     vr1->value_id = get_or_alloc_constant_value_id (result);
3671   vr1->vuse = vuse_ssa_val (vuse);
3672   vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy ();
3673   vr1->type = TREE_TYPE (op);
3674   vr1->punned = false;
3675   ao_ref op_ref;
3676   ao_ref_init (&op_ref, op);
3677   vr1->set = ao_ref_alias_set (&op_ref);
3678   vr1->base_set = ao_ref_base_alias_set (&op_ref);
3679   vr1->hashcode = vn_reference_compute_hash (vr1);
3680   vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
3681   vr1->result_vdef = vdef;
3682 
3683   slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
3684 						      INSERT);
3685 
3686   /* Because IL walking on reference lookup can end up visiting
3687      a def that is only to be visited later in iteration order
3688      when we are about to make an irreducible region reducible
3689      the def can be effectively processed and its ref being inserted
3690      by vn_reference_lookup_3 already.  So we cannot assert (!*slot)
3691      but save a lookup if we deal with already inserted refs here.  */
3692   if (*slot)
3693     {
3694       /* We cannot assert that we have the same value either because
3695          when disentangling an irreducible region we may end up visiting
3696 	 a use before the corresponding def.  That's a missed optimization
3697 	 only though.  See gcc.dg/tree-ssa/pr87126.c for example.  */
3698       if (dump_file && (dump_flags & TDF_DETAILS)
3699 	  && !operand_equal_p ((*slot)->result, vr1->result, 0))
3700 	{
3701 	  fprintf (dump_file, "Keeping old value ");
3702 	  print_generic_expr (dump_file, (*slot)->result);
3703 	  fprintf (dump_file, " because of collision\n");
3704 	}
3705       free_reference (vr1);
3706       obstack_free (&vn_tables_obstack, vr1);
3707       return;
3708     }
3709 
3710   *slot = vr1;
3711   vr1->next = last_inserted_ref;
3712   last_inserted_ref = vr1;
3713 }
3714 
3715 /* Insert a reference by it's pieces into the current hash table with
3716    a value number of RESULT.  Return the resulting reference
3717    structure we created.  */
3718 
3719 vn_reference_t
vn_reference_insert_pieces(tree vuse,alias_set_type set,alias_set_type base_set,tree type,vec<vn_reference_op_s> operands,tree result,unsigned int value_id)3720 vn_reference_insert_pieces (tree vuse, alias_set_type set,
3721 			    alias_set_type base_set, tree type,
3722 			    vec<vn_reference_op_s> operands,
3723 			    tree result, unsigned int value_id)
3724 
3725 {
3726   vn_reference_s **slot;
3727   vn_reference_t vr1;
3728 
3729   vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
3730   vr1->value_id = value_id;
3731   vr1->vuse = vuse_ssa_val (vuse);
3732   vr1->operands = operands;
3733   valueize_refs (&vr1->operands);
3734   vr1->type = type;
3735   vr1->punned = false;
3736   vr1->set = set;
3737   vr1->base_set = base_set;
3738   vr1->hashcode = vn_reference_compute_hash (vr1);
3739   if (result && TREE_CODE (result) == SSA_NAME)
3740     result = SSA_VAL (result);
3741   vr1->result = result;
3742 
3743   slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
3744 						      INSERT);
3745 
3746   /* At this point we should have all the things inserted that we have
3747      seen before, and we should never try inserting something that
3748      already exists.  */
3749   gcc_assert (!*slot);
3750 
3751   *slot = vr1;
3752   vr1->next = last_inserted_ref;
3753   last_inserted_ref = vr1;
3754   return vr1;
3755 }
3756 
3757 /* Compute and return the hash value for nary operation VBO1.  */
3758 
3759 static hashval_t
vn_nary_op_compute_hash(const vn_nary_op_t vno1)3760 vn_nary_op_compute_hash (const vn_nary_op_t vno1)
3761 {
3762   inchash::hash hstate;
3763   unsigned i;
3764 
3765   for (i = 0; i < vno1->length; ++i)
3766     if (TREE_CODE (vno1->op[i]) == SSA_NAME)
3767       vno1->op[i] = SSA_VAL (vno1->op[i]);
3768 
3769   if (((vno1->length == 2
3770 	&& commutative_tree_code (vno1->opcode))
3771        || (vno1->length == 3
3772 	   && commutative_ternary_tree_code (vno1->opcode)))
3773       && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
3774     std::swap (vno1->op[0], vno1->op[1]);
3775   else if (TREE_CODE_CLASS (vno1->opcode) == tcc_comparison
3776 	   && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
3777     {
3778       std::swap (vno1->op[0], vno1->op[1]);
3779       vno1->opcode = swap_tree_comparison  (vno1->opcode);
3780     }
3781 
3782   hstate.add_int (vno1->opcode);
3783   for (i = 0; i < vno1->length; ++i)
3784     inchash::add_expr (vno1->op[i], hstate);
3785 
3786   return hstate.end ();
3787 }
3788 
3789 /* Compare nary operations VNO1 and VNO2 and return true if they are
3790    equivalent.  */
3791 
3792 bool
vn_nary_op_eq(const_vn_nary_op_t const vno1,const_vn_nary_op_t const vno2)3793 vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
3794 {
3795   unsigned i;
3796 
3797   if (vno1->hashcode != vno2->hashcode)
3798     return false;
3799 
3800   if (vno1->length != vno2->length)
3801     return false;
3802 
3803   if (vno1->opcode != vno2->opcode
3804       || !types_compatible_p (vno1->type, vno2->type))
3805     return false;
3806 
3807   for (i = 0; i < vno1->length; ++i)
3808     if (!expressions_equal_p (vno1->op[i], vno2->op[i]))
3809       return false;
3810 
3811   /* BIT_INSERT_EXPR has an implict operand as the type precision
3812      of op1.  Need to check to make sure they are the same.  */
3813   if (vno1->opcode == BIT_INSERT_EXPR
3814       && TREE_CODE (vno1->op[1]) == INTEGER_CST
3815       && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
3816 	 != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
3817     return false;
3818 
3819   return true;
3820 }
3821 
3822 /* Initialize VNO from the pieces provided.  */
3823 
3824 static void
init_vn_nary_op_from_pieces(vn_nary_op_t vno,unsigned int length,enum tree_code code,tree type,tree * ops)3825 init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
3826 			     enum tree_code code, tree type, tree *ops)
3827 {
3828   vno->opcode = code;
3829   vno->length = length;
3830   vno->type = type;
3831   memcpy (&vno->op[0], ops, sizeof (tree) * length);
3832 }
3833 
3834 /* Return the number of operands for a vn_nary ops structure from STMT.  */
3835 
3836 static unsigned int
vn_nary_length_from_stmt(gimple * stmt)3837 vn_nary_length_from_stmt (gimple *stmt)
3838 {
3839   switch (gimple_assign_rhs_code (stmt))
3840     {
3841     case REALPART_EXPR:
3842     case IMAGPART_EXPR:
3843     case VIEW_CONVERT_EXPR:
3844       return 1;
3845 
3846     case BIT_FIELD_REF:
3847       return 3;
3848 
3849     case CONSTRUCTOR:
3850       return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
3851 
3852     default:
3853       return gimple_num_ops (stmt) - 1;
3854     }
3855 }
3856 
3857 /* Initialize VNO from STMT.  */
3858 
3859 static void
init_vn_nary_op_from_stmt(vn_nary_op_t vno,gimple * stmt)3860 init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple *stmt)
3861 {
3862   unsigned i;
3863 
3864   vno->opcode = gimple_assign_rhs_code (stmt);
3865   vno->type = gimple_expr_type (stmt);
3866   switch (vno->opcode)
3867     {
3868     case REALPART_EXPR:
3869     case IMAGPART_EXPR:
3870     case VIEW_CONVERT_EXPR:
3871       vno->length = 1;
3872       vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
3873       break;
3874 
3875     case BIT_FIELD_REF:
3876       vno->length = 3;
3877       vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
3878       vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
3879       vno->op[2] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
3880       break;
3881 
3882     case CONSTRUCTOR:
3883       vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
3884       for (i = 0; i < vno->length; ++i)
3885 	vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
3886       break;
3887 
3888     default:
3889       gcc_checking_assert (!gimple_assign_single_p (stmt));
3890       vno->length = gimple_num_ops (stmt) - 1;
3891       for (i = 0; i < vno->length; ++i)
3892 	vno->op[i] = gimple_op (stmt, i + 1);
3893     }
3894 }
3895 
3896 /* Compute the hashcode for VNO and look for it in the hash table;
3897    return the resulting value number if it exists in the hash table.
3898    Return NULL_TREE if it does not exist in the hash table or if the
3899    result field of the operation is NULL.  VNRESULT will contain the
3900    vn_nary_op_t from the hashtable if it exists.  */
3901 
3902 static tree
vn_nary_op_lookup_1(vn_nary_op_t vno,vn_nary_op_t * vnresult)3903 vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
3904 {
3905   vn_nary_op_s **slot;
3906 
3907   if (vnresult)
3908     *vnresult = NULL;
3909 
3910   vno->hashcode = vn_nary_op_compute_hash (vno);
3911   slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
3912   if (!slot)
3913     return NULL_TREE;
3914   if (vnresult)
3915     *vnresult = *slot;
3916   return (*slot)->predicated_values ? NULL_TREE : (*slot)->u.result;
3917 }
3918 
3919 /* Lookup a n-ary operation by its pieces and return the resulting value
3920    number if it exists in the hash table.  Return NULL_TREE if it does
3921    not exist in the hash table or if the result field of the operation
3922    is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
3923    if it exists.  */
3924 
3925 tree
vn_nary_op_lookup_pieces(unsigned int length,enum tree_code code,tree type,tree * ops,vn_nary_op_t * vnresult)3926 vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
3927 			  tree type, tree *ops, vn_nary_op_t *vnresult)
3928 {
3929   vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
3930 				  sizeof_vn_nary_op (length));
3931   init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
3932   return vn_nary_op_lookup_1 (vno1, vnresult);
3933 }
3934 
3935 /* Lookup the rhs of STMT in the current hash table, and return the resulting
3936    value number if it exists in the hash table.  Return NULL_TREE if
3937    it does not exist in the hash table.  VNRESULT will contain the
3938    vn_nary_op_t from the hashtable if it exists.  */
3939 
3940 tree
vn_nary_op_lookup_stmt(gimple * stmt,vn_nary_op_t * vnresult)3941 vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
3942 {
3943   vn_nary_op_t vno1
3944     = XALLOCAVAR (struct vn_nary_op_s,
3945 		  sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
3946   init_vn_nary_op_from_stmt (vno1, stmt);
3947   return vn_nary_op_lookup_1 (vno1, vnresult);
3948 }
3949 
3950 /* Allocate a vn_nary_op_t with LENGTH operands on STACK.  */
3951 
3952 static vn_nary_op_t
alloc_vn_nary_op_noinit(unsigned int length,struct obstack * stack)3953 alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
3954 {
3955   return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
3956 }
3957 
3958 /* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's
3959    obstack.  */
3960 
3961 static vn_nary_op_t
alloc_vn_nary_op(unsigned int length,tree result,unsigned int value_id)3962 alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
3963 {
3964   vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack);
3965 
3966   vno1->value_id = value_id;
3967   vno1->length = length;
3968   vno1->predicated_values = 0;
3969   vno1->u.result = result;
3970 
3971   return vno1;
3972 }
3973 
3974 /* Insert VNO into TABLE.  If COMPUTE_HASH is true, then compute
3975    VNO->HASHCODE first.  */
3976 
3977 static vn_nary_op_t
vn_nary_op_insert_into(vn_nary_op_t vno,vn_nary_op_table_type * table,bool compute_hash)3978 vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table,
3979 			bool compute_hash)
3980 {
3981   vn_nary_op_s **slot;
3982 
3983   if (compute_hash)
3984     {
3985       vno->hashcode = vn_nary_op_compute_hash (vno);
3986       gcc_assert (! vno->predicated_values
3987 		  || (! vno->u.values->next
3988 		      && vno->u.values->n == 1));
3989     }
3990 
3991   slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT);
3992   vno->unwind_to = *slot;
3993   if (*slot)
3994     {
3995       /* Prefer non-predicated values.
3996          ???  Only if those are constant, otherwise, with constant predicated
3997 	 value, turn them into predicated values with entry-block validity
3998 	 (???  but we always find the first valid result currently).  */
3999       if ((*slot)->predicated_values
4000 	  && ! vno->predicated_values)
4001 	{
4002 	  /* ???  We cannot remove *slot from the unwind stack list.
4003 	     For the moment we deal with this by skipping not found
4004 	     entries but this isn't ideal ...  */
4005 	  *slot = vno;
4006 	  /* ???  Maintain a stack of states we can unwind in
4007 	     vn_nary_op_s?  But how far do we unwind?  In reality
4008 	     we need to push change records somewhere...  Or not
4009 	     unwind vn_nary_op_s and linking them but instead
4010 	     unwind the results "list", linking that, which also
4011 	     doesn't move on hashtable resize.  */
4012 	  /* We can also have a ->unwind_to recording *slot there.
4013 	     That way we can make u.values a fixed size array with
4014 	     recording the number of entries but of course we then
4015 	     have always N copies for each unwind_to-state.  Or we
4016              make sure to only ever append and each unwinding will
4017 	     pop off one entry (but how to deal with predicated
4018 	     replaced with non-predicated here?)  */
4019 	  vno->next = last_inserted_nary;
4020 	  last_inserted_nary = vno;
4021 	  return vno;
4022 	}
4023       else if (vno->predicated_values
4024 	       && ! (*slot)->predicated_values)
4025 	return *slot;
4026       else if (vno->predicated_values
4027 	       && (*slot)->predicated_values)
4028 	{
4029 	  /* ???  Factor this all into a insert_single_predicated_value
4030 	     routine.  */
4031 	  gcc_assert (!vno->u.values->next && vno->u.values->n == 1);
4032 	  basic_block vno_bb
4033 	    = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]);
4034 	  vn_pval *nval = vno->u.values;
4035 	  vn_pval **next = &vno->u.values;
4036 	  bool found = false;
4037 	  for (vn_pval *val = (*slot)->u.values; val; val = val->next)
4038 	    {
4039 	      if (expressions_equal_p (val->result, vno->u.values->result))
4040 		{
4041 		  found = true;
4042 		  for (unsigned i = 0; i < val->n; ++i)
4043 		    {
4044 		      basic_block val_bb
4045 			= BASIC_BLOCK_FOR_FN (cfun,
4046 					      val->valid_dominated_by_p[i]);
4047 		      if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb))
4048 			/* Value registered with more generic predicate.  */
4049 			return *slot;
4050 		      else if (dominated_by_p (CDI_DOMINATORS, val_bb, vno_bb))
4051 			/* Shouldn't happen, we insert in RPO order.  */
4052 			gcc_unreachable ();
4053 		    }
4054 		  /* Append value.  */
4055 		  *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4056 						     sizeof (vn_pval)
4057 						     + val->n * sizeof (int));
4058 		  (*next)->next = NULL;
4059 		  (*next)->result = val->result;
4060 		  (*next)->n = val->n + 1;
4061 		  memcpy ((*next)->valid_dominated_by_p,
4062 			  val->valid_dominated_by_p,
4063 			  val->n * sizeof (int));
4064 		  (*next)->valid_dominated_by_p[val->n] = vno_bb->index;
4065 		  next = &(*next)->next;
4066 		  if (dump_file && (dump_flags & TDF_DETAILS))
4067 		    fprintf (dump_file, "Appending predicate to value.\n");
4068 		  continue;
4069 		}
4070 	      /* Copy other predicated values.  */
4071 	      *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4072 						 sizeof (vn_pval)
4073 						 + (val->n-1) * sizeof (int));
4074 	      memcpy (*next, val, sizeof (vn_pval) + (val->n-1) * sizeof (int));
4075 	      (*next)->next = NULL;
4076 	      next = &(*next)->next;
4077 	    }
4078 	  if (!found)
4079 	    *next = nval;
4080 
4081 	  *slot = vno;
4082 	  vno->next = last_inserted_nary;
4083 	  last_inserted_nary = vno;
4084 	  return vno;
4085 	}
4086 
4087       /* While we do not want to insert things twice it's awkward to
4088 	 avoid it in the case where visit_nary_op pattern-matches stuff
4089 	 and ends up simplifying the replacement to itself.  We then
4090 	 get two inserts, one from visit_nary_op and one from
4091 	 vn_nary_build_or_lookup.
4092 	 So allow inserts with the same value number.  */
4093       if ((*slot)->u.result == vno->u.result)
4094 	return *slot;
4095     }
4096 
4097   /* ???  There's also optimistic vs. previous commited state merging
4098      that is problematic for the case of unwinding.  */
4099 
4100   /* ???  We should return NULL if we do not use 'vno' and have the
4101      caller release it.  */
4102   gcc_assert (!*slot);
4103 
4104   *slot = vno;
4105   vno->next = last_inserted_nary;
4106   last_inserted_nary = vno;
4107   return vno;
4108 }
4109 
4110 /* Insert a n-ary operation into the current hash table using it's
4111    pieces.  Return the vn_nary_op_t structure we created and put in
4112    the hashtable.  */
4113 
4114 vn_nary_op_t
vn_nary_op_insert_pieces(unsigned int length,enum tree_code code,tree type,tree * ops,tree result,unsigned int value_id)4115 vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
4116 			  tree type, tree *ops,
4117 			  tree result, unsigned int value_id)
4118 {
4119   vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
4120   init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4121   return vn_nary_op_insert_into (vno1, valid_info->nary, true);
4122 }
4123 
4124 static vn_nary_op_t
vn_nary_op_insert_pieces_predicated(unsigned int length,enum tree_code code,tree type,tree * ops,tree result,unsigned int value_id,edge pred_e)4125 vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
4126 				     tree type, tree *ops,
4127 				     tree result, unsigned int value_id,
4128 				     edge pred_e)
4129 {
4130   /* ???  Currently tracking BBs.  */
4131   if (! single_pred_p (pred_e->dest))
4132     {
4133       /* Never record for backedges.  */
4134       if (pred_e->flags & EDGE_DFS_BACK)
4135 	return NULL;
4136       edge_iterator ei;
4137       edge e;
4138       int cnt = 0;
4139       /* Ignore backedges.  */
4140       FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
4141 	if (! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
4142 	  cnt++;
4143       if (cnt != 1)
4144 	return NULL;
4145     }
4146   if (dump_file && (dump_flags & TDF_DETAILS)
4147       /* ???  Fix dumping, but currently we only get comparisons.  */
4148       && TREE_CODE_CLASS (code) == tcc_comparison)
4149     {
4150       fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index,
4151 	       pred_e->dest->index);
4152       print_generic_expr (dump_file, ops[0], TDF_SLIM);
4153       fprintf (dump_file, " %s ", get_tree_code_name (code));
4154       print_generic_expr (dump_file, ops[1], TDF_SLIM);
4155       fprintf (dump_file, " == %s\n",
4156 	       integer_zerop (result) ? "false" : "true");
4157     }
4158   vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id);
4159   init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
4160   vno1->predicated_values = 1;
4161   vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack,
4162 					      sizeof (vn_pval));
4163   vno1->u.values->next = NULL;
4164   vno1->u.values->result = result;
4165   vno1->u.values->n = 1;
4166   vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index;
4167   return vn_nary_op_insert_into (vno1, valid_info->nary, true);
4168 }
4169 
4170 static bool
4171 dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool);
4172 
4173 static tree
vn_nary_op_get_predicated_value(vn_nary_op_t vno,basic_block bb)4174 vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb)
4175 {
4176   if (! vno->predicated_values)
4177     return vno->u.result;
4178   for (vn_pval *val = vno->u.values; val; val = val->next)
4179     for (unsigned i = 0; i < val->n; ++i)
4180       /* Do not handle backedge executability optimistically since
4181 	 when figuring out whether to iterate we do not consider
4182 	 changed predication.  */
4183       if (dominated_by_p_w_unex
4184 	    (bb, BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]),
4185 	     false))
4186 	return val->result;
4187   return NULL_TREE;
4188 }
4189 
4190 /* Insert the rhs of STMT into the current hash table with a value number of
4191    RESULT.  */
4192 
4193 static vn_nary_op_t
vn_nary_op_insert_stmt(gimple * stmt,tree result)4194 vn_nary_op_insert_stmt (gimple *stmt, tree result)
4195 {
4196   vn_nary_op_t vno1
4197     = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
4198 			result, VN_INFO (result)->value_id);
4199   init_vn_nary_op_from_stmt (vno1, stmt);
4200   return vn_nary_op_insert_into (vno1, valid_info->nary, true);
4201 }
4202 
4203 /* Compute a hashcode for PHI operation VP1 and return it.  */
4204 
4205 static inline hashval_t
vn_phi_compute_hash(vn_phi_t vp1)4206 vn_phi_compute_hash (vn_phi_t vp1)
4207 {
4208   inchash::hash hstate (EDGE_COUNT (vp1->block->preds) > 2
4209 			? vp1->block->index : EDGE_COUNT (vp1->block->preds));
4210   tree phi1op;
4211   tree type;
4212   edge e;
4213   edge_iterator ei;
4214 
4215   /* If all PHI arguments are constants we need to distinguish
4216      the PHI node via its type.  */
4217   type = vp1->type;
4218   hstate.merge_hash (vn_hash_type (type));
4219 
4220   FOR_EACH_EDGE (e, ei, vp1->block->preds)
4221     {
4222       /* Don't hash backedge values they need to be handled as VN_TOP
4223          for optimistic value-numbering.  */
4224       if (e->flags & EDGE_DFS_BACK)
4225 	continue;
4226 
4227       phi1op = vp1->phiargs[e->dest_idx];
4228       if (phi1op == VN_TOP)
4229 	continue;
4230       inchash::add_expr (phi1op, hstate);
4231     }
4232 
4233   return hstate.end ();
4234 }
4235 
4236 
4237 /* Return true if COND1 and COND2 represent the same condition, set
4238    *INVERTED_P if one needs to be inverted to make it the same as
4239    the other.  */
4240 
4241 static bool
cond_stmts_equal_p(gcond * cond1,tree lhs1,tree rhs1,gcond * cond2,tree lhs2,tree rhs2,bool * inverted_p)4242 cond_stmts_equal_p (gcond *cond1, tree lhs1, tree rhs1,
4243 		    gcond *cond2, tree lhs2, tree rhs2, bool *inverted_p)
4244 {
4245   enum tree_code code1 = gimple_cond_code (cond1);
4246   enum tree_code code2 = gimple_cond_code (cond2);
4247 
4248   *inverted_p = false;
4249   if (code1 == code2)
4250     ;
4251   else if (code1 == swap_tree_comparison (code2))
4252     std::swap (lhs2, rhs2);
4253   else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
4254     *inverted_p = true;
4255   else if (code1 == invert_tree_comparison
4256 	   	      (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
4257     {
4258       std::swap (lhs2, rhs2);
4259       *inverted_p = true;
4260     }
4261   else
4262     return false;
4263 
4264   return ((expressions_equal_p (lhs1, lhs2)
4265 	   && expressions_equal_p (rhs1, rhs2))
4266 	  || (commutative_tree_code (code1)
4267 	      && expressions_equal_p (lhs1, rhs2)
4268 	      && expressions_equal_p (rhs1, lhs2)));
4269 }
4270 
4271 /* Compare two phi entries for equality, ignoring VN_TOP arguments.  */
4272 
4273 static int
vn_phi_eq(const_vn_phi_t const vp1,const_vn_phi_t const vp2)4274 vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
4275 {
4276   if (vp1->hashcode != vp2->hashcode)
4277     return false;
4278 
4279   if (vp1->block != vp2->block)
4280     {
4281       if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds))
4282 	return false;
4283 
4284       switch (EDGE_COUNT (vp1->block->preds))
4285 	{
4286 	case 1:
4287 	  /* Single-arg PHIs are just copies.  */
4288 	  break;
4289 
4290 	case 2:
4291 	  {
4292 	    /* Rule out backedges into the PHI.  */
4293 	    if (vp1->block->loop_father->header == vp1->block
4294 		|| vp2->block->loop_father->header == vp2->block)
4295 	      return false;
4296 
4297 	    /* If the PHI nodes do not have compatible types
4298 	       they are not the same.  */
4299 	    if (!types_compatible_p (vp1->type, vp2->type))
4300 	      return false;
4301 
4302 	    basic_block idom1
4303 	      = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
4304 	    basic_block idom2
4305 	      = get_immediate_dominator (CDI_DOMINATORS, vp2->block);
4306 	    /* If the immediate dominator end in switch stmts multiple
4307 	       values may end up in the same PHI arg via intermediate
4308 	       CFG merges.  */
4309 	    if (EDGE_COUNT (idom1->succs) != 2
4310 		|| EDGE_COUNT (idom2->succs) != 2)
4311 	      return false;
4312 
4313 	    /* Verify the controlling stmt is the same.  */
4314 	    gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1));
4315 	    gcond *last2 = safe_dyn_cast <gcond *> (last_stmt (idom2));
4316 	    if (! last1 || ! last2)
4317 	      return false;
4318 	    bool inverted_p;
4319 	    if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
4320 				      last2, vp2->cclhs, vp2->ccrhs,
4321 				      &inverted_p))
4322 	      return false;
4323 
4324 	    /* Get at true/false controlled edges into the PHI.  */
4325 	    edge te1, te2, fe1, fe2;
4326 	    if (! extract_true_false_controlled_edges (idom1, vp1->block,
4327 						       &te1, &fe1)
4328 		|| ! extract_true_false_controlled_edges (idom2, vp2->block,
4329 							  &te2, &fe2))
4330 	      return false;
4331 
4332 	    /* Swap edges if the second condition is the inverted of the
4333 	       first.  */
4334 	    if (inverted_p)
4335 	      std::swap (te2, fe2);
4336 
4337 	    /* ???  Handle VN_TOP specially.  */
4338 	    if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
4339 				       vp2->phiargs[te2->dest_idx])
4340 		|| ! expressions_equal_p (vp1->phiargs[fe1->dest_idx],
4341 					  vp2->phiargs[fe2->dest_idx]))
4342 	      return false;
4343 
4344 	    return true;
4345 	  }
4346 
4347 	default:
4348 	  return false;
4349 	}
4350     }
4351 
4352   /* If the PHI nodes do not have compatible types
4353      they are not the same.  */
4354   if (!types_compatible_p (vp1->type, vp2->type))
4355     return false;
4356 
4357   /* Any phi in the same block will have it's arguments in the
4358      same edge order, because of how we store phi nodes.  */
4359   for (unsigned i = 0; i < EDGE_COUNT (vp1->block->preds); ++i)
4360     {
4361       tree phi1op = vp1->phiargs[i];
4362       tree phi2op = vp2->phiargs[i];
4363       if (phi1op == VN_TOP || phi2op == VN_TOP)
4364 	continue;
4365       if (!expressions_equal_p (phi1op, phi2op))
4366 	return false;
4367     }
4368 
4369   return true;
4370 }
4371 
4372 /* Lookup PHI in the current hash table, and return the resulting
4373    value number if it exists in the hash table.  Return NULL_TREE if
4374    it does not exist in the hash table. */
4375 
4376 static tree
vn_phi_lookup(gimple * phi,bool backedges_varying_p)4377 vn_phi_lookup (gimple *phi, bool backedges_varying_p)
4378 {
4379   vn_phi_s **slot;
4380   struct vn_phi_s *vp1;
4381   edge e;
4382   edge_iterator ei;
4383 
4384   vp1 = XALLOCAVAR (struct vn_phi_s,
4385 		    sizeof (struct vn_phi_s)
4386 		    + (gimple_phi_num_args (phi) - 1) * sizeof (tree));
4387 
4388   /* Canonicalize the SSA_NAME's to their value number.  */
4389   FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
4390     {
4391       tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
4392       if (TREE_CODE (def) == SSA_NAME
4393 	  && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
4394 	def = SSA_VAL (def);
4395       vp1->phiargs[e->dest_idx] = def;
4396     }
4397   vp1->type = TREE_TYPE (gimple_phi_result (phi));
4398   vp1->block = gimple_bb (phi);
4399   /* Extract values of the controlling condition.  */
4400   vp1->cclhs = NULL_TREE;
4401   vp1->ccrhs = NULL_TREE;
4402   basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
4403   if (EDGE_COUNT (idom1->succs) == 2)
4404     if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
4405       {
4406 	/* ???  We want to use SSA_VAL here.  But possibly not
4407 	   allow VN_TOP.  */
4408 	vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
4409 	vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
4410       }
4411   vp1->hashcode = vn_phi_compute_hash (vp1);
4412   slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
4413   if (!slot)
4414     return NULL_TREE;
4415   return (*slot)->result;
4416 }
4417 
4418 /* Insert PHI into the current hash table with a value number of
4419    RESULT.  */
4420 
4421 static vn_phi_t
vn_phi_insert(gimple * phi,tree result,bool backedges_varying_p)4422 vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
4423 {
4424   vn_phi_s **slot;
4425   vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack,
4426 					   sizeof (vn_phi_s)
4427 					   + ((gimple_phi_num_args (phi) - 1)
4428 					      * sizeof (tree)));
4429   edge e;
4430   edge_iterator ei;
4431 
4432   /* Canonicalize the SSA_NAME's to their value number.  */
4433   FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
4434     {
4435       tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
4436       if (TREE_CODE (def) == SSA_NAME
4437 	  && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
4438 	def = SSA_VAL (def);
4439       vp1->phiargs[e->dest_idx] = def;
4440     }
4441   vp1->value_id = VN_INFO (result)->value_id;
4442   vp1->type = TREE_TYPE (gimple_phi_result (phi));
4443   vp1->block = gimple_bb (phi);
4444   /* Extract values of the controlling condition.  */
4445   vp1->cclhs = NULL_TREE;
4446   vp1->ccrhs = NULL_TREE;
4447   basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
4448   if (EDGE_COUNT (idom1->succs) == 2)
4449     if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
4450       {
4451 	/* ???  We want to use SSA_VAL here.  But possibly not
4452 	   allow VN_TOP.  */
4453 	vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
4454 	vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
4455       }
4456   vp1->result = result;
4457   vp1->hashcode = vn_phi_compute_hash (vp1);
4458 
4459   slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
4460   gcc_assert (!*slot);
4461 
4462   *slot = vp1;
4463   vp1->next = last_inserted_phi;
4464   last_inserted_phi = vp1;
4465   return vp1;
4466 }
4467 
4468 
4469 /* Return true if BB1 is dominated by BB2 taking into account edges
4470    that are not executable.  When ALLOW_BACK is false consider not
4471    executable backedges as executable.  */
4472 
4473 static bool
dominated_by_p_w_unex(basic_block bb1,basic_block bb2,bool allow_back)4474 dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
4475 {
4476   edge_iterator ei;
4477   edge e;
4478 
4479   if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
4480     return true;
4481 
4482   /* Before iterating we'd like to know if there exists a
4483      (executable) path from bb2 to bb1 at all, if not we can
4484      directly return false.  For now simply iterate once.  */
4485 
4486   /* Iterate to the single executable bb1 predecessor.  */
4487   if (EDGE_COUNT (bb1->preds) > 1)
4488     {
4489       edge prede = NULL;
4490       FOR_EACH_EDGE (e, ei, bb1->preds)
4491 	if ((e->flags & EDGE_EXECUTABLE)
4492 	    || (!allow_back && (e->flags & EDGE_DFS_BACK)))
4493 	  {
4494 	    if (prede)
4495 	      {
4496 		prede = NULL;
4497 		break;
4498 	      }
4499 	    prede = e;
4500 	  }
4501       if (prede)
4502 	{
4503 	  bb1 = prede->src;
4504 
4505 	  /* Re-do the dominance check with changed bb1.  */
4506 	  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
4507 	    return true;
4508 	}
4509     }
4510 
4511   /* Iterate to the single executable bb2 successor.  */
4512   edge succe = NULL;
4513   FOR_EACH_EDGE (e, ei, bb2->succs)
4514     if ((e->flags & EDGE_EXECUTABLE)
4515 	|| (!allow_back && (e->flags & EDGE_DFS_BACK)))
4516       {
4517 	if (succe)
4518 	  {
4519 	    succe = NULL;
4520 	    break;
4521 	  }
4522 	succe = e;
4523       }
4524   if (succe)
4525     {
4526       /* Verify the reached block is only reached through succe.
4527 	 If there is only one edge we can spare us the dominator
4528 	 check and iterate directly.  */
4529       if (EDGE_COUNT (succe->dest->preds) > 1)
4530 	{
4531 	  FOR_EACH_EDGE (e, ei, succe->dest->preds)
4532 	    if (e != succe
4533 		&& ((e->flags & EDGE_EXECUTABLE)
4534 		    || (!allow_back && (e->flags & EDGE_DFS_BACK))))
4535 	      {
4536 		succe = NULL;
4537 		break;
4538 	      }
4539 	}
4540       if (succe)
4541 	{
4542 	  bb2 = succe->dest;
4543 
4544 	  /* Re-do the dominance check with changed bb2.  */
4545 	  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
4546 	    return true;
4547 	}
4548     }
4549 
4550   /* We could now iterate updating bb1 / bb2.  */
4551   return false;
4552 }
4553 
4554 /* Set the value number of FROM to TO, return true if it has changed
4555    as a result.  */
4556 
4557 static inline bool
set_ssa_val_to(tree from,tree to)4558 set_ssa_val_to (tree from, tree to)
4559 {
4560   vn_ssa_aux_t from_info = VN_INFO (from);
4561   tree currval = from_info->valnum; // SSA_VAL (from)
4562   poly_int64 toff, coff;
4563   bool curr_undefined = false;
4564   bool curr_invariant = false;
4565 
4566   /* The only thing we allow as value numbers are ssa_names
4567      and invariants.  So assert that here.  We don't allow VN_TOP
4568      as visiting a stmt should produce a value-number other than
4569      that.
4570      ???  Still VN_TOP can happen for unreachable code, so force
4571      it to varying in that case.  Not all code is prepared to
4572      get VN_TOP on valueization.  */
4573   if (to == VN_TOP)
4574     {
4575       /* ???  When iterating and visiting PHI <undef, backedge-value>
4576          for the first time we rightfully get VN_TOP and we need to
4577 	 preserve that to optimize for example gcc.dg/tree-ssa/ssa-sccvn-2.c.
4578 	 With SCCVN we were simply lucky we iterated the other PHI
4579 	 cycles first and thus visited the backedge-value DEF.  */
4580       if (currval == VN_TOP)
4581 	goto set_and_exit;
4582       if (dump_file && (dump_flags & TDF_DETAILS))
4583 	fprintf (dump_file, "Forcing value number to varying on "
4584 		 "receiving VN_TOP\n");
4585       to = from;
4586     }
4587 
4588   gcc_checking_assert (to != NULL_TREE
4589 		       && ((TREE_CODE (to) == SSA_NAME
4590 			    && (to == from || SSA_VAL (to) == to))
4591 			   || is_gimple_min_invariant (to)));
4592 
4593   if (from != to)
4594     {
4595       if (currval == from)
4596 	{
4597 	  if (dump_file && (dump_flags & TDF_DETAILS))
4598 	    {
4599 	      fprintf (dump_file, "Not changing value number of ");
4600 	      print_generic_expr (dump_file, from);
4601 	      fprintf (dump_file, " from VARYING to ");
4602 	      print_generic_expr (dump_file, to);
4603 	      fprintf (dump_file, "\n");
4604 	    }
4605 	  return false;
4606 	}
4607       curr_invariant = is_gimple_min_invariant (currval);
4608       curr_undefined = (TREE_CODE (currval) == SSA_NAME
4609 			&& ssa_undefined_value_p (currval, false));
4610       if (currval != VN_TOP
4611 	  && !curr_invariant
4612 	  && !curr_undefined
4613 	  && is_gimple_min_invariant (to))
4614 	{
4615 	  if (dump_file && (dump_flags & TDF_DETAILS))
4616 	    {
4617 	      fprintf (dump_file, "Forcing VARYING instead of changing "
4618 		       "value number of ");
4619 	      print_generic_expr (dump_file, from);
4620 	      fprintf (dump_file, " from ");
4621 	      print_generic_expr (dump_file, currval);
4622 	      fprintf (dump_file, " (non-constant) to ");
4623 	      print_generic_expr (dump_file, to);
4624 	      fprintf (dump_file, " (constant)\n");
4625 	    }
4626 	  to = from;
4627 	}
4628       else if (currval != VN_TOP
4629 	       && !curr_undefined
4630 	       && TREE_CODE (to) == SSA_NAME
4631 	       && ssa_undefined_value_p (to, false))
4632 	{
4633 	  if (dump_file && (dump_flags & TDF_DETAILS))
4634 	    {
4635 	      fprintf (dump_file, "Forcing VARYING instead of changing "
4636 		       "value number of ");
4637 	      print_generic_expr (dump_file, from);
4638 	      fprintf (dump_file, " from ");
4639 	      print_generic_expr (dump_file, currval);
4640 	      fprintf (dump_file, " (non-undefined) to ");
4641 	      print_generic_expr (dump_file, to);
4642 	      fprintf (dump_file, " (undefined)\n");
4643 	    }
4644 	  to = from;
4645 	}
4646       else if (TREE_CODE (to) == SSA_NAME
4647 	       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to))
4648 	to = from;
4649     }
4650 
4651 set_and_exit:
4652   if (dump_file && (dump_flags & TDF_DETAILS))
4653     {
4654       fprintf (dump_file, "Setting value number of ");
4655       print_generic_expr (dump_file, from);
4656       fprintf (dump_file, " to ");
4657       print_generic_expr (dump_file, to);
4658     }
4659 
4660   if (currval != to
4661       && !operand_equal_p (currval, to, 0)
4662       /* Different undefined SSA names are not actually different.  See
4663          PR82320 for a testcase were we'd otherwise not terminate iteration.  */
4664       && !(curr_undefined
4665 	   && TREE_CODE (to) == SSA_NAME
4666 	   && ssa_undefined_value_p (to, false))
4667       /* ???  For addresses involving volatile objects or types operand_equal_p
4668          does not reliably detect ADDR_EXPRs as equal.  We know we are only
4669 	 getting invariant gimple addresses here, so can use
4670 	 get_addr_base_and_unit_offset to do this comparison.  */
4671       && !(TREE_CODE (currval) == ADDR_EXPR
4672 	   && TREE_CODE (to) == ADDR_EXPR
4673 	   && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff)
4674 	       == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
4675 	   && known_eq (coff, toff)))
4676     {
4677       if (to != from
4678 	  && currval != VN_TOP
4679 	  && !curr_undefined
4680 	  /* We do not want to allow lattice transitions from one value
4681 	     to another since that may lead to not terminating iteration
4682 	     (see PR95049).  Since there's no convenient way to check
4683 	     for the allowed transition of VAL -> PHI (loop entry value,
4684 	     same on two PHIs, to same PHI result) we restrict the check
4685 	     to invariants.  */
4686 	  && curr_invariant
4687 	  && is_gimple_min_invariant (to))
4688 	{
4689 	  if (dump_file && (dump_flags & TDF_DETAILS))
4690 	    fprintf (dump_file, " forced VARYING");
4691 	  to = from;
4692 	}
4693       if (dump_file && (dump_flags & TDF_DETAILS))
4694 	fprintf (dump_file, " (changed)\n");
4695       from_info->valnum = to;
4696       return true;
4697     }
4698   if (dump_file && (dump_flags & TDF_DETAILS))
4699     fprintf (dump_file, "\n");
4700   return false;
4701 }
4702 
4703 /* Set all definitions in STMT to value number to themselves.
4704    Return true if a value number changed. */
4705 
4706 static bool
defs_to_varying(gimple * stmt)4707 defs_to_varying (gimple *stmt)
4708 {
4709   bool changed = false;
4710   ssa_op_iter iter;
4711   def_operand_p defp;
4712 
4713   FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
4714     {
4715       tree def = DEF_FROM_PTR (defp);
4716       changed |= set_ssa_val_to (def, def);
4717     }
4718   return changed;
4719 }
4720 
4721 /* Visit a copy between LHS and RHS, return true if the value number
4722    changed.  */
4723 
4724 static bool
visit_copy(tree lhs,tree rhs)4725 visit_copy (tree lhs, tree rhs)
4726 {
4727   /* Valueize.  */
4728   rhs = SSA_VAL (rhs);
4729 
4730   return set_ssa_val_to (lhs, rhs);
4731 }
4732 
4733 /* Lookup a value for OP in type WIDE_TYPE where the value in type of OP
4734    is the same.  */
4735 
4736 static tree
valueized_wider_op(tree wide_type,tree op,bool allow_truncate)4737 valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
4738 {
4739   if (TREE_CODE (op) == SSA_NAME)
4740     op = vn_valueize (op);
4741 
4742   /* Either we have the op widened available.  */
4743   tree ops[3] = {};
4744   ops[0] = op;
4745   tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR,
4746 				       wide_type, ops, NULL);
4747   if (tem)
4748     return tem;
4749 
4750   /* Or the op is truncated from some existing value.  */
4751   if (allow_truncate && TREE_CODE (op) == SSA_NAME)
4752     {
4753       gimple *def = SSA_NAME_DEF_STMT (op);
4754       if (is_gimple_assign (def)
4755 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
4756 	{
4757 	  tem = gimple_assign_rhs1 (def);
4758 	  if (useless_type_conversion_p (wide_type, TREE_TYPE (tem)))
4759 	    {
4760 	      if (TREE_CODE (tem) == SSA_NAME)
4761 		tem = vn_valueize (tem);
4762 	      return tem;
4763 	    }
4764 	}
4765     }
4766 
4767   /* For constants simply extend it.  */
4768   if (TREE_CODE (op) == INTEGER_CST)
4769     return wide_int_to_tree (wide_type, wi::to_widest (op));
4770 
4771   return NULL_TREE;
4772 }
4773 
4774 /* Visit a nary operator RHS, value number it, and return true if the
4775    value number of LHS has changed as a result.  */
4776 
4777 static bool
visit_nary_op(tree lhs,gassign * stmt)4778 visit_nary_op (tree lhs, gassign *stmt)
4779 {
4780   vn_nary_op_t vnresult;
4781   tree result = vn_nary_op_lookup_stmt (stmt, &vnresult);
4782   if (! result && vnresult)
4783     result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt));
4784   if (result)
4785     return set_ssa_val_to (lhs, result);
4786 
4787   /* Do some special pattern matching for redundancies of operations
4788      in different types.  */
4789   enum tree_code code = gimple_assign_rhs_code (stmt);
4790   tree type = TREE_TYPE (lhs);
4791   tree rhs1 = gimple_assign_rhs1 (stmt);
4792   switch (code)
4793     {
4794     CASE_CONVERT:
4795       /* Match arithmetic done in a different type where we can easily
4796          substitute the result from some earlier sign-changed or widened
4797 	 operation.  */
4798       if (INTEGRAL_TYPE_P (type)
4799 	  && TREE_CODE (rhs1) == SSA_NAME
4800 	  /* We only handle sign-changes, zero-extension -> & mask or
4801 	     sign-extension if we know the inner operation doesn't
4802 	     overflow.  */
4803 	  && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
4804 		|| (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
4805 		    && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
4806 	       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
4807 	      || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
4808 	{
4809 	  gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
4810 	  if (def
4811 	      && (gimple_assign_rhs_code (def) == PLUS_EXPR
4812 		  || gimple_assign_rhs_code (def) == MINUS_EXPR
4813 		  || gimple_assign_rhs_code (def) == MULT_EXPR))
4814 	    {
4815 	      tree ops[3] = {};
4816 	      /* When requiring a sign-extension we cannot model a
4817 		 previous truncation with a single op so don't bother.  */
4818 	      bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
4819 	      /* Either we have the op widened available.  */
4820 	      ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
4821 					   allow_truncate);
4822 	      if (ops[0])
4823 		ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
4824 					     allow_truncate);
4825 	      if (ops[0] && ops[1])
4826 		{
4827 		  ops[0] = vn_nary_op_lookup_pieces
4828 		      (2, gimple_assign_rhs_code (def), type, ops, NULL);
4829 		  /* We have wider operation available.  */
4830 		  if (ops[0]
4831 		      /* If the leader is a wrapping operation we can
4832 		         insert it for code hoisting w/o introducing
4833 			 undefined overflow.  If it is not it has to
4834 			 be available.  See PR86554.  */
4835 		      && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (ops[0]))
4836 			  || (rpo_avail && vn_context_bb
4837 			      && rpo_avail->eliminate_avail (vn_context_bb,
4838 							     ops[0]))))
4839 		    {
4840 		      unsigned lhs_prec = TYPE_PRECISION (type);
4841 		      unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
4842 		      if (lhs_prec == rhs_prec
4843 			  || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
4844 			      && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
4845 			{
4846 			  gimple_match_op match_op (gimple_match_cond::UNCOND,
4847 						    NOP_EXPR, type, ops[0]);
4848 			  result = vn_nary_build_or_lookup (&match_op);
4849 			  if (result)
4850 			    {
4851 			      bool changed = set_ssa_val_to (lhs, result);
4852 			      vn_nary_op_insert_stmt (stmt, result);
4853 			      return changed;
4854 			    }
4855 			}
4856 		      else
4857 			{
4858 			  tree mask = wide_int_to_tree
4859 			    (type, wi::mask (rhs_prec, false, lhs_prec));
4860 			  gimple_match_op match_op (gimple_match_cond::UNCOND,
4861 						    BIT_AND_EXPR,
4862 						    TREE_TYPE (lhs),
4863 						    ops[0], mask);
4864 			  result = vn_nary_build_or_lookup (&match_op);
4865 			  if (result)
4866 			    {
4867 			      bool changed = set_ssa_val_to (lhs, result);
4868 			      vn_nary_op_insert_stmt (stmt, result);
4869 			      return changed;
4870 			    }
4871 			}
4872 		    }
4873 		}
4874 	    }
4875 	}
4876       break;
4877     case BIT_AND_EXPR:
4878       if (INTEGRAL_TYPE_P (type)
4879 	  && TREE_CODE (rhs1) == SSA_NAME
4880 	  && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
4881 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)
4882 	  && default_vn_walk_kind != VN_NOWALK
4883 	  && CHAR_BIT == 8
4884 	  && BITS_PER_UNIT == 8
4885 	  && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
4886 	  && !integer_all_onesp (gimple_assign_rhs2 (stmt))
4887 	  && !integer_zerop (gimple_assign_rhs2 (stmt)))
4888 	{
4889 	  gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
4890 	  if (ass
4891 	      && !gimple_has_volatile_ops (ass)
4892 	      && vn_get_stmt_kind (ass) == VN_REFERENCE)
4893 	    {
4894 	      tree last_vuse = gimple_vuse (ass);
4895 	      tree op = gimple_assign_rhs1 (ass);
4896 	      tree result = vn_reference_lookup (op, gimple_vuse (ass),
4897 						 default_vn_walk_kind,
4898 						 NULL, true, &last_vuse,
4899 						 gimple_assign_rhs2 (stmt));
4900 	      if (result
4901 		  && useless_type_conversion_p (TREE_TYPE (result),
4902 						TREE_TYPE (op)))
4903 		return set_ssa_val_to (lhs, result);
4904 	    }
4905 	}
4906       break;
4907     default:
4908       break;
4909     }
4910 
4911   bool changed = set_ssa_val_to (lhs, lhs);
4912   vn_nary_op_insert_stmt (stmt, lhs);
4913   return changed;
4914 }
4915 
4916 /* Visit a call STMT storing into LHS.  Return true if the value number
4917    of the LHS has changed as a result.  */
4918 
4919 static bool
visit_reference_op_call(tree lhs,gcall * stmt)4920 visit_reference_op_call (tree lhs, gcall *stmt)
4921 {
4922   bool changed = false;
4923   struct vn_reference_s vr1;
4924   vn_reference_t vnresult = NULL;
4925   tree vdef = gimple_vdef (stmt);
4926 
4927   /* Non-ssa lhs is handled in copy_reference_ops_from_call.  */
4928   if (lhs && TREE_CODE (lhs) != SSA_NAME)
4929     lhs = NULL_TREE;
4930 
4931   vn_reference_lookup_call (stmt, &vnresult, &vr1);
4932   if (vnresult)
4933     {
4934       if (vnresult->result_vdef && vdef)
4935 	changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
4936       else if (vdef)
4937 	/* If the call was discovered to be pure or const reflect
4938 	   that as far as possible.  */
4939 	changed |= set_ssa_val_to (vdef, vuse_ssa_val (gimple_vuse (stmt)));
4940 
4941       if (!vnresult->result && lhs)
4942 	vnresult->result = lhs;
4943 
4944       if (vnresult->result && lhs)
4945 	changed |= set_ssa_val_to (lhs, vnresult->result);
4946     }
4947   else
4948     {
4949       vn_reference_t vr2;
4950       vn_reference_s **slot;
4951       tree vdef_val = vdef;
4952       if (vdef)
4953 	{
4954 	  /* If we value numbered an indirect functions function to
4955 	     one not clobbering memory value number its VDEF to its
4956 	     VUSE.  */
4957 	  tree fn = gimple_call_fn (stmt);
4958 	  if (fn && TREE_CODE (fn) == SSA_NAME)
4959 	    {
4960 	      fn = SSA_VAL (fn);
4961 	      if (TREE_CODE (fn) == ADDR_EXPR
4962 		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
4963 		  && (flags_from_decl_or_type (TREE_OPERAND (fn, 0))
4964 		      & (ECF_CONST | ECF_PURE)))
4965 		vdef_val = vuse_ssa_val (gimple_vuse (stmt));
4966 	    }
4967 	  changed |= set_ssa_val_to (vdef, vdef_val);
4968 	}
4969       if (lhs)
4970 	changed |= set_ssa_val_to (lhs, lhs);
4971       vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s);
4972       vr2->vuse = vr1.vuse;
4973       /* As we are not walking the virtual operand chain we know the
4974 	 shared_lookup_references are still original so we can re-use
4975 	 them here.  */
4976       vr2->operands = vr1.operands.copy ();
4977       vr2->type = vr1.type;
4978       vr2->punned = vr1.punned;
4979       vr2->set = vr1.set;
4980       vr2->base_set = vr1.base_set;
4981       vr2->hashcode = vr1.hashcode;
4982       vr2->result = lhs;
4983       vr2->result_vdef = vdef_val;
4984       vr2->value_id = 0;
4985       slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
4986 							  INSERT);
4987       gcc_assert (!*slot);
4988       *slot = vr2;
4989       vr2->next = last_inserted_ref;
4990       last_inserted_ref = vr2;
4991     }
4992 
4993   return changed;
4994 }
4995 
4996 /* Visit a load from a reference operator RHS, part of STMT, value number it,
4997    and return true if the value number of the LHS has changed as a result.  */
4998 
4999 static bool
visit_reference_op_load(tree lhs,tree op,gimple * stmt)5000 visit_reference_op_load (tree lhs, tree op, gimple *stmt)
5001 {
5002   bool changed = false;
5003   tree last_vuse;
5004   tree result;
5005   vn_reference_t res;
5006 
5007   last_vuse = gimple_vuse (stmt);
5008   result = vn_reference_lookup (op, gimple_vuse (stmt),
5009 				default_vn_walk_kind, &res, true, &last_vuse);
5010 
5011   /* We handle type-punning through unions by value-numbering based
5012      on offset and size of the access.  Be prepared to handle a
5013      type-mismatch here via creating a VIEW_CONVERT_EXPR.  */
5014   if (result
5015       && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
5016     {
5017       /* Avoid the type punning in case the result mode has padding where
5018 	 the op we lookup has not.  */
5019       if (maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
5020 		    GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)))))
5021 	result = NULL_TREE;
5022       else
5023 	{
5024 	  /* We will be setting the value number of lhs to the value number
5025 	     of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
5026 	     So first simplify and lookup this expression to see if it
5027 	     is already available.  */
5028 	  gimple_match_op res_op (gimple_match_cond::UNCOND,
5029 				  VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
5030 	  result = vn_nary_build_or_lookup (&res_op);
5031 	  if (result
5032 	      && TREE_CODE (result) == SSA_NAME
5033 	      && VN_INFO (result)->needs_insertion)
5034 	    /* Track whether this is the canonical expression for different
5035 	       typed loads.  We use that as a stopgap measure for code
5036 	       hoisting when dealing with floating point loads.  */
5037 	    res->punned = true;
5038 	}
5039 
5040       /* When building the conversion fails avoid inserting the reference
5041          again.  */
5042       if (!result)
5043 	return set_ssa_val_to (lhs, lhs);
5044     }
5045 
5046   if (result)
5047     changed = set_ssa_val_to (lhs, result);
5048   else
5049     {
5050       changed = set_ssa_val_to (lhs, lhs);
5051       vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
5052     }
5053 
5054   return changed;
5055 }
5056 
5057 
5058 /* Visit a store to a reference operator LHS, part of STMT, value number it,
5059    and return true if the value number of the LHS has changed as a result.  */
5060 
5061 static bool
visit_reference_op_store(tree lhs,tree op,gimple * stmt)5062 visit_reference_op_store (tree lhs, tree op, gimple *stmt)
5063 {
5064   bool changed = false;
5065   vn_reference_t vnresult = NULL;
5066   tree assign;
5067   bool resultsame = false;
5068   tree vuse = gimple_vuse (stmt);
5069   tree vdef = gimple_vdef (stmt);
5070 
5071   if (TREE_CODE (op) == SSA_NAME)
5072     op = SSA_VAL (op);
5073 
5074   /* First we want to lookup using the *vuses* from the store and see
5075      if there the last store to this location with the same address
5076      had the same value.
5077 
5078      The vuses represent the memory state before the store.  If the
5079      memory state, address, and value of the store is the same as the
5080      last store to this location, then this store will produce the
5081      same memory state as that store.
5082 
5083      In this case the vdef versions for this store are value numbered to those
5084      vuse versions, since they represent the same memory state after
5085      this store.
5086 
5087      Otherwise, the vdefs for the store are used when inserting into
5088      the table, since the store generates a new memory state.  */
5089 
5090   vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
5091   if (vnresult
5092       && vnresult->result)
5093     {
5094       tree result = vnresult->result;
5095       gcc_checking_assert (TREE_CODE (result) != SSA_NAME
5096 			   || result == SSA_VAL (result));
5097       resultsame = expressions_equal_p (result, op);
5098       if (resultsame)
5099 	{
5100 	  /* If the TBAA state isn't compatible for downstream reads
5101 	     we cannot value-number the VDEFs the same.  */
5102 	  ao_ref lhs_ref;
5103 	  ao_ref_init (&lhs_ref, lhs);
5104 	  alias_set_type set = ao_ref_alias_set (&lhs_ref);
5105 	  alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
5106 	  if ((vnresult->set != set
5107 	       && ! alias_set_subset_of (set, vnresult->set))
5108 	      || (vnresult->base_set != base_set
5109 		  && ! alias_set_subset_of (base_set, vnresult->base_set)))
5110 	    resultsame = false;
5111 	}
5112     }
5113 
5114   if (!resultsame)
5115     {
5116       if (dump_file && (dump_flags & TDF_DETAILS))
5117 	{
5118 	  fprintf (dump_file, "No store match\n");
5119 	  fprintf (dump_file, "Value numbering store ");
5120 	  print_generic_expr (dump_file, lhs);
5121 	  fprintf (dump_file, " to ");
5122 	  print_generic_expr (dump_file, op);
5123 	  fprintf (dump_file, "\n");
5124 	}
5125       /* Have to set value numbers before insert, since insert is
5126 	 going to valueize the references in-place.  */
5127       if (vdef)
5128 	changed |= set_ssa_val_to (vdef, vdef);
5129 
5130       /* Do not insert structure copies into the tables.  */
5131       if (is_gimple_min_invariant (op)
5132 	  || is_gimple_reg (op))
5133         vn_reference_insert (lhs, op, vdef, NULL);
5134 
5135       /* Only perform the following when being called from PRE
5136 	 which embeds tail merging.  */
5137       if (default_vn_walk_kind == VN_WALK)
5138 	{
5139 	  assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
5140 	  vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
5141 	  if (!vnresult)
5142 	    vn_reference_insert (assign, lhs, vuse, vdef);
5143 	}
5144     }
5145   else
5146     {
5147       /* We had a match, so value number the vdef to have the value
5148 	 number of the vuse it came from.  */
5149 
5150       if (dump_file && (dump_flags & TDF_DETAILS))
5151 	fprintf (dump_file, "Store matched earlier value, "
5152 		 "value numbering store vdefs to matching vuses.\n");
5153 
5154       changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
5155     }
5156 
5157   return changed;
5158 }
5159 
5160 /* Visit and value number PHI, return true if the value number
5161    changed.  When BACKEDGES_VARYING_P is true then assume all
5162    backedge values are varying.  When INSERTED is not NULL then
5163    this is just a ahead query for a possible iteration, set INSERTED
5164    to true if we'd insert into the hashtable.  */
5165 
5166 static bool
visit_phi(gimple * phi,bool * inserted,bool backedges_varying_p)5167 visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
5168 {
5169   tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
5170   tree backedge_val = NULL_TREE;
5171   bool seen_non_backedge = false;
5172   tree sameval_base = NULL_TREE;
5173   poly_int64 soff, doff;
5174   unsigned n_executable = 0;
5175   edge_iterator ei;
5176   edge e;
5177 
5178   /* TODO: We could check for this in initialization, and replace this
5179      with a gcc_assert.  */
5180   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
5181     return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
5182 
5183   /* We track whether a PHI was CSEd to to avoid excessive iterations
5184      that would be necessary only because the PHI changed arguments
5185      but not value.  */
5186   if (!inserted)
5187     gimple_set_plf (phi, GF_PLF_1, false);
5188 
5189   /* See if all non-TOP arguments have the same value.  TOP is
5190      equivalent to everything, so we can ignore it.  */
5191   FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
5192     if (e->flags & EDGE_EXECUTABLE)
5193       {
5194 	tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
5195 
5196 	if (def == PHI_RESULT (phi))
5197 	  continue;
5198 	++n_executable;
5199 	if (TREE_CODE (def) == SSA_NAME)
5200 	  {
5201 	    if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
5202 	      def = SSA_VAL (def);
5203 	    if (e->flags & EDGE_DFS_BACK)
5204 	      backedge_val = def;
5205 	  }
5206 	if (!(e->flags & EDGE_DFS_BACK))
5207 	  seen_non_backedge = true;
5208 	if (def == VN_TOP)
5209 	  ;
5210 	/* Ignore undefined defs for sameval but record one.  */
5211 	else if (TREE_CODE (def) == SSA_NAME
5212 		 && ! virtual_operand_p (def)
5213 		 && ssa_undefined_value_p (def, false))
5214 	  seen_undef = def;
5215 	else if (sameval == VN_TOP)
5216 	  sameval = def;
5217 	else if (!expressions_equal_p (def, sameval))
5218 	  {
5219 	    /* We know we're arriving only with invariant addresses here,
5220 	       try harder comparing them.  We can do some caching here
5221 	       which we cannot do in expressions_equal_p.  */
5222 	    if (TREE_CODE (def) == ADDR_EXPR
5223 		&& TREE_CODE (sameval) == ADDR_EXPR
5224 		&& sameval_base != (void *)-1)
5225 	      {
5226 		if (!sameval_base)
5227 		  sameval_base = get_addr_base_and_unit_offset
5228 				   (TREE_OPERAND (sameval, 0), &soff);
5229 		if (!sameval_base)
5230 		  sameval_base = (tree)(void *)-1;
5231 		else if ((get_addr_base_and_unit_offset
5232 			    (TREE_OPERAND (def, 0), &doff) == sameval_base)
5233 			 && known_eq (soff, doff))
5234 		  continue;
5235 	      }
5236 	    sameval = NULL_TREE;
5237 	    break;
5238 	  }
5239       }
5240 
5241   /* If the value we want to use is flowing over the backedge and we
5242      should take it as VARYING but it has a non-VARYING value drop to
5243      VARYING.
5244      If we value-number a virtual operand never value-number to the
5245      value from the backedge as that confuses the alias-walking code.
5246      See gcc.dg/torture/pr87176.c.  If the value is the same on a
5247      non-backedge everything is OK though.  */
5248   bool visited_p;
5249   if ((backedge_val
5250        && !seen_non_backedge
5251        && TREE_CODE (backedge_val) == SSA_NAME
5252        && sameval == backedge_val
5253        && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
5254 	   || SSA_VAL (backedge_val) != backedge_val))
5255       /* Do not value-number a virtual operand to sth not visited though
5256 	 given that allows us to escape a region in alias walking.  */
5257       || (sameval
5258 	  && TREE_CODE (sameval) == SSA_NAME
5259 	  && !SSA_NAME_IS_DEFAULT_DEF (sameval)
5260 	  && SSA_NAME_IS_VIRTUAL_OPERAND (sameval)
5261 	  && (SSA_VAL (sameval, &visited_p), !visited_p)))
5262     /* Note this just drops to VARYING without inserting the PHI into
5263        the hashes.  */
5264     result = PHI_RESULT (phi);
5265   /* If none of the edges was executable keep the value-number at VN_TOP,
5266      if only a single edge is exectuable use its value.  */
5267   else if (n_executable <= 1)
5268     result = seen_undef ? seen_undef : sameval;
5269   /* If we saw only undefined values and VN_TOP use one of the
5270      undefined values.  */
5271   else if (sameval == VN_TOP)
5272     result = seen_undef ? seen_undef : sameval;
5273   /* First see if it is equivalent to a phi node in this block.  We prefer
5274      this as it allows IV elimination - see PRs 66502 and 67167.  */
5275   else if ((result = vn_phi_lookup (phi, backedges_varying_p)))
5276     {
5277       if (!inserted
5278 	  && TREE_CODE (result) == SSA_NAME
5279 	  && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI)
5280 	{
5281 	  gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true);
5282 	  if (dump_file && (dump_flags & TDF_DETAILS))
5283 	    {
5284 	      fprintf (dump_file, "Marking CSEd to PHI node ");
5285 	      print_gimple_expr (dump_file, SSA_NAME_DEF_STMT (result),
5286 				 0, TDF_SLIM);
5287 	      fprintf (dump_file, "\n");
5288 	    }
5289 	}
5290     }
5291   /* If all values are the same use that, unless we've seen undefined
5292      values as well and the value isn't constant.
5293      CCP/copyprop have the same restriction to not remove uninit warnings.  */
5294   else if (sameval
5295 	   && (! seen_undef || is_gimple_min_invariant (sameval)))
5296     result = sameval;
5297   else
5298     {
5299       result = PHI_RESULT (phi);
5300       /* Only insert PHIs that are varying, for constant value numbers
5301          we mess up equivalences otherwise as we are only comparing
5302 	 the immediate controlling predicates.  */
5303       vn_phi_insert (phi, result, backedges_varying_p);
5304       if (inserted)
5305 	*inserted = true;
5306     }
5307 
5308   return set_ssa_val_to (PHI_RESULT (phi), result);
5309 }
5310 
5311 /* Try to simplify RHS using equivalences and constant folding.  */
5312 
5313 static tree
try_to_simplify(gassign * stmt)5314 try_to_simplify (gassign *stmt)
5315 {
5316   enum tree_code code = gimple_assign_rhs_code (stmt);
5317   tree tem;
5318 
5319   /* For stores we can end up simplifying a SSA_NAME rhs.  Just return
5320      in this case, there is no point in doing extra work.  */
5321   if (code == SSA_NAME)
5322     return NULL_TREE;
5323 
5324   /* First try constant folding based on our current lattice.  */
5325   mprts_hook = vn_lookup_simplify_result;
5326   tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
5327   mprts_hook = NULL;
5328   if (tem
5329       && (TREE_CODE (tem) == SSA_NAME
5330 	  || is_gimple_min_invariant (tem)))
5331     return tem;
5332 
5333   return NULL_TREE;
5334 }
5335 
5336 /* Visit and value number STMT, return true if the value number
5337    changed.  */
5338 
5339 static bool
5340 visit_stmt (gimple *stmt, bool backedges_varying_p = false)
5341 {
5342   bool changed = false;
5343 
5344   if (dump_file && (dump_flags & TDF_DETAILS))
5345     {
5346       fprintf (dump_file, "Value numbering stmt = ");
5347       print_gimple_stmt (dump_file, stmt, 0);
5348     }
5349 
5350   if (gimple_code (stmt) == GIMPLE_PHI)
5351     changed = visit_phi (stmt, NULL, backedges_varying_p);
5352   else if (gimple_has_volatile_ops (stmt))
5353     changed = defs_to_varying (stmt);
5354   else if (gassign *ass = dyn_cast <gassign *> (stmt))
5355     {
5356       enum tree_code code = gimple_assign_rhs_code (ass);
5357       tree lhs = gimple_assign_lhs (ass);
5358       tree rhs1 = gimple_assign_rhs1 (ass);
5359       tree simplified;
5360 
5361       /* Shortcut for copies. Simplifying copies is pointless,
5362 	 since we copy the expression and value they represent.  */
5363       if (code == SSA_NAME
5364 	  && TREE_CODE (lhs) == SSA_NAME)
5365 	{
5366 	  changed = visit_copy (lhs, rhs1);
5367 	  goto done;
5368 	}
5369       simplified = try_to_simplify (ass);
5370       if (simplified)
5371 	{
5372 	  if (dump_file && (dump_flags & TDF_DETAILS))
5373 	    {
5374 	      fprintf (dump_file, "RHS ");
5375 	      print_gimple_expr (dump_file, ass, 0);
5376 	      fprintf (dump_file, " simplified to ");
5377 	      print_generic_expr (dump_file, simplified);
5378 	      fprintf (dump_file, "\n");
5379 	    }
5380 	}
5381       /* Setting value numbers to constants will occasionally
5382 	 screw up phi congruence because constants are not
5383 	 uniquely associated with a single ssa name that can be
5384 	 looked up.  */
5385       if (simplified
5386 	  && is_gimple_min_invariant (simplified)
5387 	  && TREE_CODE (lhs) == SSA_NAME)
5388 	{
5389 	  changed = set_ssa_val_to (lhs, simplified);
5390 	  goto done;
5391 	}
5392       else if (simplified
5393 	       && TREE_CODE (simplified) == SSA_NAME
5394 	       && TREE_CODE (lhs) == SSA_NAME)
5395 	{
5396 	  changed = visit_copy (lhs, simplified);
5397 	  goto done;
5398 	}
5399 
5400       if ((TREE_CODE (lhs) == SSA_NAME
5401 	   /* We can substitute SSA_NAMEs that are live over
5402 	      abnormal edges with their constant value.  */
5403 	   && !(gimple_assign_copy_p (ass)
5404 		&& is_gimple_min_invariant (rhs1))
5405 	   && !(simplified
5406 		&& is_gimple_min_invariant (simplified))
5407 	   && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
5408 	  /* Stores or copies from SSA_NAMEs that are live over
5409 	     abnormal edges are a problem.  */
5410 	  || (code == SSA_NAME
5411 	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
5412 	changed = defs_to_varying (ass);
5413       else if (REFERENCE_CLASS_P (lhs)
5414 	       || DECL_P (lhs))
5415 	changed = visit_reference_op_store (lhs, rhs1, ass);
5416       else if (TREE_CODE (lhs) == SSA_NAME)
5417 	{
5418 	  if ((gimple_assign_copy_p (ass)
5419 	       && is_gimple_min_invariant (rhs1))
5420 	      || (simplified
5421 		  && is_gimple_min_invariant (simplified)))
5422 	    {
5423 	      if (simplified)
5424 		changed = set_ssa_val_to (lhs, simplified);
5425 	      else
5426 		changed = set_ssa_val_to (lhs, rhs1);
5427 	    }
5428 	  else
5429 	    {
5430 	      /* Visit the original statement.  */
5431 	      switch (vn_get_stmt_kind (ass))
5432 		{
5433 		case VN_NARY:
5434 		  changed = visit_nary_op (lhs, ass);
5435 		  break;
5436 		case VN_REFERENCE:
5437 		  changed = visit_reference_op_load (lhs, rhs1, ass);
5438 		  break;
5439 		default:
5440 		  changed = defs_to_varying (ass);
5441 		  break;
5442 		}
5443 	    }
5444 	}
5445       else
5446 	changed = defs_to_varying (ass);
5447     }
5448   else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
5449     {
5450       tree lhs = gimple_call_lhs (call_stmt);
5451       if (lhs && TREE_CODE (lhs) == SSA_NAME)
5452 	{
5453 	  /* Try constant folding based on our current lattice.  */
5454 	  tree simplified = gimple_fold_stmt_to_constant_1 (call_stmt,
5455 							    vn_valueize);
5456 	  if (simplified)
5457 	    {
5458 	      if (dump_file && (dump_flags & TDF_DETAILS))
5459 		{
5460 		  fprintf (dump_file, "call ");
5461 		  print_gimple_expr (dump_file, call_stmt, 0);
5462 		  fprintf (dump_file, " simplified to ");
5463 		  print_generic_expr (dump_file, simplified);
5464 		  fprintf (dump_file, "\n");
5465 		}
5466 	    }
5467 	  /* Setting value numbers to constants will occasionally
5468 	     screw up phi congruence because constants are not
5469 	     uniquely associated with a single ssa name that can be
5470 	     looked up.  */
5471 	  if (simplified
5472 	      && is_gimple_min_invariant (simplified))
5473 	    {
5474 	      changed = set_ssa_val_to (lhs, simplified);
5475 	      if (gimple_vdef (call_stmt))
5476 		changed |= set_ssa_val_to (gimple_vdef (call_stmt),
5477 					   SSA_VAL (gimple_vuse (call_stmt)));
5478 	      goto done;
5479 	    }
5480 	  else if (simplified
5481 		   && TREE_CODE (simplified) == SSA_NAME)
5482 	    {
5483 	      changed = visit_copy (lhs, simplified);
5484 	      if (gimple_vdef (call_stmt))
5485 		changed |= set_ssa_val_to (gimple_vdef (call_stmt),
5486 					   SSA_VAL (gimple_vuse (call_stmt)));
5487 	      goto done;
5488 	    }
5489 	  else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
5490 	    {
5491 	      changed = defs_to_varying (call_stmt);
5492 	      goto done;
5493 	    }
5494 	}
5495 
5496       /* Pick up flags from a devirtualization target.  */
5497       tree fn = gimple_call_fn (stmt);
5498       int extra_fnflags = 0;
5499       if (fn && TREE_CODE (fn) == SSA_NAME)
5500 	{
5501 	  fn = SSA_VAL (fn);
5502 	  if (TREE_CODE (fn) == ADDR_EXPR
5503 	      && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
5504 	    extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
5505 	}
5506       if (!gimple_call_internal_p (call_stmt)
5507 	  && (/* Calls to the same function with the same vuse
5508 		 and the same operands do not necessarily return the same
5509 		 value, unless they're pure or const.  */
5510 	      ((gimple_call_flags (call_stmt) | extra_fnflags)
5511 	       & (ECF_PURE | ECF_CONST))
5512 	      /* If calls have a vdef, subsequent calls won't have
5513 		 the same incoming vuse.  So, if 2 calls with vdef have the
5514 		 same vuse, we know they're not subsequent.
5515 		 We can value number 2 calls to the same function with the
5516 		 same vuse and the same operands which are not subsequent
5517 		 the same, because there is no code in the program that can
5518 		 compare the 2 values...  */
5519 	      || (gimple_vdef (call_stmt)
5520 		  /* ... unless the call returns a pointer which does
5521 		     not alias with anything else.  In which case the
5522 		     information that the values are distinct are encoded
5523 		     in the IL.  */
5524 		  && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
5525 		  /* Only perform the following when being called from PRE
5526 		     which embeds tail merging.  */
5527 		  && default_vn_walk_kind == VN_WALK)))
5528 	changed = visit_reference_op_call (lhs, call_stmt);
5529       else
5530 	changed = defs_to_varying (call_stmt);
5531     }
5532   else
5533     changed = defs_to_varying (stmt);
5534  done:
5535   return changed;
5536 }
5537 
5538 
5539 /* Allocate a value number table.  */
5540 
5541 static void
allocate_vn_table(vn_tables_t table,unsigned size)5542 allocate_vn_table (vn_tables_t table, unsigned size)
5543 {
5544   table->phis = new vn_phi_table_type (size);
5545   table->nary = new vn_nary_op_table_type (size);
5546   table->references = new vn_reference_table_type (size);
5547 }
5548 
5549 /* Free a value number table.  */
5550 
5551 static void
free_vn_table(vn_tables_t table)5552 free_vn_table (vn_tables_t table)
5553 {
5554   /* Walk over elements and release vectors.  */
5555   vn_reference_iterator_type hir;
5556   vn_reference_t vr;
5557   FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir)
5558     vr->operands.release ();
5559   delete table->phis;
5560   table->phis = NULL;
5561   delete table->nary;
5562   table->nary = NULL;
5563   delete table->references;
5564   table->references = NULL;
5565 }
5566 
5567 /* Set *ID according to RESULT.  */
5568 
5569 static void
set_value_id_for_result(tree result,unsigned int * id)5570 set_value_id_for_result (tree result, unsigned int *id)
5571 {
5572   if (result && TREE_CODE (result) == SSA_NAME)
5573     *id = VN_INFO (result)->value_id;
5574   else if (result && is_gimple_min_invariant (result))
5575     *id = get_or_alloc_constant_value_id (result);
5576   else
5577     *id = get_next_value_id ();
5578 }
5579 
5580 /* Set the value ids in the valid hash tables.  */
5581 
5582 static void
set_hashtable_value_ids(void)5583 set_hashtable_value_ids (void)
5584 {
5585   vn_nary_op_iterator_type hin;
5586   vn_phi_iterator_type hip;
5587   vn_reference_iterator_type hir;
5588   vn_nary_op_t vno;
5589   vn_reference_t vr;
5590   vn_phi_t vp;
5591 
5592   /* Now set the value ids of the things we had put in the hash
5593      table.  */
5594 
5595   FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin)
5596     if (! vno->predicated_values)
5597       set_value_id_for_result (vno->u.result, &vno->value_id);
5598 
5599   FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip)
5600     set_value_id_for_result (vp->result, &vp->value_id);
5601 
5602   FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t,
5603 			       hir)
5604     set_value_id_for_result (vr->result, &vr->value_id);
5605 }
5606 
5607 /* Return the maximum value id we have ever seen.  */
5608 
5609 unsigned int
get_max_value_id(void)5610 get_max_value_id (void)
5611 {
5612   return next_value_id;
5613 }
5614 
5615 /* Return the next unique value id.  */
5616 
5617 unsigned int
get_next_value_id(void)5618 get_next_value_id (void)
5619 {
5620   return next_value_id++;
5621 }
5622 
5623 
5624 /* Compare two expressions E1 and E2 and return true if they are equal.  */
5625 
5626 bool
expressions_equal_p(tree e1,tree e2)5627 expressions_equal_p (tree e1, tree e2)
5628 {
5629   /* The obvious case.  */
5630   if (e1 == e2)
5631     return true;
5632 
5633   /* If either one is VN_TOP consider them equal.  */
5634   if (e1 == VN_TOP || e2 == VN_TOP)
5635     return true;
5636 
5637   /* If only one of them is null, they cannot be equal.  */
5638   if (!e1 || !e2)
5639     return false;
5640 
5641   /* Now perform the actual comparison.  */
5642   if (TREE_CODE (e1) == TREE_CODE (e2)
5643       && operand_equal_p (e1, e2, OEP_PURE_SAME))
5644     return true;
5645 
5646   return false;
5647 }
5648 
5649 
5650 /* Return true if the nary operation NARY may trap.  This is a copy
5651    of stmt_could_throw_1_p adjusted to the SCCVN IL.  */
5652 
5653 bool
vn_nary_may_trap(vn_nary_op_t nary)5654 vn_nary_may_trap (vn_nary_op_t nary)
5655 {
5656   tree type;
5657   tree rhs2 = NULL_TREE;
5658   bool honor_nans = false;
5659   bool honor_snans = false;
5660   bool fp_operation = false;
5661   bool honor_trapv = false;
5662   bool handled, ret;
5663   unsigned i;
5664 
5665   if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
5666       || TREE_CODE_CLASS (nary->opcode) == tcc_unary
5667       || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
5668     {
5669       type = nary->type;
5670       fp_operation = FLOAT_TYPE_P (type);
5671       if (fp_operation)
5672 	{
5673 	  honor_nans = flag_trapping_math && !flag_finite_math_only;
5674 	  honor_snans = flag_signaling_nans != 0;
5675 	}
5676       else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
5677 	honor_trapv = true;
5678     }
5679   if (nary->length >= 2)
5680     rhs2 = nary->op[1];
5681   ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
5682 				       honor_trapv, honor_nans, honor_snans,
5683 				       rhs2, &handled);
5684   if (handled && ret)
5685     return true;
5686 
5687   for (i = 0; i < nary->length; ++i)
5688     if (tree_could_trap_p (nary->op[i]))
5689       return true;
5690 
5691   return false;
5692 }
5693 
5694 /* Return true if the reference operation REF may trap.  */
5695 
5696 bool
vn_reference_may_trap(vn_reference_t ref)5697 vn_reference_may_trap (vn_reference_t ref)
5698 {
5699   switch (ref->operands[0].opcode)
5700     {
5701     case MODIFY_EXPR:
5702     case CALL_EXPR:
5703       /* We do not handle calls.  */
5704     case ADDR_EXPR:
5705       /* And toplevel address computations never trap.  */
5706       return false;
5707     default:;
5708     }
5709 
5710   vn_reference_op_t op;
5711   unsigned i;
5712   FOR_EACH_VEC_ELT (ref->operands, i, op)
5713     {
5714       switch (op->opcode)
5715 	{
5716 	case WITH_SIZE_EXPR:
5717 	case TARGET_MEM_REF:
5718 	  /* Always variable.  */
5719 	  return true;
5720 	case COMPONENT_REF:
5721 	  if (op->op1 && TREE_CODE (op->op1) == SSA_NAME)
5722 	    return true;
5723 	  break;
5724 	case ARRAY_RANGE_REF:
5725 	case ARRAY_REF:
5726 	  if (TREE_CODE (op->op0) == SSA_NAME)
5727 	    return true;
5728 	  break;
5729 	case MEM_REF:
5730 	  /* Nothing interesting in itself, the base is separate.  */
5731 	  break;
5732 	/* The following are the address bases.  */
5733 	case SSA_NAME:
5734 	  return true;
5735 	case ADDR_EXPR:
5736 	  if (op->op0)
5737 	    return tree_could_trap_p (TREE_OPERAND (op->op0, 0));
5738 	  return false;
5739 	default:;
5740 	}
5741     }
5742   return false;
5743 }
5744 
eliminate_dom_walker(cdi_direction direction,bitmap inserted_exprs_)5745 eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction,
5746 					    bitmap inserted_exprs_)
5747   : dom_walker (direction), do_pre (inserted_exprs_ != NULL),
5748     el_todo (0), eliminations (0), insertions (0),
5749     inserted_exprs (inserted_exprs_)
5750 {
5751   need_eh_cleanup = BITMAP_ALLOC (NULL);
5752   need_ab_cleanup = BITMAP_ALLOC (NULL);
5753 }
5754 
~eliminate_dom_walker()5755 eliminate_dom_walker::~eliminate_dom_walker ()
5756 {
5757   BITMAP_FREE (need_eh_cleanup);
5758   BITMAP_FREE (need_ab_cleanup);
5759 }
5760 
5761 /* Return a leader for OP that is available at the current point of the
5762    eliminate domwalk.  */
5763 
5764 tree
eliminate_avail(basic_block,tree op)5765 eliminate_dom_walker::eliminate_avail (basic_block, tree op)
5766 {
5767   tree valnum = VN_INFO (op)->valnum;
5768   if (TREE_CODE (valnum) == SSA_NAME)
5769     {
5770       if (SSA_NAME_IS_DEFAULT_DEF (valnum))
5771 	return valnum;
5772       if (avail.length () > SSA_NAME_VERSION (valnum))
5773 	return avail[SSA_NAME_VERSION (valnum)];
5774     }
5775   else if (is_gimple_min_invariant (valnum))
5776     return valnum;
5777   return NULL_TREE;
5778 }
5779 
5780 /* At the current point of the eliminate domwalk make OP available.  */
5781 
5782 void
eliminate_push_avail(basic_block,tree op)5783 eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
5784 {
5785   tree valnum = VN_INFO (op)->valnum;
5786   if (TREE_CODE (valnum) == SSA_NAME)
5787     {
5788       if (avail.length () <= SSA_NAME_VERSION (valnum))
5789 	avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1);
5790       tree pushop = op;
5791       if (avail[SSA_NAME_VERSION (valnum)])
5792 	pushop = avail[SSA_NAME_VERSION (valnum)];
5793       avail_stack.safe_push (pushop);
5794       avail[SSA_NAME_VERSION (valnum)] = op;
5795     }
5796 }
5797 
5798 /* Insert the expression recorded by SCCVN for VAL at *GSI.  Returns
5799    the leader for the expression if insertion was successful.  */
5800 
5801 tree
eliminate_insert(basic_block bb,gimple_stmt_iterator * gsi,tree val)5802 eliminate_dom_walker::eliminate_insert (basic_block bb,
5803 					gimple_stmt_iterator *gsi, tree val)
5804 {
5805   /* We can insert a sequence with a single assignment only.  */
5806   gimple_seq stmts = VN_INFO (val)->expr;
5807   if (!gimple_seq_singleton_p (stmts))
5808     return NULL_TREE;
5809   gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts));
5810   if (!stmt
5811       || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
5812 	  && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
5813 	  && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF
5814 	  && (gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
5815 	      || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)))
5816     return NULL_TREE;
5817 
5818   tree op = gimple_assign_rhs1 (stmt);
5819   if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
5820       || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
5821     op = TREE_OPERAND (op, 0);
5822   tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op;
5823   if (!leader)
5824     return NULL_TREE;
5825 
5826   tree res;
5827   stmts = NULL;
5828   if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
5829     res = gimple_build (&stmts, BIT_FIELD_REF,
5830 			TREE_TYPE (val), leader,
5831 			TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
5832 			TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
5833   else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
5834     res = gimple_build (&stmts, BIT_AND_EXPR,
5835 			TREE_TYPE (val), leader, gimple_assign_rhs2 (stmt));
5836   else
5837     res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
5838 			TREE_TYPE (val), leader);
5839   if (TREE_CODE (res) != SSA_NAME
5840       || SSA_NAME_IS_DEFAULT_DEF (res)
5841       || gimple_bb (SSA_NAME_DEF_STMT (res)))
5842     {
5843       gimple_seq_discard (stmts);
5844 
5845       /* During propagation we have to treat SSA info conservatively
5846          and thus we can end up simplifying the inserted expression
5847 	 at elimination time to sth not defined in stmts.  */
5848       /* But then this is a redundancy we failed to detect.  Which means
5849          res now has two values.  That doesn't play well with how
5850 	 we track availability here, so give up.  */
5851       if (dump_file && (dump_flags & TDF_DETAILS))
5852 	{
5853 	  if (TREE_CODE (res) == SSA_NAME)
5854 	    res = eliminate_avail (bb, res);
5855 	  if (res)
5856 	    {
5857 	      fprintf (dump_file, "Failed to insert expression for value ");
5858 	      print_generic_expr (dump_file, val);
5859 	      fprintf (dump_file, " which is really fully redundant to ");
5860 	      print_generic_expr (dump_file, res);
5861 	      fprintf (dump_file, "\n");
5862 	    }
5863 	}
5864 
5865       return NULL_TREE;
5866     }
5867   else
5868     {
5869       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
5870       VN_INFO (res)->valnum = val;
5871       VN_INFO (res)->visited = true;
5872     }
5873 
5874   insertions++;
5875   if (dump_file && (dump_flags & TDF_DETAILS))
5876     {
5877       fprintf (dump_file, "Inserted ");
5878       print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0);
5879     }
5880 
5881   return res;
5882 }
5883 
5884 void
eliminate_stmt(basic_block b,gimple_stmt_iterator * gsi)5885 eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
5886 {
5887   tree sprime = NULL_TREE;
5888   gimple *stmt = gsi_stmt (*gsi);
5889   tree lhs = gimple_get_lhs (stmt);
5890   if (lhs && TREE_CODE (lhs) == SSA_NAME
5891       && !gimple_has_volatile_ops (stmt)
5892       /* See PR43491.  Do not replace a global register variable when
5893 	 it is a the RHS of an assignment.  Do replace local register
5894 	 variables since gcc does not guarantee a local variable will
5895 	 be allocated in register.
5896 	 ???  The fix isn't effective here.  This should instead
5897 	 be ensured by not value-numbering them the same but treating
5898 	 them like volatiles?  */
5899       && !(gimple_assign_single_p (stmt)
5900 	   && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
5901 	       && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
5902 	       && is_global_var (gimple_assign_rhs1 (stmt)))))
5903     {
5904       sprime = eliminate_avail (b, lhs);
5905       if (!sprime)
5906 	{
5907 	  /* If there is no existing usable leader but SCCVN thinks
5908 	     it has an expression it wants to use as replacement,
5909 	     insert that.  */
5910 	  tree val = VN_INFO (lhs)->valnum;
5911 	  if (val != VN_TOP
5912 	      && TREE_CODE (val) == SSA_NAME
5913 	      && VN_INFO (val)->needs_insertion
5914 	      && VN_INFO (val)->expr != NULL
5915 	      && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE)
5916 	    eliminate_push_avail (b, sprime);
5917 	}
5918 
5919       /* If this now constitutes a copy duplicate points-to
5920 	 and range info appropriately.  This is especially
5921 	 important for inserted code.  See tree-ssa-copy.c
5922 	 for similar code.  */
5923       if (sprime
5924 	  && TREE_CODE (sprime) == SSA_NAME)
5925 	{
5926 	  basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime));
5927 	  if (POINTER_TYPE_P (TREE_TYPE (lhs))
5928 	      && SSA_NAME_PTR_INFO (lhs)
5929 	      && ! SSA_NAME_PTR_INFO (sprime))
5930 	    {
5931 	      duplicate_ssa_name_ptr_info (sprime,
5932 					   SSA_NAME_PTR_INFO (lhs));
5933 	      if (b != sprime_b)
5934 		reset_flow_sensitive_info (sprime);
5935 	    }
5936 	  else if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
5937 		   && SSA_NAME_RANGE_INFO (lhs)
5938 		   && ! SSA_NAME_RANGE_INFO (sprime)
5939 		   && b == sprime_b)
5940 	    duplicate_ssa_name_range_info (sprime,
5941 					   SSA_NAME_RANGE_TYPE (lhs),
5942 					   SSA_NAME_RANGE_INFO (lhs));
5943 	}
5944 
5945       /* Inhibit the use of an inserted PHI on a loop header when
5946 	 the address of the memory reference is a simple induction
5947 	 variable.  In other cases the vectorizer won't do anything
5948 	 anyway (either it's loop invariant or a complicated
5949 	 expression).  */
5950       if (sprime
5951 	  && TREE_CODE (sprime) == SSA_NAME
5952 	  && do_pre
5953 	  && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1)
5954 	  && loop_outer (b->loop_father)
5955 	  && has_zero_uses (sprime)
5956 	  && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
5957 	  && gimple_assign_load_p (stmt))
5958 	{
5959 	  gimple *def_stmt = SSA_NAME_DEF_STMT (sprime);
5960 	  basic_block def_bb = gimple_bb (def_stmt);
5961 	  if (gimple_code (def_stmt) == GIMPLE_PHI
5962 	      && def_bb->loop_father->header == def_bb)
5963 	    {
5964 	      loop_p loop = def_bb->loop_father;
5965 	      ssa_op_iter iter;
5966 	      tree op;
5967 	      bool found = false;
5968 	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
5969 		{
5970 		  affine_iv iv;
5971 		  def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
5972 		  if (def_bb
5973 		      && flow_bb_inside_loop_p (loop, def_bb)
5974 		      && simple_iv (loop, loop, op, &iv, true))
5975 		    {
5976 		      found = true;
5977 		      break;
5978 		    }
5979 		}
5980 	      if (found)
5981 		{
5982 		  if (dump_file && (dump_flags & TDF_DETAILS))
5983 		    {
5984 		      fprintf (dump_file, "Not replacing ");
5985 		      print_gimple_expr (dump_file, stmt, 0);
5986 		      fprintf (dump_file, " with ");
5987 		      print_generic_expr (dump_file, sprime);
5988 		      fprintf (dump_file, " which would add a loop"
5989 			       " carried dependence to loop %d\n",
5990 			       loop->num);
5991 		    }
5992 		  /* Don't keep sprime available.  */
5993 		  sprime = NULL_TREE;
5994 		}
5995 	    }
5996 	}
5997 
5998       if (sprime)
5999 	{
6000 	  /* If we can propagate the value computed for LHS into
6001 	     all uses don't bother doing anything with this stmt.  */
6002 	  if (may_propagate_copy (lhs, sprime))
6003 	    {
6004 	      /* Mark it for removal.  */
6005 	      to_remove.safe_push (stmt);
6006 
6007 	      /* ???  Don't count copy/constant propagations.  */
6008 	      if (gimple_assign_single_p (stmt)
6009 		  && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
6010 		      || gimple_assign_rhs1 (stmt) == sprime))
6011 		return;
6012 
6013 	      if (dump_file && (dump_flags & TDF_DETAILS))
6014 		{
6015 		  fprintf (dump_file, "Replaced ");
6016 		  print_gimple_expr (dump_file, stmt, 0);
6017 		  fprintf (dump_file, " with ");
6018 		  print_generic_expr (dump_file, sprime);
6019 		  fprintf (dump_file, " in all uses of ");
6020 		  print_gimple_stmt (dump_file, stmt, 0);
6021 		}
6022 
6023 	      eliminations++;
6024 	      return;
6025 	    }
6026 
6027 	  /* If this is an assignment from our leader (which
6028 	     happens in the case the value-number is a constant)
6029 	     then there is nothing to do.  Likewise if we run into
6030 	     inserted code that needed a conversion because of
6031 	     our type-agnostic value-numbering of loads.  */
6032 	  if ((gimple_assign_single_p (stmt)
6033 	       || (is_gimple_assign (stmt)
6034 		   && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
6035 		       || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)))
6036 	      && sprime == gimple_assign_rhs1 (stmt))
6037 	    return;
6038 
6039 	  /* Else replace its RHS.  */
6040 	  if (dump_file && (dump_flags & TDF_DETAILS))
6041 	    {
6042 	      fprintf (dump_file, "Replaced ");
6043 	      print_gimple_expr (dump_file, stmt, 0);
6044 	      fprintf (dump_file, " with ");
6045 	      print_generic_expr (dump_file, sprime);
6046 	      fprintf (dump_file, " in ");
6047 	      print_gimple_stmt (dump_file, stmt, 0);
6048 	    }
6049 	  eliminations++;
6050 
6051 	  bool can_make_abnormal_goto = (is_gimple_call (stmt)
6052 					 && stmt_can_make_abnormal_goto (stmt));
6053 	  gimple *orig_stmt = stmt;
6054 	  if (!useless_type_conversion_p (TREE_TYPE (lhs),
6055 					  TREE_TYPE (sprime)))
6056 	    {
6057 	      /* We preserve conversions to but not from function or method
6058 		 types.  This asymmetry makes it necessary to re-instantiate
6059 		 conversions here.  */
6060 	      if (POINTER_TYPE_P (TREE_TYPE (lhs))
6061 		  && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (lhs))))
6062 		sprime = fold_convert (TREE_TYPE (lhs), sprime);
6063 	      else
6064 		gcc_unreachable ();
6065 	    }
6066 	  tree vdef = gimple_vdef (stmt);
6067 	  tree vuse = gimple_vuse (stmt);
6068 	  propagate_tree_value_into_stmt (gsi, sprime);
6069 	  stmt = gsi_stmt (*gsi);
6070 	  update_stmt (stmt);
6071 	  /* In case the VDEF on the original stmt was released, value-number
6072 	     it to the VUSE.  This is to make vuse_ssa_val able to skip
6073 	     released virtual operands.  */
6074 	  if (vdef != gimple_vdef (stmt))
6075 	    {
6076 	      gcc_assert (SSA_NAME_IN_FREE_LIST (vdef));
6077 	      VN_INFO (vdef)->valnum = vuse;
6078 	    }
6079 
6080 	  /* If we removed EH side-effects from the statement, clean
6081 	     its EH information.  */
6082 	  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
6083 	    {
6084 	      bitmap_set_bit (need_eh_cleanup,
6085 			      gimple_bb (stmt)->index);
6086 	      if (dump_file && (dump_flags & TDF_DETAILS))
6087 		fprintf (dump_file, "  Removed EH side-effects.\n");
6088 	    }
6089 
6090 	  /* Likewise for AB side-effects.  */
6091 	  if (can_make_abnormal_goto
6092 	      && !stmt_can_make_abnormal_goto (stmt))
6093 	    {
6094 	      bitmap_set_bit (need_ab_cleanup,
6095 			      gimple_bb (stmt)->index);
6096 	      if (dump_file && (dump_flags & TDF_DETAILS))
6097 		fprintf (dump_file, "  Removed AB side-effects.\n");
6098 	    }
6099 
6100 	  return;
6101 	}
6102     }
6103 
6104   /* If the statement is a scalar store, see if the expression
6105      has the same value number as its rhs.  If so, the store is
6106      dead.  */
6107   if (gimple_assign_single_p (stmt)
6108       && !gimple_has_volatile_ops (stmt)
6109       && !is_gimple_reg (gimple_assign_lhs (stmt))
6110       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
6111 	  || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
6112     {
6113       tree rhs = gimple_assign_rhs1 (stmt);
6114       vn_reference_t vnresult;
6115       /* ???  gcc.dg/torture/pr91445.c shows that we lookup a boolean
6116          typed load of a byte known to be 0x11 as 1 so a store of
6117 	 a boolean 1 is detected as redundant.  Because of this we
6118 	 have to make sure to lookup with a ref where its size
6119 	 matches the precision.  */
6120       tree lookup_lhs = lhs;
6121       if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6122 	  && (TREE_CODE (lhs) != COMPONENT_REF
6123 	      || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
6124 	  && !type_has_mode_precision_p (TREE_TYPE (lhs)))
6125 	{
6126 	  if (TREE_CODE (lhs) == COMPONENT_REF
6127 	      || TREE_CODE (lhs) == MEM_REF)
6128 	    {
6129 	      tree ltype = build_nonstandard_integer_type
6130 				(TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhs))),
6131 				 TYPE_UNSIGNED (TREE_TYPE (lhs)));
6132 	      if (TREE_CODE (lhs) == COMPONENT_REF)
6133 		{
6134 		  tree foff = component_ref_field_offset (lhs);
6135 		  tree f = TREE_OPERAND (lhs, 1);
6136 		  if (!poly_int_tree_p (foff))
6137 		    lookup_lhs = NULL_TREE;
6138 		  else
6139 		    lookup_lhs = build3 (BIT_FIELD_REF, ltype,
6140 					 TREE_OPERAND (lhs, 0),
6141 					 TYPE_SIZE (TREE_TYPE (lhs)),
6142 					 bit_from_pos
6143 					   (foff, DECL_FIELD_BIT_OFFSET (f)));
6144 		}
6145 	      else
6146 		lookup_lhs = build2 (MEM_REF, ltype,
6147 				     TREE_OPERAND (lhs, 0),
6148 				     TREE_OPERAND (lhs, 1));
6149 	    }
6150 	  else
6151 	    lookup_lhs = NULL_TREE;
6152 	}
6153       tree val = NULL_TREE;
6154       if (lookup_lhs)
6155 	val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
6156 				   VN_WALKREWRITE, &vnresult, false);
6157       if (TREE_CODE (rhs) == SSA_NAME)
6158 	rhs = VN_INFO (rhs)->valnum;
6159       if (val
6160 	  && (operand_equal_p (val, rhs, 0)
6161 	      /* Due to the bitfield lookups above we can get bit
6162 		 interpretations of the same RHS as values here.  Those
6163 		 are redundant as well.  */
6164 	      || (TREE_CODE (val) == SSA_NAME
6165 		  && gimple_assign_single_p (SSA_NAME_DEF_STMT (val))
6166 		  && (val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val)))
6167 		  && TREE_CODE (val) == VIEW_CONVERT_EXPR
6168 		  && TREE_OPERAND (val, 0) == rhs)))
6169 	{
6170 	  /* We can only remove the later store if the former aliases
6171 	     at least all accesses the later one does or if the store
6172 	     was to readonly memory storing the same value.  */
6173 	  ao_ref lhs_ref;
6174 	  ao_ref_init (&lhs_ref, lhs);
6175 	  alias_set_type set = ao_ref_alias_set (&lhs_ref);
6176 	  alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
6177 	  if (! vnresult
6178 	      || ((vnresult->set == set
6179 		   || alias_set_subset_of (set, vnresult->set))
6180 		  && (vnresult->base_set == base_set
6181 		      || alias_set_subset_of (base_set, vnresult->base_set))))
6182 	    {
6183 	      if (dump_file && (dump_flags & TDF_DETAILS))
6184 		{
6185 		  fprintf (dump_file, "Deleted redundant store ");
6186 		  print_gimple_stmt (dump_file, stmt, 0);
6187 		}
6188 
6189 	      /* Queue stmt for removal.  */
6190 	      to_remove.safe_push (stmt);
6191 	      return;
6192 	    }
6193 	}
6194     }
6195 
6196   /* If this is a control statement value numbering left edges
6197      unexecuted on force the condition in a way consistent with
6198      that.  */
6199   if (gcond *cond = dyn_cast <gcond *> (stmt))
6200     {
6201       if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
6202 	  ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
6203 	{
6204 	  if (dump_file && (dump_flags & TDF_DETAILS))
6205 	    {
6206 	      fprintf (dump_file, "Removing unexecutable edge from ");
6207 	      print_gimple_stmt (dump_file, stmt, 0);
6208 	    }
6209 	  if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
6210 	      == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
6211 	    gimple_cond_make_true (cond);
6212 	  else
6213 	    gimple_cond_make_false (cond);
6214 	  update_stmt (cond);
6215 	  el_todo |= TODO_cleanup_cfg;
6216 	  return;
6217 	}
6218     }
6219 
6220   bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
6221   bool was_noreturn = (is_gimple_call (stmt)
6222 		       && gimple_call_noreturn_p (stmt));
6223   tree vdef = gimple_vdef (stmt);
6224   tree vuse = gimple_vuse (stmt);
6225 
6226   /* If we didn't replace the whole stmt (or propagate the result
6227      into all uses), replace all uses on this stmt with their
6228      leaders.  */
6229   bool modified = false;
6230   use_operand_p use_p;
6231   ssa_op_iter iter;
6232   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
6233     {
6234       tree use = USE_FROM_PTR (use_p);
6235       /* ???  The call code above leaves stmt operands un-updated.  */
6236       if (TREE_CODE (use) != SSA_NAME)
6237 	continue;
6238       tree sprime;
6239       if (SSA_NAME_IS_DEFAULT_DEF (use))
6240 	/* ???  For default defs BB shouldn't matter, but we have to
6241 	   solve the inconsistency between rpo eliminate and
6242 	   dom eliminate avail valueization first.  */
6243 	sprime = eliminate_avail (b, use);
6244       else
6245 	/* Look for sth available at the definition block of the argument.
6246 	   This avoids inconsistencies between availability there which
6247 	   decides if the stmt can be removed and availability at the
6248 	   use site.  The SSA property ensures that things available
6249 	   at the definition are also available at uses.  */
6250 	sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use);
6251       if (sprime && sprime != use
6252 	  && may_propagate_copy (use, sprime, true)
6253 	  /* We substitute into debug stmts to avoid excessive
6254 	     debug temporaries created by removed stmts, but we need
6255 	     to avoid doing so for inserted sprimes as we never want
6256 	     to create debug temporaries for them.  */
6257 	  && (!inserted_exprs
6258 	      || TREE_CODE (sprime) != SSA_NAME
6259 	      || !is_gimple_debug (stmt)
6260 	      || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
6261 	{
6262 	  propagate_value (use_p, sprime);
6263 	  modified = true;
6264 	}
6265     }
6266 
6267   /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated
6268      into which is a requirement for the IPA devirt machinery.  */
6269   gimple *old_stmt = stmt;
6270   if (modified)
6271     {
6272       /* If a formerly non-invariant ADDR_EXPR is turned into an
6273 	 invariant one it was on a separate stmt.  */
6274       if (gimple_assign_single_p (stmt)
6275 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
6276 	recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
6277       gimple_stmt_iterator prev = *gsi;
6278       gsi_prev (&prev);
6279       if (fold_stmt (gsi))
6280 	{
6281 	  /* fold_stmt may have created new stmts inbetween
6282 	     the previous stmt and the folded stmt.  Mark
6283 	     all defs created there as varying to not confuse
6284 	     the SCCVN machinery as we're using that even during
6285 	     elimination.  */
6286 	  if (gsi_end_p (prev))
6287 	    prev = gsi_start_bb (b);
6288 	  else
6289 	    gsi_next (&prev);
6290 	  if (gsi_stmt (prev) != gsi_stmt (*gsi))
6291 	    do
6292 	      {
6293 		tree def;
6294 		ssa_op_iter dit;
6295 		FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),
6296 					   dit, SSA_OP_ALL_DEFS)
6297 		    /* As existing DEFs may move between stmts
6298 		       only process new ones.  */
6299 		    if (! has_VN_INFO (def))
6300 		      {
6301 			VN_INFO (def)->valnum = def;
6302 			VN_INFO (def)->visited = true;
6303 		      }
6304 		if (gsi_stmt (prev) == gsi_stmt (*gsi))
6305 		  break;
6306 		gsi_next (&prev);
6307 	      }
6308 	    while (1);
6309 	}
6310       stmt = gsi_stmt (*gsi);
6311       /* In case we folded the stmt away schedule the NOP for removal.  */
6312       if (gimple_nop_p (stmt))
6313 	to_remove.safe_push (stmt);
6314     }
6315 
6316   /* Visit indirect calls and turn them into direct calls if
6317      possible using the devirtualization machinery.  Do this before
6318      checking for required EH/abnormal/noreturn cleanup as devird
6319      may expose more of those.  */
6320   if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
6321     {
6322       tree fn = gimple_call_fn (call_stmt);
6323       if (fn
6324 	  && flag_devirtualize
6325 	  && virtual_method_call_p (fn))
6326 	{
6327 	  tree otr_type = obj_type_ref_class (fn);
6328 	  unsigned HOST_WIDE_INT otr_tok
6329 	      = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));
6330 	  tree instance;
6331 	  ipa_polymorphic_call_context context (current_function_decl,
6332 						fn, stmt, &instance);
6333 	  context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),
6334 				    otr_type, stmt, NULL);
6335 	  bool final;
6336 	  vec <cgraph_node *> targets
6337 	      = possible_polymorphic_call_targets (obj_type_ref_class (fn),
6338 						   otr_tok, context, &final);
6339 	  if (dump_file)
6340 	    dump_possible_polymorphic_call_targets (dump_file,
6341 						    obj_type_ref_class (fn),
6342 						    otr_tok, context);
6343 	  if (final && targets.length () <= 1 && dbg_cnt (devirt))
6344 	    {
6345 	      tree fn;
6346 	      if (targets.length () == 1)
6347 		fn = targets[0]->decl;
6348 	      else
6349 		fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
6350 	      if (dump_enabled_p ())
6351 		{
6352 		  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
6353 				   "converting indirect call to "
6354 				   "function %s\n",
6355 				   lang_hooks.decl_printable_name (fn, 2));
6356 		}
6357 	      gimple_call_set_fndecl (call_stmt, fn);
6358 	      /* If changing the call to __builtin_unreachable
6359 		 or similar noreturn function, adjust gimple_call_fntype
6360 		 too.  */
6361 	      if (gimple_call_noreturn_p (call_stmt)
6362 		  && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
6363 		  && TYPE_ARG_TYPES (TREE_TYPE (fn))
6364 		  && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn)))
6365 		      == void_type_node))
6366 		gimple_call_set_fntype (call_stmt, TREE_TYPE (fn));
6367 	      maybe_remove_unused_call_args (cfun, call_stmt);
6368 	      modified = true;
6369 	    }
6370 	}
6371     }
6372 
6373   if (modified)
6374     {
6375       /* When changing a call into a noreturn call, cfg cleanup
6376 	 is needed to fix up the noreturn call.  */
6377       if (!was_noreturn
6378 	  && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
6379 	to_fixup.safe_push  (stmt);
6380       /* When changing a condition or switch into one we know what
6381 	 edge will be executed, schedule a cfg cleanup.  */
6382       if ((gimple_code (stmt) == GIMPLE_COND
6383 	   && (gimple_cond_true_p (as_a <gcond *> (stmt))
6384 	       || gimple_cond_false_p (as_a <gcond *> (stmt))))
6385 	  || (gimple_code (stmt) == GIMPLE_SWITCH
6386 	      && TREE_CODE (gimple_switch_index
6387 			    (as_a <gswitch *> (stmt))) == INTEGER_CST))
6388 	el_todo |= TODO_cleanup_cfg;
6389       /* If we removed EH side-effects from the statement, clean
6390 	 its EH information.  */
6391       if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
6392 	{
6393 	  bitmap_set_bit (need_eh_cleanup,
6394 			  gimple_bb (stmt)->index);
6395 	  if (dump_file && (dump_flags & TDF_DETAILS))
6396 	    fprintf (dump_file, "  Removed EH side-effects.\n");
6397 	}
6398       /* Likewise for AB side-effects.  */
6399       if (can_make_abnormal_goto
6400 	  && !stmt_can_make_abnormal_goto (stmt))
6401 	{
6402 	  bitmap_set_bit (need_ab_cleanup,
6403 			  gimple_bb (stmt)->index);
6404 	  if (dump_file && (dump_flags & TDF_DETAILS))
6405 	    fprintf (dump_file, "  Removed AB side-effects.\n");
6406 	}
6407       update_stmt (stmt);
6408       /* In case the VDEF on the original stmt was released, value-number
6409          it to the VUSE.  This is to make vuse_ssa_val able to skip
6410 	 released virtual operands.  */
6411       if (vdef && SSA_NAME_IN_FREE_LIST (vdef))
6412 	VN_INFO (vdef)->valnum = vuse;
6413     }
6414 
6415   /* Make new values available - for fully redundant LHS we
6416      continue with the next stmt above and skip this.  */
6417   def_operand_p defp;
6418   FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
6419     eliminate_push_avail (b, DEF_FROM_PTR (defp));
6420 }
6421 
6422 /* Perform elimination for the basic-block B during the domwalk.  */
6423 
6424 edge
before_dom_children(basic_block b)6425 eliminate_dom_walker::before_dom_children (basic_block b)
6426 {
6427   /* Mark new bb.  */
6428   avail_stack.safe_push (NULL_TREE);
6429 
6430   /* Skip unreachable blocks marked unreachable during the SCCVN domwalk.  */
6431   if (!(b->flags & BB_EXECUTABLE))
6432     return NULL;
6433 
6434   vn_context_bb = b;
6435 
6436   for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
6437     {
6438       gphi *phi = gsi.phi ();
6439       tree res = PHI_RESULT (phi);
6440 
6441       if (virtual_operand_p (res))
6442 	{
6443 	  gsi_next (&gsi);
6444 	  continue;
6445 	}
6446 
6447       tree sprime = eliminate_avail (b, res);
6448       if (sprime
6449 	  && sprime != res)
6450 	{
6451 	  if (dump_file && (dump_flags & TDF_DETAILS))
6452 	    {
6453 	      fprintf (dump_file, "Replaced redundant PHI node defining ");
6454 	      print_generic_expr (dump_file, res);
6455 	      fprintf (dump_file, " with ");
6456 	      print_generic_expr (dump_file, sprime);
6457 	      fprintf (dump_file, "\n");
6458 	    }
6459 
6460 	  /* If we inserted this PHI node ourself, it's not an elimination.  */
6461 	  if (! inserted_exprs
6462 	      || ! bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
6463 	    eliminations++;
6464 
6465 	  /* If we will propagate into all uses don't bother to do
6466 	     anything.  */
6467 	  if (may_propagate_copy (res, sprime))
6468 	    {
6469 	      /* Mark the PHI for removal.  */
6470 	      to_remove.safe_push (phi);
6471 	      gsi_next (&gsi);
6472 	      continue;
6473 	    }
6474 
6475 	  remove_phi_node (&gsi, false);
6476 
6477 	  if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
6478 	    sprime = fold_convert (TREE_TYPE (res), sprime);
6479 	  gimple *stmt = gimple_build_assign (res, sprime);
6480 	  gimple_stmt_iterator gsi2 = gsi_after_labels (b);
6481 	  gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
6482 	  continue;
6483 	}
6484 
6485       eliminate_push_avail (b, res);
6486       gsi_next (&gsi);
6487     }
6488 
6489   for (gimple_stmt_iterator gsi = gsi_start_bb (b);
6490        !gsi_end_p (gsi);
6491        gsi_next (&gsi))
6492     eliminate_stmt (b, &gsi);
6493 
6494   /* Replace destination PHI arguments.  */
6495   edge_iterator ei;
6496   edge e;
6497   FOR_EACH_EDGE (e, ei, b->succs)
6498     if (e->flags & EDGE_EXECUTABLE)
6499       for (gphi_iterator gsi = gsi_start_phis (e->dest);
6500 	   !gsi_end_p (gsi);
6501 	   gsi_next (&gsi))
6502 	{
6503 	  gphi *phi = gsi.phi ();
6504 	  use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
6505 	  tree arg = USE_FROM_PTR (use_p);
6506 	  if (TREE_CODE (arg) != SSA_NAME
6507 	      || virtual_operand_p (arg))
6508 	    continue;
6509 	  tree sprime = eliminate_avail (b, arg);
6510 	  if (sprime && may_propagate_copy (arg, sprime))
6511 	    propagate_value (use_p, sprime);
6512 	}
6513 
6514   vn_context_bb = NULL;
6515 
6516   return NULL;
6517 }
6518 
6519 /* Make no longer available leaders no longer available.  */
6520 
6521 void
after_dom_children(basic_block)6522 eliminate_dom_walker::after_dom_children (basic_block)
6523 {
6524   tree entry;
6525   while ((entry = avail_stack.pop ()) != NULL_TREE)
6526     {
6527       tree valnum = VN_INFO (entry)->valnum;
6528       tree old = avail[SSA_NAME_VERSION (valnum)];
6529       if (old == entry)
6530 	avail[SSA_NAME_VERSION (valnum)] = NULL_TREE;
6531       else
6532 	avail[SSA_NAME_VERSION (valnum)] = entry;
6533     }
6534 }
6535 
6536 /* Remove queued stmts and perform delayed cleanups.  */
6537 
6538 unsigned
eliminate_cleanup(bool region_p)6539 eliminate_dom_walker::eliminate_cleanup (bool region_p)
6540 {
6541   statistics_counter_event (cfun, "Eliminated", eliminations);
6542   statistics_counter_event (cfun, "Insertions", insertions);
6543 
6544   /* We cannot remove stmts during BB walk, especially not release SSA
6545      names there as this confuses the VN machinery.  The stmts ending
6546      up in to_remove are either stores or simple copies.
6547      Remove stmts in reverse order to make debug stmt creation possible.  */
6548   while (!to_remove.is_empty ())
6549     {
6550       bool do_release_defs = true;
6551       gimple *stmt = to_remove.pop ();
6552 
6553       /* When we are value-numbering a region we do not require exit PHIs to
6554 	 be present so we have to make sure to deal with uses outside of the
6555 	 region of stmts that we thought are eliminated.
6556 	 ??? Note we may be confused by uses in dead regions we didn't run
6557 	 elimination on.  Rather than checking individual uses we accept
6558 	 dead copies to be generated here (gcc.c-torture/execute/20060905-1.c
6559 	 contains such example).  */
6560       if (region_p)
6561 	{
6562 	  if (gphi *phi = dyn_cast <gphi *> (stmt))
6563 	    {
6564 	      tree lhs = gimple_phi_result (phi);
6565 	      if (!has_zero_uses (lhs))
6566 		{
6567 		  if (dump_file && (dump_flags & TDF_DETAILS))
6568 		    fprintf (dump_file, "Keeping eliminated stmt live "
6569 			     "as copy because of out-of-region uses\n");
6570 		  tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
6571 		  gimple *copy = gimple_build_assign (lhs, sprime);
6572 		  gimple_stmt_iterator gsi
6573 		    = gsi_after_labels (gimple_bb (stmt));
6574 		  gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
6575 		  do_release_defs = false;
6576 		}
6577 	    }
6578 	  else if (tree lhs = gimple_get_lhs (stmt))
6579 	    if (TREE_CODE (lhs) == SSA_NAME
6580 		&& !has_zero_uses (lhs))
6581 	      {
6582 		if (dump_file && (dump_flags & TDF_DETAILS))
6583 		  fprintf (dump_file, "Keeping eliminated stmt live "
6584 			   "as copy because of out-of-region uses\n");
6585 		tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
6586 		gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6587 		if (is_gimple_assign (stmt))
6588 		  {
6589 		    gimple_assign_set_rhs_from_tree (&gsi, sprime);
6590 		    stmt = gsi_stmt (gsi);
6591 		    update_stmt (stmt);
6592 		    if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
6593 		      bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
6594 		    continue;
6595 		  }
6596 		else
6597 		  {
6598 		    gimple *copy = gimple_build_assign (lhs, sprime);
6599 		    gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
6600 		    do_release_defs = false;
6601 		  }
6602 	      }
6603 	}
6604 
6605       if (dump_file && (dump_flags & TDF_DETAILS))
6606 	{
6607 	  fprintf (dump_file, "Removing dead stmt ");
6608 	  print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
6609 	}
6610 
6611       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6612       if (gimple_code (stmt) == GIMPLE_PHI)
6613 	remove_phi_node (&gsi, do_release_defs);
6614       else
6615 	{
6616 	  basic_block bb = gimple_bb (stmt);
6617 	  unlink_stmt_vdef (stmt);
6618 	  if (gsi_remove (&gsi, true))
6619 	    bitmap_set_bit (need_eh_cleanup, bb->index);
6620 	  if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt))
6621 	    bitmap_set_bit (need_ab_cleanup, bb->index);
6622 	  if (do_release_defs)
6623 	    release_defs (stmt);
6624 	}
6625 
6626       /* Removing a stmt may expose a forwarder block.  */
6627       el_todo |= TODO_cleanup_cfg;
6628     }
6629 
6630   /* Fixup stmts that became noreturn calls.  This may require splitting
6631      blocks and thus isn't possible during the dominator walk.  Do this
6632      in reverse order so we don't inadvertedly remove a stmt we want to
6633      fixup by visiting a dominating now noreturn call first.  */
6634   while (!to_fixup.is_empty ())
6635     {
6636       gimple *stmt = to_fixup.pop ();
6637 
6638       if (dump_file && (dump_flags & TDF_DETAILS))
6639 	{
6640 	  fprintf (dump_file, "Fixing up noreturn call ");
6641 	  print_gimple_stmt (dump_file, stmt, 0);
6642 	}
6643 
6644       if (fixup_noreturn_call (stmt))
6645 	el_todo |= TODO_cleanup_cfg;
6646     }
6647 
6648   bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
6649   bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
6650 
6651   if (do_eh_cleanup)
6652     gimple_purge_all_dead_eh_edges (need_eh_cleanup);
6653 
6654   if (do_ab_cleanup)
6655     gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
6656 
6657   if (do_eh_cleanup || do_ab_cleanup)
6658     el_todo |= TODO_cleanup_cfg;
6659 
6660   return el_todo;
6661 }
6662 
6663 /* Eliminate fully redundant computations.  */
6664 
6665 unsigned
eliminate_with_rpo_vn(bitmap inserted_exprs)6666 eliminate_with_rpo_vn (bitmap inserted_exprs)
6667 {
6668   eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);
6669 
6670   walker.walk (cfun->cfg->x_entry_block_ptr);
6671   return walker.eliminate_cleanup ();
6672 }
6673 
6674 static unsigned
6675 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
6676 	   bool iterate, bool eliminate);
6677 
6678 void
run_rpo_vn(vn_lookup_kind kind)6679 run_rpo_vn (vn_lookup_kind kind)
6680 {
6681   default_vn_walk_kind = kind;
6682   do_rpo_vn (cfun, NULL, NULL, true, false);
6683 
6684   /* ???  Prune requirement of these.  */
6685   constant_to_value_id = new hash_table<vn_constant_hasher> (23);
6686   constant_value_ids = BITMAP_ALLOC (NULL);
6687 
6688   /* Initialize the value ids and prune out remaining VN_TOPs
6689      from dead code.  */
6690   tree name;
6691   unsigned i;
6692   FOR_EACH_SSA_NAME (i, name, cfun)
6693     {
6694       vn_ssa_aux_t info = VN_INFO (name);
6695       if (!info->visited
6696 	  || info->valnum == VN_TOP)
6697 	info->valnum = name;
6698       if (info->valnum == name)
6699 	info->value_id = get_next_value_id ();
6700       else if (is_gimple_min_invariant (info->valnum))
6701 	info->value_id = get_or_alloc_constant_value_id (info->valnum);
6702     }
6703 
6704   /* Propagate.  */
6705   FOR_EACH_SSA_NAME (i, name, cfun)
6706     {
6707       vn_ssa_aux_t info = VN_INFO (name);
6708       if (TREE_CODE (info->valnum) == SSA_NAME
6709 	  && info->valnum != name
6710 	  && info->value_id != VN_INFO (info->valnum)->value_id)
6711 	info->value_id = VN_INFO (info->valnum)->value_id;
6712     }
6713 
6714   set_hashtable_value_ids ();
6715 
6716   if (dump_file && (dump_flags & TDF_DETAILS))
6717     {
6718       fprintf (dump_file, "Value numbers:\n");
6719       FOR_EACH_SSA_NAME (i, name, cfun)
6720 	{
6721 	  if (VN_INFO (name)->visited
6722 	      && SSA_VAL (name) != name)
6723 	    {
6724 	      print_generic_expr (dump_file, name);
6725 	      fprintf (dump_file, " = ");
6726 	      print_generic_expr (dump_file, SSA_VAL (name));
6727 	      fprintf (dump_file, " (%04d)\n", VN_INFO (name)->value_id);
6728 	    }
6729 	}
6730     }
6731 }
6732 
6733 /* Free VN associated data structures.  */
6734 
6735 void
free_rpo_vn(void)6736 free_rpo_vn (void)
6737 {
6738   free_vn_table (valid_info);
6739   XDELETE (valid_info);
6740   obstack_free (&vn_tables_obstack, NULL);
6741   obstack_free (&vn_tables_insert_obstack, NULL);
6742 
6743   vn_ssa_aux_iterator_type it;
6744   vn_ssa_aux_t info;
6745   FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it)
6746     if (info->needs_insertion)
6747       release_ssa_name (info->name);
6748   obstack_free (&vn_ssa_aux_obstack, NULL);
6749   delete vn_ssa_aux_hash;
6750 
6751   delete constant_to_value_id;
6752   constant_to_value_id = NULL;
6753   BITMAP_FREE (constant_value_ids);
6754 }
6755 
6756 /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables.  */
6757 
6758 static tree
vn_lookup_simplify_result(gimple_match_op * res_op)6759 vn_lookup_simplify_result (gimple_match_op *res_op)
6760 {
6761   if (!res_op->code.is_tree_code ())
6762     return NULL_TREE;
6763   tree *ops = res_op->ops;
6764   unsigned int length = res_op->num_ops;
6765   if (res_op->code == CONSTRUCTOR
6766       /* ???  We're arriving here with SCCVNs view, decomposed CONSTRUCTOR
6767          and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree.  */
6768       && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR)
6769     {
6770       length = CONSTRUCTOR_NELTS (res_op->ops[0]);
6771       ops = XALLOCAVEC (tree, length);
6772       for (unsigned i = 0; i < length; ++i)
6773 	ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value;
6774     }
6775   vn_nary_op_t vnresult = NULL;
6776   tree res = vn_nary_op_lookup_pieces (length, (tree_code) res_op->code,
6777 				       res_op->type, ops, &vnresult);
6778   /* If this is used from expression simplification make sure to
6779      return an available expression.  */
6780   if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail)
6781     res = rpo_avail->eliminate_avail (vn_context_bb, res);
6782   return res;
6783 }
6784 
6785 /* Return a leader for OPs value that is valid at BB.  */
6786 
6787 tree
eliminate_avail(basic_block bb,tree op)6788 rpo_elim::eliminate_avail (basic_block bb, tree op)
6789 {
6790   bool visited;
6791   tree valnum = SSA_VAL (op, &visited);
6792   /* If we didn't visit OP then it must be defined outside of the
6793      region we process and also dominate it.  So it is available.  */
6794   if (!visited)
6795     return op;
6796   if (TREE_CODE (valnum) == SSA_NAME)
6797     {
6798       if (SSA_NAME_IS_DEFAULT_DEF (valnum))
6799 	return valnum;
6800       vn_avail *av = VN_INFO (valnum)->avail;
6801       if (!av)
6802 	return NULL_TREE;
6803       if (av->location == bb->index)
6804 	/* On tramp3d 90% of the cases are here.  */
6805 	return ssa_name (av->leader);
6806       do
6807 	{
6808 	  basic_block abb = BASIC_BLOCK_FOR_FN (cfun, av->location);
6809 	  /* ???  During elimination we have to use availability at the
6810 	     definition site of a use we try to replace.  This
6811 	     is required to not run into inconsistencies because
6812 	     of dominated_by_p_w_unex behavior and removing a definition
6813 	     while not replacing all uses.
6814 	     ???  We could try to consistently walk dominators
6815 	     ignoring non-executable regions.  The nearest common
6816 	     dominator of bb and abb is where we can stop walking.  We
6817 	     may also be able to "pre-compute" (bits of) the next immediate
6818 	     (non-)dominator during the RPO walk when marking edges as
6819 	     executable.  */
6820 	  if (dominated_by_p_w_unex (bb, abb, true))
6821 	    {
6822 	      tree leader = ssa_name (av->leader);
6823 	      /* Prevent eliminations that break loop-closed SSA.  */
6824 	      if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
6825 		  && ! SSA_NAME_IS_DEFAULT_DEF (leader)
6826 		  && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT
6827 							 (leader))->loop_father,
6828 					      bb))
6829 		return NULL_TREE;
6830 	      if (dump_file && (dump_flags & TDF_DETAILS))
6831 		{
6832 		  print_generic_expr (dump_file, leader);
6833 		  fprintf (dump_file, " is available for ");
6834 		  print_generic_expr (dump_file, valnum);
6835 		  fprintf (dump_file, "\n");
6836 		}
6837 	      /* On tramp3d 99% of the _remaining_ cases succeed at
6838 	         the first enty.  */
6839 	      return leader;
6840 	    }
6841 	  /* ???  Can we somehow skip to the immediate dominator
6842 	     RPO index (bb_to_rpo)?  Again, maybe not worth, on
6843 	     tramp3d the worst number of elements in the vector is 9.  */
6844 	  av = av->next;
6845 	}
6846       while (av);
6847     }
6848   else if (valnum != VN_TOP)
6849     /* valnum is is_gimple_min_invariant.  */
6850     return valnum;
6851   return NULL_TREE;
6852 }
6853 
6854 /* Make LEADER a leader for its value at BB.  */
6855 
6856 void
eliminate_push_avail(basic_block bb,tree leader)6857 rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
6858 {
6859   tree valnum = VN_INFO (leader)->valnum;
6860   if (valnum == VN_TOP
6861       || is_gimple_min_invariant (valnum))
6862     return;
6863   if (dump_file && (dump_flags & TDF_DETAILS))
6864     {
6865       fprintf (dump_file, "Making available beyond BB%d ", bb->index);
6866       print_generic_expr (dump_file, leader);
6867       fprintf (dump_file, " for value ");
6868       print_generic_expr (dump_file, valnum);
6869       fprintf (dump_file, "\n");
6870     }
6871   vn_ssa_aux_t value = VN_INFO (valnum);
6872   vn_avail *av;
6873   if (m_avail_freelist)
6874     {
6875       av = m_avail_freelist;
6876       m_avail_freelist = m_avail_freelist->next;
6877     }
6878   else
6879     av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
6880   av->location = bb->index;
6881   av->leader = SSA_NAME_VERSION (leader);
6882   av->next = value->avail;
6883   value->avail = av;
6884 }
6885 
6886 /* Valueization hook for RPO VN plus required state.  */
6887 
6888 tree
rpo_vn_valueize(tree name)6889 rpo_vn_valueize (tree name)
6890 {
6891   if (TREE_CODE (name) == SSA_NAME)
6892     {
6893       vn_ssa_aux_t val = VN_INFO (name);
6894       if (val)
6895 	{
6896 	  tree tem = val->valnum;
6897 	  if (tem != VN_TOP && tem != name)
6898 	    {
6899 	      if (TREE_CODE (tem) != SSA_NAME)
6900 		return tem;
6901 	      /* For all values we only valueize to an available leader
6902 		 which means we can use SSA name info without restriction.  */
6903 	      tem = rpo_avail->eliminate_avail (vn_context_bb, tem);
6904 	      if (tem)
6905 		return tem;
6906 	    }
6907 	}
6908     }
6909   return name;
6910 }
6911 
6912 /* Insert on PRED_E predicates derived from CODE OPS being true besides the
6913    inverted condition.  */
6914 
6915 static void
insert_related_predicates_on_edge(enum tree_code code,tree * ops,edge pred_e)6916 insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e)
6917 {
6918   switch (code)
6919     {
6920     case LT_EXPR:
6921       /* a < b -> a {!,<}= b */
6922       vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
6923 					   ops, boolean_true_node, 0, pred_e);
6924       vn_nary_op_insert_pieces_predicated (2, LE_EXPR, boolean_type_node,
6925 					   ops, boolean_true_node, 0, pred_e);
6926       /* a < b -> ! a {>,=} b */
6927       vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
6928 					   ops, boolean_false_node, 0, pred_e);
6929       vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
6930 					   ops, boolean_false_node, 0, pred_e);
6931       break;
6932     case GT_EXPR:
6933       /* a > b -> a {!,>}= b */
6934       vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
6935 					   ops, boolean_true_node, 0, pred_e);
6936       vn_nary_op_insert_pieces_predicated (2, GE_EXPR, boolean_type_node,
6937 					   ops, boolean_true_node, 0, pred_e);
6938       /* a > b -> ! a {<,=} b */
6939       vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
6940 					   ops, boolean_false_node, 0, pred_e);
6941       vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
6942 					   ops, boolean_false_node, 0, pred_e);
6943       break;
6944     case EQ_EXPR:
6945       /* a == b -> ! a {<,>} b */
6946       vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
6947 					   ops, boolean_false_node, 0, pred_e);
6948       vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
6949 					   ops, boolean_false_node, 0, pred_e);
6950       break;
6951     case LE_EXPR:
6952     case GE_EXPR:
6953     case NE_EXPR:
6954       /* Nothing besides inverted condition.  */
6955       break;
6956     default:;
6957     }
6958 }
6959 
6960 /* Main stmt worker for RPO VN, process BB.  */
6961 
6962 static unsigned
process_bb(rpo_elim & avail,basic_block bb,bool bb_visited,bool iterate_phis,bool iterate,bool eliminate,bool do_region,bitmap exit_bbs,bool skip_phis)6963 process_bb (rpo_elim &avail, basic_block bb,
6964 	    bool bb_visited, bool iterate_phis, bool iterate, bool eliminate,
6965 	    bool do_region, bitmap exit_bbs, bool skip_phis)
6966 {
6967   unsigned todo = 0;
6968   edge_iterator ei;
6969   edge e;
6970 
6971   vn_context_bb = bb;
6972 
6973   /* If we are in loop-closed SSA preserve this state.  This is
6974      relevant when called on regions from outside of FRE/PRE.  */
6975   bool lc_phi_nodes = false;
6976   if (!skip_phis
6977       && loops_state_satisfies_p (LOOP_CLOSED_SSA))
6978     FOR_EACH_EDGE (e, ei, bb->preds)
6979       if (e->src->loop_father != e->dest->loop_father
6980 	  && flow_loop_nested_p (e->dest->loop_father,
6981 				 e->src->loop_father))
6982 	{
6983 	  lc_phi_nodes = true;
6984 	  break;
6985 	}
6986 
6987   /* When we visit a loop header substitute into loop info.  */
6988   if (!iterate && eliminate && bb->loop_father->header == bb)
6989     {
6990       /* Keep fields in sync with substitute_in_loop_info.  */
6991       if (bb->loop_father->nb_iterations)
6992 	bb->loop_father->nb_iterations
6993 	  = simplify_replace_tree (bb->loop_father->nb_iterations,
6994 				   NULL_TREE, NULL_TREE, &vn_valueize_wrapper);
6995     }
6996 
6997   /* Value-number all defs in the basic-block.  */
6998   if (!skip_phis)
6999     for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
7000 	 gsi_next (&gsi))
7001       {
7002 	gphi *phi = gsi.phi ();
7003 	tree res = PHI_RESULT (phi);
7004 	vn_ssa_aux_t res_info = VN_INFO (res);
7005 	if (!bb_visited)
7006 	  {
7007 	    gcc_assert (!res_info->visited);
7008 	    res_info->valnum = VN_TOP;
7009 	    res_info->visited = true;
7010 	  }
7011 
7012 	/* When not iterating force backedge values to varying.  */
7013 	visit_stmt (phi, !iterate_phis);
7014 	if (virtual_operand_p (res))
7015 	  continue;
7016 
7017 	/* Eliminate */
7018 	/* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness
7019 	   how we handle backedges and availability.
7020 	   And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization.  */
7021 	tree val = res_info->valnum;
7022 	if (res != val && !iterate && eliminate)
7023 	  {
7024 	    if (tree leader = avail.eliminate_avail (bb, res))
7025 	      {
7026 		if (leader != res
7027 		    /* Preserve loop-closed SSA form.  */
7028 		    && (! lc_phi_nodes
7029 			|| is_gimple_min_invariant (leader)))
7030 		  {
7031 		    if (dump_file && (dump_flags & TDF_DETAILS))
7032 		      {
7033 			fprintf (dump_file, "Replaced redundant PHI node "
7034 				 "defining ");
7035 			print_generic_expr (dump_file, res);
7036 			fprintf (dump_file, " with ");
7037 			print_generic_expr (dump_file, leader);
7038 			fprintf (dump_file, "\n");
7039 		      }
7040 		    avail.eliminations++;
7041 
7042 		    if (may_propagate_copy (res, leader))
7043 		      {
7044 			/* Schedule for removal.  */
7045 			avail.to_remove.safe_push (phi);
7046 			continue;
7047 		      }
7048 		    /* ???  Else generate a copy stmt.  */
7049 		  }
7050 	      }
7051 	  }
7052 	/* Only make defs available that not already are.  But make
7053 	   sure loop-closed SSA PHI node defs are picked up for
7054 	   downstream uses.  */
7055 	if (lc_phi_nodes
7056 	    || res == val
7057 	    || ! avail.eliminate_avail (bb, res))
7058 	  avail.eliminate_push_avail (bb, res);
7059       }
7060 
7061   /* For empty BBs mark outgoing edges executable.  For non-empty BBs
7062      we do this when processing the last stmt as we have to do this
7063      before elimination which otherwise forces GIMPLE_CONDs to
7064      if (1 != 0) style when seeing non-executable edges.  */
7065   if (gsi_end_p (gsi_start_bb (bb)))
7066     {
7067       FOR_EACH_EDGE (e, ei, bb->succs)
7068 	{
7069 	  if (!(e->flags & EDGE_EXECUTABLE))
7070 	    {
7071 	      if (dump_file && (dump_flags & TDF_DETAILS))
7072 		fprintf (dump_file,
7073 			 "marking outgoing edge %d -> %d executable\n",
7074 			 e->src->index, e->dest->index);
7075 	      e->flags |= EDGE_EXECUTABLE;
7076 	      e->dest->flags |= BB_EXECUTABLE;
7077 	    }
7078 	  else if (!(e->dest->flags & BB_EXECUTABLE))
7079 	    {
7080 	      if (dump_file && (dump_flags & TDF_DETAILS))
7081 		fprintf (dump_file,
7082 			 "marking destination block %d reachable\n",
7083 			 e->dest->index);
7084 	      e->dest->flags |= BB_EXECUTABLE;
7085 	    }
7086 	}
7087     }
7088   for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
7089        !gsi_end_p (gsi); gsi_next (&gsi))
7090     {
7091       ssa_op_iter i;
7092       tree op;
7093       if (!bb_visited)
7094 	{
7095 	  FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
7096 	    {
7097 	      vn_ssa_aux_t op_info = VN_INFO (op);
7098 	      gcc_assert (!op_info->visited);
7099 	      op_info->valnum = VN_TOP;
7100 	      op_info->visited = true;
7101 	    }
7102 
7103 	  /* We somehow have to deal with uses that are not defined
7104 	     in the processed region.  Forcing unvisited uses to
7105 	     varying here doesn't play well with def-use following during
7106 	     expression simplification, so we deal with this by checking
7107 	     the visited flag in SSA_VAL.  */
7108 	}
7109 
7110       visit_stmt (gsi_stmt (gsi));
7111 
7112       gimple *last = gsi_stmt (gsi);
7113       e = NULL;
7114       switch (gimple_code (last))
7115 	{
7116 	case GIMPLE_SWITCH:
7117 	  e = find_taken_edge (bb, vn_valueize (gimple_switch_index
7118 						(as_a <gswitch *> (last))));
7119 	  break;
7120 	case GIMPLE_COND:
7121 	  {
7122 	    tree lhs = vn_valueize (gimple_cond_lhs (last));
7123 	    tree rhs = vn_valueize (gimple_cond_rhs (last));
7124 	    tree val = gimple_simplify (gimple_cond_code (last),
7125 					boolean_type_node, lhs, rhs,
7126 					NULL, vn_valueize);
7127 	    /* If the condition didn't simplfy see if we have recorded
7128 	       an expression from sofar taken edges.  */
7129 	    if (! val || TREE_CODE (val) != INTEGER_CST)
7130 	      {
7131 		vn_nary_op_t vnresult;
7132 		tree ops[2];
7133 		ops[0] = lhs;
7134 		ops[1] = rhs;
7135 		val = vn_nary_op_lookup_pieces (2, gimple_cond_code (last),
7136 						boolean_type_node, ops,
7137 						&vnresult);
7138 		/* Did we get a predicated value?  */
7139 		if (! val && vnresult && vnresult->predicated_values)
7140 		  {
7141 		    val = vn_nary_op_get_predicated_value (vnresult, bb);
7142 		    if (val && dump_file && (dump_flags & TDF_DETAILS))
7143 		      {
7144 			fprintf (dump_file, "Got predicated value ");
7145 			print_generic_expr (dump_file, val, TDF_NONE);
7146 			fprintf (dump_file, " for ");
7147 			print_gimple_stmt (dump_file, last, TDF_SLIM);
7148 		      }
7149 		  }
7150 	      }
7151 	    if (val)
7152 	      e = find_taken_edge (bb, val);
7153 	    if (! e)
7154 	      {
7155 		/* If we didn't manage to compute the taken edge then
7156 		   push predicated expressions for the condition itself
7157 		   and related conditions to the hashtables.  This allows
7158 		   simplification of redundant conditions which is
7159 		   important as early cleanup.  */
7160 		edge true_e, false_e;
7161 		extract_true_false_edges_from_block (bb, &true_e, &false_e);
7162 		enum tree_code code = gimple_cond_code (last);
7163 		enum tree_code icode
7164 		  = invert_tree_comparison (code, HONOR_NANS (lhs));
7165 		tree ops[2];
7166 		ops[0] = lhs;
7167 		ops[1] = rhs;
7168 		if (do_region
7169 		    && bitmap_bit_p (exit_bbs, true_e->dest->index))
7170 		  true_e = NULL;
7171 		if (do_region
7172 		    && bitmap_bit_p (exit_bbs, false_e->dest->index))
7173 		  false_e = NULL;
7174 		if (true_e)
7175 		  vn_nary_op_insert_pieces_predicated
7176 		    (2, code, boolean_type_node, ops,
7177 		     boolean_true_node, 0, true_e);
7178 		if (false_e)
7179 		  vn_nary_op_insert_pieces_predicated
7180 		    (2, code, boolean_type_node, ops,
7181 		     boolean_false_node, 0, false_e);
7182 		if (icode != ERROR_MARK)
7183 		  {
7184 		    if (true_e)
7185 		      vn_nary_op_insert_pieces_predicated
7186 			(2, icode, boolean_type_node, ops,
7187 			 boolean_false_node, 0, true_e);
7188 		    if (false_e)
7189 		      vn_nary_op_insert_pieces_predicated
7190 			(2, icode, boolean_type_node, ops,
7191 			 boolean_true_node, 0, false_e);
7192 		  }
7193 		/* Relax for non-integers, inverted condition handled
7194 		   above.  */
7195 		if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
7196 		  {
7197 		    if (true_e)
7198 		      insert_related_predicates_on_edge (code, ops, true_e);
7199 		    if (false_e)
7200 		      insert_related_predicates_on_edge (icode, ops, false_e);
7201 		  }
7202 	      }
7203 	    break;
7204 	  }
7205 	case GIMPLE_GOTO:
7206 	  e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last)));
7207 	  break;
7208 	default:
7209 	  e = NULL;
7210 	}
7211       if (e)
7212 	{
7213 	  todo = TODO_cleanup_cfg;
7214 	  if (!(e->flags & EDGE_EXECUTABLE))
7215 	    {
7216 	      if (dump_file && (dump_flags & TDF_DETAILS))
7217 		fprintf (dump_file,
7218 			 "marking known outgoing %sedge %d -> %d executable\n",
7219 			 e->flags & EDGE_DFS_BACK ? "back-" : "",
7220 			 e->src->index, e->dest->index);
7221 	      e->flags |= EDGE_EXECUTABLE;
7222 	      e->dest->flags |= BB_EXECUTABLE;
7223 	    }
7224 	  else if (!(e->dest->flags & BB_EXECUTABLE))
7225 	    {
7226 	      if (dump_file && (dump_flags & TDF_DETAILS))
7227 		fprintf (dump_file,
7228 			 "marking destination block %d reachable\n",
7229 			 e->dest->index);
7230 	      e->dest->flags |= BB_EXECUTABLE;
7231 	    }
7232 	}
7233       else if (gsi_one_before_end_p (gsi))
7234 	{
7235 	  FOR_EACH_EDGE (e, ei, bb->succs)
7236 	    {
7237 	      if (!(e->flags & EDGE_EXECUTABLE))
7238 		{
7239 		  if (dump_file && (dump_flags & TDF_DETAILS))
7240 		    fprintf (dump_file,
7241 			     "marking outgoing edge %d -> %d executable\n",
7242 			     e->src->index, e->dest->index);
7243 		  e->flags |= EDGE_EXECUTABLE;
7244 		  e->dest->flags |= BB_EXECUTABLE;
7245 		}
7246 	      else if (!(e->dest->flags & BB_EXECUTABLE))
7247 		{
7248 		  if (dump_file && (dump_flags & TDF_DETAILS))
7249 		    fprintf (dump_file,
7250 			     "marking destination block %d reachable\n",
7251 			     e->dest->index);
7252 		  e->dest->flags |= BB_EXECUTABLE;
7253 		}
7254 	    }
7255 	}
7256 
7257       /* Eliminate.  That also pushes to avail.  */
7258       if (eliminate && ! iterate)
7259 	avail.eliminate_stmt (bb, &gsi);
7260       else
7261 	/* If not eliminating, make all not already available defs
7262 	   available.  */
7263 	FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF)
7264 	  if (! avail.eliminate_avail (bb, op))
7265 	    avail.eliminate_push_avail (bb, op);
7266     }
7267 
7268   /* Eliminate in destination PHI arguments.  Always substitute in dest
7269      PHIs, even for non-executable edges.  This handles region
7270      exits PHIs.  */
7271   if (!iterate && eliminate)
7272     FOR_EACH_EDGE (e, ei, bb->succs)
7273       for (gphi_iterator gsi = gsi_start_phis (e->dest);
7274 	   !gsi_end_p (gsi); gsi_next (&gsi))
7275 	{
7276 	  gphi *phi = gsi.phi ();
7277 	  use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
7278 	  tree arg = USE_FROM_PTR (use_p);
7279 	  if (TREE_CODE (arg) != SSA_NAME
7280 	      || virtual_operand_p (arg))
7281 	    continue;
7282 	  tree sprime;
7283 	  if (SSA_NAME_IS_DEFAULT_DEF (arg))
7284 	    {
7285 	      sprime = SSA_VAL (arg);
7286 	      gcc_assert (TREE_CODE (sprime) != SSA_NAME
7287 			  || SSA_NAME_IS_DEFAULT_DEF (sprime));
7288 	    }
7289 	  else
7290 	    /* Look for sth available at the definition block of the argument.
7291 	       This avoids inconsistencies between availability there which
7292 	       decides if the stmt can be removed and availability at the
7293 	       use site.  The SSA property ensures that things available
7294 	       at the definition are also available at uses.  */
7295 	    sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)),
7296 					    arg);
7297 	  if (sprime
7298 	      && sprime != arg
7299 	      && may_propagate_copy (arg, sprime))
7300 	    propagate_value (use_p, sprime);
7301 	}
7302 
7303   vn_context_bb = NULL;
7304   return todo;
7305 }
7306 
7307 /* Unwind state per basic-block.  */
7308 
7309 struct unwind_state
7310 {
7311   /* Times this block has been visited.  */
7312   unsigned visited;
7313   /* Whether to handle this as iteration point or whether to treat
7314      incoming backedge PHI values as varying.  */
7315   bool iterate;
7316   /* Maximum RPO index this block is reachable from.  */
7317   int max_rpo;
7318   /* Unwind state.  */
7319   void *ob_top;
7320   vn_reference_t ref_top;
7321   vn_phi_t phi_top;
7322   vn_nary_op_t nary_top;
7323 };
7324 
7325 /* Unwind the RPO VN state for iteration.  */
7326 
7327 static void
do_unwind(unwind_state * to,int rpo_idx,rpo_elim & avail,int * bb_to_rpo)7328 do_unwind (unwind_state *to, int rpo_idx, rpo_elim &avail, int *bb_to_rpo)
7329 {
7330   gcc_assert (to->iterate);
7331   for (; last_inserted_nary != to->nary_top;
7332        last_inserted_nary = last_inserted_nary->next)
7333     {
7334       vn_nary_op_t *slot;
7335       slot = valid_info->nary->find_slot_with_hash
7336 	(last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT);
7337       /* Predication causes the need to restore previous state.  */
7338       if ((*slot)->unwind_to)
7339 	*slot = (*slot)->unwind_to;
7340       else
7341 	valid_info->nary->clear_slot (slot);
7342     }
7343   for (; last_inserted_phi != to->phi_top;
7344        last_inserted_phi = last_inserted_phi->next)
7345     {
7346       vn_phi_t *slot;
7347       slot = valid_info->phis->find_slot_with_hash
7348 	(last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT);
7349       valid_info->phis->clear_slot (slot);
7350     }
7351   for (; last_inserted_ref != to->ref_top;
7352        last_inserted_ref = last_inserted_ref->next)
7353     {
7354       vn_reference_t *slot;
7355       slot = valid_info->references->find_slot_with_hash
7356 	(last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT);
7357       (*slot)->operands.release ();
7358       valid_info->references->clear_slot (slot);
7359     }
7360   obstack_free (&vn_tables_obstack, to->ob_top);
7361 
7362   /* Prune [rpo_idx, ] from avail.  */
7363   /* ???  This is O(number-of-values-in-region) which is
7364      O(region-size) rather than O(iteration-piece).  */
7365   for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
7366        i != vn_ssa_aux_hash->end (); ++i)
7367     {
7368       while ((*i)->avail)
7369 	{
7370 	  if (bb_to_rpo[(*i)->avail->location] < rpo_idx)
7371 	    break;
7372 	  vn_avail *av = (*i)->avail;
7373 	  (*i)->avail = (*i)->avail->next;
7374 	  av->next = avail.m_avail_freelist;
7375 	  avail.m_avail_freelist = av;
7376 	}
7377     }
7378 }
7379 
7380 /* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
7381    If ITERATE is true then treat backedges optimistically as not
7382    executed and iterate.  If ELIMINATE is true then perform
7383    elimination, otherwise leave that to the caller.  */
7384 
7385 static unsigned
do_rpo_vn(function * fn,edge entry,bitmap exit_bbs,bool iterate,bool eliminate)7386 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
7387 	   bool iterate, bool eliminate)
7388 {
7389   unsigned todo = 0;
7390 
7391   /* We currently do not support region-based iteration when
7392      elimination is requested.  */
7393   gcc_assert (!entry || !iterate || !eliminate);
7394   /* When iterating we need loop info up-to-date.  */
7395   gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP));
7396 
7397   bool do_region = entry != NULL;
7398   if (!do_region)
7399     {
7400       entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn));
7401       exit_bbs = BITMAP_ALLOC (NULL);
7402       bitmap_set_bit (exit_bbs, EXIT_BLOCK);
7403     }
7404 
7405   /* Clear EDGE_DFS_BACK on "all" entry edges, RPO order compute will
7406      re-mark those that are contained in the region.  */
7407   edge_iterator ei;
7408   edge e;
7409   FOR_EACH_EDGE (e, ei, entry->dest->preds)
7410     e->flags &= ~EDGE_DFS_BACK;
7411 
7412   int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS);
7413   auto_vec<std::pair<int, int> > toplevel_scc_extents;
7414   int n = rev_post_order_and_mark_dfs_back_seme
7415     (fn, entry, exit_bbs, true, rpo, !iterate ? &toplevel_scc_extents : NULL);
7416 
7417   if (!do_region)
7418     BITMAP_FREE (exit_bbs);
7419 
7420   /* If there are any non-DFS_BACK edges into entry->dest skip
7421      processing PHI nodes for that block.  This supports
7422      value-numbering loop bodies w/o the actual loop.  */
7423   FOR_EACH_EDGE (e, ei, entry->dest->preds)
7424     if (e != entry
7425 	&& !(e->flags & EDGE_DFS_BACK))
7426       break;
7427   bool skip_entry_phis = e != NULL;
7428   if (skip_entry_phis && dump_file && (dump_flags & TDF_DETAILS))
7429     fprintf (dump_file, "Region does not contain all edges into "
7430 	     "the entry block, skipping its PHIs.\n");
7431 
7432   int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
7433   for (int i = 0; i < n; ++i)
7434     bb_to_rpo[rpo[i]] = i;
7435 
7436   unwind_state *rpo_state = XNEWVEC (unwind_state, n);
7437 
7438   rpo_elim avail (entry->dest);
7439   rpo_avail = &avail;
7440 
7441   /* Verify we have no extra entries into the region.  */
7442   if (flag_checking && do_region)
7443     {
7444       auto_bb_flag bb_in_region (fn);
7445       for (int i = 0; i < n; ++i)
7446 	{
7447 	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
7448 	  bb->flags |= bb_in_region;
7449 	}
7450       /* We can't merge the first two loops because we cannot rely
7451          on EDGE_DFS_BACK for edges not within the region.  But if
7452 	 we decide to always have the bb_in_region flag we can
7453 	 do the checking during the RPO walk itself (but then it's
7454 	 also easy to handle MEME conservatively).  */
7455       for (int i = 0; i < n; ++i)
7456 	{
7457 	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
7458 	  edge e;
7459 	  edge_iterator ei;
7460 	  FOR_EACH_EDGE (e, ei, bb->preds)
7461 	    gcc_assert (e == entry
7462 			|| (skip_entry_phis && bb == entry->dest)
7463 			|| (e->src->flags & bb_in_region));
7464 	}
7465       for (int i = 0; i < n; ++i)
7466 	{
7467 	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
7468 	  bb->flags &= ~bb_in_region;
7469 	}
7470     }
7471 
7472   /* Create the VN state.  For the initial size of the various hashtables
7473      use a heuristic based on region size and number of SSA names.  */
7474   unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names)
7475 			  / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS));
7476   VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
7477   next_value_id = 1;
7478 
7479   vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2);
7480   gcc_obstack_init (&vn_ssa_aux_obstack);
7481 
7482   gcc_obstack_init (&vn_tables_obstack);
7483   gcc_obstack_init (&vn_tables_insert_obstack);
7484   valid_info = XCNEW (struct vn_tables_s);
7485   allocate_vn_table (valid_info, region_size);
7486   last_inserted_ref = NULL;
7487   last_inserted_phi = NULL;
7488   last_inserted_nary = NULL;
7489 
7490   vn_valueize = rpo_vn_valueize;
7491 
7492   /* Initialize the unwind state and edge/BB executable state.  */
7493   unsigned curr_scc = 0;
7494   for (int i = 0; i < n; ++i)
7495     {
7496       basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
7497       rpo_state[i].visited = 0;
7498       rpo_state[i].max_rpo = i;
7499       if (!iterate && curr_scc < toplevel_scc_extents.length ())
7500 	{
7501 	  if (i >= toplevel_scc_extents[curr_scc].first
7502 	      && i <= toplevel_scc_extents[curr_scc].second)
7503 	    rpo_state[i].max_rpo = toplevel_scc_extents[curr_scc].second;
7504 	  if (i == toplevel_scc_extents[curr_scc].second)
7505 	    curr_scc++;
7506 	}
7507       bb->flags &= ~BB_EXECUTABLE;
7508       bool has_backedges = false;
7509       edge e;
7510       edge_iterator ei;
7511       FOR_EACH_EDGE (e, ei, bb->preds)
7512 	{
7513 	  if (e->flags & EDGE_DFS_BACK)
7514 	    has_backedges = true;
7515 	  e->flags &= ~EDGE_EXECUTABLE;
7516 	  if (iterate || e == entry || (skip_entry_phis && bb == entry->dest))
7517 	    continue;
7518 	}
7519       rpo_state[i].iterate = iterate && has_backedges;
7520     }
7521   entry->flags |= EDGE_EXECUTABLE;
7522   entry->dest->flags |= BB_EXECUTABLE;
7523 
7524   /* As heuristic to improve compile-time we handle only the N innermost
7525      loops and the outermost one optimistically.  */
7526   if (iterate)
7527     {
7528       loop_p loop;
7529       unsigned max_depth = param_rpo_vn_max_loop_depth;
7530       FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
7531 	if (loop_depth (loop) > max_depth)
7532 	  for (unsigned i = 2;
7533 	       i < loop_depth (loop) - max_depth; ++i)
7534 	    {
7535 	      basic_block header = superloop_at_depth (loop, i)->header;
7536 	      bool non_latch_backedge = false;
7537 	      edge e;
7538 	      edge_iterator ei;
7539 	      FOR_EACH_EDGE (e, ei, header->preds)
7540 		if (e->flags & EDGE_DFS_BACK)
7541 		  {
7542 		    /* There can be a non-latch backedge into the header
7543 		       which is part of an outer irreducible region.  We
7544 		       cannot avoid iterating this block then.  */
7545 		    if (!dominated_by_p (CDI_DOMINATORS,
7546 					 e->src, e->dest))
7547 		      {
7548 			if (dump_file && (dump_flags & TDF_DETAILS))
7549 			  fprintf (dump_file, "non-latch backedge %d -> %d "
7550 				   "forces iteration of loop %d\n",
7551 				   e->src->index, e->dest->index, loop->num);
7552 			non_latch_backedge = true;
7553 		      }
7554 		    else
7555 		      e->flags |= EDGE_EXECUTABLE;
7556 		  }
7557 	      rpo_state[bb_to_rpo[header->index]].iterate = non_latch_backedge;
7558 	    }
7559     }
7560 
7561   uint64_t nblk = 0;
7562   int idx = 0;
7563   if (iterate)
7564     /* Go and process all blocks, iterating as necessary.  */
7565     do
7566       {
7567 	basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
7568 
7569 	/* If the block has incoming backedges remember unwind state.  This
7570 	   is required even for non-executable blocks since in irreducible
7571 	   regions we might reach them via the backedge and re-start iterating
7572 	   from there.
7573 	   Note we can individually mark blocks with incoming backedges to
7574 	   not iterate where we then handle PHIs conservatively.  We do that
7575 	   heuristically to reduce compile-time for degenerate cases.  */
7576 	if (rpo_state[idx].iterate)
7577 	  {
7578 	    rpo_state[idx].ob_top = obstack_alloc (&vn_tables_obstack, 0);
7579 	    rpo_state[idx].ref_top = last_inserted_ref;
7580 	    rpo_state[idx].phi_top = last_inserted_phi;
7581 	    rpo_state[idx].nary_top = last_inserted_nary;
7582 	  }
7583 
7584 	if (!(bb->flags & BB_EXECUTABLE))
7585 	  {
7586 	    if (dump_file && (dump_flags & TDF_DETAILS))
7587 	      fprintf (dump_file, "Block %d: BB%d found not executable\n",
7588 		       idx, bb->index);
7589 	    idx++;
7590 	    continue;
7591 	  }
7592 
7593 	if (dump_file && (dump_flags & TDF_DETAILS))
7594 	  fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
7595 	nblk++;
7596 	todo |= process_bb (avail, bb,
7597 			    rpo_state[idx].visited != 0,
7598 			    rpo_state[idx].iterate,
7599 			    iterate, eliminate, do_region, exit_bbs, false);
7600 	rpo_state[idx].visited++;
7601 
7602 	/* Verify if changed values flow over executable outgoing backedges
7603 	   and those change destination PHI values (that's the thing we
7604 	   can easily verify).  Reduce over all such edges to the farthest
7605 	   away PHI.  */
7606 	int iterate_to = -1;
7607 	edge_iterator ei;
7608 	edge e;
7609 	FOR_EACH_EDGE (e, ei, bb->succs)
7610 	  if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE))
7611 	      == (EDGE_DFS_BACK|EDGE_EXECUTABLE)
7612 	      && rpo_state[bb_to_rpo[e->dest->index]].iterate)
7613 	    {
7614 	      int destidx = bb_to_rpo[e->dest->index];
7615 	      if (!rpo_state[destidx].visited)
7616 		{
7617 		  if (dump_file && (dump_flags & TDF_DETAILS))
7618 		    fprintf (dump_file, "Unvisited destination %d\n",
7619 			     e->dest->index);
7620 		  if (iterate_to == -1 || destidx < iterate_to)
7621 		    iterate_to = destidx;
7622 		  continue;
7623 		}
7624 	      if (dump_file && (dump_flags & TDF_DETAILS))
7625 		fprintf (dump_file, "Looking for changed values of backedge"
7626 			 " %d->%d destination PHIs\n",
7627 			 e->src->index, e->dest->index);
7628 	      vn_context_bb = e->dest;
7629 	      gphi_iterator gsi;
7630 	      for (gsi = gsi_start_phis (e->dest);
7631 		   !gsi_end_p (gsi); gsi_next (&gsi))
7632 		{
7633 		  bool inserted = false;
7634 		  /* While we'd ideally just iterate on value changes
7635 		     we CSE PHIs and do that even across basic-block
7636 		     boundaries.  So even hashtable state changes can
7637 		     be important (which is roughly equivalent to
7638 		     PHI argument value changes).  To not excessively
7639 		     iterate because of that we track whether a PHI
7640 		     was CSEd to with GF_PLF_1.  */
7641 		  bool phival_changed;
7642 		  if ((phival_changed = visit_phi (gsi.phi (),
7643 						   &inserted, false))
7644 		      || (inserted && gimple_plf (gsi.phi (), GF_PLF_1)))
7645 		    {
7646 		      if (!phival_changed
7647 			  && dump_file && (dump_flags & TDF_DETAILS))
7648 			fprintf (dump_file, "PHI was CSEd and hashtable "
7649 				 "state (changed)\n");
7650 		      if (iterate_to == -1 || destidx < iterate_to)
7651 			iterate_to = destidx;
7652 		      break;
7653 		    }
7654 		}
7655 	      vn_context_bb = NULL;
7656 	    }
7657 	if (iterate_to != -1)
7658 	  {
7659 	    do_unwind (&rpo_state[iterate_to], iterate_to, avail, bb_to_rpo);
7660 	    idx = iterate_to;
7661 	    if (dump_file && (dump_flags & TDF_DETAILS))
7662 	      fprintf (dump_file, "Iterating to %d BB%d\n",
7663 		       iterate_to, rpo[iterate_to]);
7664 	    continue;
7665 	  }
7666 
7667 	idx++;
7668       }
7669     while (idx < n);
7670 
7671   else /* !iterate */
7672     {
7673       /* Process all blocks greedily with a worklist that enforces RPO
7674          processing of reachable blocks.  */
7675       auto_bitmap worklist;
7676       bitmap_set_bit (worklist, 0);
7677       while (!bitmap_empty_p (worklist))
7678 	{
7679 	  int idx = bitmap_first_set_bit (worklist);
7680 	  bitmap_clear_bit (worklist, idx);
7681 	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
7682 	  gcc_assert ((bb->flags & BB_EXECUTABLE)
7683 		      && !rpo_state[idx].visited);
7684 
7685 	  if (dump_file && (dump_flags & TDF_DETAILS))
7686 	    fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
7687 
7688 	  /* When we run into predecessor edges where we cannot trust its
7689 	     executable state mark them executable so PHI processing will
7690 	     be conservative.
7691 	     ???  Do we need to force arguments flowing over that edge
7692 	     to be varying or will they even always be?  */
7693 	  edge_iterator ei;
7694 	  edge e;
7695 	  FOR_EACH_EDGE (e, ei, bb->preds)
7696 	    if (!(e->flags & EDGE_EXECUTABLE)
7697 		&& (bb == entry->dest
7698 		    || (!rpo_state[bb_to_rpo[e->src->index]].visited
7699 			&& (rpo_state[bb_to_rpo[e->src->index]].max_rpo
7700 			    >= (int)idx))))
7701 	      {
7702 		if (dump_file && (dump_flags & TDF_DETAILS))
7703 		  fprintf (dump_file, "Cannot trust state of predecessor "
7704 			   "edge %d -> %d, marking executable\n",
7705 			   e->src->index, e->dest->index);
7706 		e->flags |= EDGE_EXECUTABLE;
7707 	      }
7708 
7709 	  nblk++;
7710 	  todo |= process_bb (avail, bb, false, false, false, eliminate,
7711 			      do_region, exit_bbs,
7712 			      skip_entry_phis && bb == entry->dest);
7713 	  rpo_state[idx].visited++;
7714 
7715 	  FOR_EACH_EDGE (e, ei, bb->succs)
7716 	    if ((e->flags & EDGE_EXECUTABLE)
7717 		&& e->dest->index != EXIT_BLOCK
7718 		&& (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index))
7719 		&& !rpo_state[bb_to_rpo[e->dest->index]].visited)
7720 	      bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]);
7721 	}
7722     }
7723 
7724   /* If statistics or dump file active.  */
7725   int nex = 0;
7726   unsigned max_visited = 1;
7727   for (int i = 0; i < n; ++i)
7728     {
7729       basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
7730       if (bb->flags & BB_EXECUTABLE)
7731 	nex++;
7732       statistics_histogram_event (cfun, "RPO block visited times",
7733 				  rpo_state[i].visited);
7734       if (rpo_state[i].visited > max_visited)
7735 	max_visited = rpo_state[i].visited;
7736     }
7737   unsigned nvalues = 0, navail = 0;
7738   for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
7739        i != vn_ssa_aux_hash->end (); ++i)
7740     {
7741       nvalues++;
7742       vn_avail *av = (*i)->avail;
7743       while (av)
7744 	{
7745 	  navail++;
7746 	  av = av->next;
7747 	}
7748     }
7749   statistics_counter_event (cfun, "RPO blocks", n);
7750   statistics_counter_event (cfun, "RPO blocks visited", nblk);
7751   statistics_counter_event (cfun, "RPO blocks executable", nex);
7752   statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex);
7753   statistics_histogram_event (cfun, "RPO num values", nvalues);
7754   statistics_histogram_event (cfun, "RPO num avail", navail);
7755   statistics_histogram_event (cfun, "RPO num lattice",
7756 			      vn_ssa_aux_hash->elements ());
7757   if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS)))
7758     {
7759       fprintf (dump_file, "RPO iteration over %d blocks visited %" PRIu64
7760 	       " blocks in total discovering %d executable blocks iterating "
7761 	       "%d.%d times, a block was visited max. %u times\n",
7762 	       n, nblk, nex,
7763 	       (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10),
7764 	       max_visited);
7765       fprintf (dump_file, "RPO tracked %d values available at %d locations "
7766 	       "and %" PRIu64 " lattice elements\n",
7767 	       nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ());
7768     }
7769 
7770   if (eliminate)
7771     {
7772       /* When !iterate we already performed elimination during the RPO
7773          walk.  */
7774       if (iterate)
7775 	{
7776 	  /* Elimination for region-based VN needs to be done within the
7777 	     RPO walk.  */
7778 	  gcc_assert (! do_region);
7779 	  /* Note we can't use avail.walk here because that gets confused
7780 	     by the existing availability and it will be less efficient
7781 	     as well.  */
7782 	  todo |= eliminate_with_rpo_vn (NULL);
7783 	}
7784       else
7785 	todo |= avail.eliminate_cleanup (do_region);
7786     }
7787 
7788   vn_valueize = NULL;
7789   rpo_avail = NULL;
7790 
7791   XDELETEVEC (bb_to_rpo);
7792   XDELETEVEC (rpo);
7793   XDELETEVEC (rpo_state);
7794 
7795   return todo;
7796 }
7797 
7798 /* Region-based entry for RPO VN.  Performs value-numbering and elimination
7799    on the SEME region specified by ENTRY and EXIT_BBS.  If ENTRY is not
7800    the only edge into the region at ENTRY->dest PHI nodes in ENTRY->dest
7801    are not considered.  */
7802 
7803 unsigned
do_rpo_vn(function * fn,edge entry,bitmap exit_bbs)7804 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs)
7805 {
7806   default_vn_walk_kind = VN_WALKREWRITE;
7807   unsigned todo = do_rpo_vn (fn, entry, exit_bbs, false, true);
7808   free_rpo_vn ();
7809   return todo;
7810 }
7811 
7812 
7813 namespace {
7814 
7815 const pass_data pass_data_fre =
7816 {
7817   GIMPLE_PASS, /* type */
7818   "fre", /* name */
7819   OPTGROUP_NONE, /* optinfo_flags */
7820   TV_TREE_FRE, /* tv_id */
7821   ( PROP_cfg | PROP_ssa ), /* properties_required */
7822   0, /* properties_provided */
7823   0, /* properties_destroyed */
7824   0, /* todo_flags_start */
7825   0, /* todo_flags_finish */
7826 };
7827 
7828 class pass_fre : public gimple_opt_pass
7829 {
7830 public:
pass_fre(gcc::context * ctxt)7831   pass_fre (gcc::context *ctxt)
7832     : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
7833   {}
7834 
7835   /* opt_pass methods: */
clone()7836   opt_pass * clone () { return new pass_fre (m_ctxt); }
set_pass_param(unsigned int n,bool param)7837   void set_pass_param (unsigned int n, bool param)
7838     {
7839       gcc_assert (n == 0);
7840       may_iterate = param;
7841     }
gate(function *)7842   virtual bool gate (function *)
7843     {
7844       return flag_tree_fre != 0 && (may_iterate || optimize > 1);
7845     }
7846   virtual unsigned int execute (function *);
7847 
7848 private:
7849   bool may_iterate;
7850 }; // class pass_fre
7851 
7852 unsigned int
execute(function * fun)7853 pass_fre::execute (function *fun)
7854 {
7855   unsigned todo = 0;
7856 
7857   /* At -O[1g] use the cheap non-iterating mode.  */
7858   bool iterate_p = may_iterate && (optimize > 1);
7859   calculate_dominance_info (CDI_DOMINATORS);
7860   if (iterate_p)
7861     loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
7862 
7863   default_vn_walk_kind = VN_WALKREWRITE;
7864   todo = do_rpo_vn (fun, NULL, NULL, iterate_p, true);
7865   free_rpo_vn ();
7866 
7867   if (iterate_p)
7868     loop_optimizer_finalize ();
7869 
7870   /* For late FRE after IVOPTs and unrolling, see if we can
7871      remove some TREE_ADDRESSABLE and rewrite stuff into SSA.  */
7872   if (!may_iterate)
7873     todo |= TODO_update_address_taken;
7874 
7875   return todo;
7876 }
7877 
7878 } // anon namespace
7879 
7880 gimple_opt_pass *
make_pass_fre(gcc::context * ctxt)7881 make_pass_fre (gcc::context *ctxt)
7882 {
7883   return new pass_fre (ctxt);
7884 }
7885 
7886 #undef BB_EXECUTABLE
7887