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-el...@google.com/

gcc/ChangeLog:

        * params.opt: Add --param=tsan-instrument-func-entry-exit=.
        * tsan.c (instrument_gimple): Make return value if
          func entry and exit  should be instrumented dependent on
          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.
---
 gcc/params.opt                                |  4 +++
 .../c-c++-common/tsan/func_entry_exit.c       | 28 +++++++++++++++++++
 .../tsan/func_entry_exit_disabled.c           | 28 +++++++++++++++++++
 gcc/tsan.c                                    |  4 +--
 4 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/tsan/func_entry_exit.c
 create mode 100644 gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c

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..5bb524c73ae
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/func_entry_exit.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-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-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..b7e0d9d1019
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "--param=tsan-instrument-func-entry-exit=0 
-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_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..02625a952c3 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -718,7 +718,7 @@ instrument_gimple (gimple_stmt_iterator *gsi)
       gimple_call_set_tail (as_a <gcall *> (stmt), false);
       if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
        instrument_builtin_call (gsi);
-      return true;
+      return param_tsan_instrument_func_entry_exit;
     }
   else if (is_gimple_assign (stmt)
           && !gimple_clobber_p (stmt))
@@ -734,7 +734,7 @@ instrument_gimple (gimple_stmt_iterator *gsi)
          instrumented = instrument_expr (*gsi, rhs, false);
        }
     }
-  return instrumented;
+  return param_tsan_instrument_func_entry_exit && instrumented;
 }
 
 /* Replace TSAN_FUNC_EXIT internal call with function exit tsan builtin.  */
-- 
2.27.0.290.gba653c62da-goog

Reply via email to