From 5e94175fa5906a1417a229fe9ec93faa10502583 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 14 Nov 2013 13:57:38 -0700 Subject: [PATCH] basic-block.h (has_abnormal_outgoing_edge_p): Moved here from... * 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 | 12 +++++++++++ gcc/basic-block.h | 15 ++++++++++++++ gcc/gimple-ssa-isolate-paths.c | 37 +++++++++++++++++++++++++++++++--- gcc/tree-inline.c | 15 -------------- 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 + + 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 * 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