tsan_update_shadow_word_inl.h revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
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;
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      StoreIfNotYetStored(sp, &store_word);
42      break;
43    }
44    if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
45      break;
46    goto RACE;
47  }
48  // Do the memory access intersect?
49  if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) {
50    StatInc(thr, StatShadowIntersect);
51    if (Shadow::TidsAreEqual(old, cur)) {
52      StatInc(thr, StatShadowSameThread);
53      break;
54    }
55    StatInc(thr, StatShadowAnotherThread);
56    if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
57      break;
58    if (HappensBefore(old, thr))
59      break;
60    goto RACE;
61  }
62  // The accesses do not intersect.
63  StatInc(thr, StatShadowNotIntersect);
64  break;
65} while (0);
66