[gcc/devel/c++-coroutines] tsan: Add param to disable func-entry-exit instrumentation

Iain D Sandoe iains@gcc.gnu.org
Mon Jun 15 20:12:05 GMT 2020


https://gcc.gnu.org/g:06712fc68dc9843d9af7c7ac10047f49d305ad76

commit 06712fc68dc9843d9af7c7ac10047f49d305ad76
Author: Marco Elver <elver@google.com>
Date:   Wed Jun 10 16:21:21 2020 +0200

    tsan: Add param to disable func-entry-exit instrumentation
    
    Adds param tsan-instrument-func-entry-exit, which controls if
    __tsan_func_{entry,exit} calls should be emitted or not. The default
    behaviour is to emit the calls.
    
    This may be required by alternative race detection runtimes. One such
    runtime is the Kernel Concurrency Sanitizer (KCSAN):
    
            https://github.com/google/ktsan/wiki/KCSAN
    
    After this change, GCC should satisfy all requirements for KCSAN:
    
            https://lore.kernel.org/lkml/20200515150338.190344-7-elver@google.com/
    
    gcc/ChangeLog:
    
            * gimplify.c (gimplify_function_tree): Optimize and do not emit
            IFN_TSAN_FUNC_EXIT in a finally block if we do not need it.
            * params.opt: Add --param=tsan-instrument-func-entry-exit=.
            * tsan.c (instrument_memory_accesses): Make
            fentry_exit_instrument bool depend on new param.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/tsan/func_entry_exit.c: New test.
            * c-c++-common/tsan/func_entry_exit_disabled.c: New test.

Diff:
---
 gcc/gimplify.c                                     |  3 ++-
 gcc/params.opt                                     |  4 +++
 gcc/testsuite/c-c++-common/tsan/func_entry_exit.c  | 29 ++++++++++++++++++++++
 .../c-c++-common/tsan/func_entry_exit_disabled.c   | 29 ++++++++++++++++++++++
 gcc/tsan.c                                         |  4 ++-
 5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e14932fafaf..416fb609b94 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -15011,7 +15011,8 @@ gimplify_function_tree (tree fndecl)
       bind = new_bind;
     }
 
-  if (sanitize_flags_p (SANITIZE_THREAD))
+  if (sanitize_flags_p (SANITIZE_THREAD)
+      && param_tsan_instrument_func_entry_exit)
     {
       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
diff --git a/gcc/params.opt b/gcc/params.opt
index 9b564bb046c..e29a44e7712 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -912,6 +912,10 @@ Set the maximum number of instructions executed in parallel in reassociated tree
 Common Joined UInteger Var(param_tsan_distinguish_volatile) IntegerRange(0, 1) Param
 Emit special instrumentation for accesses to volatiles.
 
+-param=tsan-instrument-func-entry-exit=
+Common Joined UInteger Var(param_tsan_instrument_func_entry_exit) Init(1) IntegerRange(0, 1) Param
+Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit().
+
 -param=uninit-control-dep-attempts=
 Common Joined UInteger Var(param_uninit_control_dep_attempts) Init(1000) IntegerRange(1, 65536) Param Optimization
 Maximum number of nested calls to search for control dependencies during uninitialized variable analysis.
diff --git a/gcc/testsuite/c-c++-common/tsan/func_entry_exit.c b/gcc/testsuite/c-c++-common/tsan/func_entry_exit.c
new file mode 100644
index 00000000000..9c1b697411c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/func_entry_exit.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple -fdump-tree-optimized" } */
+
+int x;
+
+__attribute__((noinline))
+void fn1(void)
+{
+  x++;
+}
+
+__attribute__((noinline))
+void fn2(void)
+{
+  fn1();
+}
+
+__attribute__((noinline))
+int main(int argc, char *argv[])
+{
+  fn1();
+  fn2();
+  return 0;
+}
+
+// { dg-final { scan-tree-dump "TSAN_FUNC_EXIT" "gimple" } }
+// { dg-final { scan-tree-dump-times "__tsan_func_entry" 3 "optimized" } }
+// { dg-final { scan-tree-dump-times "__tsan_func_exit" 3 "optimized" } }
+// { dg-final { scan-tree-dump "__tsan_write" "optimized" } }
diff --git a/gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c b/gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c
new file mode 100644
index 00000000000..63cc73b9eba
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "--param=tsan-instrument-func-entry-exit=0 -fdump-tree-gimple -fdump-tree-optimized" } */
+
+int x;
+
+__attribute__((noinline))
+void fn1(void)
+{
+  x++;
+}
+
+__attribute__((noinline))
+void fn2(void)
+{
+  fn1();
+}
+
+__attribute__((noinline))
+int main(int argc, char *argv[])
+{
+  fn1();
+  fn2();
+  return 0;
+}
+
+// { dg-final { scan-tree-dump-not "TSAN_FUNC_EXIT" "gimple" } }
+// { dg-final { scan-tree-dump-not "__tsan_func_entry" "optimized" } }
+// { dg-final { scan-tree-dump-not "__tsan_func_exit" "optimized" } }
+// { dg-final { scan-tree-dump "__tsan_write" "optimized" } }
diff --git a/gcc/tsan.c b/gcc/tsan.c
index 447acccfafd..4d6223454b5 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -804,7 +804,9 @@ instrument_memory_accesses (bool *cfg_changed)
 	      func_exit_seen = true;
 	    }
 	  else
-	    fentry_exit_instrument |= instrument_gimple (&gsi);
+	    fentry_exit_instrument
+	      |= (instrument_gimple (&gsi)
+		  && param_tsan_instrument_func_entry_exit);
 	}
       if (gimple_purge_dead_eh_edges (bb))
 	*cfg_changed = true;


More information about the Gcc-cvs mailing list