[PATCH] D25858: [tsan][llvm] Implement the function attribute to disable TSan checking at run time
Anna Zaks via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 1 15:56:04 PDT 2016
zaks.anna updated this revision to Diff 76646.
zaks.anna added a comment.
Addressed review comments.
https://reviews.llvm.org/D25858
Files:
lib/Transforms/Instrumentation/ThreadSanitizer.cpp
test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
Index: test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
===================================================================
--- /dev/null
+++ test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -tsan -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @"\01-[MyObject1 dealloc]"(i32* %a) "sanitize_thread_no_checking_at_run_time" {
+entry:
+ %tmp1 = load i32, i32* %a, align 4
+ ret i32 %tmp1
+}
+
+; CHECK: define i32 @"\01-[MyObject1 dealloc]"(i32* %a)
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @__tsan_ignore_thread_begin()
+; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4
+; CHECK-NEXT: call void @__tsan_ignore_thread_end()
+; CHECK-NEXT: ret i32 %tmp1
Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp
===================================================================
--- lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -99,12 +99,15 @@
const DataLayout &DL);
bool addrPointsToConstantData(Value *Addr);
int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL);
+ void InsertRuntimeIgnores(Function &F, SmallVector<Instruction*, 8> &RetVec);
Type *IntptrTy;
IntegerType *OrdTy;
// Callbacks to run-time library are computed in doInitialization.
Function *TsanFuncEntry;
Function *TsanFuncExit;
+ Function *TsanIgnoreBegin;
+ Function *TsanIgnoreEnd;
// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
static const size_t kNumberOfAccessSizes = 5;
Function *TsanRead[kNumberOfAccessSizes];
@@ -152,6 +155,10 @@
"__tsan_func_entry", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
TsanFuncExit = checkSanitizerInterfaceFunction(
M.getOrInsertFunction("__tsan_func_exit", IRB.getVoidTy(), nullptr));
+ TsanIgnoreBegin = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ "__tsan_ignore_thread_begin", IRB.getVoidTy(), nullptr));
+ TsanIgnoreEnd = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ "__tsan_ignore_thread_end", IRB.getVoidTy(), nullptr));
OrdTy = IRB.getInt32Ty();
for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
const unsigned ByteSize = 1U << i;
@@ -376,6 +383,16 @@
return false;
}
+void ThreadSanitizer::InsertRuntimeIgnores(Function &F,
+ SmallVector<Instruction*, 8> &RetVec) {
+ IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
+ IRB.CreateCall(TsanIgnoreBegin);
+ for (auto RetInst : RetVec) {
+ IRBuilder<> IRB(RetInst);
+ IRB.CreateCall(TsanIgnoreEnd);
+ }
+}
+
bool ThreadSanitizer::runOnFunction(Function &F) {
// This is required to prevent instrumenting call to __tsan_init from within
// the module constructor.
@@ -438,6 +455,11 @@
Res |= instrumentMemIntrinsic(Inst);
}
+ if (F.hasFnAttribute("sanitize_thread_no_checking_at_run_time")) {
+ assert(!F.hasFnAttribute(Attribute::SanitizeThread));
+ InsertRuntimeIgnores(F, RetVec);
+ }
+
// Instrument function entry/exit points if there were instrumented accesses.
if ((Res || HasCalls) && ClInstrumentFuncEntryExit) {
IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25858.76646.patch
Type: text/x-patch
Size: 3441 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161101/ae08e0f3/attachment.bin>
More information about the llvm-commits
mailing list