]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-ssa-dce.c
Update copyright years.
[thirdparty/gcc.git] / gcc / tree-ssa-dce.c
index fd5f24c746ca0359fdf5f883bfefeaf87e473848..d155bdfb2aefd121a578fc81f609946592ca4933 100644 (file)
@@ -1,5 +1,5 @@
 /* Dead code elimination pass for the GNU compiler.
-   Copyright (C) 2002-2020 Free Software Foundation, Inc.
+   Copyright (C) 2002-2021 Free Software Foundation, Inc.
    Contributed by Ben Elliston <bje@redhat.com>
    and Andrew MacLeod <amacleod@redhat.com>
    Adapted to use control dependence by Steven Bosscher, SUSE Labs.
@@ -201,9 +201,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
 {
   /* With non-call exceptions, we have to assume that all statements could
      throw.  If a statement could throw, it can be deemed necessary.  */
-  if (cfun->can_throw_non_call_exceptions
-      && !cfun->can_delete_dead_exceptions
-      && stmt_could_throw_p (cfun, stmt))
+  if (stmt_unremovable_because_of_non_call_eh_p (cfun, stmt))
     {
       mark_stmt_necessary (stmt, true);
       return;
@@ -241,6 +239,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
            CASE_BUILT_IN_ALLOCA:
            case BUILT_IN_STRDUP:
            case BUILT_IN_STRNDUP:
+           case BUILT_IN_GOMP_ALLOC:
              return;
 
            default:;
@@ -595,9 +594,9 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
 
   /* We want to skip statments that do not constitute stores but have
      a virtual definition.  */
-  if (is_gimple_call (def_stmt))
+  if (gcall *call = dyn_cast <gcall *> (def_stmt))
     {
-      tree callee = gimple_call_fndecl (def_stmt);
+      tree callee = gimple_call_fndecl (call);
       if (callee != NULL_TREE
          && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
        switch (DECL_FUNCTION_CODE (callee))
@@ -607,6 +606,8 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
          case BUILT_IN_CALLOC:
          CASE_BUILT_IN_ALLOCA:
          case BUILT_IN_FREE:
+         case BUILT_IN_GOMP_ALLOC:
+         case BUILT_IN_GOMP_FREE:
            return false;
 
          default:;
@@ -614,7 +615,8 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
 
       if (callee != NULL_TREE
          && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
-             || DECL_IS_REPLACEABLE_OPERATOR_DELETE_P (callee)))
+             || DECL_IS_OPERATOR_DELETE_P (callee))
+         && gimple_call_from_new_or_delete (call))
        return false;
     }
 
@@ -646,6 +648,17 @@ degenerate_phi_p (gimple *phi)
   return true;
 }
 
