Index: compiler-rt/lib/xray/xray_AArch64.cc =================================================================== --- compiler-rt/lib/xray/xray_AArch64.cc +++ compiler-rt/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/lib/xray/xray_arm.cc =================================================================== --- compiler-rt/lib/xray/xray_arm.cc +++ compiler-rt/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/lib/xray/xray_fdr_logging.cc =================================================================== --- compiler-rt/lib/xray/xray_fdr_logging.cc +++ compiler-rt/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/lib/xray/xray_inmemory_log.cc =================================================================== --- compiler-rt/lib/xray/xray_inmemory_log.cc +++ compiler-rt/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/lib/xray/xray_interface_internal.h =================================================================== --- compiler-rt/lib/xray/xray_interface_internal.h +++ compiler-rt/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/lib/xray/xray_tsc.h =================================================================== --- compiler-rt/lib/xray/xray_tsc.h +++ compiler-rt/lib/xray/xray_tsc.h @@ -1,4 +1,4 @@ -//===-- xray_emulate_tsc.h --------------------------------------*- C++ -*-===// +//===-- xray_tsc.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,6 +13,19 @@ #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" @@ -24,6 +37,8 @@ static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; +bool probeRequiredCPUFeatures() { return true; } + ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { timespec TS; int result = clock_gettime(CLOCK_REALTIME, &TS); @@ -36,8 +51,12 @@ return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; } -bool probeRequiredCPUFeatures(); +uint64_t getTSCFrequency() { return NanosecondsPerSecond; } } // namespace __xray +#else +"Unsupported CPU Architecture" +#endif // CPU architecture + #endif // XRAY_EMULATE_TSC_H Index: compiler-rt/lib/xray/xray_utils.h =================================================================== --- compiler-rt/lib/xray/xray_utils.h +++ compiler-rt/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/lib/xray/xray_utils.cc =================================================================== --- compiler-rt/lib/xray/xray_utils.cc +++ compiler-rt/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/lib/xray/xray_x86_64.cc =================================================================== --- compiler-rt/lib/xray/xray_x86_64.cc +++ compiler-rt/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/lib/xray/xray_x86_64.inc =================================================================== --- compiler-rt/lib/xray/xray_x86_64.inc +++ compiler-rt/lib/xray/xray_x86_64.inc @@ -1,4 +1,4 @@ -//===-- xray_x86_64.h -------------------------------------------*- C++ -*-===// +//===-- xray_x86_64.inc -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,8 +10,6 @@ // This file is a part of XRay, a dynamic runtime instrumentation system. // //===----------------------------------------------------------------------===// -#ifndef XRAY_X86_64_H -#define XRAY_X86_64_H #include #include @@ -28,8 +26,8 @@ return TSC; } +uint64_t getTSCFrequency(); + bool probeRequiredCPUFeatures(); } // namespace __xray - -#endif // XRAY_X86_64_H