1343171Sdim//===----------------------- HWEventListener.h ------------------*- C++ -*-===//
2343171Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343171Sdim//
7343171Sdim//===----------------------------------------------------------------------===//
8343171Sdim/// \file
9343171Sdim///
10343171Sdim/// This file defines the main interface for hardware event listeners.
11343171Sdim///
12343171Sdim//===----------------------------------------------------------------------===//
13343171Sdim
14343171Sdim#ifndef LLVM_MCA_HWEVENTLISTENER_H
15343171Sdim#define LLVM_MCA_HWEVENTLISTENER_H
16343171Sdim
17343171Sdim#include "llvm/ADT/ArrayRef.h"
18343171Sdim#include "llvm/MCA/Instruction.h"
19343171Sdim#include "llvm/MCA/Support.h"
20343171Sdim
21343171Sdimnamespace llvm {
22343171Sdimnamespace mca {
23343171Sdim
24343171Sdim// An HWInstructionEvent represents state changes of instructions that
25343171Sdim// listeners might be interested in. Listeners can choose to ignore any event
26343171Sdim// they are not interested in.
27343171Sdimclass HWInstructionEvent {
28343171Sdimpublic:
29343171Sdim  // This is the list of event types that are shared by all targets, that
30343171Sdim  // generic subtarget-agnostic classes (e.g., Pipeline, HWInstructionEvent,
31343171Sdim  // ...) and generic Views can manipulate.
32343171Sdim  // Subtargets are free to define additional event types, that are goin to be
33343171Sdim  // handled by generic components as opaque values, but can still be
34343171Sdim  // emitted by subtarget-specific pipeline stages (e.g., ExecuteStage,
35343171Sdim  // DispatchStage, ...) and interpreted by subtarget-specific EventListener
36343171Sdim  // implementations.
37343171Sdim  enum GenericEventType {
38343171Sdim    Invalid = 0,
39343171Sdim    // Events generated by the Retire Control Unit.
40343171Sdim    Retired,
41343171Sdim    // Events generated by the Scheduler.
42353358Sdim    Pending,
43343171Sdim    Ready,
44343171Sdim    Issued,
45343171Sdim    Executed,
46343171Sdim    // Events generated by the Dispatch logic.
47343171Sdim    Dispatched,
48343171Sdim
49343171Sdim    LastGenericEventType,
50343171Sdim  };
51343171Sdim
52343171Sdim  HWInstructionEvent(unsigned type, const InstRef &Inst)
53343171Sdim      : Type(type), IR(Inst) {}
54343171Sdim
55343171Sdim  // The event type. The exact meaning depends on the subtarget.
56343171Sdim  const unsigned Type;
57343171Sdim
58343171Sdim  // The instruction this event was generated for.
59343171Sdim  const InstRef &IR;
60343171Sdim};
61343171Sdim
62343171Sdimclass HWInstructionIssuedEvent : public HWInstructionEvent {
63343171Sdimpublic:
64343171Sdim  using ResourceRef = std::pair<uint64_t, uint64_t>;
65343171Sdim  HWInstructionIssuedEvent(const InstRef &IR,
66343171Sdim                           ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR)
67343171Sdim      : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
68343171Sdim
69343171Sdim  ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources;
70343171Sdim};
71343171Sdim
72343171Sdimclass HWInstructionDispatchedEvent : public HWInstructionEvent {
73343171Sdimpublic:
74343171Sdim  HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs,
75343171Sdim                               unsigned UOps)
76343171Sdim      : HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
77343171Sdim        UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
78343171Sdim  // Number of physical register allocated for this instruction. There is one
79343171Sdim  // entry per register file.
80343171Sdim  ArrayRef<unsigned> UsedPhysRegs;
81343171Sdim  // Number of micro opcodes dispatched.
82343171Sdim  // This field is often set to the total number of micro-opcodes specified by
83343171Sdim  // the instruction descriptor of IR.
84343171Sdim  // The only exception is when IR declares a number of micro opcodes
85343171Sdim  // which exceeds the processor DispatchWidth, and - by construction - it
86343171Sdim  // requires multiple cycles to be fully dispatched. In that particular case,
87343171Sdim  // the dispatch logic would generate more than one dispatch event (one per
88343171Sdim  // cycle), and each event would declare how many micro opcodes are effectively
89343171Sdim  // been dispatched to the schedulers.
90343171Sdim  unsigned MicroOpcodes;
91343171Sdim};
92343171Sdim
93343171Sdimclass HWInstructionRetiredEvent : public HWInstructionEvent {
94343171Sdimpublic:
95343171Sdim  HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs)
96343171Sdim      : HWInstructionEvent(HWInstructionEvent::Retired, IR),
97343171Sdim        FreedPhysRegs(Regs) {}
98343171Sdim  // Number of register writes that have been architecturally committed. There
99343171Sdim  // is one entry per register file.
100343171Sdim  ArrayRef<unsigned> FreedPhysRegs;
101343171Sdim};
102343171Sdim
103343171Sdim// A HWStallEvent represents a pipeline stall caused by the lack of hardware
104343171Sdim// resources.
105343171Sdimclass HWStallEvent {
106343171Sdimpublic:
107343171Sdim  enum GenericEventType {
108343171Sdim    Invalid = 0,
109343171Sdim    // Generic stall events generated by the DispatchStage.
110343171Sdim    RegisterFileStall,
111343171Sdim    RetireControlUnitStall,
112343171Sdim    // Generic stall events generated by the Scheduler.
113343171Sdim    DispatchGroupStall,
114343171Sdim    SchedulerQueueFull,
115343171Sdim    LoadQueueFull,
116343171Sdim    StoreQueueFull,
117343171Sdim    LastGenericEvent
118343171Sdim  };
119343171Sdim
120343171Sdim  HWStallEvent(unsigned type, const InstRef &Inst) : Type(type), IR(Inst) {}
121343171Sdim
122343171Sdim  // The exact meaning of the stall event type depends on the subtarget.
123343171Sdim  const unsigned Type;
124343171Sdim
125343171Sdim  // The instruction this event was generated for.
126343171Sdim  const InstRef &IR;
127343171Sdim};
128343171Sdim
129353358Sdim// A HWPressureEvent describes an increase in backend pressure caused by
130353358Sdim// the presence of data dependencies or unavailability of pipeline resources.
131353358Sdimclass HWPressureEvent {
132353358Sdimpublic:
133353358Sdim  enum GenericReason {
134353358Sdim    INVALID = 0,
135353358Sdim    // Scheduler was unable to issue all the ready instructions because some
136353358Sdim    // pipeline resources were unavailable.
137353358Sdim    RESOURCES,
138353358Sdim    // Instructions could not be issued because of register data dependencies.
139353358Sdim    REGISTER_DEPS,
140353358Sdim    // Instructions could not be issued because of memory dependencies.
141353358Sdim    MEMORY_DEPS
142353358Sdim  };
143353358Sdim
144353358Sdim  HWPressureEvent(GenericReason reason, ArrayRef<InstRef> Insts,
145353358Sdim                  uint64_t Mask = 0)
146353358Sdim      : Reason(reason), AffectedInstructions(Insts), ResourceMask(Mask) {}
147353358Sdim
148353358Sdim  // Reason for this increase in backend pressure.
149353358Sdim  GenericReason Reason;
150353358Sdim
151353358Sdim  // Instructions affected (i.e. delayed) by this increase in backend pressure.
152353358Sdim  ArrayRef<InstRef> AffectedInstructions;
153353358Sdim
154353358Sdim  // A mask of unavailable processor resources.
155353358Sdim  const uint64_t ResourceMask;
156353358Sdim};
157353358Sdim
158343171Sdimclass HWEventListener {
159343171Sdimpublic:
160343171Sdim  // Generic events generated by the pipeline.
161343171Sdim  virtual void onCycleBegin() {}
162343171Sdim  virtual void onCycleEnd() {}
163343171Sdim
164343171Sdim  virtual void onEvent(const HWInstructionEvent &Event) {}
165343171Sdim  virtual void onEvent(const HWStallEvent &Event) {}
166353358Sdim  virtual void onEvent(const HWPressureEvent &Event) {}
167343171Sdim
168343171Sdim  using ResourceRef = std::pair<uint64_t, uint64_t>;
169343171Sdim  virtual void onResourceAvailable(const ResourceRef &RRef) {}
170343171Sdim
171343171Sdim  // Events generated by the Scheduler when buffered resources are
172343171Sdim  // consumed/freed for an instruction.
173343171Sdim  virtual void onReservedBuffers(const InstRef &Inst,
174343171Sdim                                 ArrayRef<unsigned> Buffers) {}
175343171Sdim  virtual void onReleasedBuffers(const InstRef &Inst,
176343171Sdim                                 ArrayRef<unsigned> Buffers) {}
177343171Sdim
178343171Sdim  virtual ~HWEventListener() {}
179343171Sdim
180343171Sdimprivate:
181343171Sdim  virtual void anchor();
182343171Sdim};
183343171Sdim} // namespace mca
184343171Sdim} // namespace llvm
185343171Sdim
186343171Sdim#endif // LLVM_MCA_HWEVENTLISTENER_H
187