]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/lib/tsan/rtl/tsan_update_shadow_word_inl.h
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / lib / tsan / rtl / tsan_update_shadow_word_inl.h
CommitLineData
1a4d82fc
JJ
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//===----------------------------------------------------------------------===//
16do {
17 StatInc(thr, StatShadowProcessed);
18 const unsigned kAccessSize = 1 << kAccessSizeLog;
92a42be0 19 u64 *sp = &shadow_mem[idx];
1a4d82fc
JJ
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);
1a4d82fc
JJ
35 if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
36 StoreIfNotYetStored(sp, &store_word);
37 break;
38 }
39 StatInc(thr, StatShadowAnotherThread);
40 if (HappensBefore(old, thr)) {
92a42be0
SL
41 if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
42 StoreIfNotYetStored(sp, &store_word);
1a4d82fc
JJ
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);