LCOV - code coverage report
Current view: top level - gcc - tree-ssa-sccvn.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.7 % 4699 4498
Test Date: 2026-10-17 16:30:31 Functions: 97.7 % 132 129
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.