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