Index: compiler-rt/trunk/lib/xray/xray_AArch64.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_AArch64.cc +++ compiler-rt/trunk/lib/xray/xray_AArch64.cc @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" #include "xray_defs.h" -#include "xray_emulate_tsc.h" #include "xray_interface_internal.h" #include #include @@ -24,19 +23,6 @@ namespace __xray { -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86[_64]; it may go faster or - // slower depending on CPU's turbo or power saving modes. Furthermore, to - // read from CP15 on ARM a kernel modification or a driver is needed. - // We can not require this from users of compiler-rt. - // So on ARM we use clock_gettime(2) which gives the result in nanoseconds. - // To get the measurements per second, we scale this by the number of - // nanoseconds per second, pretending that the TSC frequency is 1GHz and - // one TSC tick is 1 nanosecond. - return NanosecondsPerSecond; -} - // The machine codes for some instructions used in runtime patching. enum class PatchOpcodes : uint32_t { PO_StpX0X30SP_m16e = 0xA9BF7BE0, // STP X0, X30, [SP, #-16]! Index: compiler-rt/trunk/lib/xray/xray_arm.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_arm.cc +++ compiler-rt/trunk/lib/xray/xray_arm.cc @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" #include "xray_defs.h" -#include "xray_emulate_tsc.h" #include "xray_interface_internal.h" #include #include @@ -23,19 +22,6 @@ namespace __xray { -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86[_64]; it may go faster or - // slower depending on CPU's turbo or power saving modes. Furthermore, to - // read from CP15 on ARM a kernel modification or a driver is needed. - // We can not require this from users of compiler-rt. - // So on ARM we use clock_gettime(2) which gives the result in nanoseconds. - // To get the measurements per second, we scale this by the number of - // nanoseconds per second, pretending that the TSC frequency is 1GHz and - // one TSC tick is 1 nanosecond. - return NanosecondsPerSecond; -} - // The machine codes for some instructions used in runtime patching. enum class PatchOpcodes : uint32_t { PO_PushR0Lr = 0xE92D4001, // PUSH {r0, lr} Index: compiler-rt/trunk/lib/xray/xray_emulate_tsc.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_emulate_tsc.h +++ compiler-rt/trunk/lib/xray/xray_emulate_tsc.h @@ -1,43 +0,0 @@ -//===-- xray_emulate_tsc.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of XRay, a dynamic runtime instrumentation system. -// -//===----------------------------------------------------------------------===// -#ifndef XRAY_EMULATE_TSC_H -#define XRAY_EMULATE_TSC_H - -#include "sanitizer_common/sanitizer_common.h" -#include "sanitizer_common/sanitizer_internal_defs.h" -#include "xray_defs.h" -#include -#include -#include - -namespace __xray { - -static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; - -ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { - timespec TS; - int result = clock_gettime(CLOCK_REALTIME, &TS); - if (result != 0) { - Report("clock_gettime(2) returned %d, errno=%d.", result, int(errno)); - TS.tv_sec = 0; - TS.tv_nsec = 0; - } - CPU = 0; - return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; -} - -bool probeRequiredCPUFeatures(); - -} // namespace __xray - -#endif // XRAY_EMULATE_TSC_H Index: compiler-rt/trunk/lib/xray/xray_fdr_logging.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_fdr_logging.cc +++ compiler-rt/trunk/lib/xray/xray_fdr_logging.cc @@ -32,16 +32,9 @@ #include "xray_buffer_queue.h" #include "xray_defs.h" #include "xray_flags.h" +#include "xray_tsc.h" #include "xray_utils.h" -#if defined(__x86_64__) -#include "xray_x86_64.h" -#elif defined(__arm__) || defined(__aarch64__) -#include "xray_emulate_tsc.h" -#else -#error "Unsupported CPU Architecture" -#endif /* CPU architecture */ - namespace __xray { // Global BufferQueue. @@ -123,9 +116,9 @@ XRayFileHeader Header; Header.Version = 1; Header.Type = FileTypes::FDR_LOG; - auto CPUFrequency = getCPUFrequency(); + auto TSCFrequency = getTSCFrequency(); Header.CycleFrequency = - CPUFrequency == -1 ? 0 : static_cast(CPUFrequency); + TSCFrequency == -1 ? 0 : static_cast(TSCFrequency); // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc' // before setting the values in the header. Header.ConstantTSC = 1; Index: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc +++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc @@ -24,19 +24,12 @@ #include #include -#if defined(__x86_64__) -#include "xray_x86_64.h" -#elif defined(__arm__) || defined(__aarch64__) -#include "xray_emulate_tsc.h" -#else -#error "Unsupported CPU Architecture" -#endif /* Architecture-specific inline intrinsics */ - #include "sanitizer_common/sanitizer_libc.h" #include "xray/xray_records.h" #include "xray_defs.h" #include "xray_flags.h" #include "xray_interface_internal.h" +#include "xray_tsc.h" #include "xray_utils.h" // __xray_InMemoryRawLog will use a thread-local aligned buffer capped to a @@ -84,7 +77,7 @@ static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT { int F = getLogFD(); - auto CPUFrequency = getCPUFrequency(); + auto TSCFrequency = getTSCFrequency(); if (F == -1) return -1; // Since we're here, we get to write the header. We set it up so that the @@ -94,7 +87,7 @@ Header.Version = 1; Header.Type = FileTypes::NAIVE_LOG; Header.CycleFrequency = - CPUFrequency == -1 ? 0 : static_cast(CPUFrequency); + TSCFrequency == -1 ? 0 : static_cast(TSCFrequency); // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc' // before setting the values in the header. Index: compiler-rt/trunk/lib/xray/xray_interface_internal.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_interface_internal.h +++ compiler-rt/trunk/lib/xray/xray_interface_internal.h @@ -48,8 +48,6 @@ size_t Entries; }; -uint64_t cycleFrequency(); - bool patchFunctionEntry(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); bool patchFunctionExit(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); Index: compiler-rt/trunk/lib/xray/xray_tsc.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_tsc.h +++ compiler-rt/trunk/lib/xray/xray_tsc.h @@ -0,0 +1,64 @@ +//===-- xray_tsc.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of XRay, a dynamic runtime instrumentation system. +// +//===----------------------------------------------------------------------===// +#ifndef XRAY_EMULATE_TSC_H +#define XRAY_EMULATE_TSC_H + +#if defined(__x86_64__) +#include "xray_x86_64.inc" +#elif defined(__arm__) || defined(__aarch64__) +// Emulated TSC. +// There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does +// not have a constant frequency like TSC on x86(_64), it may go faster +// or slower depending on CPU turbo or power saving mode. Furthermore, +// to read from CP15 on ARM a kernel modification or a driver is needed. +// We can not require this from users of compiler-rt. +// So on ARM we use clock_gettime() which gives the result in nanoseconds. +// To get the measurements per second, we scale this by the number of +// nanoseconds per second, pretending that the TSC frequency is 1GHz and +// one TSC tick is 1 nanosecond. +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "xray_defs.h" +#include +#include +#include + +namespace __xray { + +static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; + +inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } + +ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { + timespec TS; + int result = clock_gettime(CLOCK_REALTIME, &TS); + if (result != 0) { + Report("clock_gettime(2) returned %d, errno=%d.", result, int(errno)); + TS.tv_sec = 0; + TS.tv_nsec = 0; + } + CPU = 0; + return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; +} + +inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { + return NanosecondsPerSecond; +} + +} // namespace __xray + +#else +"Unsupported CPU Architecture" +#endif // CPU architecture + +#endif // XRAY_EMULATE_TSC_H Index: compiler-rt/trunk/lib/xray/xray_utils.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_utils.h +++ compiler-rt/trunk/lib/xray/xray_utils.h @@ -36,9 +36,6 @@ // file. int getLogFD(); -// EINTR-safe read of CPU frquency for the current CPU. -long long getCPUFrequency(); - } // namespace __xray #endif // XRAY_UTILS_H Index: compiler-rt/trunk/lib/xray/xray_utils.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_utils.cc +++ compiler-rt/trunk/lib/xray/xray_utils.cc @@ -24,14 +24,6 @@ #include #include -#if defined(__x86_64__) -#include "xray_x86_64.h" -#elif defined(__arm__) || defined(__aarch64__) -#include "xray_emulate_tsc.h" -#else -#error "Unsupported CPU Architecture" -#endif /* CPU architecture */ - namespace __xray { void printToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT { @@ -99,37 +91,6 @@ return Result; } -long long getCPUFrequency() XRAY_NEVER_INSTRUMENT { - // Get the cycle frequency from SysFS on Linux. - long long CPUFrequency = -1; -#if defined(__x86_64__) - if (readValueFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", - &CPUFrequency)) { - CPUFrequency *= 1000; - } else if (readValueFromFile( - "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", - &CPUFrequency)) { - CPUFrequency *= 1000; - } else { - Report("Unable to determine CPU frequency for TSC accounting.\n"); - } -#elif defined(__arm__) || defined(__aarch64__) - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86(_64), it may go faster - // or slower depending on CPU turbo or power saving mode. Furthermore, - // to read from CP15 on ARM a kernel modification or a driver is needed. - // We can not require this from users of compiler-rt. - // So on ARM we use clock_gettime() which gives the result in nanoseconds. - // To get the measurements per second, we scale this by the number of - // nanoseconds per second, pretending that the TSC frequency is 1GHz and - // one TSC tick is 1 nanosecond. - CPUFrequency = NanosecondsPerSecond; -#else -#error "Unsupported CPU Architecture" -#endif /* CPU architecture */ - return CPUFrequency; -} - int getLogFD() XRAY_NEVER_INSTRUMENT { // FIXME: Figure out how to make this less stderr-dependent. SetPrintfAndReportCallback(printToStdErr); Index: compiler-rt/trunk/lib/xray/xray_x86_64.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_x86_64.h +++ compiler-rt/trunk/lib/xray/xray_x86_64.h @@ -1,35 +0,0 @@ -//===-- xray_x86_64.h -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of XRay, a dynamic runtime instrumentation system. -// -//===----------------------------------------------------------------------===// -#ifndef XRAY_X86_64_H -#define XRAY_X86_64_H - -#include -#include - -#include "sanitizer_common/sanitizer_internal_defs.h" -#include "xray_defs.h" - -namespace __xray { - -ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { - unsigned LongCPU; - uint64_t TSC = __rdtscp(&LongCPU); - CPU = LongCPU; - return TSC; -} - -bool probeRequiredCPUFeatures(); - -} // namespace __xray - -#endif // XRAY_X86_64_H Index: compiler-rt/trunk/lib/xray/xray_x86_64.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_x86_64.cc +++ compiler-rt/trunk/lib/xray/xray_x86_64.cc @@ -57,19 +57,19 @@ return Result; } -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - long long CPUFrequency = -1; +uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { + long long TSCFrequency = -1; if (readValueFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", - &CPUFrequency)) { - CPUFrequency *= 1000; + &TSCFrequency)) { + TSCFrequency *= 1000; } else if (readValueFromFile( "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", - &CPUFrequency)) { - CPUFrequency *= 1000; + &TSCFrequency)) { + TSCFrequency *= 1000; } else { Report("Unable to determine CPU frequency for TSC accounting.\n"); } - return CPUFrequency == -1 ? 0 : static_cast(CPUFrequency); + return TSCFrequency == -1 ? 0 : static_cast(TSCFrequency); } static constexpr uint8_t CallOpCode = 0xe8; Index: compiler-rt/trunk/lib/xray/xray_x86_64.inc =================================================================== --- compiler-rt/trunk/lib/xray/xray_x86_64.inc +++ compiler-rt/trunk/lib/xray/xray_x86_64.inc @@ -0,0 +1,33 @@ +//===-- xray_x86_64.inc -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of XRay, a dynamic runtime instrumentation system. +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "xray_defs.h" + +namespace __xray { + +ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { + unsigned LongCPU; + uint64_t TSC = __rdtscp(&LongCPU); + CPU = LongCPU; + return TSC; +} + +uint64_t getTSCFrequency(); + +bool probeRequiredCPUFeatures(); + +} // namespace __xray