aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-optimize.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-optimize.c')
-rw-r--r--gcc/tree-optimize.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index d13c04f..3e7ca89 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -180,6 +180,25 @@ execute_fixup_cfg (void)
FOR_EACH_EDGE (e, ei, bb->succs)
e->count = (e->count * count_scale
+ REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+
+ /* If we have a basic block with no successors that does not
+ end with a control statement or a noreturn call end it with
+ a call to __builtin_unreachable. This situation can occur
+ when inlining a noreturn call that does in fact return. */
+ if (EDGE_COUNT (bb->succs) == 0)
+ {
+ gimple stmt = last_stmt (bb);
+ if (!stmt
+ || (!is_ctrl_stmt (stmt)
+ && (!is_gimple_call (stmt)
+ || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
+ {
+ stmt = gimple_build_call
+ (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ }
+ }
}
if (count_scale != REG_BR_PROB_BASE)
compute_function_frequency ();