aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2012-07-09 13:28:51 +0000
committerTom de Vries <vries@gcc.gnu.org>2012-07-09 13:28:51 +0000
commitc61e5cc19a30f5e8cb6ea3bd2a23b643f0dfbadf (patch)
tree1b9cd1549e86b0e1d14b1a7cfacbb928e0d5e245 /gcc/tree-ssa-ccp.c
parent44a9d0eac23440d76f06ef9b3d429d5c3d286ded (diff)
downloadgcc-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.c71
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 ");