/* Data flow functions for trees.
- Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
unsigned long size, total = 0;
const char * const fmt_str = "%-30s%-13s%12s\n";
- const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
- const char * const fmt_str_3 = "%-43s%11lu%c\n";
+ const char * const fmt_str_1 = "%-30s%13lu" PRsa (11) "\n";
+ const char * const fmt_str_3 = "%-43s" PRsa (11) "\n";
const char *funcname
= lang_hooks.decl_printable_name (current_function_decl, 2);
size = dfa_stats.num_uses * sizeof (tree *);
total += size;
fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
size = dfa_stats.num_defs * sizeof (tree *);
total += size;
fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
size = dfa_stats.num_vuses * sizeof (tree *);
total += size;
fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
size = dfa_stats.num_vdefs * sizeof (tree *);
total += size;
fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
size = dfa_stats.num_phis * sizeof (struct gphi);
total += size;
fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
total += size;
fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
- SCALE (size), LABEL (size));
+ SIZE_AMOUNT (size));
fprintf (file, "---------------------------------------------------------\n");
- fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
- LABEL (total));
+ fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data",
+ SIZE_AMOUNT (total));
fprintf (file, "---------------------------------------------------------\n");
fprintf (file, "\n");
referenced the last field of a struct or a union member
then we have to adjust maxsize by the padding at the end
of our field. */
- if (seen_variable_array_ref && known_size_p (maxsize))
+ if (seen_variable_array_ref)
{
tree stype = TREE_TYPE (TREE_OPERAND (exp, 0));
tree next = DECL_CHAIN (field);
|| ssize == NULL
|| !poly_int_tree_p (ssize))
maxsize = -1;
- else
+ else if (known_size_p (maxsize))
{
poly_offset_int tem
= (wi::to_poly_offset (ssize)
maxsize += tem;
}
}
+ /* An component ref with an adjacent field up in the
+ structure hierarchy constrains the size of any variable
+ array ref lower in the access hierarchy. */
+ else
+ seen_variable_array_ref = false;
}
}
else
/* Remember that we have seen an array ref with a variable
index. */
seen_variable_array_ref = true;
+
+ wide_int min, max;
+ if (TREE_CODE (index) == SSA_NAME
+ && (low_bound = array_ref_low_bound (exp),
+ poly_int_tree_p (low_bound))
+ && (unit_size = array_ref_element_size (exp),
+ TREE_CODE (unit_size) == INTEGER_CST)
+ && get_range_info (index, &min, &max) == VR_RANGE)
+ {
+ poly_offset_int lbound = wi::to_poly_offset (low_bound);
+ /* Try to constrain maxsize with range information. */
+ offset_int omax
+ = offset_int::from (max, TYPE_SIGN (TREE_TYPE (index)));
+ if (known_lt (lbound, omax))
+ {
+ poly_offset_int rmaxsize;
+ rmaxsize = (omax - lbound + 1)
+ * wi::to_offset (unit_size) << LOG2_BITS_PER_UNIT;
+ if (!known_size_p (maxsize)
+ || known_lt (rmaxsize, maxsize))
+ {
+ /* If we know an upper bound below the declared
+ one this is no longer variable. */
+ if (known_size_p (maxsize))
+ seen_variable_array_ref = false;
+ maxsize = rmaxsize;
+ }
+ }
+ /* Try to adjust bit_offset with range information. */
+ offset_int omin
+ = offset_int::from (min, TYPE_SIGN (TREE_TYPE (index)));
+ if (known_le (lbound, omin))
+ {
+ poly_offset_int woffset
+ = wi::sext (omin - lbound,
+ TYPE_PRECISION (TREE_TYPE (index)));
+ woffset *= wi::to_offset (unit_size);
+ woffset <<= LOG2_BITS_PER_UNIT;
+ bit_offset += woffset;
+ if (known_size_p (maxsize))
+ maxsize -= woffset;
+ }
+ }
}
}
break;
if (DECL_P (exp))
{
- if (flag_unconstrained_commons && VAR_P (exp) && DECL_COMMON (exp))
+ if (VAR_P (exp)
+ && ((flag_unconstrained_commons && DECL_COMMON (exp))
+ || (DECL_EXTERNAL (exp) && seen_variable_array_ref)))
{
tree sz_tree = TYPE_SIZE (TREE_TYPE (exp));
/* If size is unknown, or we have read to the end, assume there
{
if (!integer_zerop (TREE_OPERAND (exp, 1)))
{
- offset_int off = mem_ref_offset (exp);
- byte_offset += off.to_short_addr ();
+ poly_offset_int off = mem_ref_offset (exp);
+ byte_offset += off.force_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
return NULL_TREE;
if (!integer_zerop (TMR_OFFSET (exp)))
{
- offset_int off = mem_ref_offset (exp);
- byte_offset += off.to_short_addr ();
+ poly_offset_int off = mem_ref_offset (exp);
+ byte_offset += off.force_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
void
dump_enumerated_decls (FILE *file, dump_flags_t flags)
{
+ if (!cfun->cfg)
+ return;
+
basic_block bb;
struct walk_stmt_info wi;
auto_vec<numbered_tree, 40> decl_list;