diff options
author | Tom de Vries <tom@codesourcery.com> | 2012-07-09 13:28:51 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2012-07-09 13:28:51 +0000 |
commit | c61e5cc19a30f5e8cb6ea3bd2a23b643f0dfbadf (patch) | |
tree | 1b9cd1549e86b0e1d14b1a7cfacbb928e0d5e245 /gcc/tree-ssa-ccp.c | |
parent | 44a9d0eac23440d76f06ef9b3d429d5c3d286ded (diff) | |
download | gcc-c61e5cc19a30f5e8cb6ea3bd2a23b643f0dfbadf.zip gcc-c61e5cc19a30f5e8cb6ea3bd2a23b643f0dfbadf.tar.gz gcc-c61e5cc19a30f5e8cb6ea3bd2a23b643f0dfbadf.tar.bz2 |
tree-ssa-ccp.c (optimize_unreachable): New function.
2012-07-09 Tom de Vries <tom@codesourcery.com>
Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (optimize_unreachable): New function.
(execute_fold_all_builtins): Use optimize_unreachable to optimize
BUILT_IN_UNREACHABLE. Don't optimize after BUILT_IN_UNREACHABLE.
Co-Authored-By: Richard Guenther <rguenther@suse.de>
From-SVN: r189383
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index c248cf2..384bbb7 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2318,6 +2318,69 @@ optimize_stdarg_builtin (gimple call) } } +/* Attemp to make the block of __builtin_unreachable I unreachable by changing + the incoming jumps. Return true if at least one jump was changed. */ + +static bool +optimize_unreachable (gimple_stmt_iterator i) +{ + basic_block bb = gsi_bb (i); + gimple_stmt_iterator gsi; + gimple stmt; + edge_iterator ei; + edge e; + bool ret; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + stmt = gsi_stmt (gsi); + + if (is_gimple_debug (stmt)) + continue; + + if (gimple_code (stmt) == GIMPLE_LABEL) + { + /* Verify we do not need to preserve the label. */ + if (FORCED_LABEL (gimple_label_label (stmt))) + return false; + + continue; + } + + /* Only handle the case that __builtin_unreachable is the first statement + in the block. We rely on DCE to remove stmts without side-effects + before __builtin_unreachable. */ + if (gsi_stmt (gsi) != gsi_stmt (i)) + return false; + } + + ret = false; + FOR_EACH_EDGE (e, ei, bb->preds) + { + gsi = gsi_last_bb (e->src); + stmt = gsi_stmt (gsi); + + if (stmt && gimple_code (stmt) == GIMPLE_COND) + { + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_false (stmt); + else if (e->flags & EDGE_FALSE_VALUE) + gimple_cond_make_true (stmt); + else + gcc_unreachable (); + } + else + { + /* Todo: handle other cases, f.i. switch statement. */ + continue; + } + + ret = true; + } + + return ret; +} + /* A simple pass that attempts to fold all builtin functions. This pass is run after we've propagated as many constants as we can. */ @@ -2379,6 +2442,11 @@ execute_fold_all_builtins (void) gsi_next (&i); continue; + case BUILT_IN_UNREACHABLE: + if (optimize_unreachable (i)) + cfg_changed = true; + break; + case BUILT_IN_VA_START: case BUILT_IN_VA_END: case BUILT_IN_VA_COPY: @@ -2393,6 +2461,9 @@ execute_fold_all_builtins (void) continue; } + if (result == NULL_TREE) + break; + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Simplified\n "); |