+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.
#include "ssa-iterators.h"
#include "cfgloop.h"
#include "tree-pass.h"
+#include "tree-cfg.h"
static bool cfg_altered;
{
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
{
/* 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))
{
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. */
/* 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);