]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* tree-cfgcleanup.c (fixup_noreturn_call): Break out from ...;
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Jun 2010 20:35:08 +0000 (20:35 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Jun 2010 20:35:08 +0000 (20:35 +0000)
remove return value.
(split_bbs_on_noreturn_calls) .... here.
* tree-optimize.c (execute_fixup_cfg): Fixup noreturn calls too.
* tree-flow.h (fixup_noreturn_call): New.
* testsuite/gcc.dg/lto/noreturn-1_1.c: New testcase.
* testsuite/gcc.dg/lto/noreturn-1_0.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160122 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/noreturn-1_0.c
gcc/testsuite/gcc.dg/lto/noreturn-1_1.c
gcc/tree-cfgcleanup.c
gcc/tree-flow.h
gcc/tree-optimize.c

index df5d3c648b4ab3cf5e6fb78818408908ec4a2ea6..513b3181ac60f96c64ea6380d369fe98090e2a56 100644 (file)
@@ -1,3 +1,11 @@
+2010-06-01  Jan Hubicka  <jh@suse.cz>
+
+       * tree-cfgcleanup.c (fixup_noreturn_call): Break out from ...;
+       remove return value.
+       (split_bbs_on_noreturn_calls) .... here.
+       * tree-optimize.c (execute_fixup_cfg): Fixup noreturn calls too.
+       * tree-flow.h (fixup_noreturn_call): New.
+
 2010-06-01  Jan Hubicka  <jh@suse.cz>
 
        * emit-rtl.c (remove_insn): Fix thinko in prevoius patch.
index 4011291c8c0dfbdb644574b2589eeafe8de73b64..464f02a4641a22b995486f56cf43b54f26656b69 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-31 Jan Hubicka  <jh@suse.cz>
+
+       * testsuite/gcc.dg/lto/noreturn-1_1.c: New testcase.
+       * testsuite/gcc.dg/lto/noreturn-1_0.c: New testcase.
+
 2010-05-31  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/36928
index eb71c64910e325c7e46bb27d23d1fe06a71b7d05..daac35dce35c3b49093e756213bd5dd9c3cf61bc 100644 (file)
@@ -5,17 +5,3 @@ call_me (void)
 {
   exit (0);
 }
-void exit (int);
-__attribute__ ((noreturn))
-int
-call_me (void)
-{
-  exit (0);
-}
-void exit (int);
-__attribute__ ((noreturn))
-int
-call_me (void)
-{
-  exit (0);
-}
index 8e8b0607cdda0d4d69f289a005fcfd2d364bc8ff..6dbded718d86dd47a137ab4f0f86efdde5ba3a69 100644 (file)
@@ -7,21 +7,3 @@ main(void)
 {
  return call_me ();
 }
-/* { dg-lto-do run } */
-/* { dg-lto-options {{-O2 -fwhopr} } } */
-
-int call_me (void);
-int
-main(void)
-{
- return call_me ();
-}
-/* { dg-lto-do run } */
-/* { dg-lto-options {{-O2 -fwhopr} } } */
-
-int call_me (void);
-int
-main(void)
-{
- return call_me ();
-}
index b8f5a549b303c4cd042f701751a408db50f1ddb2..10fc7aceb644def9118458dc3542dada71064f2a 100644 (file)
@@ -538,6 +538,49 @@ remove_forwarder_block (basic_block bb)
   return true;
 }
 
