]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-ssa.c
Update copyright years.
[thirdparty/gcc.git] / gcc / tree-ssa.c
index b4b5c903e13b1695daeff66a680c64fa7da0829d..2a6d0866e9f8d2f2ba0e107abb25b356d0659d42 100644 (file)
@@ -1,5 +1,5 @@
 /* Miscellaneous SSA utility functions.
-   Copyright (C) 2001-2019 Free Software Foundation, Inc.
+   Copyright (C) 2001-2021 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -987,6 +987,12 @@ verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
          err = true;
        }
 
+      if ((e->flags & EDGE_ABNORMAL) && TREE_CODE (op) != SSA_NAME)
+       {
+         error ("PHI argument on abnormal edge is not SSA_NAME");
+         err = true;
+       }
+
       if (TREE_CODE (op) == SSA_NAME)
        {
          err = verify_ssa_name (op, virtual_operand_p (gimple_phi_result (phi)));
@@ -1212,15 +1218,16 @@ err:
 #  pragma GCC diagnostic pop
 #endif
 
-/* Initialize global DFA and SSA structures.  */
+/* Initialize global DFA and SSA structures.
+   If SIZE is non-zero allocated ssa names array of a given size.  */
 
 void
-init_tree_ssa (struct function *fn)
+init_tree_ssa (struct function *fn, int size)
 {
   fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
   fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
   pt_solution_reset (&fn->gimple_df->escaped);
-  init_ssanames (fn, 0);
+  init_ssanames (fn, size);
 }
 
 /* Deallocate memory associated with SSA data structures for FNDECL.  */
@@ -1543,14 +1550,17 @@ non_rewritable_lvalue_p (tree lhs)
          && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
                       mem_ref_offset (lhs))
          && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
-                           TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
+                           TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
+         && known_ge (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (decl))),
+                      wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (lhs)))))
        {
          poly_uint64 lhs_bits, nelts;
          if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)), &lhs_bits)
              && multiple_p (lhs_bits,
                             tree_to_uhwi
                               (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl)))),
-                            &nelts))
+                            &nelts)
+             && valid_vector_subparts_p (nelts))
            {
              if (known_eq (nelts, 1u))
                return false;
@@ -1580,8 +1590,8 @@ non_rewritable_lvalue_p (tree lhs)
   return true;
 }
 
-/* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
-   mark the variable VAR for conversion into SSA.  Return true when updating
+/* When possible, clear TREE_ADDRESSABLE bit, set or clear DECL_NOT_GIMPLE_REG_P
+   and mark the variable VAR for conversion into SSA.  Return true when updating
    stmts is required.  */
 
 static void
@@ -1594,24 +1604,11 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
       || bitmap_bit_p (addresses_taken, DECL_UID (var)))
     return;
 
-  if (TREE_ADDRESSABLE (var)
-      /* Do not change TREE_ADDRESSABLE if we need to preserve var as
-        a non-register.  Otherwise we are confused and forget to
-        add virtual operands for it.  */
-      && (!is_gimple_reg_type (TREE_TYPE (var))
-         || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
-         || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
-         || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
+  bool maybe_reg = false;
+  if (TREE_ADDRESSABLE (var))
     {
       TREE_ADDRESSABLE (var) = 0;
-      /* If we cleared TREE_ADDRESSABLE make sure DECL_GIMPLE_REG_P
-         is unset if we cannot rewrite the var into SSA.  */
-      if ((TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
-          || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
-         && bitmap_bit_p (not_reg_needs, DECL_UID (var)))
-       DECL_GIMPLE_REG_P (var) = 0;
-      if (is_gimple_reg (var))
-       bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
+      maybe_reg = true;
       if (dump_file)
        {
          fprintf (dump_file, "No longer having address taken: ");
@@ -1620,20 +1617,36 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
        }
     }
 
-  if (!DECL_GIMPLE_REG_P (var)
-      && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
-      && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
-         || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
-      && !TREE_THIS_VOLATILE (var)
-      && (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
+  /* For register type decls if we do not have any partial defs
+     we cannot express in SSA form mark them as DECL_NOT_GIMPLE_REG_P
+     as to avoid SSA rewrite.  For the others go ahead and mark
+     them for renaming.  */
+  if (is_gimple_reg_type (TREE_TYPE (var)))
     {
-      DECL_GIMPLE_REG_P (var) = 1;
-      bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
-      if (dump_file)
+      if (bitmap_bit_p (not_reg_needs, DECL_UID (var)))
        {
-         fprintf (dump_file, "Now a gimple register: ");
-         print_generic_expr (dump_file, var);
-         fprintf (dump_file, "\n");
+         DECL_NOT_GIMPLE_REG_P (var) = 1;
+         if (dump_file)
+           {
+             fprintf (dump_file, "Has partial defs: ");
+             print_generic_expr (dump_file, var);
+             fprintf (dump_file, "\n");
+           }
+       }
+      else if (DECL_NOT_GIMPLE_REG_P (var))
+       {
+         maybe_reg = true;
+         DECL_NOT_GIMPLE_REG_P (var) = 0;
+       }
+      if (maybe_reg && is_gimple_reg (var))
+       {
+         if (dump_file)
+           {
+             fprintf (dump_file, "Now a gimple register: ");
+             print_generic_expr (dump_file, var);
+             fprintf (dump_file, "\n");
+           }
+         bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
        }
     }
 }
@@ -1666,7 +1679,8 @@ is_asan_mark_p (gimple *stmt)
   return false;
 }
 
-/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables.  */
+/* Compute TREE_ADDRESSABLE and whether we have unhandled partial defs
+   for local variables.  */
 
 void
 execute_update_addresses_taken (void)
@@ -1899,6 +1913,11 @@ execute_update_addresses_taken (void)
                    && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
                    && VECTOR_TYPE_P (TREE_TYPE (sym))
                    && TYPE_MODE (TREE_TYPE (sym)) != BLKmode
+                   /* If it is a full replacement we can do better below.  */
+                   && maybe_ne (wi::to_poly_offset
+                                  (TYPE_SIZE_UNIT (TREE_TYPE (lhs))),
+                                wi::to_poly_offset
+                                   (TYPE_SIZE_UNIT (TREE_TYPE (sym))))
                    && known_ge (mem_ref_offset (lhs), 0)
                    && known_gt (wi::to_poly_offset
                                   (TYPE_SIZE_UNIT (TREE_TYPE (sym))),
@@ -1920,7 +1939,8 @@ execute_update_addresses_taken (void)
                                             (TYPE_SIZE (TREE_TYPE
                                                           (TREE_TYPE (sym)))),
                                           &nelts)
-                           && maybe_ne (nelts, 1u))
+                           && maybe_ne (nelts, 1u)
+                           && valid_vector_subparts_p (nelts))
                          temtype = build_vector_type (temtype, nelts);
                        tree tem = make_ssa_name (temtype);
                        gimple *pun
@@ -2016,9 +2036,7 @@ execute_update_addresses_taken (void)
                            /* In ASAN_MARK (UNPOISON, &b, ...) the variable
                               is uninitialized.  Avoid dependencies on
                               previous out of scope value.  */
-                           tree clobber
-                             = build_constructor (TREE_TYPE (var), NULL);
-                           TREE_THIS_VOLATILE (clobber) = 1;
+                           tree clobber = build_clobber (TREE_TYPE (var));
                            gimple *g = gimple_build_assign (var, clobber);
                            gsi_replace (&gsi, g, GSI_SAME_STMT);
                          }