From c4bfe8bfdb11a5fe0734b84a3c60b4db312b22f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 13 Feb 2013 21:47:39 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 +++++++++++++ gcc/asan.c | 39 +++++++++++++++++++++++++++++++-------- gcc/tree-flow.h | 1 + gcc/tree-ssa-phiopt.c | 2 +- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfaa7d302e5..4dd2753a72a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-02-13 Jakub Jelinek + + * 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 * expmed.c (expand_shift_1): Only strip scalar integer subregs. diff --git a/gcc/asan.c b/gcc/asan.c index 3cb95112329..9e22c42743b 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -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); diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index a87eeaef263..80cb2945dce 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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 */ diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 61199437dbe..300016f7a0b 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -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)