- warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
- return true;
- }
- }
-
- switch (gimple_code (stmt))
- {
- /* Unfortunately, we need the CFG now to detect unreachable
- branches in a conditional, so conditionals are not handled here. */
-
- case GIMPLE_TRY:
- if (remove_useless_stmts_warn_notreached (gimple_try_eval (stmt)))
- return true;
- if (remove_useless_stmts_warn_notreached (gimple_try_cleanup (stmt)))
- return true;
- break;
-
- case GIMPLE_CATCH:
- return remove_useless_stmts_warn_notreached (gimple_catch_handler (stmt));
-
- case GIMPLE_EH_FILTER:
- return remove_useless_stmts_warn_notreached (gimple_eh_filter_failure (stmt));
-
- case GIMPLE_BIND:
- return remove_useless_stmts_warn_notreached (gimple_bind_body (stmt));
-
- default:
- break;
- }
- }
-
- return false;
-}
-
-/* Helper for remove_useless_stmts_1. Handle GIMPLE_COND statements. */
-
-static void
-remove_useless_stmts_cond (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
- gimple stmt = gsi_stmt (*gsi);
-
- /* The folded result must still be a conditional statement. */
- fold_stmt_inplace (stmt);
-
- data->may_branch = true;
-
- /* Replace trivial conditionals with gotos. */
- if (gimple_cond_true_p (stmt))
- {
- /* Goto THEN label. */
- tree then_label = gimple_cond_true_label (stmt);
-
- gsi_replace (gsi, gimple_build_goto (then_label), false);
- data->last_goto_gsi = *gsi;
- data->last_was_goto = true;
- data->repeat = true;
- }
- else if (gimple_cond_false_p (stmt))
- {
- /* Goto ELSE label. */
- tree else_label = gimple_cond_false_label (stmt);
-
- gsi_replace (gsi, gimple_build_goto (else_label), false);
- data->last_goto_gsi = *gsi;
- data->last_was_goto = true;
- data->repeat = true;
- }
- else
- {
- tree then_label = gimple_cond_true_label (stmt);
- tree else_label = gimple_cond_false_label (stmt);
-
- if (then_label == else_label)
- {
- /* Goto common destination. */
- gsi_replace (gsi, gimple_build_goto (then_label), false);
- data->last_goto_gsi = *gsi;
- data->last_was_goto = true;
- data->repeat = true;
- }
- }
-
- gsi_next (gsi);
-
- data->last_was_goto = false;
-}
-
-/* Helper for remove_useless_stmts_1.
- Handle the try-finally case for GIMPLE_TRY statements. */
-
-static void
-remove_useless_stmts_tf (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
- bool save_may_branch, save_may_throw;
- bool this_may_branch, this_may_throw;
-
- gimple_seq eval_seq, cleanup_seq;
- gimple_stmt_iterator eval_gsi, cleanup_gsi;
-
- gimple stmt = gsi_stmt (*gsi);
-
- /* Collect may_branch and may_throw information for the body only. */
- save_may_branch = data->may_branch;
- save_may_throw = data->may_throw;
- data->may_branch = false;
- data->may_throw = false;
- data->last_was_goto = false;
-
- eval_seq = gimple_try_eval (stmt);
- eval_gsi = gsi_start (eval_seq);
- remove_useless_stmts_1 (&eval_gsi, data);
-
- this_may_branch = data->may_branch;
- this_may_throw = data->may_throw;
- data->may_branch |= save_may_branch;
- data->may_throw |= save_may_throw;
- data->last_was_goto = false;
-
- cleanup_seq = gimple_try_cleanup (stmt);
- cleanup_gsi = gsi_start (cleanup_seq);
- remove_useless_stmts_1 (&cleanup_gsi, data);
-
- /* If the body is empty, then we can emit the FINALLY block without
- the enclosing TRY_FINALLY_EXPR. */
- if (gimple_seq_empty_p (eval_seq))
- {
- gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
- gsi_remove (gsi, false);
- data->repeat = true;
- }
-
- /* If the handler is empty, then we can emit the TRY block without
- the enclosing TRY_FINALLY_EXPR. */
- else if (gimple_seq_empty_p (cleanup_seq))
- {
- gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
- gsi_remove (gsi, false);
- data->repeat = true;
- }
-
- /* If the body neither throws, nor branches, then we can safely
- string the TRY and FINALLY blocks together. */
- else if (!this_may_branch && !this_may_throw)
- {
- gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
- gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
- gsi_remove (gsi, false);
- data->repeat = true;
- }
- else
- gsi_next (gsi);
-}
-
-/* Helper for remove_useless_stmts_1.
- Handle the try-catch case for GIMPLE_TRY statements. */
-
-static void
-remove_useless_stmts_tc (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
- bool save_may_throw, this_may_throw;
-
- gimple_seq eval_seq, cleanup_seq, handler_seq, failure_seq;
- gimple_stmt_iterator eval_gsi, cleanup_gsi, handler_gsi, failure_gsi;
-
- gimple stmt = gsi_stmt (*gsi);
-
- /* Collect may_throw information for the body only. */
- save_may_throw = data->may_throw;
- data->may_throw = false;
- data->last_was_goto = false;
-
- eval_seq = gimple_try_eval (stmt);
- eval_gsi = gsi_start (eval_seq);
- remove_useless_stmts_1 (&eval_gsi, data);
-
- this_may_throw = data->may_throw;
- data->may_throw = save_may_throw;
-
- cleanup_seq = gimple_try_cleanup (stmt);
-
- /* If the body cannot throw, then we can drop the entire TRY_CATCH_EXPR. */
- if (!this_may_throw)
- {
- if (warn_notreached)
- {
- remove_useless_stmts_warn_notreached (cleanup_seq);
- }
- gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
- gsi_remove (gsi, false);
- data->repeat = true;
- return;
- }
-
- /* Process the catch clause specially. We may be able to tell that
- no exceptions propagate past this point. */
-
- this_may_throw = true;
- cleanup_gsi = gsi_start (cleanup_seq);
- stmt = gsi_stmt (cleanup_gsi);
- data->last_was_goto = false;
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_CATCH:
- /* If the first element is a catch, they all must be. */
- while (!gsi_end_p (cleanup_gsi))
- {
- stmt = gsi_stmt (cleanup_gsi);
- /* If we catch all exceptions, then the body does not
- propagate exceptions past this point. */
- if (gimple_catch_types (stmt) == NULL)
- this_may_throw = false;
- data->last_was_goto = false;
- handler_seq = gimple_catch_handler (stmt);
- handler_gsi = gsi_start (handler_seq);
- remove_useless_stmts_1 (&handler_gsi, data);
- gsi_next (&cleanup_gsi);
- }
- gsi_next (gsi);
- break;
-
- case GIMPLE_EH_FILTER:
- /* If the first element is an eh_filter, it should stand alone. */
- if (gimple_eh_filter_must_not_throw (stmt))
- this_may_throw = false;
- else if (gimple_eh_filter_types (stmt) == NULL)
- this_may_throw = false;
- failure_seq = gimple_eh_filter_failure (stmt);
- failure_gsi = gsi_start (failure_seq);
- remove_useless_stmts_1 (&failure_gsi, data);
- gsi_next (gsi);
- break;
-
- default:
- /* Otherwise this is a list of cleanup statements. */
- remove_useless_stmts_1 (&cleanup_gsi, data);
-
- /* If the cleanup is empty, then we can emit the TRY block without
- the enclosing TRY_CATCH_EXPR. */
- if (gimple_seq_empty_p (cleanup_seq))
- {
- gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
- gsi_remove(gsi, false);
- data->repeat = true;