tree-ssa-ccp.c (optimize_unreachable): New function.
authorTom de Vries <tom@codesourcery.com>
Mon, 9 Jul 2012 13:28:51 +0000 (13:28 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Mon, 9 Jul 2012 13:28:51 +0000 (13:28 +0000)
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

gcc/ChangeLog
gcc/tree-ssa-ccp.c

index 7a61eb6baabbc129d1606836c5ceb8f9bc9c09f2..2b0ebab4002f349c95f2e7c05cd1fe84909ee627 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2012-07-09  Richard Guenther  <rguenther@suse.de>
 
        PR bootstrap/53898
index c248cf23c735bc386cac5254fa6313b76474e6ac..384bbb7c91f1b4c27e9c99183e4c82e6df69137b 100644 (file)
@@ -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  ");