diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-13 20:47:39 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-13 20:47:39 +0000 |
commit | e8d4d8a908637488faa562e234ac2b90e0cc46ff (patch) | |
tree | c169eabab6c01a54a69fc9413c4019ef7aaa3d74 /gcc/asan.c | |
parent | 944c79222e4ddeffd586d449597a1b5586601240 (diff) | |
download | gcc-e8d4d8a908637488faa562e234ac2b90e0cc46ff.tar.gz |
* 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
Diffstat (limited to 'gcc/asan.c')
-rw-r--r-- | gcc/asan.c | 39 |
1 files changed, 31 insertions, 8 deletions
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); |