Home | History | Annotate | Download | only in rtl
      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);
     67