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
21namespace llvm {
22namespace mca {
23
24// An HWInstructionEvent represents state changes of instructions that
25// listeners might be interested in. Listeners can choose to ignore any event
26// they are not interested in.
27class HWInstructionEvent {
28public:
29  // This is the list of event types that are shared by all targets, that
30  // generic subtarget-agnostic classes (e.g., Pipeline, HWInstructionEvent,
31  // ...) and generic Views can manipulate.
32  // Subtargets are free to define additional event types, that are goin to be
33  // handled by generic components as opaque values, but can still be
34  // emitted by subtarget-specific pipeline stages (e.g., ExecuteStage,
35  // DispatchStage, ...) and interpreted by subtarget-specific EventListener
36  // implementations.
37  enum GenericEventType {
38    Invalid = 0,
39    // Events generated by the Retire Control Unit.
40    Retired,
41    // Events generated by the Scheduler.
42    Pending,
43    Ready,
44    Issued,
45    Executed,
46    // Events generated by the Dispatch logic.
47    Dispatched,
48
49    LastGenericEventType,
50  };
51
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
62class HWInstructionIssuedEvent : public HWInstructionEvent {
63public:
64  using ResourceRef = std::pair<uint64_t, uint64_t>;
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
72class HWInstructionDispatchedEvent : public HWInstructionEvent {
73public:
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
93class HWInstructionRetiredEvent : public HWInstructionEvent {
94public:
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.
105class HWStallEvent {
106public:
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
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// A HWPressureEvent describes an increase in backend pressure caused by
130// the presence of data dependencies or unavailability of pipeline resources.
131class HWPressureEvent {
132public:
133  enum GenericReason {
134    INVALID = 0,
135    // Scheduler was unable to issue all the ready instructions because some
136    // pipeline resources were unavailable.
137    RESOURCES,
138    // Instructions could not be issued because of register data dependencies.
139    REGISTER_DEPS,
140    // Instructions could not be issued because of memory dependencies.
141    MEMORY_DEPS
142  };
143
144  HWPressureEvent(GenericReason reason, ArrayRef<InstRef> Insts,
145                  uint64_t Mask = 0)
146      : Reason(reason), AffectedInstructions(Insts), ResourceMask(Mask) {}
147
148  // Reason for this increase in backend pressure.
149  GenericReason Reason;
150
151  // Instructions affected (i.e. delayed) by this increase in backend pressure.
152  ArrayRef<InstRef> AffectedInstructions;
153
154  // A mask of unavailable processor resources.
155  const uint64_t ResourceMask;
156};
157
158class HWEventListener {
159public:
160  // Generic events generated by the pipeline.
161  virtual void onCycleBegin() {}
162  virtual void onCycleEnd() {}
163
164  virtual void onEvent(const HWInstructionEvent &Event) {}
165  virtual void onEvent(const HWStallEvent &Event) {}
166  virtual void onEvent(const HWPressureEvent &Event) {}
167
168  using ResourceRef = std::pair<uint64_t, uint64_t>;
169  virtual void onResourceAvailable(const ResourceRef &RRef) {}
170
171  // Events generated by the Scheduler when buffered resources are
172  // consumed/freed for an instruction.
173  virtual void onReservedBuffers(const InstRef &Inst,
174                                 ArrayRef<unsigned> Buffers) {}
175  virtual void onReleasedBuffers(const InstRef &Inst,
176                                 ArrayRef<unsigned> Buffers) {}
177
178  virtual ~HWEventListener() {}
179
180private:
181  virtual void anchor();
182};
183} // namespace mca
184} // namespace llvm
185
186#endif // LLVM_MCA_HWEVENTLISTENER_H
187