[llvm] [JIT] Respect `JITDUMP_USE_ARCH_TIMESTAMP` environment variable (PR #146085)
Cody Tapscott via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 27 07:22:21 PDT 2025
https://github.com/topolarity created https://github.com/llvm/llvm-project/pull/146085
This environment variable is set by `perf record -e intel_pt` to indicate that an arch-specific timestamp should be used when emitting the jitdump instead of CLOCK_MONOTONIC, which allows the dump to be correlated to the Intel PT recording data by `perf inject --jit`.
Without this change `perf inject` complains that the recording was taken improperly:
```console
$ perf inject --jit --input perf.data --output perf.jit.data
error, jitted code must be sampled with perf record -k 1
```
>From 62e0f161bff37a1cbd100ed13c1ed2a5174a741c Mon Sep 17 00:00:00 2001
From: Cody Tapscott <topolarity at tapscott.me>
Date: Fri, 27 Jun 2025 10:14:33 -0400
Subject: [PATCH] [JIT] Respect `JITDUMP_USE_ARCH_TIMESTAMP` environment
variable
This environment variable is set by `perf record -e intel_pt` to indicate that an
arch-specific timestamp should be used when emitting the jitdump instead of
CLOCK_MONOTONIC, which allows the dump to be correlated to the Intel PT recording
data by `perf inject --jit`.
---
.../PerfJITEvents/PerfJITEventListener.cpp | 32 ++++++++++++++++---
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp
index 4d14a606b98b0..e0cc72751394d 100644
--- a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp
+++ b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp
@@ -36,6 +36,10 @@
#include <time.h> // clock_gettime(), time(), localtime_r() */
#include <unistd.h> // for read(), close()
+#if defined(__x86_64__)
+#include <x86intrin.h> // for __rdtsc()
+#endif
+
using namespace llvm;
using namespace llvm::object;
typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
@@ -100,6 +104,9 @@ class PerfJITEventListener : public JITEventListener {
// perf mmap marker
void *MarkerAddr = NULL;
+ // use arch-specific timestamp instead of CLOCK_MONOTONIC
+ bool UseArchTimestamp = false;
+
// perf support ready
bool SuccessfullyInitialized = false;
@@ -168,10 +175,16 @@ static inline uint64_t timespec_to_ns(const struct timespec *ts) {
return ((uint64_t)ts->tv_sec * NanoSecPerSec) + ts->tv_nsec;
}
-static inline uint64_t perf_get_timestamp(void) {
+static inline uint64_t perf_get_timestamp(bool use_arch_timestamp) {
struct timespec ts;
int ret;
+ if (use_arch_timestamp) {
+#if defined(__x86_64__)
+ return __rdtsc();
+#endif
+ }
+
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
if (ret)
return 0;
@@ -181,8 +194,16 @@ static inline uint64_t perf_get_timestamp(void) {
PerfJITEventListener::PerfJITEventListener()
: Pid(sys::Process::getProcessId()) {
+
+ // check if arch-specific timestamp should be used
+#if defined(__x86_64__)
+ if (const char *UseArchTimestampEnv = getenv("JITDUMP_USE_ARCH_TIMESTAMP")) {
+ UseArchTimestamp = strcmp(UseArchTimestampEnv, "1") == 0;
+ }
+#endif
+
// check if clock-source is supported
- if (!perf_get_timestamp()) {
+ if (!UseArchTimestamp && !perf_get_timestamp(false)) {
errs() << "kernel does not support CLOCK_MONOTONIC\n";
return;
}
@@ -221,7 +242,8 @@ PerfJITEventListener::PerfJITEventListener()
Header.Version = LLVM_PERF_JIT_VERSION;
Header.TotalSize = sizeof(Header);
Header.Pid = Pid;
- Header.Timestamp = perf_get_timestamp();
+ Header.Timestamp = perf_get_timestamp(UseArchTimestamp);
+ Header.Flags = UseArchTimestamp ? JITDUMP_FLAGS_ARCH_TIMESTAMP : 0;
Dumpstream->write(reinterpret_cast<const char *>(&Header), sizeof(Header));
// Everything initialized, can do profiling now.
@@ -417,7 +439,7 @@ void PerfJITEventListener::NotifyCode(Expected<llvm::StringRef> &Symbol,
rec.Prefix.TotalSize = sizeof(rec) + // debug record itself
Symbol->size() + 1 + // symbol name
CodeSize; // and code
- rec.Prefix.Timestamp = perf_get_timestamp();
+ rec.Prefix.Timestamp = perf_get_timestamp(UseArchTimestamp);
rec.CodeSize = CodeSize;
rec.Vma = CodeAddr;
@@ -446,7 +468,7 @@ void PerfJITEventListener::NotifyDebug(uint64_t CodeAddr,
LLVMPerfJitRecordDebugInfo rec;
rec.Prefix.Id = JIT_CODE_DEBUG_INFO;
rec.Prefix.TotalSize = sizeof(rec); // will be increased further
- rec.Prefix.Timestamp = perf_get_timestamp();
+ rec.Prefix.Timestamp = perf_get_timestamp(UseArchTimestamp);
rec.CodeAddr = CodeAddr;
rec.NrEntry = Lines.size();
More information about the llvm-commits
mailing list