1 //===----------------------- HWEventListener.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 /// \file
10 ///
11 /// This file defines the main interface for hardware event listeners.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_MCA_HWEVENTLISTENER_H
16 #define LLVM_MCA_HWEVENTLISTENER_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/MCA/Instruction.h"
20 #include "llvm/MCA/Support.h"
21 
22 namespace llvm {
23 namespace mca {
24 
25 // An HWInstructionEvent represents state changes of instructions that
26 // listeners might be interested in. Listeners can choose to ignore any event
27 // they are not interested in.
28 class HWInstructionEvent {
29 public:
30   // This is the list of event types that are shared by all targets, that
31   // generic subtarget-agnostic classes (e.g., Pipeline, HWInstructionEvent,
32   // ...) and generic Views can manipulate.
33   // Subtargets are free to define additional event types, that are goin to be
34   // handled by generic components as opaque values, but can still be
35   // emitted by subtarget-specific pipeline stages (e.g., ExecuteStage,
36   // DispatchStage, ...) and interpreted by subtarget-specific EventListener
37   // implementations.
38   enum GenericEventType {
39     Invalid = 0,
40     // Events generated by the Retire Control Unit.
41     Retired,
42     // Events generated by the Scheduler.
43     Ready,
44     Issued,
45     Executed,
46     // Events generated by the Dispatch logic.
47     Dispatched,
48 
49     LastGenericEventType,
50   };
51 
HWInstructionEvent(unsigned type,const InstRef & Inst)52   HWInstructionEvent(unsigned type, const InstRef &Inst)
53       : Type(type), IR(Inst) {}
54 
55   // The event type. The exact meaning depends on the subtarget.
56   const unsigned Type;
57 
58   // The instruction this event was generated for.
59   const InstRef &IR;
60 };
61 
62 class HWInstructionIssuedEvent : public HWInstructionEvent {
63 public:
64   using ResourceRef = std::pair<uint64_t, uint64_t>;
HWInstructionIssuedEvent(const InstRef & IR,ArrayRef<std::pair<ResourceRef,ResourceCycles>> UR)65   HWInstructionIssuedEvent(const InstRef &IR,
66                            ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR)
67       : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
68 
69   ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources;
70 };
71 
72 class HWInstructionDispatchedEvent : public HWInstructionEvent {
73 public:
HWInstructionDispatchedEvent(const InstRef & IR,ArrayRef<unsigned> Regs,unsigned UOps)74   HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs,
75                                unsigned UOps)
76       : HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
77         UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
78   // Number of physical register allocated for this instruction. There is one
79   // entry per register file.
80   ArrayRef<unsigned> UsedPhysRegs;
81   // Number of micro opcodes dispatched.
82   // This field is often set to the total number of micro-opcodes specified by
83   // the instruction descriptor of IR.
84   // The only exception is when IR declares a number of micro opcodes
85   // which exceeds the processor DispatchWidth, and - by construction - it
86   // requires multiple cycles to be fully dispatched. In that particular case,
87   // the dispatch logic would generate more than one dispatch event (one per
88   // cycle), and each event would declare how many micro opcodes are effectively
89   // been dispatched to the schedulers.
90   unsigned MicroOpcodes;
91 };
92 
93 class HWInstructionRetiredEvent : public HWInstructionEvent {
94 public:
HWInstructionRetiredEvent(const InstRef & IR,ArrayRef<unsigned> Regs)95   HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs)
96       : HWInstructionEvent(HWInstructionEvent::Retired, IR),
97         FreedPhysRegs(Regs) {}
98   // Number of register writes that have been architecturally committed. There
99   // is one entry per register file.
100   ArrayRef<unsigned> FreedPhysRegs;
101 };
102 
103 // A HWStallEvent represents a pipeline stall caused by the lack of hardware
104 // resources.
105 class HWStallEvent {
106 public:
107   enum GenericEventType {
108     Invalid = 0,
109     // Generic stall events generated by the DispatchStage.
110     RegisterFileStall,
111     RetireControlUnitStall,
112     // Generic stall events generated by the Scheduler.
113     DispatchGroupStall,
114     SchedulerQueueFull,
115     LoadQueueFull,
116     StoreQueueFull,
117     LastGenericEvent
118   };
119 
HWStallEvent(unsigned type,const InstRef & Inst)120   HWStallEvent(unsigned type, const InstRef &Inst) : Type(type), IR(Inst) {}
121 
122   // The exact meaning of the stall event type depends on the subtarget.
123   const unsigned Type;
124 
125   // The instruction this event was generated for.
126   const InstRef &IR;
127 };
128 
129 class HWEventListener {
130 public:
131   // Generic events generated by the pipeline.
onCycleBegin()132   virtual void onCycleBegin() {}
onCycleEnd()133   virtual void onCycleEnd() {}
134 
onEvent(const HWInstructionEvent & Event)135   virtual void onEvent(const HWInstructionEvent &Event) {}
onEvent(const HWStallEvent & Event)136   virtual void onEvent(const HWStallEvent &Event) {}
137 
138   using ResourceRef = std::pair<uint64_t, uint64_t>;
onResourceAvailable(const ResourceRef & RRef)139   virtual void onResourceAvailable(const ResourceRef &RRef) {}
140 
141   // Events generated by the Scheduler when buffered resources are
142   // consumed/freed for an instruction.
onReservedBuffers(const InstRef & Inst,ArrayRef<unsigned> Buffers)143   virtual void onReservedBuffers(const InstRef &Inst,
144                                  ArrayRef<unsigned> Buffers) {}
onReleasedBuffers(const InstRef & Inst,ArrayRef<unsigned> Buffers)145   virtual void onReleasedBuffers(const InstRef &Inst,
146                                  ArrayRef<unsigned> Buffers) {}
147 
~HWEventListener()148   virtual ~HWEventListener() {}
149 
150 private:
151   virtual void anchor();
152 };
153 } // namespace mca
154 } // namespace llvm
155 
156 #endif // LLVM_MCA_HWEVENTLISTENER_H
157