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
This commit is contained in:
Jeff Law 2013-11-14 13:57:38 -07:00 committed by Jeff Law
parent 01ef823cdd
commit 5e94175fa5
4 changed files with 61 additions and 18 deletions

View 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.

View 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 */

View 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);

View 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