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