xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MCA/HWEventListener.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===----------------------- HWEventListener.h ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file defines the main interface for hardware event listeners.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_MCA_HWEVENTLISTENER_H
15 #define LLVM_MCA_HWEVENTLISTENER_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/MCA/Instruction.h"
19 #include "llvm/MCA/Support.h"
20 #include "llvm/Support/Compiler.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 going 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     Pending,
44     Ready,
45     Issued,
46     Executed,
47     // Events generated by the Dispatch logic.
48     Dispatched,
49 
50     LastGenericEventType,
51   };
52 
HWInstructionEvent(unsigned type,const InstRef & Inst)53   HWInstructionEvent(unsigned type, const InstRef &Inst)
54       : Type(type), IR(Inst) {}
55 
56   // The event type. The exact meaning depends on the subtarget.
57   const unsigned Type;
58 
59   // The instruction this event was generated for.
60   const InstRef &IR;
61 };
62 
63 // ResourceRef::first is the index of the associated Resource.
64 // ResourceRef::second is a bitmask of the referenced sub-unit of the resource.
65 using ResourceRef = std::pair<uint64_t, uint64_t>;
66 
67 using ResourceUse = std::pair<ResourceRef, ReleaseAtCycles>;
68 
69 class HWInstructionIssuedEvent : public HWInstructionEvent {
70 public:
HWInstructionIssuedEvent(const InstRef & IR,ArrayRef<ResourceUse> UR)71   HWInstructionIssuedEvent(const InstRef &IR, ArrayRef<ResourceUse> UR)
72       : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
73 
74   ArrayRef<ResourceUse> UsedResources;
75 };
76 
77 class HWInstructionDispatchedEvent : public HWInstructionEvent {
78 public:
HWInstructionDispatchedEvent(const InstRef & IR,ArrayRef<unsigned> Regs,unsigned UOps)79   HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs,
80                                unsigned UOps)
81       : HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
82         UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
83   // Number of physical register allocated for this instruction. There is one
84   // entry per register file.
85   ArrayRef<unsigned> UsedPhysRegs;
86   // Number of micro opcodes dispatched.
87   // This field is often set to the total number of micro-opcodes specified by
88   // the instruction descriptor of IR.
89   // The only exception is when IR declares a number of micro opcodes
90   // which exceeds the processor DispatchWidth, and - by construction - it
91   // requires multiple cycles to be fully dispatched. In that particular case,
92   // the dispatch logic would generate more than one dispatch event (one per
93   // cycle), and each event would declare how many micro opcodes are effectively
94   // been dispatched to the schedulers.
95   unsigned MicroOpcodes;
96 };
97 
98 class HWInstructionRetiredEvent : public HWInstructionEvent {
99 public:
HWInstructionRetiredEvent(const InstRef & IR,ArrayRef<unsigned> Regs)100   HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs)
101       : HWInstructionEvent(HWInstructionEvent::Retired, IR),
102         FreedPhysRegs(Regs) {}
103   // Number of register writes that have been architecturally committed. There
104   // is one entry per register file.
105   ArrayRef<unsigned> FreedPhysRegs;
106 };
107 
108 // A HWStallEvent represents a pipeline stall caused by the lack of hardware
109 // resources.
110 class HWStallEvent {
111 public:
112   enum GenericEventType {
113     Invalid = 0,
114     // Generic stall events generated by the DispatchStage.
115     RegisterFileStall,
116     RetireControlUnitStall,
117     // Generic stall events generated by the Scheduler.
118     DispatchGroupStall,
119     SchedulerQueueFull,
120     LoadQueueFull,
121     StoreQueueFull,
122     CustomBehaviourStall,
123     LastGenericEvent
124   };
125 
HWStallEvent(unsigned type,const InstRef & Inst)126   HWStallEvent(unsigned type, const InstRef &Inst) : Type(type), IR(Inst) {}
127 
128   // The exact meaning of the stall event type depends on the subtarget.
129   const unsigned Type;
130 
131   // The instruction this event was generated for.
132   const InstRef &IR;
133 };
134 
135 // A HWPressureEvent describes an increase in backend pressure caused by
136 // the presence of data dependencies or unavailability of pipeline resources.
137 class HWPressureEvent {
138 public:
139   enum GenericReason {
140     INVALID = 0,
141     // Scheduler was unable to issue all the ready instructions because some
142     // pipeline resources were unavailable.
143     RESOURCES,
144     // Instructions could not be issued because of register data dependencies.
145     REGISTER_DEPS,
146     // Instructions could not be issued because of memory dependencies.
147     MEMORY_DEPS
148   };
149 
150   HWPressureEvent(GenericReason reason, ArrayRef<InstRef> Insts,
151                   uint64_t Mask = 0)
Reason(reason)152       : Reason(reason), AffectedInstructions(Insts), ResourceMask(Mask) {}
153 
154   // Reason for this increase in backend pressure.
155   GenericReason Reason;
156 
157   // Instructions affected (i.e. delayed) by this increase in backend pressure.
158   ArrayRef<InstRef> AffectedInstructions;
159 
160   // A mask of unavailable processor resources.
161   const uint64_t ResourceMask;
162 };
163 
164 class LLVM_ABI HWEventListener {
165 public:
166   // Generic events generated by the pipeline.
onCycleBegin()167   virtual void onCycleBegin() {}
onCycleEnd()168   virtual void onCycleEnd() {}
169 
onEvent(const HWInstructionEvent & Event)170   virtual void onEvent(const HWInstructionEvent &Event) {}
onEvent(const HWStallEvent & Event)171   virtual void onEvent(const HWStallEvent &Event) {}
onEvent(const HWPressureEvent & Event)172   virtual void onEvent(const HWPressureEvent &Event) {}
173 
onResourceAvailable(const ResourceRef & RRef)174   virtual void onResourceAvailable(const ResourceRef &RRef) {}
175 
176   // Events generated by the Scheduler when buffered resources are
177   // consumed/freed for an instruction.
onReservedBuffers(const InstRef & Inst,ArrayRef<unsigned> Buffers)178   virtual void onReservedBuffers(const InstRef &Inst,
179                                  ArrayRef<unsigned> Buffers) {}
onReleasedBuffers(const InstRef & Inst,ArrayRef<unsigned> Buffers)180   virtual void onReleasedBuffers(const InstRef &Inst,
181                                  ArrayRef<unsigned> Buffers) {}
182 
183   virtual ~HWEventListener() = default;
184 
185 private:
186   virtual void anchor();
187 };
188 } // namespace mca
189 } // namespace llvm
190 
191 #endif // LLVM_MCA_HWEVENTLISTENER_H
192