aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-06-01 22:35:08 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-06-01 20:35:08 +0000
commit566d09eff650c4722dad479494213ecf29372da7 (patch)
tree444592859a62623603f67efe10d11b809be02e54 /gcc
parentfb9ef4c18e7f5294fab9ba71f6d1fe1c03eae7aa (diff)
downloadgcc-566d09eff650c4722dad479494213ecf29372da7.zip
gcc-566d09eff650c4722dad479494213ecf29372da7.tar.gz
gcc-566d09eff650c4722dad479494213ecf29372da7.tar.bz2
tree-cfgcleanup.c (fixup_noreturn_call): Break out from ...; remove return value.
* 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. * testsuite/gcc.dg/lto/noreturn-1_1.c: New testcase. * testsuite/gcc.dg/lto/noreturn-1_0.c: New testcase. From-SVN: r160122
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/lto/noreturn-1_0.c14
-rw-r--r--gcc/testsuite/gcc.dg/lto/noreturn-1_1.c18
-rw-r--r--gcc/tree-cfgcleanup.c48
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-optimize.c34
7 files changed, 81 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index df5d3c6..513b318 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
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.
2010-06-01 Nathan Froyd <froydnj@codesourcery.com>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4011291..464f02a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/lto/noreturn-1_0.c b/gcc/testsuite/gcc.dg/lto/noreturn-1_0.c
index eb71c64..daac35d 100644
--- a/gcc/testsuite/gcc.dg/lto/noreturn-1_0.c
+++ b/gcc/testsuite/gcc.dg/lto/noreturn-1_0.c
@@ -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);
-}
diff --git a/gcc/testsuite/gcc.dg/lto/noreturn-1_1.c b/gcc/testsuite/gcc.dg/lto/noreturn-1_1.c
index 8e8b060..6dbded7 100644
--- a/gcc/testsuite/gcc.dg/lto/noreturn-1_1.c
+++ b/gcc/testsuite/gcc.dg/lto/noreturn-1_1.c
@@ -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 ();
-}
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b8f5a54..10fc7ac 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -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;
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index bcbd7fb..f28ef31 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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"
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index ed46769..2631e14 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -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);