Skip to content

Commit dff0a2d

Browse files
committed
[LLVM] add support for controlling perf sample collection
1 parent d261ea7 commit dff0a2d

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

tpde-llvm/test/llc/perf-control.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; NOTE: Do not autogenerate
2+
; SPDX-FileCopyrightText: 2026 Contributors to TPDE <https://tpde.org>
3+
; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
; RUN: echo "ack ack" | tpde-llc --target=x86_64 -o /dev/null --perf-control=/dev/stdout,/dev/stdin %s > %t
6+
; RUN: FileCheck --input-file=%t %s
7+
8+
; CHECK: enable
9+
; CHECK-NEXT: disable
10+
11+
define void @func() {
12+
ret void
13+
}

tpde-llvm/tools/tpde-llc.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
#include "tpde/base.hpp"
1616

1717
#include <cstdlib>
18+
#include <fcntl.h>
1819
#include <fstream>
1920
#include <iostream>
2021
#include <memory>
22+
#include <unistd.h>
2123

2224
#ifdef TPDE_LOGGING
2325
#include <spdlog/spdlog.h>
@@ -48,6 +50,13 @@ int main(int argc, char *argv[]) {
4850
{"compile-twice"},
4951
tpde::WithAsserts);
5052

53+
args::ValueFlag<std::string> perf_control(
54+
parser,
55+
"perf-control",
56+
"Control fifo paths for perf event management. Separated by comma",
57+
{"perf-control"},
58+
args::Options::None);
59+
5160
args::ValueFlag<std::string> target(
5261
parser, "target", "Target architecture", {"target"}, args::Options::None);
5362

@@ -98,6 +107,31 @@ int main(int argc, char *argv[]) {
98107
}
99108
#endif
100109

110+
int perf_control_fd = -1, perf_control_ack_fd = -1;
111+
112+
if (perf_control) {
113+
const std::string &str = perf_control.Get();
114+
auto delim_pos = str.find(',');
115+
if (delim_pos == std::string::npos) {
116+
std::cerr << "Invalid perf-control argument\n";
117+
return EXIT_FAILURE;
118+
}
119+
std::string control_path = str.substr(0, delim_pos);
120+
std::string ack_path = str.substr(delim_pos + 1);
121+
122+
perf_control_fd = open(control_path.c_str(), O_WRONLY);
123+
if (perf_control_fd == -1) {
124+
perror(control_path.c_str());
125+
return EXIT_FAILURE;
126+
}
127+
128+
perf_control_ack_fd = open(ack_path.c_str(), O_RDONLY);
129+
if (perf_control_ack_fd == -1) {
130+
perror(ack_path.c_str());
131+
return EXIT_FAILURE;
132+
}
133+
}
134+
101135
if (time_trace) {
102136
llvm::timeTraceProfilerInitialize(0, argv[0]);
103137
}
@@ -119,6 +153,12 @@ int main(int argc, char *argv[]) {
119153
mod->print(llvm::outs(), nullptr);
120154
}
121155

156+
if (perf_control_fd != -1) {
157+
char buf[16];
158+
write(perf_control_fd, "enable\n", 7);
159+
read(perf_control_ack_fd, buf, 5);
160+
}
161+
122162
#if LLVM_VERSION_MAJOR >= 21
123163
std::string triple_str = mod->getTargetTriple().str();
124164
#else
@@ -145,6 +185,12 @@ int main(int argc, char *argv[]) {
145185
}
146186
}
147187

188+
if (perf_control_fd != -1) {
189+
char buf[16];
190+
write(perf_control_fd, "disable\n", 8);
191+
read(perf_control_ack_fd, buf, 5);
192+
}
193+
148194
unsigned exit_code = EXIT_SUCCESS;
149195

150196
if (compile_twice.Get()) {

0 commit comments

Comments
 (0)