From: jakub Date: Wed, 13 Feb 2013 20:47:39 +0000 (+0000) Subject: * asan.c (create_cond_insert_point): Add create_then_fallthru_edge X-Git-Tag: upstream/4.9.2~7623 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e8d4d8a908637488faa562e234ac2b90e0cc46ff;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196029 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfaa7d3..4dd2753 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 3cb9511..9e22c42 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 a87eeae..80cb294 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 6119943..300016f 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)