Consider the following code:
P p;
p.x = 1;
p.y = 2;
foo(&p);
P escapes and so tsan instruments accesses to it. However, before address of the variable is actually taken, it is not shared and so cannot participate in data races. So there is no point in instrumenting these initial memory accesses.
I've built some tests in WebRTC with and without this change. With this change number of __tsan_read/write calls is reduced by 20-40%, binary size decreases by 5-10% and execution time drops by ~5%. For example:
$ ls -l old/modules_unittests new/modules_unittests
-rwxr-x--- 1 dvyukov 41708976 Jan 20 18:35 old/modules_unittests
-rwxr-x--- 1 dvyukov 38294008 Jan 20 18:29 new/modules_unittests
$ objdump -d old/modules_unittests | egrep "callq.*tsan_(read|write|unaligned)" | wc -l
239871
$ objdump -d new/modules_unittests | egrep "callq.*tsan_(read|write|unaligned)" | wc -l
148365
Don't we want to reuse DT from previous passes, i.e. require it in getAnalysisUsage() ?