]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
basic-block.h (has_abnormal_outgoing_edge_p): Moved here from...
authorJeff Law <law@redhat.com>
Thu, 14 Nov 2013 20:57:38 +0000 (13:57 -0700)
committerJeff Law <law@gcc.gnu.org>
Thu, 14 Nov 2013 20:57:38 +0000 (13:57 -0700)
* basic-block.h (has_abnormal_outgoing_edge_p): Moved here from...
* tree-inline.c (has_abnormal_outgoing_edge_p): Remove.
* gimple-ssa-isolate-paths.c: Include tree-cfg.h.
(find_implicit_erroneous_behaviour): If a block has abnormal outgoing
edges, then ignore it.  If the statement exhibiting erroneous
behaviour ends basic blocks, with the exception of GIMPLE_RETURNs,
then we can not optimize.
(find_explicit_erroneous_behaviour): Likewise.

From-SVN: r204821

gcc/ChangeLog
gcc/basic-block.h
gcc/gimple-ssa-isolate-paths.c
gcc/tree-inline.c

index e6f7a6d77139c87ef4547d1f90daee8ff4e4420d..1b395cb83178768b02fef9fb74497bea06a775ed 100644 (file)
@@ -1,3 +1,15 @@
+2013-11-14  Jeff Law  <law@redhat.com>
+
+       PR middle-end/59127
+       * basic-block.h (has_abnormal_outgoing_edge_p): Moved here from...
+       * tree-inline.c (has_abnormal_outgoing_edge_p): Remove.
+       * gimple-ssa-isolate-paths.c: Include tree-cfg.h.
+       (find_implicit_erroneous_behaviour): If a block has abnormal outgoing
+       edges, then ignore it.  If the statement exhibiting erroneous
+       behaviour ends basic blocks, with the exception of GIMPLE_RETURNs,
+       then we can not optimize.
+       (find_explicit_erroneous_behaviour): Likewise.
+
 2013-11-14  Andrew MacLeod  <amacleod@redhat.com>
 
        * gimplify-me.h:  New file.  Add prototypes.
index 9c28f14afa4f6df4a7cd0ee093485e1a411b519a..b7e3b5042ff22b31e3483c4ea31b68c256ae1db1 100644 (file)
@@ -1008,4 +1008,19 @@ inverse_probability (int prob1)
   check_probability (prob1);
   return REG_BR_PROB_BASE - prob1;
 }
+
+/* Return true if BB has at least one abnormal outgoing edge.  */
+
+static inline bool
+has_abnormal_outgoing_edge_p (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    if (e->flags & EDGE_ABNORMAL)
+      return true;
+
+  return false;
+}
 #endif /* GCC_BASIC_BLOCK_H */
index 108b98e2917b990f5d02cb4038730c43fabdc5ea..66c13f4cf6fd51025d2915c00d6ee77f067afea4 100644 (file)
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa-iterators.h"
 #include "cfgloop.h"
 #include "tree-pass.h"
+#include "tree-cfg.h"
 
 
 static bool cfg_altered;
@@ -215,6 +216,17 @@ find_implicit_erroneous_behaviour (void)
     {
       gimple_stmt_iterator si;
 
+      /* Out of an abundance of caution, do not isolate paths to a
+        block where the block has any abnormal outgoing edges.
+
+        We might be able to relax this in the future.  We have to detect
+        when we have to split the block with the NULL dereference and
+        the trap we insert.  We have to preserve abnormal edges out
+        of the isolated block which in turn means updating PHIs at
+        the targets of those abnormal outgoing edges.  */
+      if (has_abnormal_outgoing_edge_p (bb))
+       continue;
+
       /* First look for a PHI which sets a pointer to NULL and which
         is then dereferenced within BB.  This is somewhat overly
         conservative, but probably catches most of the interesting
@@ -256,8 +268,15 @@ find_implicit_erroneous_behaviour (void)
                {
                  /* We only care about uses in BB.  Catching cases in
                     in other blocks would require more complex path
-                    isolation code.  */
-                 if (gimple_bb (use_stmt) != bb)
+                    isolation code. 
+
+                    If the statement must end a block and is not a
+                    GIMPLE_RETURN, then additional work would be
+                    necessary to isolate the path.  Just punt it for
+                    now.  */
+                 if (gimple_bb (use_stmt) != bb
+                     || (stmt_ends_bb_p (use_stmt)
+                         && gimple_code (use_stmt) != GIMPLE_RETURN))
                    continue;
 
                  if (infer_nonnull_range (use_stmt, lhs))
@@ -289,6 +308,17 @@ find_explicit_erroneous_behaviour (void)
     {
       gimple_stmt_iterator si;
 
+      /* Out of an abundance of caution, do not isolate paths to a
+        block where the block has any abnormal outgoing edges.
+
+        We might be able to relax this in the future.  We have to detect
+        when we have to split the block with the NULL dereference and
+        the trap we insert.  We have to preserve abnormal edges out
+        of the isolated block which in turn means updating PHIs at
+        the targets of those abnormal outgoing edges.  */
+      if (has_abnormal_outgoing_edge_p (bb))
+       continue;
+
       /* Now look at the statements in the block and see if any of
         them explicitly dereference a NULL pointer.  This happens
         because of jump threading and constant propagation.  */
@@ -299,7 +329,8 @@ find_explicit_erroneous_behaviour (void)
          /* By passing null_pointer_node, we can use infer_nonnull_range
             to detect explicit NULL pointer dereferences and other uses
             where a non-NULL value is required.  */
-         if (infer_nonnull_range (stmt, null_pointer_node))
+         if ((!stmt_ends_bb_p (stmt) || gimple_code (stmt) == GIMPLE_RETURN)
+             && infer_nonnull_range (stmt, null_pointer_node))
            {
              insert_trap_and_remove_trailing_statements (&si,
                                                          null_pointer_node);
index fb9d2c41eb3ec7875cf703a87b339adc32ec080d..1e1285aebbe8bb950867080667a3ceefa26b10d5 100644 (file)
@@ -4506,21 +4506,6 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
       }
 }
 
-/* Return true if BB has at least one abnormal outgoing edge.  */
-
-static inline bool
-has_abnormal_outgoing_edge_p (basic_block bb)
-{
-  edge e;
-  edge_iterator ei;
-
-  FOR_EACH_EDGE (e, ei, bb->succs)
-    if (e->flags & EDGE_ABNORMAL)
-      return true;
-
-  return false;
-}
-
 /* Expand calls to inline functions in the body of FN.  */
 
 unsigned int