• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- PerfHelper.h ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// Helpers for measuring perf events.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H
16 #define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Config/config.h"
21 #include <functional>
22 #include <memory>
23 
24 struct perf_event_attr;
25 
26 namespace exegesis {
27 namespace pfm {
28 
29 // Returns true on error.
30 bool pfmInitialize();
31 void pfmTerminate();
32 
33 // Retrieves the encoding for the event described by pfm_event_string.
34 // NOTE: pfm_initialize() must be called before creating PerfEvent objects.
35 class PerfEvent {
36 public:
37   // http://perfmon2.sourceforge.net/manv4/libpfm.html
38   // Events are expressed as strings. e.g. "INSTRUCTION_RETIRED"
39   explicit PerfEvent(llvm::StringRef pfm_event_string);
40 
41   PerfEvent(const PerfEvent &) = delete;
42   PerfEvent(PerfEvent &&other);
43   ~PerfEvent();
44 
45   // The pfm_event_string passed at construction time.
46   llvm::StringRef name() const;
47 
48   // Whether the event was successfully created.
49   bool valid() const;
50 
51   // The encoded event to be passed to the Kernel.
52   const perf_event_attr *attribute() const;
53 
54   // The fully qualified name for the event.
55   // e.g. "snb_ep::INSTRUCTION_RETIRED:e=0:i=0:c=0:t=0:u=1:k=0:mg=0:mh=1"
56   llvm::StringRef getPfmEventString() const;
57 
58 private:
59   const std::string EventString;
60   std::string FullQualifiedEventString;
61   perf_event_attr *Attr;
62 };
63 
64 // Uses a valid PerfEvent to configure the Kernel so we can measure the
65 // underlying event.
66 struct Counter {
67   // event: the PerfEvent to measure.
68   explicit Counter(const PerfEvent &event);
69 
70   Counter(const Counter &) = delete;
71   Counter(Counter &&other) = default;
72 
73   ~Counter();
74 
75   void start();         // Starts the measurement of the event.
76   void stop();          // Stops the measurement of the event.
77   int64_t read() const; // Return the current value of the counter.
78 
79 private:
80 #ifdef HAVE_LIBPFM
81   int FileDescriptor = -1;
82 #endif
83 };
84 
85 // Helper to measure a list of PerfEvent for a particular function.
86 // callback is called for each successful measure (PerfEvent needs to be valid).
87 template <typename Function>
Measure(llvm::ArrayRef<PerfEvent> Events,const std::function<void (const PerfEvent & Event,int64_t Value)> & Callback,Function Fn)88 void Measure(
89     llvm::ArrayRef<PerfEvent> Events,
90     const std::function<void(const PerfEvent &Event, int64_t Value)> &Callback,
91     Function Fn) {
92   for (const auto &Event : Events) {
93     if (!Event.valid())
94       continue;
95     Counter Cnt(Event);
96     Cnt.start();
97     Fn();
98     Cnt.stop();
99     Callback(Event, Cnt.read());
100   }
101 }
102 
103 } // namespace pfm
104 } // namespace exegesis
105 
106 #endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H
107