aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/asan.c39
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-ssa-phiopt.c2
4 files changed, 46 insertions, 9 deletions
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 <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.
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)