asan.c (create_cond_insert_point): Add create_then_fallthru_edge argument.

* asan.c (create_cond_insert_point): Add create_then_fallthru_edge
	argument.  If it is false, don't create edge from then_bb to
	fallthru_bb.
	(insert_if_then_before_iter): Pass true to it.
	(build_check_stmt): Pass false to it.
	(transform_statements): Flush hash table only on extended basic
	block boundaries, rather than at the beginning of every bb.
	Don't flush hash table on nonfreeing_call_p calls.
	* tree-flow.h (nonfreeing_call_p): New prototype.
	* tree-ssa-phiopt.c (nonfreeing_call_p): No longer static.

From-SVN: r196029
This commit is contained in:
Jakub Jelinek 2013-02-13 21:47:39 +01:00 committed by Jakub Jelinek
parent 7afe28013f
commit c4bfe8bfdb
4 changed files with 46 additions and 9 deletions

View file

@ -1,3 +1,16 @@
2013-02-13 Jakub Jelinek <jakub@redhat.com>
* asan.c (create_cond_insert_point): Add create_then_fallthru_edge
argument. If it is false, don't create edge from then_bb to
fallthru_bb.
(insert_if_then_before_iter): Pass true to it.
(build_check_stmt): Pass false to it.
(transform_statements): Flush hash table only on extended basic
block boundaries, rather than at the beginning of every bb.
Don't flush hash table on nonfreeing_call_p calls.
* tree-flow.h (nonfreeing_call_p): New prototype.
* tree-ssa-phiopt.c (nonfreeing_call_p): No longer static.
2013-02-13 David S. Miller <davem@davemloft.net>
* expmed.c (expand_shift_1): Only strip scalar integer subregs.

View file

@ -1185,6 +1185,9 @@ report_error_func (bool is_store, int size_in_bytes)
'then block' of the condition statement to be inserted by the
caller.
If CREATE_THEN_FALLTHRU_EDGE is false, no edge will be created from
*THEN_BLOCK to *FALLTHROUGH_BLOCK.
Similarly, the function will set *FALLTRHOUGH_BLOCK to the 'else
block' of the condition statement to be inserted by the caller.
@ -1201,6 +1204,7 @@ static gimple_stmt_iterator
create_cond_insert_point (gimple_stmt_iterator *iter,
bool before_p,
bool then_more_likely_p,
bool create_then_fallthru_edge,
basic_block *then_block,
basic_block *fallthrough_block)
{
@ -1226,7 +1230,8 @@ create_cond_insert_point (gimple_stmt_iterator *iter,
? PROB_VERY_UNLIKELY
: PROB_ALWAYS - PROB_VERY_UNLIKELY;
e->probability = PROB_ALWAYS - fallthrough_probability;
make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
if (create_then_fallthru_edge)
make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
/* Set up the fallthrough basic block. */
e = find_edge (cond_bb, fallthru_bb);
@ -1277,6 +1282,7 @@ insert_if_then_before_iter (gimple cond,
create_cond_insert_point (iter,
/*before_p=*/true,
then_more_likely_p,
/*create_then_fallthru_edge=*/true,
then_bb,
fallthrough_bb);
gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
@ -1314,6 +1320,7 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
statement for the instrumentation. */
gsi = create_cond_insert_point (iter, before_p,
/*then_more_likely_p=*/false,
/*create_then_fallthru_edge=*/false,
&then_bb,
&else_bb);
@ -1883,15 +1890,31 @@ maybe_instrument_call (gimple_stmt_iterator *iter)
static void
transform_statements (void)
{
basic_block bb;
basic_block bb, last_bb = NULL;
gimple_stmt_iterator i;
int saved_last_basic_block = last_basic_block;
FOR_EACH_BB (bb)
{
empty_mem_ref_hash_table ();
basic_block prev_bb = bb;
if (bb->index >= saved_last_basic_block) continue;
/* Flush the mem ref hash table, if current bb doesn't have
exactly one predecessor, or if that predecessor (skipping
over asan created basic blocks) isn't the last processed
basic block. Thus we effectively flush on extended basic
block boundaries. */
while (single_pred_p (prev_bb))
{
prev_bb = single_pred (prev_bb);
if (prev_bb->index < saved_last_basic_block)
break;
}
if (prev_bb != last_bb)
empty_mem_ref_hash_table ();
last_bb = bb;
for (i = gsi_start_bb (bb); !gsi_end_p (i);)
{
gimple s = gsi_stmt (i);
@ -1909,11 +1932,11 @@ transform_statements (void)
{
/* No instrumentation happened.
If the current instruction is a function call, let's
forget about the memory references that got
instrumented. Otherwise we might miss some
instrumentation opportunities. */
if (is_gimple_call (s))
If the current instruction is a function call that
might free something, let's forget about the memory
references that got instrumented. Otherwise we might
miss some instrumentation opportunities. */
if (is_gimple_call (s) && !nonfreeing_call_p (s))
empty_mem_ref_hash_table ();
gsi_next (&i);

View file

@ -609,6 +609,7 @@ struct tree_niter_desc
/* In tree-ssa-phiopt.c */
bool empty_block_p (basic_block);
basic_block *blocks_in_phiopt_order (void);
bool nonfreeing_call_p (gimple);
/* In tree-ssa-loop*.c */

View file

@ -1339,7 +1339,7 @@ add_or_mark_expr (basic_block bb, tree exp,
/* Return true when CALL is a call stmt that definitely doesn't
free any memory or makes it unavailable otherwise. */
static bool
bool
nonfreeing_call_p (gimple call)
{
if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)