diff options
Diffstat (limited to 'gcc/tree-cfgcleanup.cc')
-rw-r--r-- | gcc/tree-cfgcleanup.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc index a34a51e..5aaa18d 100644 --- a/gcc/tree-cfgcleanup.cc +++ b/gcc/tree-cfgcleanup.cc @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-into-ssa.h" #include "tree-cfgcleanup.h" #include "gimple-pretty-print.h" +#include "target.h" /* The set of blocks in that at least one of the following changes happened: @@ -1569,6 +1570,29 @@ execute_cleanup_cfg_post_optimizing (void) cleanup_dead_labels (); if (group_case_labels ()) todo |= TODO_cleanup_cfg; + + basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (bb); + /* If the first (and only) bb and the only non debug + statement is __builtin_unreachable call, then replace it with a trap + so the function is at least one instruction in size. */ + if (!gsi_end_p (gsi) + && gimple_call_builtin_p (gsi_stmt (gsi), BUILT_IN_UNREACHABLE)) + { + if (targetm.have_trap ()) + { + gimple_call_set_fndecl (gsi_stmt (gsi), builtin_decl_implicit (BUILT_IN_UNREACHABLE_TRAP)); + update_stmt (gsi_stmt (gsi)); + } + /* If the target does not have a trap, convert it into an infinite loop. */ + else + { + gsi_remove (&gsi, true); + make_single_succ_edge (bb, bb, EDGE_FALLTHRU); + fix_loop_structure (NULL); + } + } + if ((flag_compare_debug_opt || flag_compare_debug) && flag_dump_final_insns) { |