+/* STMT is a call that has been discovered noreturn.  Fixup the CFG
+   and remove LHS.  Return true if something changed.  */
+
+bool
+fixup_noreturn_call (gimple stmt)
+{
+  basic_block bb = gimple_bb (stmt);
+  bool changed = false;
+
+  if (gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
+    return false;
+
+  /* First split basic block if stmt is not last.  */
+  if (stmt != gsi_stmt (gsi_last_bb (bb)))
+    split_block (bb, stmt);
+
+  changed |= remove_fallthru_edge (bb->succs);
+
+  /* If there is LHS, remove it.  */
+  if (gimple_call_lhs (stmt))
+    {
+      tree op = gimple_call_lhs (stmt);
+      gimple_call_set_lhs (stmt, NULL_TREE);
+      /* We need to remove SSA name to avoid checking.
+        All uses are dominated by the noreturn and thus will
+        be removed afterwards.  */
+      if (TREE_CODE (op) == SSA_NAME)
+       {
+         use_operand_p use_p;
+          imm_use_iterator iter;
+         gimple use_stmt;
+
+          FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
+           FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+             SET_USE (use_p, error_mark_node);
+       }
+      update_stmt (stmt);
+      changed = true;
+    }
+  return changed;
+}
+
+
 /* Split basic blocks on calls in the middle of a basic block that are now
    known not to return, and remove the unreachable code.  */
 
@@ -560,13 +603,10 @@ split_bbs_on_noreturn_calls (void)
            || bb->index < NUM_FIXED_BLOCKS
            || bb->index >= n_basic_blocks
            || BASIC_BLOCK (bb->index) != bb
-           || last_stmt (bb) == stmt
            || !gimple_call_noreturn_p (stmt))
          continue;
 
-       changed = true;
-       split_block (bb, stmt);
-       remove_fallthru_edge (bb->succs);
+       changed |= fixup_noreturn_call (stmt);
       }
 
   return changed;
index bcbd7fbe440e746b552458e10b83057bcf148308..f28ef31c2a91d0c32f8621411158f8ecca8a16d2 100644 (file)
@@ -870,6 +870,7 @@ tree maybe_fold_tmr (tree);
 
 unsigned int execute_free_datastructures (void);
 unsigned int execute_fixup_cfg (void);
+bool fixup_noreturn_call (gimple stmt);
 
 #include "tree-flow-inline.h"
 
index ed4676996dd55ff9b6be77067dbe64a1909818ea..2631e14cce4e56f519fee0269390301f8b7ad9f0 100644 (file)
@@ -231,7 +231,8 @@ execute_free_datastructures (void)
 }
 
 /* Pass: fixup_cfg.  IPA passes, compilation of earlier functions or inlining
-   might have changed some properties, such as marked functions nothrow.
+   might have changed some properties, such as marked functions nothrow,
+   pure, const or noreturn.
    Remove redundant edges and basic blocks, and create new ones if necessary.
 
    This pass can't be executed as stand alone pass from pass manager, because
@@ -267,19 +268,23 @@ execute_fixup_cfg (void)
          tree decl = is_gimple_call (stmt)
                      ? gimple_call_fndecl (stmt)
                      : NULL;
-
-         if (decl
-             && gimple_call_flags (stmt) & (ECF_CONST
-                                            | ECF_PURE
-                                            | ECF_LOOPING_CONST_OR_PURE))
+         if (decl)
            {
-             if (gimple_in_ssa_p (cfun))
+             int flags = gimple_call_flags (stmt);
+             if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
                {
-                 todo |= TODO_update_ssa | TODO_cleanup_cfg;
-                 mark_symbols_for_renaming (stmt);
-                 update_stmt (stmt);
+                 if (gimple_in_ssa_p (cfun))
+                   {
+                     todo |= TODO_update_ssa | TODO_cleanup_cfg;
+                     mark_symbols_for_renaming (stmt);
+                     update_stmt (stmt);
+                   }
                }
-           }
+             
+             if (flags & ECF_NORETURN
+                 && fixup_noreturn_call (stmt))
+               todo |= TODO_cleanup_cfg;
+            }
 
          maybe_clean_eh_stmt (stmt);
        }
@@ -293,6 +298,13 @@ execute_fixup_cfg (void)
   if (count_scale != REG_BR_PROB_BASE)
     compute_function_frequency ();
 
+  /* We just processed all calls.  */
+  if (cfun->gimple_df)
+    {
+      VEC_free (gimple, gc, MODIFIED_NORETURN_CALLS (cfun));
+      MODIFIED_NORETURN_CALLS (cfun) = NULL;
+    }
+
   /* Dump a textual representation of the flowgraph.  */
   if (dump_file)
     gimple_dump_cfg (dump_file, dump_flags);