* asan.c (create_cond_insert_point): Add create_then_fallthru_edge
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2013 20:47:39 +0000 (20:47 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2013 20:47:39 +0000 (20:47 +0000)
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

gcc/ChangeLog
gcc/asan.c
gcc/tree-flow.h
gcc/tree-ssa-phiopt.c

index bfaa7d3..4dd2753 100644 (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.
index 3cb9511..9e22c42 100644 (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);
index a87eeae..80cb294 100644 (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  */
 
index 6119943..300016f 100644 (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)