return FullQualifiedEventString;
}
-Counter::Counter(PerfEvent &&E) : Event(std::move(E)){
+Counter::Counter(PerfEvent &&E, pid_t ProcessID) : Event(std::move(E)) {
assert(Event.valid());
IsDummyEvent = Event.name() == PerfEvent::DummyEventString;
if (!IsDummyEvent)
- initRealEvent(E);
+ initRealEvent(E, ProcessID);
}
#ifdef HAVE_LIBPFM
-void Counter::initRealEvent(const PerfEvent &E) {
- const pid_t Pid = 0; // measure current process/thread.
+void Counter::initRealEvent(const PerfEvent &E, pid_t ProcessID) {
const int Cpu = -1; // measure any processor.
const int GroupFd = -1; // no grouping of counters.
const uint32_t Flags = 0;
perf_event_attr AttrCopy = *Event.attribute();
- FileDescriptor = perf_event_open(&AttrCopy, Pid, Cpu, GroupFd, Flags);
+ FileDescriptor = perf_event_open(&AttrCopy, ProcessID, Cpu, GroupFd, Flags);
if (FileDescriptor == -1) {
errs() << "Unable to open event. ERRNO: " << strerror(errno)
<< ". Make sure your kernel allows user "
int Counter::numValues() const { return 1; }
#else
-void Counter::initRealEvent(const PerfEvent &) {}
+void Counter::initRealEvent(const PerfEvent &, pid_t ProcessID) {}
Counter::~Counter() = default;
#include <functional>
#include <memory>
+#ifdef _MSC_VER
+typedef int pid_t;
+#else
+#include <sys/types.h>
+#endif // HAVE_LIBPFM
+
struct perf_event_attr;
namespace llvm {
class Counter {
public:
// event: the PerfEvent to measure.
- explicit Counter(PerfEvent &&event);
+ explicit Counter(PerfEvent &&event, pid_t ProcessID = 0);
Counter(const Counter &) = delete;
Counter(Counter &&other) = default;
virtual int numValues() const;
+ int getFileDescriptor() const { return FileDescriptor; }
+
protected:
PerfEvent Event;
-#ifdef HAVE_LIBPFM
int FileDescriptor = -1;
-#endif
bool IsDummyEvent;
private:
- void initRealEvent(const PerfEvent &E);
+ void initRealEvent(const PerfEvent &E, pid_t ProcessID);
};
} // namespace pfm
}
Expected<std::unique_ptr<pfm::Counter>>
-ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &) const {
+ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &,
+ const pid_t ProcessID) const {
pfm::PerfEvent Event(CounterName);
if (!Event.valid())
return llvm::make_error<Failure>(
.concat(CounterName)
.concat("'"));
- return std::make_unique<pfm::Counter>(std::move(Event));
+ return std::make_unique<pfm::Counter>(std::move(Event), ProcessID);
}
void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
// Targets can use this to create target-specific perf counters.
virtual Expected<std::unique_ptr<pfm::Counter>>
- createCounter(StringRef CounterName, const LLVMState &State) const;
+ createCounter(StringRef CounterName, const LLVMState &State,
+ const pid_t ProcessID = 0) const;
// Targets can use this to add target-specific passes in assembleToStream();
virtual void addTargetSpecificPasses(PassManagerBase &PM) const {}
ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {}
Expected<std::unique_ptr<pfm::Counter>>
- createCounter(StringRef CounterName, const LLVMState &State) const override {
+ createCounter(StringRef CounterName, const LLVMState &State,
+ const pid_t ProcessID) const override {
// If LbrSamplingPeriod was provided, then ignore the
// CounterName because we only have one for LBR.
if (LbrSamplingPeriod > 0) {
llvm::errc::invalid_argument);
#endif
}
- return ExegesisTarget::createCounter(CounterName, State);
+ return ExegesisTarget::createCounter(CounterName, State, ProcessID);
}
private: