diff --git a/openmp/tools/archer/README.md b/openmp/tools/archer/README.md
--- a/openmp/tools/archer/README.md
+++ b/openmp/tools/archer/README.md
@@ -104,7 +104,11 @@
flush_shadow |
0 |
-Flush shadow memory at the end of an outer OpenMP parallel region. Our experiments show that this can reduce memory overhead by ~30% and runtime overhead by ~10%. This flag is useful for large OpenMP applications that typically require large amounts of memory, causing out-of-memory exceptions when checked by Archer. |
+Flush shadow memory at the end of an outer OpenMP
+parallel region. Our experiments show that this can reduce memory overhead
+by ~30% and runtime overhead by ~10%. This flag is useful for large OpenMP
+applications that typically require large amounts of memory, causing
+out-of-memory exceptions when checked by Archer. |
@@ -116,6 +120,17 @@
+
+
+ignore_serial |
+0 |
+Turn off tracking and analysis of memory accesses in
+the sequential part of an OpenMP program. (Only effective when OpenMP
+runtime is initialized. In doubt, insert omp_get_max_threads() as first
+statement in main!) |
+
+
+
verbose |
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -56,18 +56,14 @@
class ArcherFlags {
public:
#if (LLVM_VERSION) >= 40
- int flush_shadow;
+ int flush_shadow{0};
#endif
- int print_max_rss;
- int verbose;
- int enabled;
+ int print_max_rss{0};
+ int verbose{0};
+ int enabled{1};
+ int ignore_serial{0};
- ArcherFlags(const char *env)
- :
-#if (LLVM_VERSION) >= 40
- flush_shadow(0),
-#endif
- print_max_rss(0), verbose(0), enabled(1) {
+ ArcherFlags(const char *env) {
if (env) {
std::vector tokens;
std::string token;
@@ -88,6 +84,8 @@
continue;
if (sscanf(it->c_str(), "enable=%d", &enabled))
continue;
+ if (sscanf(it->c_str(), "ignore_serial=%d", &ignore_serial))
+ continue;
std::cerr << "Illegal values for ARCHER_OPTIONS variable: " << token
<< std::endl;
}
@@ -410,7 +408,7 @@
bool InBarrier;
/// Whether this task is an included task.
- bool Included;
+ int TaskType{0};
/// Index of which barrier to use next.
char BarrierIndex;
@@ -443,8 +441,8 @@
int execution;
int freed;
- TaskData(TaskData *Parent)
- : InBarrier(false), Included(false), BarrierIndex(0), RefCount(1),
+ TaskData(TaskData *Parent, int taskType)
+ : InBarrier(false), TaskType(taskType), BarrierIndex(0), RefCount(1),
Parent(Parent), ImplicitTask(nullptr), Team(Parent->Team),
TaskGroup(nullptr), DependencyCount(0), execution(0), freed(0) {
if (Parent != nullptr) {
@@ -455,8 +453,8 @@
}
}
- TaskData(ParallelData *Team = nullptr)
- : InBarrier(false), Included(false), BarrierIndex(0), RefCount(1),
+ TaskData(ParallelData *Team, int taskType)
+ : InBarrier(false), TaskType(taskType), BarrierIndex(0), RefCount(1),
Parent(nullptr), ImplicitTask(this), Team(Team), TaskGroup(nullptr),
DependencyCount(0), execution(1), freed(0) {}
@@ -465,6 +463,17 @@
TsanDeleteClock(&Taskwait);
}
+ bool isIncluded() { return TaskType & ompt_task_undeferred; }
+ bool isUntied() { return TaskType & ompt_task_untied; }
+ bool isFinal() { return TaskType & ompt_task_final; }
+ bool isMergable() { return TaskType & ompt_task_mergeable; }
+ bool isMerged() { return TaskType & ompt_task_merged; }
+
+ bool isExplicit() { return TaskType & ompt_task_explicit; }
+ bool isImplicit() { return TaskType & ompt_task_implicit; }
+ bool isInitial() { return TaskType & ompt_task_initial; }
+ bool isTarget() { return TaskType & ompt_task_target; }
+
void *GetTaskPtr() { return &Task; }
void *GetTaskwaitPtr() { return &Taskwait; }
@@ -517,11 +526,15 @@
parallel_data->ptr = Data;
TsanHappensBefore(Data->GetParallelPtr());
+ if (archer_flags->ignore_serial && ToTaskData(parent_task_data)->isInitial())
+ TsanIgnoreWritesEnd();
}
static void ompt_tsan_parallel_end(ompt_data_t *parallel_data,
ompt_data_t *task_data, int flag,
const void *codeptr_ra) {
+ if (archer_flags->ignore_serial && ToTaskData(task_data)->isInitial())
+ TsanIgnoreWritesBegin();
ParallelData *Data = ToParallelData(parallel_data);
TsanHappensAfter(Data->GetBarrierPtr(0));
TsanHappensAfter(Data->GetBarrierPtr(1));
@@ -546,7 +559,7 @@
if (type & ompt_task_initial) {
parallel_data->ptr = new ParallelData(nullptr);
}
- task_data->ptr = new TaskData(ToParallelData(parallel_data));
+ task_data->ptr = new TaskData(ToParallelData(parallel_data), type);
TsanHappensAfter(ToParallelData(parallel_data)->GetParallelPtr());
TsanFuncEntry(ToParallelData(parallel_data)->codePtr);
break;
@@ -727,14 +740,13 @@
ParallelData *PData = new ParallelData(nullptr);
parallel_data->ptr = PData;
- Data = new TaskData(PData);
+ Data = new TaskData(PData, type);
new_task_data->ptr = Data;
} else if (type & ompt_task_undeferred) {
- Data = new TaskData(ToTaskData(parent_task_data));
+ Data = new TaskData(ToTaskData(parent_task_data), type);
new_task_data->ptr = Data;
- Data->Included = true;
} else if (type & ompt_task_explicit || type & ompt_task_target) {
- Data = new TaskData(ToTaskData(parent_task_data));
+ Data = new TaskData(ToTaskData(parent_task_data), type);
new_task_data->ptr = Data;
// Use the newly created address. We cannot use a single address from the
@@ -801,7 +813,7 @@
prior_task_status == ompt_task_late_fulfill) {
// Included tasks are executed sequentially, no need to track
// synchronization
- if (!FromTask->Included) {
+ if (!FromTask->isIncluded()) {
// Task will finish before a barrier in the surrounding parallel region
// ...
ParallelData *PData = FromTask->Team;
@@ -976,10 +988,14 @@
"Warning: please export "
"TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
"to avoid false positive reports from the OpenMP runtime!\n");
+ if (archer_flags->ignore_serial)
+ TsanIgnoreWritesBegin();
return 1; // success
}
static void ompt_tsan_finalize(ompt_data_t *tool_data) {
+ if (archer_flags->ignore_serial)
+ TsanIgnoreWritesEnd();
if (archer_flags->print_max_rss) {
struct rusage end;
getrusage(RUSAGE_SELF, &end);
diff --git a/openmp/tools/archer/tests/lit.cfg b/openmp/tools/archer/tests/lit.cfg
--- a/openmp/tools/archer/tests/lit.cfg
+++ b/openmp/tools/archer/tests/lit.cfg
@@ -91,6 +91,8 @@
config.environment['INTEL_LICENSE_FILE'] = os.environ['INTEL_LICENSE_FILE']
# Race Tests
+config.substitutions.append(("%libarcher-compile-and-run-race-noserial", \
+ "%libarcher-compile && env ARCHER_OPTIONS=ignore_serial=1 %libarcher-run-race"))
config.substitutions.append(("%libarcher-compile-and-run-race", \
"%libarcher-compile && %libarcher-run-race"))
config.substitutions.append(("%libarcher-compile-and-run-nosuppression", \
diff --git a/openmp/tools/archer/tests/races/critical-unrelated.c b/openmp/tools/archer/tests/races/critical-unrelated.c
--- a/openmp/tools/archer/tests/races/critical-unrelated.c
+++ b/openmp/tools/archer/tests/races/critical-unrelated.c
@@ -1,7 +1,6 @@
/*
* critical-unrelated.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include
#include
diff --git a/openmp/tools/archer/tests/races/lock-nested-unrelated.c b/openmp/tools/archer/tests/races/lock-nested-unrelated.c
--- a/openmp/tools/archer/tests/races/lock-nested-unrelated.c
+++ b/openmp/tools/archer/tests/races/lock-nested-unrelated.c
@@ -1,7 +1,6 @@
/*
* lock-nested-unrelated.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include
#include
diff --git a/openmp/tools/archer/tests/races/lock-unrelated.c b/openmp/tools/archer/tests/races/lock-unrelated.c
--- a/openmp/tools/archer/tests/races/lock-unrelated.c
+++ b/openmp/tools/archer/tests/races/lock-unrelated.c
@@ -1,7 +1,6 @@
/*
* lock-unrelated.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include
#include
diff --git a/openmp/tools/archer/tests/races/parallel-simple.c b/openmp/tools/archer/tests/races/parallel-simple.c
--- a/openmp/tools/archer/tests/races/parallel-simple.c
+++ b/openmp/tools/archer/tests/races/parallel-simple.c
@@ -1,7 +1,6 @@
/*
* parallel-simple.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include
#include
diff --git a/openmp/tools/archer/tests/races/task-dependency.c b/openmp/tools/archer/tests/races/task-dependency.c
--- a/openmp/tools/archer/tests/races/task-dependency.c
+++ b/openmp/tools/archer/tests/races/task-dependency.c
@@ -1,7 +1,6 @@
/*
* task-dependency.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include "ompt/ompt-signal.h"
#include
diff --git a/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c b/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
--- a/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
+++ b/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
@@ -1,7 +1,6 @@
/*
* task-taskgroup-unrelated.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include "ompt/ompt-signal.h"
#include
diff --git a/openmp/tools/archer/tests/races/task-taskwait-nested.c b/openmp/tools/archer/tests/races/task-taskwait-nested.c
--- a/openmp/tools/archer/tests/races/task-taskwait-nested.c
+++ b/openmp/tools/archer/tests/races/task-taskwait-nested.c
@@ -1,7 +1,6 @@
/*
* task-taskwait-nested.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include "ompt/ompt-signal.h"
#include
diff --git a/openmp/tools/archer/tests/races/task-two.c b/openmp/tools/archer/tests/races/task-two.c
--- a/openmp/tools/archer/tests/races/task-two.c
+++ b/openmp/tools/archer/tests/races/task-two.c
@@ -1,7 +1,6 @@
/*
* task-two.c -- Archer testcase
*/
-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
//===----------------------------------------------------------------------===//
// RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
// REQUIRES: tsan
#include
#include