[STATS] Have CMake do real check for stats functionality
authorJonathan Peyton <jonathan.l.peyton@intel.com>
Fri, 18 Dec 2015 16:19:35 +0000 (16:19 +0000)
committerJonathan Peyton <jonathan.l.peyton@intel.com>
Fri, 18 Dec 2015 16:19:35 +0000 (16:19 +0000)
This change allows clang to build the stats library for every architecture
which supports __builtin_readcyclecounter().  CMake also checks for all
necessary features for stats and will error out if the platform does not
support it.

Patch by Hal Finkel and Johnny Peyton

llvm-svn: 256002

openmp/runtime/CMakeLists.txt
openmp/runtime/cmake/config-ix.cmake
openmp/runtime/src/kmp_config.h.cmake
openmp/runtime/src/kmp_stats_timing.h

index 635edb9b8ccde0171e4e088750234ff1fbd7f3c9..9380ab52ff6b0244348998c4ccdd608164d2f824 100644 (file)
@@ -267,7 +267,6 @@ endif()
 
 # - stats-gathering enables OpenMP stats where things like the number of
 # parallel regions, clock ticks spent in particular openmp regions are recorded.
-# TODO: Make this a real feature check
 set(LIBOMP_STATS FALSE CACHE BOOL
   "Stats-Gathering functionality?")
 if(LIBOMP_STATS AND (NOT LIBOMP_HAVE_STATS))
index eccb8634b3bffb4a7aa03ce1e9849831cc171ebf..6a78a7aebc530d3ef8b434ea0931c8db9554d4ce 100644 (file)
@@ -182,10 +182,33 @@ else()
 endif()
 
 # Check if stats-gathering is available
-if(NOT (WIN32 OR APPLE) AND (${IA32} OR ${INTEL64} OR ${MIC}))
-  set(LIBOMP_HAVE_STATS TRUE)
-else()
-  set(LIBOMP_HAVE_STATS FALSE)
+if(${LIBOMP_STATS})
+  check_c_source_compiles(
+     "__thread int x;
+     int main(int argc, char** argv) 
+     { x = argc; return x; }"
+     LIBOMP_HAVE___THREAD)
+  check_c_source_compiles(
+     "int main(int argc, char** argv) 
+     { unsigned long long t = __builtin_readcyclecounter(); return 0; }"
+     LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
+  if(NOT LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
+    if(${IA32} OR ${INTEL64})
+      check_include_file(x86intrin.h LIBOMP_HAVE_X86INTRIN_H)
+      libomp_append(CMAKE_REQUIRED_DEFINITIONS -DLIBOMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H)
+      check_c_source_compiles(
+        "#ifdef LIBOMP_HAVE_X86INTRIN_H
+         # include <x86intrin.h>
+         #endif
+         int main(int argc, char** argv) { unsigned long long t = __rdtsc(); return 0; }" LIBOMP_HAVE___RDTSC)
+      set(CMAKE_REQUIRED_DEFINITIONS)
+    endif()
+  endif()
+  if(LIBOMP_HAVE___THREAD AND (LIBOMP_HAVE___RDTSC OR LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER))
+    set(LIBOMP_HAVE_STATS TRUE)
+  else()
+    set(LIBOMP_HAVE_STATS FALSE)
+  endif()
 endif()
 
 # Check if OMPT support is available
index e9d8fdf7739c857c5c1eeeb8ab9a66b0768a3105..9fe12b32edca1bc0bba758eae8f689fc2b5a854d 100644 (file)
 #define KMP_HAVE_PSAPI LIBOMP_HAVE_PSAPI
 #cmakedefine01 LIBOMP_STATS
 #define KMP_STATS_ENABLED LIBOMP_STATS
+#cmakedefine01 LIBOMP_HAVE_X86INTRIN_H
+#define KMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H
+#cmakedefine01 LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER
+#define KMP_HAVE___BUILTIN_READCYCLECOUNTER LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER
+#cmakedefine01 LIBOMP_HAVE___RDTSC
+#define KMP_HAVE___RDTSC LIBOMP_HAVE___RDTSC
 #cmakedefine01 LIBOMP_USE_DEBUGGER
 #define USE_DEBUGGER LIBOMP_USE_DEBUGGER
 #cmakedefine01 LIBOMP_OMPT_DEBUG
index 83fb85bea32c1e60f41b164e867e909777ec208f..b878bbd620ddd443d33c53856eb1422003ebf968 100644 (file)
@@ -21,6 +21,9 @@
 #include <string>
 #include <limits>
 #include "kmp_os.h"
+#if KMP_HAVE_X86INTRIN_H
+# include <x86intrin.h>
+#endif
 
 class tsc_tick_count {
   private:
@@ -44,7 +47,13 @@ class tsc_tick_count {
         const tsc_tick_count t1, const tsc_tick_count t0);
     };
 
+#if KMP_HAVE___BUILTIN_READCYCLECOUNTER
+    tsc_tick_count() : my_count(static_cast<int64_t>(__builtin_readcyclecounter())) {}
+#elif KMP_HAVE___RDTSC
     tsc_tick_count() : my_count(static_cast<int64_t>(__rdtsc())) {};
+#else
+# error Must have high resolution timer defined
+#endif
     tsc_tick_count(int64_t value) : my_count(value) {};
     int64_t getValue() const { return my_count; }
     tsc_tick_count later (tsc_tick_count const other) const {