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:
parent
01ef823cdd
commit
5e94175fa5
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue