xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-dfa.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Data flow functions for trees.
2*8feb0f0bSmrg    Copyright (C) 2001-2020 Free Software Foundation, Inc.
31debfc3dSmrg    Contributed by Diego Novillo <dnovillo@redhat.com>
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify
81debfc3dSmrg it under the terms of the GNU General Public License as published by
91debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg any later version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful,
131debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
141debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151debfc3dSmrg GNU General Public License for more details.
161debfc3dSmrg 
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3.  If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>.  */
201debfc3dSmrg 
211debfc3dSmrg #include "config.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "backend.h"
251debfc3dSmrg #include "rtl.h"
261debfc3dSmrg #include "tree.h"
271debfc3dSmrg #include "gimple.h"
281debfc3dSmrg #include "tree-pass.h"
291debfc3dSmrg #include "ssa.h"
301debfc3dSmrg #include "tree-pretty-print.h"
311debfc3dSmrg #include "fold-const.h"
321debfc3dSmrg #include "stor-layout.h"
331debfc3dSmrg #include "langhooks.h"
341debfc3dSmrg #include "gimple-iterator.h"
351debfc3dSmrg #include "gimple-walk.h"
361debfc3dSmrg #include "tree-dfa.h"
371debfc3dSmrg 
381debfc3dSmrg /* Build and maintain data flow information for trees.  */
391debfc3dSmrg 
401debfc3dSmrg /* Counters used to display DFA and SSA statistics.  */
411debfc3dSmrg struct dfa_stats_d
421debfc3dSmrg {
431debfc3dSmrg   long num_defs;
441debfc3dSmrg   long num_uses;
451debfc3dSmrg   long num_phis;
461debfc3dSmrg   long num_phi_args;
471debfc3dSmrg   size_t max_num_phi_args;
481debfc3dSmrg   long num_vdefs;
491debfc3dSmrg   long num_vuses;
501debfc3dSmrg };
511debfc3dSmrg 
521debfc3dSmrg 
531debfc3dSmrg /* Local functions.  */
541debfc3dSmrg static void collect_dfa_stats (struct dfa_stats_d *);
551debfc3dSmrg 
561debfc3dSmrg 
571debfc3dSmrg /*---------------------------------------------------------------------------
581debfc3dSmrg 			Dataflow analysis (DFA) routines
591debfc3dSmrg ---------------------------------------------------------------------------*/
601debfc3dSmrg 
611debfc3dSmrg /* Renumber all of the gimple stmt uids.  */
621debfc3dSmrg 
631debfc3dSmrg void
renumber_gimple_stmt_uids(struct function * fun)64c0a68be4Smrg renumber_gimple_stmt_uids (struct function *fun)
651debfc3dSmrg {
661debfc3dSmrg   basic_block bb;
671debfc3dSmrg 
68c0a68be4Smrg   set_gimple_stmt_max_uid (fun, 0);
69c0a68be4Smrg   FOR_ALL_BB_FN (bb, fun)
701debfc3dSmrg     {
711debfc3dSmrg       gimple_stmt_iterator bsi;
721debfc3dSmrg       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
731debfc3dSmrg 	{
741debfc3dSmrg 	  gimple *stmt = gsi_stmt (bsi);
75c0a68be4Smrg 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (fun));
761debfc3dSmrg 	}
771debfc3dSmrg       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
781debfc3dSmrg 	{
791debfc3dSmrg 	  gimple *stmt = gsi_stmt (bsi);
80c0a68be4Smrg 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (fun));
811debfc3dSmrg 	}
821debfc3dSmrg     }
831debfc3dSmrg }
841debfc3dSmrg 
851debfc3dSmrg /* Like renumber_gimple_stmt_uids, but only do work on the basic blocks
861debfc3dSmrg    in BLOCKS, of which there are N_BLOCKS.  Also renumbers PHIs.  */
871debfc3dSmrg 
881debfc3dSmrg void
renumber_gimple_stmt_uids_in_blocks(basic_block * blocks,int n_blocks)891debfc3dSmrg renumber_gimple_stmt_uids_in_blocks (basic_block *blocks, int n_blocks)
901debfc3dSmrg {
911debfc3dSmrg   int i;
921debfc3dSmrg 
931debfc3dSmrg   set_gimple_stmt_max_uid (cfun, 0);
941debfc3dSmrg   for (i = 0; i < n_blocks; i++)
951debfc3dSmrg     {
961debfc3dSmrg       basic_block bb = blocks[i];
971debfc3dSmrg       gimple_stmt_iterator bsi;
981debfc3dSmrg       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
991debfc3dSmrg 	{
1001debfc3dSmrg 	  gimple *stmt = gsi_stmt (bsi);
1011debfc3dSmrg 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
1021debfc3dSmrg 	}
1031debfc3dSmrg       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
1041debfc3dSmrg 	{
1051debfc3dSmrg 	  gimple *stmt = gsi_stmt (bsi);
1061debfc3dSmrg 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
1071debfc3dSmrg 	}
1081debfc3dSmrg     }
1091debfc3dSmrg }
1101debfc3dSmrg 
1111debfc3dSmrg 
1121debfc3dSmrg 
1131debfc3dSmrg /*---------------------------------------------------------------------------
1141debfc3dSmrg 			      Debugging functions
1151debfc3dSmrg ---------------------------------------------------------------------------*/
1161debfc3dSmrg 
1171debfc3dSmrg /* Dump variable VAR and its may-aliases to FILE.  */
1181debfc3dSmrg 
1191debfc3dSmrg void
dump_variable(FILE * file,tree var)1201debfc3dSmrg dump_variable (FILE *file, tree var)
1211debfc3dSmrg {
1221debfc3dSmrg   if (TREE_CODE (var) == SSA_NAME)
1231debfc3dSmrg     {
1241debfc3dSmrg       if (POINTER_TYPE_P (TREE_TYPE (var)))
1251debfc3dSmrg 	dump_points_to_info_for (file, var);
1261debfc3dSmrg       var = SSA_NAME_VAR (var);
1271debfc3dSmrg     }
1281debfc3dSmrg 
1291debfc3dSmrg   if (var == NULL_TREE)
1301debfc3dSmrg     {
1311debfc3dSmrg       fprintf (file, "<nil>");
1321debfc3dSmrg       return;
1331debfc3dSmrg     }
1341debfc3dSmrg 
1351debfc3dSmrg   print_generic_expr (file, var, dump_flags);
1361debfc3dSmrg 
1371debfc3dSmrg   fprintf (file, ", UID D.%u", (unsigned) DECL_UID (var));
1381debfc3dSmrg   if (DECL_PT_UID (var) != DECL_UID (var))
1391debfc3dSmrg     fprintf (file, ", PT-UID D.%u", (unsigned) DECL_PT_UID (var));
1401debfc3dSmrg 
1411debfc3dSmrg   fprintf (file, ", ");
1421debfc3dSmrg   print_generic_expr (file, TREE_TYPE (var), dump_flags);
1431debfc3dSmrg 
1441debfc3dSmrg   if (TREE_ADDRESSABLE (var))
1451debfc3dSmrg     fprintf (file, ", is addressable");
1461debfc3dSmrg 
1471debfc3dSmrg   if (is_global_var (var))
1481debfc3dSmrg     fprintf (file, ", is global");
1491debfc3dSmrg 
1501debfc3dSmrg   if (TREE_THIS_VOLATILE (var))
1511debfc3dSmrg     fprintf (file, ", is volatile");
1521debfc3dSmrg 
1531debfc3dSmrg   if (cfun && ssa_default_def (cfun, var))
1541debfc3dSmrg     {
1551debfc3dSmrg       fprintf (file, ", default def: ");
1561debfc3dSmrg       print_generic_expr (file, ssa_default_def (cfun, var), dump_flags);
1571debfc3dSmrg     }
1581debfc3dSmrg 
1591debfc3dSmrg   if (DECL_INITIAL (var))
1601debfc3dSmrg     {
1611debfc3dSmrg       fprintf (file, ", initial: ");
1621debfc3dSmrg       print_generic_expr (file, DECL_INITIAL (var), dump_flags);
1631debfc3dSmrg     }
1641debfc3dSmrg 
1651debfc3dSmrg   fprintf (file, "\n");
1661debfc3dSmrg }
1671debfc3dSmrg 
1681debfc3dSmrg 
1691debfc3dSmrg /* Dump variable VAR and its may-aliases to stderr.  */
1701debfc3dSmrg 
1711debfc3dSmrg DEBUG_FUNCTION void
debug_variable(tree var)1721debfc3dSmrg debug_variable (tree var)
1731debfc3dSmrg {
1741debfc3dSmrg   dump_variable (stderr, var);
1751debfc3dSmrg }
1761debfc3dSmrg 
1771debfc3dSmrg 
1781debfc3dSmrg /* Dump various DFA statistics to FILE.  */
1791debfc3dSmrg 
1801debfc3dSmrg void
dump_dfa_stats(FILE * file)1811debfc3dSmrg dump_dfa_stats (FILE *file)
1821debfc3dSmrg {
1831debfc3dSmrg   struct dfa_stats_d dfa_stats;
1841debfc3dSmrg 
1851debfc3dSmrg   unsigned long size, total = 0;
1861debfc3dSmrg   const char * const fmt_str   = "%-30s%-13s%12s\n";
187c0a68be4Smrg   const char * const fmt_str_1 = "%-30s%13lu" PRsa (11) "\n";
188c0a68be4Smrg   const char * const fmt_str_3 = "%-43s" PRsa (11) "\n";
1891debfc3dSmrg   const char *funcname
1901debfc3dSmrg     = lang_hooks.decl_printable_name (current_function_decl, 2);
1911debfc3dSmrg 
1921debfc3dSmrg   collect_dfa_stats (&dfa_stats);
1931debfc3dSmrg 
1941debfc3dSmrg   fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
1951debfc3dSmrg 
1961debfc3dSmrg   fprintf (file, "---------------------------------------------------------\n");
1971debfc3dSmrg   fprintf (file, fmt_str, "", "  Number of  ", "Memory");
1981debfc3dSmrg   fprintf (file, fmt_str, "", "  instances  ", "used ");
1991debfc3dSmrg   fprintf (file, "---------------------------------------------------------\n");
2001debfc3dSmrg 
2011debfc3dSmrg   size = dfa_stats.num_uses * sizeof (tree *);
2021debfc3dSmrg   total += size;
2031debfc3dSmrg   fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
204c0a68be4Smrg 	   SIZE_AMOUNT (size));
2051debfc3dSmrg 
2061debfc3dSmrg   size = dfa_stats.num_defs * sizeof (tree *);
2071debfc3dSmrg   total += size;
2081debfc3dSmrg   fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
209c0a68be4Smrg 	   SIZE_AMOUNT (size));
2101debfc3dSmrg 
2111debfc3dSmrg   size = dfa_stats.num_vuses * sizeof (tree *);
2121debfc3dSmrg   total += size;
2131debfc3dSmrg   fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
214c0a68be4Smrg 	   SIZE_AMOUNT (size));
2151debfc3dSmrg 
2161debfc3dSmrg   size = dfa_stats.num_vdefs * sizeof (tree *);
2171debfc3dSmrg   total += size;
2181debfc3dSmrg   fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
219c0a68be4Smrg 	   SIZE_AMOUNT (size));
2201debfc3dSmrg 
2211debfc3dSmrg   size = dfa_stats.num_phis * sizeof (struct gphi);
2221debfc3dSmrg   total += size;
2231debfc3dSmrg   fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
224c0a68be4Smrg 	   SIZE_AMOUNT (size));
2251debfc3dSmrg 
2261debfc3dSmrg   size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
2271debfc3dSmrg   total += size;
2281debfc3dSmrg   fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
229c0a68be4Smrg 	   SIZE_AMOUNT (size));
2301debfc3dSmrg 
2311debfc3dSmrg   fprintf (file, "---------------------------------------------------------\n");
232c0a68be4Smrg   fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data",
233c0a68be4Smrg 	   SIZE_AMOUNT (total));
2341debfc3dSmrg   fprintf (file, "---------------------------------------------------------\n");
2351debfc3dSmrg   fprintf (file, "\n");
2361debfc3dSmrg 
2371debfc3dSmrg   if (dfa_stats.num_phis)
2381debfc3dSmrg     fprintf (file, "Average number of arguments per PHI node: %.1f (max: %ld)\n",
2391debfc3dSmrg 	     (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
2401debfc3dSmrg 	     (long) dfa_stats.max_num_phi_args);
2411debfc3dSmrg 
2421debfc3dSmrg   fprintf (file, "\n");
2431debfc3dSmrg }
2441debfc3dSmrg 
2451debfc3dSmrg 
2461debfc3dSmrg /* Dump DFA statistics on stderr.  */
2471debfc3dSmrg 
2481debfc3dSmrg DEBUG_FUNCTION void
debug_dfa_stats(void)2491debfc3dSmrg debug_dfa_stats (void)
2501debfc3dSmrg {
2511debfc3dSmrg   dump_dfa_stats (stderr);
2521debfc3dSmrg }
2531debfc3dSmrg 
2541debfc3dSmrg 
2551debfc3dSmrg /* Collect DFA statistics and store them in the structure pointed to by
2561debfc3dSmrg    DFA_STATS_P.  */
2571debfc3dSmrg 
2581debfc3dSmrg static void
collect_dfa_stats(struct dfa_stats_d * dfa_stats_p ATTRIBUTE_UNUSED)2591debfc3dSmrg collect_dfa_stats (struct dfa_stats_d *dfa_stats_p ATTRIBUTE_UNUSED)
2601debfc3dSmrg {
2611debfc3dSmrg   basic_block bb;
2621debfc3dSmrg 
2631debfc3dSmrg   gcc_assert (dfa_stats_p);
2641debfc3dSmrg 
2651debfc3dSmrg   memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
2661debfc3dSmrg 
2671debfc3dSmrg   /* Walk all the statements in the function counting references.  */
2681debfc3dSmrg   FOR_EACH_BB_FN (bb, cfun)
2691debfc3dSmrg     {
2701debfc3dSmrg       for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
2711debfc3dSmrg 	   gsi_next (&si))
2721debfc3dSmrg 	{
2731debfc3dSmrg 	  gphi *phi = si.phi ();
2741debfc3dSmrg 	  dfa_stats_p->num_phis++;
2751debfc3dSmrg 	  dfa_stats_p->num_phi_args += gimple_phi_num_args (phi);
2761debfc3dSmrg 	  if (gimple_phi_num_args (phi) > dfa_stats_p->max_num_phi_args)
2771debfc3dSmrg 	    dfa_stats_p->max_num_phi_args = gimple_phi_num_args (phi);
2781debfc3dSmrg 	}
2791debfc3dSmrg 
2801debfc3dSmrg       for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
2811debfc3dSmrg 	   gsi_next (&si))
2821debfc3dSmrg 	{
2831debfc3dSmrg 	  gimple *stmt = gsi_stmt (si);
2841debfc3dSmrg 	  dfa_stats_p->num_defs += NUM_SSA_OPERANDS (stmt, SSA_OP_DEF);
2851debfc3dSmrg 	  dfa_stats_p->num_uses += NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
2861debfc3dSmrg 	  dfa_stats_p->num_vdefs += gimple_vdef (stmt) ? 1 : 0;
2871debfc3dSmrg 	  dfa_stats_p->num_vuses += gimple_vuse (stmt) ? 1 : 0;
2881debfc3dSmrg 	}
2891debfc3dSmrg     }
2901debfc3dSmrg }
2911debfc3dSmrg 
2921debfc3dSmrg 
2931debfc3dSmrg /*---------------------------------------------------------------------------
2941debfc3dSmrg 			     Miscellaneous helpers
2951debfc3dSmrg ---------------------------------------------------------------------------*/
2961debfc3dSmrg 
2971debfc3dSmrg /* Lookup VAR UID in the default_defs hashtable and return the associated
2981debfc3dSmrg    variable.  */
2991debfc3dSmrg 
3001debfc3dSmrg tree
ssa_default_def(struct function * fn,tree var)3011debfc3dSmrg ssa_default_def (struct function *fn, tree var)
3021debfc3dSmrg {
3031debfc3dSmrg   struct tree_decl_minimal ind;
3041debfc3dSmrg   struct tree_ssa_name in;
3051debfc3dSmrg   gcc_assert (VAR_P (var)
3061debfc3dSmrg 	      || TREE_CODE (var) == PARM_DECL
3071debfc3dSmrg 	      || TREE_CODE (var) == RESULT_DECL);
3081debfc3dSmrg 
3091debfc3dSmrg   /* Always NULL_TREE for rtl function dumps.  */
3101debfc3dSmrg   if (!fn->gimple_df)
3111debfc3dSmrg     return NULL_TREE;
3121debfc3dSmrg 
3131debfc3dSmrg   in.var = (tree)&ind;
3141debfc3dSmrg   ind.uid = DECL_UID (var);
3151debfc3dSmrg   return DEFAULT_DEFS (fn)->find_with_hash ((tree)&in, DECL_UID (var));
3161debfc3dSmrg }
3171debfc3dSmrg 
3181debfc3dSmrg /* Insert the pair VAR's UID, DEF into the default_defs hashtable
3191debfc3dSmrg    of function FN.  */
3201debfc3dSmrg 
3211debfc3dSmrg void
set_ssa_default_def(struct function * fn,tree var,tree def)3221debfc3dSmrg set_ssa_default_def (struct function *fn, tree var, tree def)
3231debfc3dSmrg {
3241debfc3dSmrg   struct tree_decl_minimal ind;
3251debfc3dSmrg   struct tree_ssa_name in;
3261debfc3dSmrg 
3271debfc3dSmrg   gcc_assert (VAR_P (var)
3281debfc3dSmrg 	      || TREE_CODE (var) == PARM_DECL
3291debfc3dSmrg 	      || TREE_CODE (var) == RESULT_DECL);
3301debfc3dSmrg   in.var = (tree)&ind;
3311debfc3dSmrg   ind.uid = DECL_UID (var);
3321debfc3dSmrg   if (!def)
3331debfc3dSmrg     {
3341debfc3dSmrg       tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
3351debfc3dSmrg 							  DECL_UID (var),
3361debfc3dSmrg 							  NO_INSERT);
3371debfc3dSmrg       if (loc)
3381debfc3dSmrg 	{
3391debfc3dSmrg 	  SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false;
3401debfc3dSmrg 	  DEFAULT_DEFS (fn)->clear_slot (loc);
3411debfc3dSmrg 	}
3421debfc3dSmrg       return;
3431debfc3dSmrg     }
3441debfc3dSmrg   gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var);
3451debfc3dSmrg   tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
3461debfc3dSmrg 						      DECL_UID (var), INSERT);
3471debfc3dSmrg 
3481debfc3dSmrg   /* Default definition might be changed by tail call optimization.  */
3491debfc3dSmrg   if (*loc)
3501debfc3dSmrg     SSA_NAME_IS_DEFAULT_DEF (*loc) = false;
3511debfc3dSmrg 
3521debfc3dSmrg    /* Mark DEF as the default definition for VAR.  */
3531debfc3dSmrg   *loc = def;
3541debfc3dSmrg   SSA_NAME_IS_DEFAULT_DEF (def) = true;
3551debfc3dSmrg }
3561debfc3dSmrg 
3571debfc3dSmrg /* Retrieve or create a default definition for VAR.  */
3581debfc3dSmrg 
3591debfc3dSmrg tree
get_or_create_ssa_default_def(struct function * fn,tree var)3601debfc3dSmrg get_or_create_ssa_default_def (struct function *fn, tree var)
3611debfc3dSmrg {
3621debfc3dSmrg   tree ddef = ssa_default_def (fn, var);
3631debfc3dSmrg   if (ddef == NULL_TREE)
3641debfc3dSmrg     {
3651debfc3dSmrg       ddef = make_ssa_name_fn (fn, var, gimple_build_nop ());
3661debfc3dSmrg       set_ssa_default_def (fn, var, ddef);
3671debfc3dSmrg     }
3681debfc3dSmrg   return ddef;
3691debfc3dSmrg }
3701debfc3dSmrg 
3711debfc3dSmrg 
3721debfc3dSmrg /* If EXP is a handled component reference for a structure, return the
3731debfc3dSmrg    base variable.  The access range is delimited by bit positions *POFFSET and
3741debfc3dSmrg    *POFFSET + *PMAX_SIZE.  The access size is *PSIZE bits.  If either
3751debfc3dSmrg    *PSIZE or *PMAX_SIZE is -1, they could not be determined.  If *PSIZE
3761debfc3dSmrg    and *PMAX_SIZE are equal, the access is non-variable.  If *PREVERSE is
3771debfc3dSmrg    true, the storage order of the reference is reversed.  */
3781debfc3dSmrg 
3791debfc3dSmrg tree
get_ref_base_and_extent(tree exp,poly_int64_pod * poffset,poly_int64_pod * psize,poly_int64_pod * pmax_size,bool * preverse)380a2dc1f3fSmrg get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
381a2dc1f3fSmrg 			 poly_int64_pod *psize,
382a2dc1f3fSmrg 			 poly_int64_pod *pmax_size,
3831debfc3dSmrg 			 bool *preverse)
3841debfc3dSmrg {
385a2dc1f3fSmrg   poly_offset_int bitsize = -1;
386a2dc1f3fSmrg   poly_offset_int maxsize;
3871debfc3dSmrg   tree size_tree = NULL_TREE;
388a2dc1f3fSmrg   poly_offset_int bit_offset = 0;
3891debfc3dSmrg   bool seen_variable_array_ref = false;
3901debfc3dSmrg 
3911debfc3dSmrg   /* First get the final access size and the storage order from just the
3921debfc3dSmrg      outermost expression.  */
3931debfc3dSmrg   if (TREE_CODE (exp) == COMPONENT_REF)
3941debfc3dSmrg     size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
3951debfc3dSmrg   else if (TREE_CODE (exp) == BIT_FIELD_REF)
3961debfc3dSmrg     size_tree = TREE_OPERAND (exp, 1);
3971debfc3dSmrg   else if (!VOID_TYPE_P (TREE_TYPE (exp)))
3981debfc3dSmrg     {
3991debfc3dSmrg       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
4001debfc3dSmrg       if (mode == BLKmode)
4011debfc3dSmrg 	size_tree = TYPE_SIZE (TREE_TYPE (exp));
4021debfc3dSmrg       else
403a2dc1f3fSmrg 	bitsize = GET_MODE_BITSIZE (mode);
4041debfc3dSmrg     }
4051debfc3dSmrg   if (size_tree != NULL_TREE
406a2dc1f3fSmrg       && poly_int_tree_p (size_tree))
407a2dc1f3fSmrg     bitsize = wi::to_poly_offset (size_tree);
4081debfc3dSmrg 
4091debfc3dSmrg   *preverse = reverse_storage_order_for_component_p (exp);
4101debfc3dSmrg 
4111debfc3dSmrg   /* Initially, maxsize is the same as the accessed element size.
4121debfc3dSmrg      In the following it will only grow (or become -1).  */
4131debfc3dSmrg   maxsize = bitsize;
4141debfc3dSmrg 
4151debfc3dSmrg   /* Compute cumulative bit-offset for nested component-refs and array-refs,
4161debfc3dSmrg      and find the ultimate containing object.  */
4171debfc3dSmrg   while (1)
4181debfc3dSmrg     {
4191debfc3dSmrg       switch (TREE_CODE (exp))
4201debfc3dSmrg 	{
4211debfc3dSmrg 	case BIT_FIELD_REF:
422a2dc1f3fSmrg 	  bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
4231debfc3dSmrg 	  break;
4241debfc3dSmrg 
4251debfc3dSmrg 	case COMPONENT_REF:
4261debfc3dSmrg 	  {
4271debfc3dSmrg 	    tree field = TREE_OPERAND (exp, 1);
4281debfc3dSmrg 	    tree this_offset = component_ref_field_offset (exp);
4291debfc3dSmrg 
430a2dc1f3fSmrg 	    if (this_offset && poly_int_tree_p (this_offset))
4311debfc3dSmrg 	      {
432a2dc1f3fSmrg 		poly_offset_int woffset = (wi::to_poly_offset (this_offset)
4331debfc3dSmrg 					   << LOG2_BITS_PER_UNIT);
4341debfc3dSmrg 		woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
4351debfc3dSmrg 		bit_offset += woffset;
4361debfc3dSmrg 
4371debfc3dSmrg 		/* If we had seen a variable array ref already and we just
4381debfc3dSmrg 		   referenced the last field of a struct or a union member
4391debfc3dSmrg 		   then we have to adjust maxsize by the padding at the end
4401debfc3dSmrg 		   of our field.  */
4411debfc3dSmrg 		if (seen_variable_array_ref)
4421debfc3dSmrg 		  {
4431debfc3dSmrg 		    tree stype = TREE_TYPE (TREE_OPERAND (exp, 0));
4441debfc3dSmrg 		    tree next = DECL_CHAIN (field);
4451debfc3dSmrg 		    while (next && TREE_CODE (next) != FIELD_DECL)
4461debfc3dSmrg 		      next = DECL_CHAIN (next);
4471debfc3dSmrg 		    if (!next
4481debfc3dSmrg 			|| TREE_CODE (stype) != RECORD_TYPE)
4491debfc3dSmrg 		      {
4501debfc3dSmrg 			tree fsize = DECL_SIZE_UNIT (field);
4511debfc3dSmrg 			tree ssize = TYPE_SIZE_UNIT (stype);
4521debfc3dSmrg 			if (fsize == NULL
453a2dc1f3fSmrg 			    || !poly_int_tree_p (fsize)
4541debfc3dSmrg 			    || ssize == NULL
455a2dc1f3fSmrg 			    || !poly_int_tree_p (ssize))
4561debfc3dSmrg 			  maxsize = -1;
457a2dc1f3fSmrg 			else if (known_size_p (maxsize))
4581debfc3dSmrg 			  {
459a2dc1f3fSmrg 			    poly_offset_int tem
460a2dc1f3fSmrg 			      = (wi::to_poly_offset (ssize)
461a2dc1f3fSmrg 				 - wi::to_poly_offset (fsize));
4621debfc3dSmrg 			    tem <<= LOG2_BITS_PER_UNIT;
4631debfc3dSmrg 			    tem -= woffset;
4641debfc3dSmrg 			    maxsize += tem;
4651debfc3dSmrg 			  }
4661debfc3dSmrg 		      }
4671debfc3dSmrg 		    /* An component ref with an adjacent field up in the
4681debfc3dSmrg 		       structure hierarchy constrains the size of any variable
4691debfc3dSmrg 		       array ref lower in the access hierarchy.  */
4701debfc3dSmrg 		    else
4711debfc3dSmrg 		      seen_variable_array_ref = false;
4721debfc3dSmrg 		  }
4731debfc3dSmrg 	      }
4741debfc3dSmrg 	    else
4751debfc3dSmrg 	      {
4761debfc3dSmrg 		tree csize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
4771debfc3dSmrg 		/* We need to adjust maxsize to the whole structure bitsize.
4781debfc3dSmrg 		   But we can subtract any constant offset seen so far,
4791debfc3dSmrg 		   because that would get us out of the structure otherwise.  */
480a2dc1f3fSmrg 		if (known_size_p (maxsize)
4811debfc3dSmrg 		    && csize
482a2dc1f3fSmrg 		    && poly_int_tree_p (csize))
483a2dc1f3fSmrg 		  maxsize = wi::to_poly_offset (csize) - bit_offset;
4841debfc3dSmrg 		else
4851debfc3dSmrg 		  maxsize = -1;
4861debfc3dSmrg 	      }
4871debfc3dSmrg 	  }
4881debfc3dSmrg 	  break;
4891debfc3dSmrg 
4901debfc3dSmrg 	case ARRAY_REF:
4911debfc3dSmrg 	case ARRAY_RANGE_REF:
4921debfc3dSmrg 	  {
4931debfc3dSmrg 	    tree index = TREE_OPERAND (exp, 1);
4941debfc3dSmrg 	    tree low_bound, unit_size;
4951debfc3dSmrg 
4961debfc3dSmrg 	    /* If the resulting bit-offset is constant, track it.  */
497a2dc1f3fSmrg 	    if (poly_int_tree_p (index)
4981debfc3dSmrg 		&& (low_bound = array_ref_low_bound (exp),
499a2dc1f3fSmrg 		    poly_int_tree_p (low_bound))
5001debfc3dSmrg 		&& (unit_size = array_ref_element_size (exp),
5011debfc3dSmrg 		    TREE_CODE (unit_size) == INTEGER_CST))
5021debfc3dSmrg 	      {
503a2dc1f3fSmrg 		poly_offset_int woffset
504a2dc1f3fSmrg 		  = wi::sext (wi::to_poly_offset (index)
505a2dc1f3fSmrg 			      - wi::to_poly_offset (low_bound),
506*8feb0f0bSmrg 			      TYPE_PRECISION (sizetype));
5071debfc3dSmrg 		woffset *= wi::to_offset (unit_size);
5081debfc3dSmrg 		woffset <<= LOG2_BITS_PER_UNIT;
5091debfc3dSmrg 		bit_offset += woffset;
5101debfc3dSmrg 
5111debfc3dSmrg 		/* An array ref with a constant index up in the structure
5121debfc3dSmrg 		   hierarchy will constrain the size of any variable array ref
5131debfc3dSmrg 		   lower in the access hierarchy.  */
5141debfc3dSmrg 		seen_variable_array_ref = false;
5151debfc3dSmrg 	      }
5161debfc3dSmrg 	    else
5171debfc3dSmrg 	      {
5181debfc3dSmrg 		tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
5191debfc3dSmrg 		/* We need to adjust maxsize to the whole array bitsize.
5201debfc3dSmrg 		   But we can subtract any constant offset seen so far,
5211debfc3dSmrg 		   because that would get us outside of the array otherwise.  */
522a2dc1f3fSmrg 		if (known_size_p (maxsize)
5231debfc3dSmrg 		    && asize
524a2dc1f3fSmrg 		    && poly_int_tree_p (asize))
525a2dc1f3fSmrg 		  maxsize = wi::to_poly_offset (asize) - bit_offset;
5261debfc3dSmrg 		else
5271debfc3dSmrg 		  maxsize = -1;
5281debfc3dSmrg 
5291debfc3dSmrg 		/* Remember that we have seen an array ref with a variable
5301debfc3dSmrg 		   index.  */
5311debfc3dSmrg 		seen_variable_array_ref = true;
532c0a68be4Smrg 
533c0a68be4Smrg 		wide_int min, max;
534c0a68be4Smrg 		if (TREE_CODE (index) == SSA_NAME
535c0a68be4Smrg 		    && (low_bound = array_ref_low_bound (exp),
536c0a68be4Smrg 			poly_int_tree_p (low_bound))
537c0a68be4Smrg 		    && (unit_size = array_ref_element_size (exp),
538c0a68be4Smrg 			TREE_CODE (unit_size) == INTEGER_CST)
539c0a68be4Smrg 		    && get_range_info (index, &min, &max) == VR_RANGE)
540c0a68be4Smrg 		  {
541c0a68be4Smrg 		    poly_offset_int lbound = wi::to_poly_offset (low_bound);
542c0a68be4Smrg 		    /* Try to constrain maxsize with range information.  */
543c0a68be4Smrg 		    offset_int omax
544c0a68be4Smrg 		      = offset_int::from (max, TYPE_SIGN (TREE_TYPE (index)));
545c0a68be4Smrg 		    if (known_lt (lbound, omax))
546c0a68be4Smrg 		      {
547c0a68be4Smrg 			poly_offset_int rmaxsize;
548c0a68be4Smrg 			rmaxsize = (omax - lbound + 1)
549c0a68be4Smrg 			    * wi::to_offset (unit_size) << LOG2_BITS_PER_UNIT;
550c0a68be4Smrg 			if (!known_size_p (maxsize)
551c0a68be4Smrg 			    || known_lt (rmaxsize, maxsize))
552c0a68be4Smrg 			  {
553c0a68be4Smrg 			    /* If we know an upper bound below the declared
554c0a68be4Smrg 			       one this is no longer variable.  */
555c0a68be4Smrg 			    if (known_size_p (maxsize))
556c0a68be4Smrg 			      seen_variable_array_ref = false;
557c0a68be4Smrg 			    maxsize = rmaxsize;
558c0a68be4Smrg 			  }
559c0a68be4Smrg 		      }
560c0a68be4Smrg 		    /* Try to adjust bit_offset with range information.  */
561c0a68be4Smrg 		    offset_int omin
562c0a68be4Smrg 		      = offset_int::from (min, TYPE_SIGN (TREE_TYPE (index)));
563c0a68be4Smrg 		    if (known_le (lbound, omin))
564c0a68be4Smrg 		      {
565c0a68be4Smrg 			poly_offset_int woffset
566c0a68be4Smrg 			  = wi::sext (omin - lbound,
567*8feb0f0bSmrg 				      TYPE_PRECISION (sizetype));
568c0a68be4Smrg 			woffset *= wi::to_offset (unit_size);
569c0a68be4Smrg 			woffset <<= LOG2_BITS_PER_UNIT;
570c0a68be4Smrg 			bit_offset += woffset;
571c0a68be4Smrg 			if (known_size_p (maxsize))
572c0a68be4Smrg 			  maxsize -= woffset;
573c0a68be4Smrg 		      }
574c0a68be4Smrg 		  }
5751debfc3dSmrg 	      }
5761debfc3dSmrg 	  }
5771debfc3dSmrg 	  break;
5781debfc3dSmrg 
5791debfc3dSmrg 	case REALPART_EXPR:
5801debfc3dSmrg 	  break;
5811debfc3dSmrg 
5821debfc3dSmrg 	case IMAGPART_EXPR:
5831debfc3dSmrg 	  bit_offset += bitsize;
5841debfc3dSmrg 	  break;
5851debfc3dSmrg 
5861debfc3dSmrg 	case VIEW_CONVERT_EXPR:
5871debfc3dSmrg 	  break;
5881debfc3dSmrg 
5891debfc3dSmrg 	case TARGET_MEM_REF:
5901debfc3dSmrg 	  /* Via the variable index or index2 we can reach the
5911debfc3dSmrg 	     whole object.  Still hand back the decl here.  */
5921debfc3dSmrg 	  if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
5931debfc3dSmrg 	      && (TMR_INDEX (exp) || TMR_INDEX2 (exp)))
5941debfc3dSmrg 	    {
5951debfc3dSmrg 	      exp = TREE_OPERAND (TMR_BASE (exp), 0);
5961debfc3dSmrg 	      bit_offset = 0;
5971debfc3dSmrg 	      maxsize = -1;
5981debfc3dSmrg 	      goto done;
5991debfc3dSmrg 	    }
6001debfc3dSmrg 	  /* Fallthru.  */
6011debfc3dSmrg 	case MEM_REF:
6021debfc3dSmrg 	  /* We need to deal with variable arrays ending structures such as
6031debfc3dSmrg 	     struct { int length; int a[1]; } x;           x.a[d]
6041debfc3dSmrg 	     struct { struct { int a; int b; } a[1]; } x;  x.a[d].a
6051debfc3dSmrg 	     struct { struct { int a[1]; } a[1]; } x;      x.a[0][d], x.a[d][0]
6061debfc3dSmrg 	     struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d]
6071debfc3dSmrg 	     where we do not know maxsize for variable index accesses to
6081debfc3dSmrg 	     the array.  The simplest way to conservatively deal with this
6091debfc3dSmrg 	     is to punt in the case that offset + maxsize reaches the
6101debfc3dSmrg 	     base type boundary.  This needs to include possible trailing
6111debfc3dSmrg 	     padding that is there for alignment purposes.  */
6121debfc3dSmrg 	  if (seen_variable_array_ref
613a2dc1f3fSmrg 	      && known_size_p (maxsize)
6141debfc3dSmrg 	      && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE
615a2dc1f3fSmrg 		  || !poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
616a2dc1f3fSmrg 		  || (maybe_eq
617a2dc1f3fSmrg 		      (bit_offset + maxsize,
618a2dc1f3fSmrg 		       wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp)))))))
6191debfc3dSmrg 	    maxsize = -1;
6201debfc3dSmrg 
6211debfc3dSmrg 	  /* Hand back the decl for MEM[&decl, off].  */
6221debfc3dSmrg 	  if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
6231debfc3dSmrg 	    {
6241debfc3dSmrg 	      if (integer_zerop (TREE_OPERAND (exp, 1)))
6251debfc3dSmrg 		exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6261debfc3dSmrg 	      else
6271debfc3dSmrg 		{
628a2dc1f3fSmrg 		  poly_offset_int off = mem_ref_offset (exp);
6291debfc3dSmrg 		  off <<= LOG2_BITS_PER_UNIT;
6301debfc3dSmrg 		  off += bit_offset;
631a2dc1f3fSmrg 		  poly_int64 off_hwi;
632a2dc1f3fSmrg 		  if (off.to_shwi (&off_hwi))
6331debfc3dSmrg 		    {
634a2dc1f3fSmrg 		      bit_offset = off_hwi;
6351debfc3dSmrg 		      exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6361debfc3dSmrg 		    }
6371debfc3dSmrg 		}
6381debfc3dSmrg 	    }
6391debfc3dSmrg 	  goto done;
6401debfc3dSmrg 
6411debfc3dSmrg 	default:
6421debfc3dSmrg 	  goto done;
6431debfc3dSmrg 	}
6441debfc3dSmrg 
6451debfc3dSmrg       exp = TREE_OPERAND (exp, 0);
6461debfc3dSmrg     }
6471debfc3dSmrg 
6481debfc3dSmrg  done:
649a2dc1f3fSmrg   if (!bitsize.to_shwi (psize) || maybe_lt (*psize, 0))
6501debfc3dSmrg     {
6511debfc3dSmrg       *poffset = 0;
6521debfc3dSmrg       *psize = -1;
6531debfc3dSmrg       *pmax_size = -1;
6541debfc3dSmrg 
6551debfc3dSmrg       return exp;
6561debfc3dSmrg     }
6571debfc3dSmrg 
658a2dc1f3fSmrg   /* ???  Due to negative offsets in ARRAY_REF we can end up with
659a2dc1f3fSmrg      negative bit_offset here.  We might want to store a zero offset
660a2dc1f3fSmrg      in this case.  */
661a2dc1f3fSmrg   if (!bit_offset.to_shwi (poffset))
6621debfc3dSmrg     {
6631debfc3dSmrg       *poffset = 0;
6641debfc3dSmrg       *pmax_size = -1;
6651debfc3dSmrg 
6661debfc3dSmrg       return exp;
6671debfc3dSmrg     }
6681debfc3dSmrg 
6691debfc3dSmrg   /* In case of a decl or constant base object we can do better.  */
6701debfc3dSmrg 
6711debfc3dSmrg   if (DECL_P (exp))
6721debfc3dSmrg     {
6731debfc3dSmrg       if (VAR_P (exp)
6741debfc3dSmrg 	  && ((flag_unconstrained_commons && DECL_COMMON (exp))
6751debfc3dSmrg 	      || (DECL_EXTERNAL (exp) && seen_variable_array_ref)))
6761debfc3dSmrg 	{
6771debfc3dSmrg 	  tree sz_tree = TYPE_SIZE (TREE_TYPE (exp));
6781debfc3dSmrg 	  /* If size is unknown, or we have read to the end, assume there
6791debfc3dSmrg 	     may be more to the structure than we are told.  */
6801debfc3dSmrg 	  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
6811debfc3dSmrg 	      || (seen_variable_array_ref
6821debfc3dSmrg 		  && (sz_tree == NULL_TREE
683a2dc1f3fSmrg 		      || !poly_int_tree_p (sz_tree)
684a2dc1f3fSmrg 		      || maybe_eq (bit_offset + maxsize,
685a2dc1f3fSmrg 				   wi::to_poly_offset (sz_tree)))))
6861debfc3dSmrg 	    maxsize = -1;
6871debfc3dSmrg 	}
6881debfc3dSmrg       /* If maxsize is unknown adjust it according to the size of the
6891debfc3dSmrg          base decl.  */
690a2dc1f3fSmrg       else if (!known_size_p (maxsize)
6911debfc3dSmrg 	       && DECL_SIZE (exp)
692a2dc1f3fSmrg 	       && poly_int_tree_p (DECL_SIZE (exp)))
693a2dc1f3fSmrg 	maxsize = wi::to_poly_offset (DECL_SIZE (exp)) - bit_offset;
6941debfc3dSmrg     }
6951debfc3dSmrg   else if (CONSTANT_CLASS_P (exp))
6961debfc3dSmrg     {
6971debfc3dSmrg       /* If maxsize is unknown adjust it according to the size of the
6981debfc3dSmrg          base type constant.  */
699a2dc1f3fSmrg       if (!known_size_p (maxsize)
7001debfc3dSmrg 	  && TYPE_SIZE (TREE_TYPE (exp))
701a2dc1f3fSmrg 	  && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp))))
702a2dc1f3fSmrg 	maxsize = (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp)))
7031debfc3dSmrg 		   - bit_offset);
7041debfc3dSmrg     }
7051debfc3dSmrg 
706a2dc1f3fSmrg   if (!maxsize.to_shwi (pmax_size)
707a2dc1f3fSmrg       || maybe_lt (*pmax_size, 0)
708a2dc1f3fSmrg       || !endpoint_representable_p (*poffset, *pmax_size))
7091debfc3dSmrg     *pmax_size = -1;
710a2dc1f3fSmrg 
711a2dc1f3fSmrg   /* Punt if *POFFSET + *PSIZE overflows in HOST_WIDE_INT, the callers don't
712a2dc1f3fSmrg      check for such overflows individually and assume it works.  */
713a2dc1f3fSmrg   if (!endpoint_representable_p (*poffset, *psize))
714a2dc1f3fSmrg     {
715a2dc1f3fSmrg       *poffset = 0;
716a2dc1f3fSmrg       *psize = -1;
717a2dc1f3fSmrg       *pmax_size = -1;
7181debfc3dSmrg 
7191debfc3dSmrg       return exp;
7201debfc3dSmrg     }
7211debfc3dSmrg 
722a2dc1f3fSmrg   return exp;
723a2dc1f3fSmrg }
724a2dc1f3fSmrg 
725a2dc1f3fSmrg /* Like get_ref_base_and_extent, but for cases in which we only care
726a2dc1f3fSmrg    about constant-width accesses at constant offsets.  Return null
727a2dc1f3fSmrg    if the access is anything else.  */
728a2dc1f3fSmrg 
729a2dc1f3fSmrg tree
get_ref_base_and_extent_hwi(tree exp,HOST_WIDE_INT * poffset,HOST_WIDE_INT * psize,bool * preverse)730a2dc1f3fSmrg get_ref_base_and_extent_hwi (tree exp, HOST_WIDE_INT *poffset,
731a2dc1f3fSmrg 			     HOST_WIDE_INT *psize, bool *preverse)
732a2dc1f3fSmrg {
733a2dc1f3fSmrg   poly_int64 offset, size, max_size;
734a2dc1f3fSmrg   HOST_WIDE_INT const_offset, const_size;
735a2dc1f3fSmrg   bool reverse;
736a2dc1f3fSmrg   tree decl = get_ref_base_and_extent (exp, &offset, &size, &max_size,
737a2dc1f3fSmrg 				       &reverse);
738a2dc1f3fSmrg   if (!offset.is_constant (&const_offset)
739a2dc1f3fSmrg       || !size.is_constant (&const_size)
740a2dc1f3fSmrg       || const_offset < 0
741a2dc1f3fSmrg       || !known_size_p (max_size)
742a2dc1f3fSmrg       || maybe_ne (max_size, const_size))
743a2dc1f3fSmrg     return NULL_TREE;
744a2dc1f3fSmrg 
745a2dc1f3fSmrg   *poffset = const_offset;
746a2dc1f3fSmrg   *psize = const_size;
747a2dc1f3fSmrg   *preverse = reverse;
748a2dc1f3fSmrg   return decl;
749a2dc1f3fSmrg }
750a2dc1f3fSmrg 
7511debfc3dSmrg /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
7521debfc3dSmrg    denotes the starting address of the memory access EXP.
7531debfc3dSmrg    Returns NULL_TREE if the offset is not constant or any component
7541debfc3dSmrg    is not BITS_PER_UNIT-aligned.
7551debfc3dSmrg    VALUEIZE if non-NULL is used to valueize SSA names.  It should return
7561debfc3dSmrg    its argument or a constant if the argument is known to be constant.  */
7571debfc3dSmrg 
7581debfc3dSmrg tree
get_addr_base_and_unit_offset_1(tree exp,poly_int64_pod * poffset,tree (* valueize)(tree))759a2dc1f3fSmrg get_addr_base_and_unit_offset_1 (tree exp, poly_int64_pod *poffset,
7601debfc3dSmrg 				 tree (*valueize) (tree))
7611debfc3dSmrg {
762a2dc1f3fSmrg   poly_int64 byte_offset = 0;
7631debfc3dSmrg 
7641debfc3dSmrg   /* Compute cumulative byte-offset for nested component-refs and array-refs,
7651debfc3dSmrg      and find the ultimate containing object.  */
7661debfc3dSmrg   while (1)
7671debfc3dSmrg     {
7681debfc3dSmrg       switch (TREE_CODE (exp))
7691debfc3dSmrg 	{
7701debfc3dSmrg 	case BIT_FIELD_REF:
7711debfc3dSmrg 	  {
772a2dc1f3fSmrg 	    poly_int64 this_byte_offset;
773a2dc1f3fSmrg 	    poly_uint64 this_bit_offset;
774a2dc1f3fSmrg 	    if (!poly_int_tree_p (TREE_OPERAND (exp, 2), &this_bit_offset)
775a2dc1f3fSmrg 		|| !multiple_p (this_bit_offset, BITS_PER_UNIT,
776a2dc1f3fSmrg 				&this_byte_offset))
7771debfc3dSmrg 	      return NULL_TREE;
778a2dc1f3fSmrg 	    byte_offset += this_byte_offset;
7791debfc3dSmrg 	  }
7801debfc3dSmrg 	  break;
7811debfc3dSmrg 
7821debfc3dSmrg 	case COMPONENT_REF:
7831debfc3dSmrg 	  {
7841debfc3dSmrg 	    tree field = TREE_OPERAND (exp, 1);
7851debfc3dSmrg 	    tree this_offset = component_ref_field_offset (exp);
786a2dc1f3fSmrg 	    poly_int64 hthis_offset;
7871debfc3dSmrg 
7881debfc3dSmrg 	    if (!this_offset
789a2dc1f3fSmrg 		|| !poly_int_tree_p (this_offset, &hthis_offset)
7901debfc3dSmrg 		|| (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
7911debfc3dSmrg 		    % BITS_PER_UNIT))
7921debfc3dSmrg 	      return NULL_TREE;
7931debfc3dSmrg 
7941debfc3dSmrg 	    hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
7951debfc3dSmrg 			     / BITS_PER_UNIT);
7961debfc3dSmrg 	    byte_offset += hthis_offset;
7971debfc3dSmrg 	  }
7981debfc3dSmrg 	  break;
7991debfc3dSmrg 
8001debfc3dSmrg 	case ARRAY_REF:
8011debfc3dSmrg 	case ARRAY_RANGE_REF:
8021debfc3dSmrg 	  {
8031debfc3dSmrg 	    tree index = TREE_OPERAND (exp, 1);
8041debfc3dSmrg 	    tree low_bound, unit_size;
8051debfc3dSmrg 
8061debfc3dSmrg 	    if (valueize
8071debfc3dSmrg 		&& TREE_CODE (index) == SSA_NAME)
8081debfc3dSmrg 	      index = (*valueize) (index);
8091debfc3dSmrg 
8101debfc3dSmrg 	    /* If the resulting bit-offset is constant, track it.  */
811a2dc1f3fSmrg 	    if (poly_int_tree_p (index)
8121debfc3dSmrg 		&& (low_bound = array_ref_low_bound (exp),
813a2dc1f3fSmrg 		    poly_int_tree_p (low_bound))
8141debfc3dSmrg 		&& (unit_size = array_ref_element_size (exp),
8151debfc3dSmrg 		    TREE_CODE (unit_size) == INTEGER_CST))
8161debfc3dSmrg 	      {
817a2dc1f3fSmrg 		poly_offset_int woffset
818a2dc1f3fSmrg 		  = wi::sext (wi::to_poly_offset (index)
819a2dc1f3fSmrg 			      - wi::to_poly_offset (low_bound),
820*8feb0f0bSmrg 			      TYPE_PRECISION (sizetype));
8211debfc3dSmrg 		woffset *= wi::to_offset (unit_size);
822a2dc1f3fSmrg 		byte_offset += woffset.force_shwi ();
8231debfc3dSmrg 	      }
8241debfc3dSmrg 	    else
8251debfc3dSmrg 	      return NULL_TREE;
8261debfc3dSmrg 	  }
8271debfc3dSmrg 	  break;
8281debfc3dSmrg 
8291debfc3dSmrg 	case REALPART_EXPR:
8301debfc3dSmrg 	  break;
8311debfc3dSmrg 
8321debfc3dSmrg 	case IMAGPART_EXPR:
8331debfc3dSmrg 	  byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (exp)));
8341debfc3dSmrg 	  break;
8351debfc3dSmrg 
8361debfc3dSmrg 	case VIEW_CONVERT_EXPR:
8371debfc3dSmrg 	  break;
8381debfc3dSmrg 
8391debfc3dSmrg 	case MEM_REF:
8401debfc3dSmrg 	  {
8411debfc3dSmrg 	    tree base = TREE_OPERAND (exp, 0);
8421debfc3dSmrg 	    if (valueize
8431debfc3dSmrg 		&& TREE_CODE (base) == SSA_NAME)
8441debfc3dSmrg 	      base = (*valueize) (base);
8451debfc3dSmrg 
8461debfc3dSmrg 	    /* Hand back the decl for MEM[&decl, off].  */
8471debfc3dSmrg 	    if (TREE_CODE (base) == ADDR_EXPR)
8481debfc3dSmrg 	      {
8491debfc3dSmrg 		if (!integer_zerop (TREE_OPERAND (exp, 1)))
8501debfc3dSmrg 		  {
851a2dc1f3fSmrg 		    poly_offset_int off = mem_ref_offset (exp);
852a2dc1f3fSmrg 		    byte_offset += off.force_shwi ();
8531debfc3dSmrg 		  }
8541debfc3dSmrg 		exp = TREE_OPERAND (base, 0);
8551debfc3dSmrg 	      }
8561debfc3dSmrg 	    goto done;
8571debfc3dSmrg 	  }
8581debfc3dSmrg 
8591debfc3dSmrg 	case TARGET_MEM_REF:
8601debfc3dSmrg 	  {
8611debfc3dSmrg 	    tree base = TREE_OPERAND (exp, 0);
8621debfc3dSmrg 	    if (valueize
8631debfc3dSmrg 		&& TREE_CODE (base) == SSA_NAME)
8641debfc3dSmrg 	      base = (*valueize) (base);
8651debfc3dSmrg 
8661debfc3dSmrg 	    /* Hand back the decl for MEM[&decl, off].  */
8671debfc3dSmrg 	    if (TREE_CODE (base) == ADDR_EXPR)
8681debfc3dSmrg 	      {
8691debfc3dSmrg 		if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
8701debfc3dSmrg 		  return NULL_TREE;
8711debfc3dSmrg 		if (!integer_zerop (TMR_OFFSET (exp)))
8721debfc3dSmrg 		  {
873a2dc1f3fSmrg 		    poly_offset_int off = mem_ref_offset (exp);
874a2dc1f3fSmrg 		    byte_offset += off.force_shwi ();
8751debfc3dSmrg 		  }
8761debfc3dSmrg 		exp = TREE_OPERAND (base, 0);
8771debfc3dSmrg 	      }
8781debfc3dSmrg 	    goto done;
8791debfc3dSmrg 	  }
8801debfc3dSmrg 
8811debfc3dSmrg 	default:
8821debfc3dSmrg 	  goto done;
8831debfc3dSmrg 	}
8841debfc3dSmrg 
8851debfc3dSmrg       exp = TREE_OPERAND (exp, 0);
8861debfc3dSmrg     }
8871debfc3dSmrg done:
8881debfc3dSmrg 
8891debfc3dSmrg   *poffset = byte_offset;
8901debfc3dSmrg   return exp;
8911debfc3dSmrg }
8921debfc3dSmrg 
8931debfc3dSmrg /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
8941debfc3dSmrg    denotes the starting address of the memory access EXP.
8951debfc3dSmrg    Returns NULL_TREE if the offset is not constant or any component
8961debfc3dSmrg    is not BITS_PER_UNIT-aligned.  */
8971debfc3dSmrg 
8981debfc3dSmrg tree
get_addr_base_and_unit_offset(tree exp,poly_int64_pod * poffset)899a2dc1f3fSmrg get_addr_base_and_unit_offset (tree exp, poly_int64_pod *poffset)
9001debfc3dSmrg {
9011debfc3dSmrg   return get_addr_base_and_unit_offset_1 (exp, poffset, NULL);
9021debfc3dSmrg }
9031debfc3dSmrg 
9041debfc3dSmrg /* Returns true if STMT references an SSA_NAME that has
9051debfc3dSmrg    SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false.  */
9061debfc3dSmrg 
9071debfc3dSmrg bool
stmt_references_abnormal_ssa_name(gimple * stmt)9081debfc3dSmrg stmt_references_abnormal_ssa_name (gimple *stmt)
9091debfc3dSmrg {
9101debfc3dSmrg   ssa_op_iter oi;
9111debfc3dSmrg   use_operand_p use_p;
9121debfc3dSmrg 
9131debfc3dSmrg   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
9141debfc3dSmrg     {
9151debfc3dSmrg       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (use_p)))
9161debfc3dSmrg 	return true;
9171debfc3dSmrg     }
9181debfc3dSmrg 
9191debfc3dSmrg   return false;
9201debfc3dSmrg }
9211debfc3dSmrg 
9221debfc3dSmrg /* If STMT takes any abnormal PHI values as input, replace them with
9231debfc3dSmrg    local copies.  */
9241debfc3dSmrg 
9251debfc3dSmrg void
replace_abnormal_ssa_names(gimple * stmt)9261debfc3dSmrg replace_abnormal_ssa_names (gimple *stmt)
9271debfc3dSmrg {
9281debfc3dSmrg   ssa_op_iter oi;
9291debfc3dSmrg   use_operand_p use_p;
9301debfc3dSmrg 
9311debfc3dSmrg   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
9321debfc3dSmrg     {
9331debfc3dSmrg       tree op = USE_FROM_PTR (use_p);
9341debfc3dSmrg       if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
9351debfc3dSmrg 	{
9361debfc3dSmrg 	  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
9371debfc3dSmrg 	  tree new_name = make_ssa_name (TREE_TYPE (op));
9381debfc3dSmrg 	  gassign *assign = gimple_build_assign (new_name, op);
9391debfc3dSmrg 	  gsi_insert_before (&gsi, assign, GSI_SAME_STMT);
9401debfc3dSmrg 	  SET_USE (use_p, new_name);
9411debfc3dSmrg 	}
9421debfc3dSmrg     }
9431debfc3dSmrg }
9441debfc3dSmrg 
9451debfc3dSmrg /* Pair of tree and a sorting index, for dump_enumerated_decls.  */
9461debfc3dSmrg struct GTY(()) numbered_tree
9471debfc3dSmrg {
9481debfc3dSmrg   tree t;
9491debfc3dSmrg   int num;
9501debfc3dSmrg };
9511debfc3dSmrg 
9521debfc3dSmrg 
9531debfc3dSmrg /* Compare two declarations references by their DECL_UID / sequence number.
9541debfc3dSmrg    Called via qsort.  */
9551debfc3dSmrg 
9561debfc3dSmrg static int
compare_decls_by_uid(const void * pa,const void * pb)9571debfc3dSmrg compare_decls_by_uid (const void *pa, const void *pb)
9581debfc3dSmrg {
9591debfc3dSmrg   const numbered_tree *nt_a = ((const numbered_tree *)pa);
9601debfc3dSmrg   const numbered_tree *nt_b = ((const numbered_tree *)pb);
9611debfc3dSmrg 
9621debfc3dSmrg   if (DECL_UID (nt_a->t) != DECL_UID (nt_b->t))
9631debfc3dSmrg     return  DECL_UID (nt_a->t) - DECL_UID (nt_b->t);
9641debfc3dSmrg   return nt_a->num - nt_b->num;
9651debfc3dSmrg }
9661debfc3dSmrg 
9671debfc3dSmrg /* Called via walk_gimple_stmt / walk_gimple_op by dump_enumerated_decls.  */
9681debfc3dSmrg static tree
dump_enumerated_decls_push(tree * tp,int * walk_subtrees,void * data)9691debfc3dSmrg dump_enumerated_decls_push (tree *tp, int *walk_subtrees, void *data)
9701debfc3dSmrg {
9711debfc3dSmrg   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9721debfc3dSmrg   vec<numbered_tree> *list = (vec<numbered_tree> *) wi->info;
9731debfc3dSmrg   numbered_tree nt;
9741debfc3dSmrg 
9751debfc3dSmrg   if (!DECL_P (*tp))
9761debfc3dSmrg     return NULL_TREE;
9771debfc3dSmrg   nt.t = *tp;
9781debfc3dSmrg   nt.num = list->length ();
9791debfc3dSmrg   list->safe_push (nt);
9801debfc3dSmrg   *walk_subtrees = 0;
9811debfc3dSmrg   return NULL_TREE;
9821debfc3dSmrg }
9831debfc3dSmrg 
9841debfc3dSmrg /* Find all the declarations used by the current function, sort them by uid,
9851debfc3dSmrg    and emit the sorted list.  Each declaration is tagged with a sequence
9861debfc3dSmrg    number indicating when it was found during statement / tree walking,
9871debfc3dSmrg    so that TDF_NOUID comparisons of anonymous declarations are still
9881debfc3dSmrg    meaningful.  Where a declaration was encountered more than once, we
9891debfc3dSmrg    emit only the sequence number of the first encounter.
9901debfc3dSmrg    FILE is the dump file where to output the list and FLAGS is as in
9911debfc3dSmrg    print_generic_expr.  */
9921debfc3dSmrg void
dump_enumerated_decls(FILE * file,dump_flags_t flags)993a2dc1f3fSmrg dump_enumerated_decls (FILE *file, dump_flags_t flags)
9941debfc3dSmrg {
995c0a68be4Smrg   if (!cfun->cfg)
996c0a68be4Smrg     return;
997c0a68be4Smrg 
9981debfc3dSmrg   basic_block bb;
9991debfc3dSmrg   struct walk_stmt_info wi;
10001debfc3dSmrg   auto_vec<numbered_tree, 40> decl_list;
10011debfc3dSmrg 
10021debfc3dSmrg   memset (&wi, '\0', sizeof (wi));
10031debfc3dSmrg   wi.info = (void *) &decl_list;
10041debfc3dSmrg   FOR_EACH_BB_FN (bb, cfun)
10051debfc3dSmrg     {
10061debfc3dSmrg       gimple_stmt_iterator gsi;
10071debfc3dSmrg 
10081debfc3dSmrg       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
10091debfc3dSmrg 	if (!is_gimple_debug (gsi_stmt (gsi)))
10101debfc3dSmrg 	  walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi);
10111debfc3dSmrg     }
10121debfc3dSmrg   decl_list.qsort (compare_decls_by_uid);
10131debfc3dSmrg   if (decl_list.length ())
10141debfc3dSmrg     {
10151debfc3dSmrg       unsigned ix;
10161debfc3dSmrg       numbered_tree *ntp;
10171debfc3dSmrg       tree last = NULL_TREE;
10181debfc3dSmrg 
10191debfc3dSmrg       fprintf (file, "Declarations used by %s, sorted by DECL_UID:\n",
10201debfc3dSmrg 	       current_function_name ());
10211debfc3dSmrg       FOR_EACH_VEC_ELT (decl_list, ix, ntp)
10221debfc3dSmrg 	{
10231debfc3dSmrg 	  if (ntp->t == last)
10241debfc3dSmrg 	    continue;
10251debfc3dSmrg 	  fprintf (file, "%d: ", ntp->num);
10261debfc3dSmrg 	  print_generic_decl (file, ntp->t, flags);
10271debfc3dSmrg 	  fprintf (file, "\n");
10281debfc3dSmrg 	  last = ntp->t;
10291debfc3dSmrg 	}
10301debfc3dSmrg     }
10311debfc3dSmrg }
1032