]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/tsan/rtl/tsan_update_shadow_word_inl.h
MFV r324145,324147:
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / tsan / rtl / tsan_update_shadow_word_inl.h
1 //===-- tsan_update_shadow_word_inl.h ---------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
12 // Body of the hottest inner loop.
13 // If we wrap this body into a function, compilers (both gcc and clang)
14 // produce sligtly less efficient code.
15 //===----------------------------------------------------------------------===//
16 do {
17   StatInc(thr, StatShadowProcessed);
18   const unsigned kAccessSize = 1 << kAccessSizeLog;
19   u64 *sp = &shadow_mem[idx];
20   old = LoadShadow(sp);
21   if (old.IsZero()) {
22     StatInc(thr, StatShadowZero);
23     if (store_word)
24       StoreIfNotYetStored(sp, &store_word);
25     // The above StoreIfNotYetStored could be done unconditionally
26     // and it even shows 4% gain on synthetic benchmarks (r4307).
27     break;
28   }
29   // is the memory access equal to the previous?
30   if (Shadow::Addr0AndSizeAreEqual(cur, old)) {
31     StatInc(thr, StatShadowSameSize);
32     // same thread?
33     if (Shadow::TidsAreEqual(old, cur)) {
34       StatInc(thr, StatShadowSameThread);
35       if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
36         StoreIfNotYetStored(sp, &store_word);
37       break;
38     }
39     StatInc(thr, StatShadowAnotherThread);
40     if (HappensBefore(old, thr)) {
41       if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
42         StoreIfNotYetStored(sp, &store_word);
43       break;
44     }
45     if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
46       break;
47     goto RACE;
48   }
49   // Do the memory access intersect?
50   if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) {
51     StatInc(thr, StatShadowIntersect);
52     if (Shadow::TidsAreEqual(old, cur)) {
53       StatInc(thr, StatShadowSameThread);
54       break;
55     }
56     StatInc(thr, StatShadowAnotherThread);
57     if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
58       break;
59     if (HappensBefore(old, thr))
60       break;
61     goto RACE;
62   }
63   // The accesses do not intersect.
64   StatInc(thr, StatShadowNotIntersect);
65   break;
66 } while (0);