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;