Skip to content

Commit a974303

Browse files
[llvm-exegesis] Refactor individual counter data to ConfiguredEvent (#77900)
This further sets things up for validation events. Having a separate abstraction for a configured event that is setup as a counter allows for much easier creation of more events in the future within a single counter group (like validation counters) without duplicating any code.
1 parent fd0e06d commit a974303

File tree

3 files changed

+81
-39
lines changed

3 files changed

+81
-39
lines changed

llvm/tools/llvm-exegesis/lib/PerfHelper.cpp

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,18 @@ StringRef PerfEvent::getPfmEventString() const {
107107
return FullQualifiedEventString;
108108
}
109109

110-
CounterGroup::CounterGroup(PerfEvent &&E, pid_t ProcessID)
111-
: Event(std::move(E)) {
110+
ConfiguredEvent::ConfiguredEvent(PerfEvent &&EventToConfigure)
111+
: Event(std::move(EventToConfigure)) {
112112
assert(Event.valid());
113-
IsDummyEvent = Event.name() == PerfEvent::DummyEventString;
114-
if (!IsDummyEvent)
115-
initRealEvent(E, ProcessID);
116113
}
117114

118115
#ifdef HAVE_LIBPFM
119-
void CounterGroup::initRealEvent(const PerfEvent &E, pid_t ProcessID) {
120-
const int Cpu = -1; // measure any processor.
121-
const int GroupFd = -1; // no grouping of counters.
116+
void ConfiguredEvent::initRealEvent(const pid_t ProcessID) {
117+
const int CPU = -1;
118+
const int GroupFD = -1;
122119
const uint32_t Flags = 0;
123120
perf_event_attr AttrCopy = *Event.attribute();
124-
FileDescriptor = perf_event_open(&AttrCopy, ProcessID, Cpu, GroupFd, Flags);
121+
FileDescriptor = perf_event_open(&AttrCopy, ProcessID, CPU, GroupFD, Flags);
125122
if (FileDescriptor == -1) {
126123
errs() << "Unable to open event. ERRNO: " << strerror(errno)
127124
<< ". Make sure your kernel allows user "
@@ -134,44 +131,67 @@ void CounterGroup::initRealEvent(const PerfEvent &E, pid_t ProcessID) {
134131
assert(FileDescriptor != -1 && "Unable to open event");
135132
}
136133

137-
CounterGroup::~CounterGroup() {
134+
Expected<SmallVector<int64_t>>
135+
ConfiguredEvent::readOrError(StringRef /*unused*/) const {
136+
int64_t Count = 0;
137+
ssize_t ReadSize = ::read(FileDescriptor, &Count, sizeof(Count));
138+
139+
if (ReadSize != sizeof(Count))
140+
return llvm::make_error<llvm::StringError>("Failed to read event counter",
141+
llvm::errc::io_error);
142+
143+
SmallVector<int64_t, 1> Result;
144+
Result.push_back(Count);
145+
return Result;
146+
}
147+
148+
ConfiguredEvent::~ConfiguredEvent() { close(FileDescriptor); }
149+
#else
150+
void ConfiguredEvent::initRealEvent(pid_t ProcessID) {}
151+
152+
Expected<SmallVector<int64_t>>
153+
ConfiguredEvent::readOrError(StringRef /*unused*/) const {
154+
return make_error<StringError>("Not implemented",
155+
errc::function_not_supported);
156+
}
157+
158+
ConfiguredEvent::~ConfiguredEvent() = default;
159+
#endif // HAVE_LIBPFM
160+
161+
CounterGroup::CounterGroup(PerfEvent &&E, pid_t ProcessID)
162+
: EventCounter(std::move(E)) {
163+
IsDummyEvent = EventCounter.isDummyEvent();
138164
if (!IsDummyEvent)
139-
close(FileDescriptor);
165+
initRealEvent(ProcessID);
166+
}
167+
168+
#ifdef HAVE_LIBPFM
169+
void CounterGroup::initRealEvent(pid_t ProcessID) {
170+
EventCounter.initRealEvent(ProcessID);
140171
}
141172

142173
void CounterGroup::start() {
143174
if (!IsDummyEvent)
144-
ioctl(FileDescriptor, PERF_EVENT_IOC_RESET, 0);
175+
ioctl(getFileDescriptor(), PERF_EVENT_IOC_RESET, 0);
145176
}
146177

147178
void CounterGroup::stop() {
148179
if (!IsDummyEvent)
149-
ioctl(FileDescriptor, PERF_EVENT_IOC_DISABLE, 0);
180+
ioctl(getFileDescriptor(), PERF_EVENT_IOC_DISABLE, 0);
150181
}
151182

152183
llvm::Expected<llvm::SmallVector<int64_t, 4>>
153-
CounterGroup::readOrError(StringRef /*unused*/) const {
154-
int64_t Count = 0;
155-
if (!IsDummyEvent) {
156-
ssize_t ReadSize = ::read(FileDescriptor, &Count, sizeof(Count));
157-
if (ReadSize != sizeof(Count))
158-
return llvm::make_error<llvm::StringError>("Failed to read event counter",
159-
llvm::errc::io_error);
160-
} else {
161-
Count = 42;
162-
}
163-
164-
llvm::SmallVector<int64_t, 4> Result;
165-
Result.push_back(Count);
166-
return Result;
184+
CounterGroup::readOrError(StringRef FunctionBytes) const {
185+
if (!IsDummyEvent)
186+
return EventCounter.readOrError(FunctionBytes);
187+
else
188+
return SmallVector<int64_t, 1>(1, 42);
167189
}
168190

169191
int CounterGroup::numValues() const { return 1; }
170192
#else
171193

172-
void CounterGroup::initRealEvent(const PerfEvent &, pid_t ProcessID) {}
173-
174-
CounterGroup::~CounterGroup() = default;
194+
void CounterGroup::initRealEvent(pid_t ProcessID) {}
175195

176196
void CounterGroup::start() {}
177197

llvm/tools/llvm-exegesis/lib/PerfHelper.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,29 @@ class PerfEvent {
7777
void initRealEvent(StringRef PfmEventString);
7878
};
7979

80+
// Represents a single event that has been configured in the Linux perf
81+
// subsystem.
82+
class ConfiguredEvent {
83+
public:
84+
ConfiguredEvent(PerfEvent &&EventToConfigure);
85+
86+
void initRealEvent(const pid_t ProcessID);
87+
Expected<SmallVector<int64_t>> readOrError(StringRef FunctionBytes) const;
88+
int getFileDescriptor() const { return FileDescriptor; }
89+
bool isDummyEvent() const {
90+
return Event.name() == PerfEvent::DummyEventString;
91+
}
92+
93+
ConfiguredEvent(const ConfiguredEvent &) = delete;
94+
ConfiguredEvent(ConfiguredEvent &&other) = default;
95+
96+
~ConfiguredEvent();
97+
98+
private:
99+
PerfEvent Event;
100+
int FileDescriptor = -1;
101+
};
102+
80103
// Consists of a counter measuring a specific event and associated validation
81104
// counters measuring execution conditions. All counters in a group are part
82105
// of a single event group and are thus scheduled on and off the CPU as a single
@@ -89,7 +112,7 @@ class CounterGroup {
89112
CounterGroup(const CounterGroup &) = delete;
90113
CounterGroup(CounterGroup &&other) = default;
91114

92-
virtual ~CounterGroup();
115+
virtual ~CounterGroup() = default;
93116

94117
/// Starts the measurement of the event.
95118
virtual void start();
@@ -108,15 +131,14 @@ class CounterGroup {
108131

109132
virtual int numValues() const;
110133

111-
int getFileDescriptor() const { return FileDescriptor; }
134+
int getFileDescriptor() const { return EventCounter.getFileDescriptor(); }
112135

113136
protected:
114-
PerfEvent Event;
115-
int FileDescriptor = -1;
137+
ConfiguredEvent EventCounter;
116138
bool IsDummyEvent;
117139

118140
private:
119-
void initRealEvent(const PerfEvent &E, pid_t ProcessID);
141+
void initRealEvent(pid_t ProcessID);
120142
};
121143

122144
} // namespace pfm

llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ X86LbrPerfEvent::X86LbrPerfEvent(unsigned SamplingPeriod) {
143143
X86LbrCounter::X86LbrCounter(pfm::PerfEvent &&NewEvent)
144144
: CounterGroup(std::move(NewEvent)) {
145145
MMappedBuffer = mmap(nullptr, kMappedBufferSize, PROT_READ | PROT_WRITE,
146-
MAP_SHARED, FileDescriptor, 0);
146+
MAP_SHARED, getFileDescriptor(), 0);
147147
if (MMappedBuffer == MAP_FAILED)
148148
llvm::errs() << "Failed to mmap buffer.";
149149
}
@@ -154,7 +154,7 @@ X86LbrCounter::~X86LbrCounter() {
154154
}
155155

156156
void X86LbrCounter::start() {
157-
ioctl(FileDescriptor, PERF_EVENT_IOC_REFRESH, 1024 /* kMaxPollsPerFd */);
157+
ioctl(getFileDescriptor(), PERF_EVENT_IOC_REFRESH, 1024 /* kMaxPollsPerFd */);
158158
}
159159

160160
llvm::Error X86LbrCounter::checkLbrSupport() {
@@ -197,7 +197,7 @@ llvm::Error X86LbrCounter::checkLbrSupport() {
197197
llvm::Expected<llvm::SmallVector<int64_t, 4>>
198198
X86LbrCounter::readOrError(StringRef FunctionBytes) const {
199199
// Disable the event before reading
200-
ioctl(FileDescriptor, PERF_EVENT_IOC_DISABLE, 0);
200+
ioctl(getFileDescriptor(), PERF_EVENT_IOC_DISABLE, 0);
201201

202202
// Find the boundary of the function so that we could filter the LBRs
203203
// to keep only the relevant records.
@@ -223,7 +223,7 @@ X86LbrCounter::doReadCounter(const void *From, const void *To) const {
223223
int PollResult = 0;
224224

225225
while (PollResult <= 0) {
226-
PollResult = pollLbrPerfEvent(FileDescriptor);
226+
PollResult = pollLbrPerfEvent(getFileDescriptor());
227227
if (PollResult > 0)
228228
break;
229229
if (PollResult == -1)

0 commit comments

Comments
 (0)