aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2013-11-14 20:57:38 +0000
committerJeff Law <law@redhat.com>2013-11-14 20:57:38 +0000
commitf665b1782dbe8f99392ecf16afe20090a40f7afb (patch)
tree844c78fddcf73f2724175bb18f2bd8e1f97aef7d /gcc
parent54b5be8484b7a9e6b6ab8a4542d776bef2b5ce16 (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204821 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/basic-block.h15
-rw-r--r--gcc/gimple-ssa-isolate-paths.c37
-rw-r--r--gcc/tree-inline.c15
4 files changed, 61 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e6f7a6d7713..1b395cb8317 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 9c28f14afa4..b7e3b5042ff 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -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 */
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index 108b98e2917..66c13f4cf6f 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -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);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index fb9d2c41eb3..1e1285aebbe 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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