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