aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarco Elver <elver@google.com>2020-06-10 16:21:21 +0200
committerMarco Elver <elver@google.com>2020-06-12 17:29:45 +0200
commit06712fc68dc9843d9af7c7ac10047f49d305ad76 (patch)
treee8c4e992fbe0a21e10eee6da02bc143cfcdfbe4b /gcc
parent1432bc368121eed511a0a004f2e21d89ceaf14ad (diff)
downloadgcc-06712fc68dc9843d9af7c7ac10047f49d305ad76.zip
gcc-06712fc68dc9843d9af7c7ac10047f49d305ad76.tar.gz
gcc-06712fc68dc9843d9af7c7ac10047f49d305ad76.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimplify.c3
-rw-r--r--gcc/params.opt4
-rw-r--r--gcc/testsuite/c-c++-common/tsan/func_entry_exit.c29
-rw-r--r--gcc/testsuite/c-c++-common/tsan/func_entry_exit_disabled.c29
-rw-r--r--gcc/tsan.c4
5 files changed, 67 insertions, 2 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e14932f..416fb60 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 9b564bb..e29a44e 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 0000000..9c1b697
--- /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 0000000..63cc73b
--- /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 447accc..4d62234 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;