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       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