+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-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
{
exit (0);
}
-void exit (int);
-__attribute__ ((noreturn))
-int
-call_me (void)
-{
- exit (0);
-}
-void exit (int);
-__attribute__ ((noreturn))
-int
-call_me (void)
-{
- exit (0);
-}
{
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 ();
-}
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. */
|| 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;
unsigned int execute_free_datastructures (void);
unsigned int execute_fixup_cfg (void);
+bool fixup_noreturn_call (gimple stmt);
#include "tree-flow-inline.h"
}
/* 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
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);
}
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);