From b9e832608879a9defe8be23384677b9335b00546 Mon Sep 17 00:00:00 2001 From: Jonathan Peyton Date: Fri, 18 Dec 2015 16:19:35 +0000 Subject: [PATCH] [STATS] Have CMake do real check for stats functionality 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 | 1 - openmp/runtime/cmake/config-ix.cmake | 31 +++++++++++++++++++++++---- openmp/runtime/src/kmp_config.h.cmake | 6 ++++++ openmp/runtime/src/kmp_stats_timing.h | 9 ++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/openmp/runtime/CMakeLists.txt b/openmp/runtime/CMakeLists.txt index 635edb9b8ccd..9380ab52ff6b 100644 --- a/openmp/runtime/CMakeLists.txt +++ b/openmp/runtime/CMakeLists.txt @@ -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)) diff --git a/openmp/runtime/cmake/config-ix.cmake b/openmp/runtime/cmake/config-ix.cmake index eccb8634b3bf..6a78a7aebc53 100644 --- a/openmp/runtime/cmake/config-ix.cmake +++ b/openmp/runtime/cmake/config-ix.cmake @@ -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 + #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 diff --git a/openmp/runtime/src/kmp_config.h.cmake b/openmp/runtime/src/kmp_config.h.cmake index e9d8fdf7739c..9fe12b32edca 100644 --- a/openmp/runtime/src/kmp_config.h.cmake +++ b/openmp/runtime/src/kmp_config.h.cmake @@ -33,6 +33,12 @@ #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 diff --git a/openmp/runtime/src/kmp_stats_timing.h b/openmp/runtime/src/kmp_stats_timing.h index 83fb85bea32c..b878bbd620dd 100644 --- a/openmp/runtime/src/kmp_stats_timing.h +++ b/openmp/runtime/src/kmp_stats_timing.h @@ -21,6 +21,9 @@ #include #include #include "kmp_os.h" +#if KMP_HAVE_X86INTRIN_H +# include +#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(__builtin_readcyclecounter())) {} +#elif KMP_HAVE___RDTSC tsc_tick_count() : my_count(static_cast(__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 {