+/* Return that NEW_CALL and DELETE_CALL are a valid pair of new
+   and delete  operators.  */
+
+static bool
+valid_new_delete_pair_p (gimple *new_call, gimple *delete_call)
+{
+  tree new_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (new_call));
+  tree delete_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (delete_call));
+  return valid_new_delete_pair_p (new_asm, delete_asm);
+}
+
 /* Propagate necessity using the operands of necessary statements.
    Process the uses on each statement in the worklist, and add all
    feeding statements which contribute to the calculation of this
@@ -806,29 +819,38 @@ propagate_necessity (bool aggressive)
             processing the argument.  */
          bool is_delete_operator
            = (is_gimple_call (stmt)
-              && gimple_call_replaceable_operator_delete_p (as_a <gcall *> (stmt)));
+              && gimple_call_from_new_or_delete (as_a <gcall *> (stmt))
+              && gimple_call_operator_delete_p (as_a <gcall *> (stmt)));
          if (is_delete_operator
-             || gimple_call_builtin_p (stmt, BUILT_IN_FREE))
+             || gimple_call_builtin_p (stmt, BUILT_IN_FREE)
+             || gimple_call_builtin_p (stmt, BUILT_IN_GOMP_FREE))
            {
              tree ptr = gimple_call_arg (stmt, 0);
-             gimple *def_stmt;
+             gcall *def_stmt;
              tree def_callee;
              /* If the pointer we free is defined by an allocation
                 function do not add the call to the worklist.  */
              if (TREE_CODE (ptr) == SSA_NAME
-                 && is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr))
+                 && (def_stmt = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (ptr)))
                  && (def_callee = gimple_call_fndecl (def_stmt))
                  && ((DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL
                       && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC
                           || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC
-                          || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC))
-                     || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee)))
+                          || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC
+                          || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_GOMP_ALLOC))
+                     || (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee)
+                         && gimple_call_from_new_or_delete (def_stmt))))
                {
-                 /* Delete operators can have alignment and (or) size as next
-                    arguments.  When being a SSA_NAME, they must be marked
-                    as necessary.  */
-                 if (is_delete_operator && gimple_call_num_args (stmt) >= 2)
-                   for (unsigned i = 1; i < gimple_call_num_args (stmt); i++)
+                 if (is_delete_operator
+                     && !valid_new_delete_pair_p (def_stmt, stmt))
+                   mark_operand_necessary (gimple_call_arg (stmt, 0));
+
+                 /* Delete operators can have alignment and (or) size
+                    as next arguments.  When being a SSA_NAME, they
+                    must be marked as necessary.  Similarly GOMP_free.  */
+                 if (gimple_call_num_args (stmt) >= 2)
+                   for (unsigned i = 1; i < gimple_call_num_args (stmt);
+                        i++)
                      {
                        tree arg = gimple_call_arg (stmt, i);
                        if (TREE_CODE (arg) == SSA_NAME)
@@ -871,9 +893,9 @@ propagate_necessity (bool aggressive)
             in 1).  By keeping a global visited bitmap for references
             we walk for 2) we avoid quadratic behavior for those.  */
 
-         if (is_gimple_call (stmt))
+         if (gcall *call = dyn_cast <gcall *> (stmt))
            {
-             tree callee = gimple_call_fndecl (stmt);
+             tree callee = gimple_call_fndecl (call);
              unsigned i;
 
              /* Calls to functions that are merely acting as barriers
@@ -896,22 +918,23 @@ propagate_necessity (bool aggressive)
 
              if (callee != NULL_TREE
                  && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
-                     || DECL_IS_REPLACEABLE_OPERATOR_DELETE_P (callee)))
+                     || DECL_IS_OPERATOR_DELETE_P (callee))
+                 && gimple_call_from_new_or_delete (call))
                continue;
 
              /* Calls implicitly load from memory, their arguments
                 in addition may explicitly perform memory loads.  */
-             mark_all_reaching_defs_necessary (stmt);
-             for (i = 0; i < gimple_call_num_args (stmt); ++i)
+             mark_all_reaching_defs_necessary (call);
+             for (i = 0; i < gimple_call_num_args (call); ++i)
                {
-                 tree arg = gimple_call_arg (stmt, i);
+                 tree arg = gimple_call_arg (call, i);
                  if (TREE_CODE (arg) == SSA_NAME
                      || is_gimple_min_invariant (arg))
                    continue;
                  if (TREE_CODE (arg) == WITH_SIZE_EXPR)
                    arg = TREE_OPERAND (arg, 0);
                  if (!ref_may_be_aliased (arg))
-                   mark_aliased_reaching_defs_necessary (stmt, arg);
+                   mark_aliased_reaching_defs_necessary (call, arg);
                }
            }
          else if (gimple_assign_single_p (stmt))
@@ -1321,7 +1344,8 @@ eliminate_unnecessary_stmts (void)
          if (gimple_plf (stmt, STMT_NECESSARY)
              && (gimple_call_builtin_p (stmt, BUILT_IN_FREE)
                  || (is_gimple_call (stmt)
-                     && gimple_call_replaceable_operator_delete_p (as_a <gcall *> (stmt)))))
+                     && gimple_call_from_new_or_delete (as_a <gcall *> (stmt))
+                     && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
            {
              tree ptr = gimple_call_arg (stmt, 0);
              if (TREE_CODE (ptr) == SSA_NAME)