[compiler-rt] r297800 - [XRay][compiler-rt] Support TSC emulation even for x86_64

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 19:28:00 PDT 2017


Author: dberris
Date: Tue Mar 14 21:28:00 2017
New Revision: 297800

URL: http://llvm.org/viewvc/llvm-project?rev=297800&view=rev
Log:
[XRay][compiler-rt] Support TSC emulation even for x86_64

Summary:
Use TSC emulation in cases where RDTSCP isn't available on the host
running an XRay instrumented binary. We can then fall back into
emulation instead of not even installing XRay's runtime functionality.
We only do this for now in the naive/basic logging implementation, but
should be useful in even FDR mode.

Should fix http://llvm.org/PR32148.

Reviewers: pelikan, rnk, sdardis

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D30677

Modified:
    compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
    compiler-rt/trunk/lib/xray/xray_tsc.h

Modified: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.cc?rev=297800&r1=297799&r2=297800&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc Tue Mar 14 21:28:00 2017
@@ -77,7 +77,6 @@ using namespace __xray;
 
 static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT {
   int F = getLogFD();
-  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
@@ -86,7 +85,9 @@ static int __xray_OpenLogFile() XRAY_NEV
   XRayFileHeader Header;
   Header.Version = 1;
   Header.Type = FileTypes::NAIVE_LOG;
-  Header.CycleFrequency = TSCFrequency;
+  Header.CycleFrequency = probeRequiredCPUFeatures()
+                              ? getTSCFrequency()
+                              : __xray::NanosecondsPerSecond;
 
   // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc'
   // before setting the values in the header.
@@ -97,8 +98,9 @@ static int __xray_OpenLogFile() XRAY_NEV
   return F;
 }
 
-void __xray_InMemoryRawLog(int32_t FuncId,
-                           XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
+template <class RDTSC>
+void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
+                           RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
   using Buffer =
       std::aligned_storage<sizeof(XRayRecord), alignof(XRayRecord)>::type;
   static constexpr size_t BuffLen = 1024;
@@ -115,7 +117,7 @@ void __xray_InMemoryRawLog(int32_t FuncI
   // through a pointer offset.
   auto &R = reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer)[Offset];
   R.RecordType = RecordTypes::NORMAL;
-  R.TSC = __xray::readTSC(R.CPU);
+  R.TSC = ReadTSC(R.CPU);
   R.TId = TId;
   R.Type = Type;
   R.FuncId = FuncId;
@@ -129,13 +131,32 @@ void __xray_InMemoryRawLog(int32_t FuncI
   }
 }
 
+void __xray_InMemoryRawLogRealTSC(int32_t FuncId,
+                                  XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
+  __xray_InMemoryRawLog(FuncId, Type, __xray::readTSC);
+}
+
+void __xray_InMemoryEmulateTSC(int32_t FuncId,
+                               XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
+  __xray_InMemoryRawLog(FuncId, Type, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
+    timespec TS;
+    int result = clock_gettime(CLOCK_REALTIME, &TS);
+    if (result != 0) {
+      Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno));
+      TS = {0, 0};
+    }
+    CPU = 0;
+    return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
+  });
+}
+
 static auto UNUSED Unused = [] {
-  if (!probeRequiredCPUFeatures()) {
-    Report("Required CPU features missing for XRay instrumentation, not "
-           "installing instrumentation hooks.\n");
-    return false;
-  }
+  auto UseRealTSC = probeRequiredCPUFeatures();
+  if (!UseRealTSC)
+    Report("WARNING: Required CPU features missing for XRay instrumentation, "
+           "using emulation instead.\n");
   if (flags()->xray_naive_log)
-    __xray_set_handler(__xray_InMemoryRawLog);
+    __xray_set_handler(UseRealTSC ? __xray_InMemoryRawLogRealTSC
+                                  : __xray_InMemoryEmulateTSC);
   return true;
 }();

Modified: compiler-rt/trunk/lib/xray/xray_tsc.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_tsc.h?rev=297800&r1=297799&r2=297800&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_tsc.h (original)
+++ compiler-rt/trunk/lib/xray/xray_tsc.h Tue Mar 14 21:28:00 2017
@@ -13,6 +13,10 @@
 #ifndef XRAY_EMULATE_TSC_H
 #define XRAY_EMULATE_TSC_H
 
+namespace __xray {
+static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000;
+}
+
 #if defined(__x86_64__)
 #include "xray_x86_64.inc"
 #elif defined(__powerpc64__)
@@ -37,8 +41,6 @@
 
 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 {
@@ -60,7 +62,7 @@ inline uint64_t getTSCFrequency() XRAY_N
 } // namespace __xray
 
 #else
-"Unsupported CPU Architecture"
+#error Target architecture is not supported.
 #endif // CPU architecture
 
 #endif // XRAY_EMULATE_TSC_H




More information about the llvm-commits mailing list