As promised in <https://gcc.gnu.org/ml/gcc-patches/2016-05/msg01638.html>,
this is a simple clean-up which makes use of a new predicate.  Richi suggested
adding maybe_drop_lhs_from_noreturn_call which would be nicer, but I didn't
know how to do that, given the handling if lhs is an SSA_NAME.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2016-05-23  Marek Polacek  <pola...@redhat.com>

        * tree.h (can_remove_lhs_p): New predicate.
        * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Use it.
        * gimple-fold.c (gimple_fold_call): Likewise.
        * gimplify.c (gimplify_modify_expr): Likewise.
        * tree-cfgcleanup.c (fixup_noreturn_call): Likewise.

diff --git gcc/cgraph.c gcc/cgraph.c
index cf9192f..a9efa39 100644
--- gcc/cgraph.c
+++ gcc/cgraph.c
@@ -1513,10 +1513,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
     }
 
   /* If the call becomes noreturn, remove the LHS if possible.  */
-  if (lhs
-      && (gimple_call_flags (new_stmt) & ECF_NORETURN)
-      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
-      && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))
+  if (gimple_call_noreturn_p (new_stmt) && can_remove_lhs_p (lhs))
     {
       if (TREE_CODE (lhs) == SSA_NAME)
        {
diff --git gcc/gimple-fold.c gcc/gimple-fold.c
index 858f484..37c7d4e 100644
--- gcc/gimple-fold.c
+++ gcc/gimple-fold.c
@@ -3052,12 +3052,9 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool 
inplace)
                          == void_type_node))
                    gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
                  /* If the call becomes noreturn, remove the lhs.  */
-                 if (lhs
-                     && (gimple_call_flags (stmt) & ECF_NORETURN)
+                 if (gimple_call_noreturn_p (stmt)
                      && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
-                         || ((TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
-                              == INTEGER_CST)
-                             && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))))
+                         || can_remove_lhs_p (lhs)))
                    {
                      if (TREE_CODE (lhs) == SSA_NAME)
                        {
diff --git gcc/gimplify.c gcc/gimplify.c
index 4a544e3..a5977f2 100644
--- gcc/gimplify.c
+++ gcc/gimplify.c
@@ -4847,9 +4847,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
            }
        }
       notice_special_calls (call_stmt);
-      if (!gimple_call_noreturn_p (call_stmt)
-         || TREE_ADDRESSABLE (TREE_TYPE (*to_p))
-         || TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
+      if (!gimple_call_noreturn_p (call_stmt) || !can_remove_lhs_p (*to_p))
        gimple_call_set_lhs (call_stmt, *to_p);
       else if (TREE_CODE (*to_p) == SSA_NAME)
        /* The above is somewhat premature, avoid ICEing later for a
diff --git gcc/tree-cfgcleanup.c gcc/tree-cfgcleanup.c
index 46d0fa3..9ca4447 100644
--- gcc/tree-cfgcleanup.c
+++ gcc/tree-cfgcleanup.c
@@ -604,8 +604,7 @@ fixup_noreturn_call (gimple *stmt)
      temporaries of variable-sized types is not supported.  Also don't
      do this with TREE_ADDRESSABLE types, as assign_temp will abort.  */
   tree lhs = gimple_call_lhs (stmt);
-  if (lhs && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
-      && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))
+  if (can_remove_lhs_p (lhs))
     {
       gimple_call_set_lhs (stmt, NULL_TREE);
 
diff --git gcc/tree.h gcc/tree.h
index 2510d16..c217510 100644
--- gcc/tree.h
+++ gcc/tree.h
@@ -5471,4 +5471,14 @@ desired_pro_or_demotion_p (const_tree to_type, 
const_tree from_type)
   return to_type_precision <= TYPE_PRECISION (from_type);
 }
 
+/* Return true if the LHS of a call can be removed.  */
+
+inline bool
+can_remove_lhs_p (tree lhs)
+{
+  return (lhs
+         && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
+         && !TREE_ADDRESSABLE (TREE_TYPE (lhs)));
+}
+
 #endif  /* GCC_TREE_H  */

        Marek

Reply via email to