Daily bump.
[gcc.git] / gcc / tree-dfa.c
index 681afbcd05646ecf1df5bfe6789cfa3ce558ba6c..9ba627c90b54fb6f76d0171ff16e5aa4d7f06026 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
@@ -184,8 +184,8 @@ dump_dfa_stats (FILE *file)
 
   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);
 
@@ -201,36 +201,36 @@ dump_dfa_stats (FILE *file)
   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");
 
@@ -438,7 +438,7 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
                   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);
@@ -454,7 +454,7 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
                            || 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)
@@ -464,6 +464,11 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
                            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
@@ -524,6 +529,49 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
                /* 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;
@@ -622,7 +670,9 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
 
   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
@@ -798,8 +848,8 @@ get_addr_base_and_unit_offset_1 (tree exp, poly_int64_pod *poffset,
              {
                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);
              }
@@ -820,8 +870,8 @@ get_addr_base_and_unit_offset_1 (tree exp, poly_int64_pod *poffset,
                  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);
              }
@@ -942,6 +992,9 @@ dump_enumerated_decls_push (tree *tp, int *walk_subtrees, void *data)
 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;