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 21 namespace llvm { 22 namespace 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. 27 class HWInstructionEvent { 28 public: 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 going 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 62 // ResourceRef::first is the index of the associated Resource. 63 // ResourceRef::second is a bitmask of the referenced sub-unit of the resource. 64 using ResourceRef = std::pair<uint64_t, uint64_t>; 65 66 using ResourceUse = std::pair<ResourceRef, ReleaseAtCycles>; 67 68 class HWInstructionIssuedEvent : public HWInstructionEvent { 69 public: 70 HWInstructionIssuedEvent(const InstRef &IR, ArrayRef<ResourceUse> UR) 71 : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {} 72 73 ArrayRef<ResourceUse> UsedResources; 74 }; 75 76 class HWInstructionDispatchedEvent : public HWInstructionEvent { 77 public: 78 HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs, 79 unsigned UOps) 80 : HWInstructionEvent(HWInstructionEvent::Dispatched, IR), 81 UsedPhysRegs(Regs), MicroOpcodes(UOps) {} 82 // Number of physical register allocated for this instruction. There is one 83 // entry per register file. 84 ArrayRef<unsigned> UsedPhysRegs; 85 // Number of micro opcodes dispatched. 86 // This field is often set to the total number of micro-opcodes specified by 87 // the instruction descriptor of IR. 88 // The only exception is when IR declares a number of micro opcodes 89 // which exceeds the processor DispatchWidth, and - by construction - it 90 // requires multiple cycles to be fully dispatched. In that particular case, 91 // the dispatch logic would generate more than one dispatch event (one per 92 // cycle), and each event would declare how many micro opcodes are effectively 93 // been dispatched to the schedulers. 94 unsigned MicroOpcodes; 95 }; 96 97 class HWInstructionRetiredEvent : public HWInstructionEvent { 98 public: 99 HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs) 100 : HWInstructionEvent(HWInstructionEvent::Retired, IR), 101 FreedPhysRegs(Regs) {} 102 // Number of register writes that have been architecturally committed. There 103 // is one entry per register file. 104 ArrayRef<unsigned> FreedPhysRegs; 105 }; 106 107 // A HWStallEvent represents a pipeline stall caused by the lack of hardware 108 // resources. 109 class HWStallEvent { 110 public: 111 enum GenericEventType { 112 Invalid = 0, 113 // Generic stall events generated by the DispatchStage. 114 RegisterFileStall, 115 RetireControlUnitStall, 116 // Generic stall events generated by the Scheduler. 117 DispatchGroupStall, 118 SchedulerQueueFull, 119 LoadQueueFull, 120 StoreQueueFull, 121 CustomBehaviourStall, 122 LastGenericEvent 123 }; 124 125 HWStallEvent(unsigned type, const InstRef &Inst) : Type(type), IR(Inst) {} 126 127 // The exact meaning of the stall event type depends on the subtarget. 128 const unsigned Type; 129 130 // The instruction this event was generated for. 131 const InstRef &IR; 132 }; 133 134 // A HWPressureEvent describes an increase in backend pressure caused by 135 // the presence of data dependencies or unavailability of pipeline resources. 136 class HWPressureEvent { 137 public: 138 enum GenericReason { 139 INVALID = 0, 140 // Scheduler was unable to issue all the ready instructions because some 141 // pipeline resources were unavailable. 142 RESOURCES, 143 // Instructions could not be issued because of register data dependencies. 144 REGISTER_DEPS, 145 // Instructions could not be issued because of memory dependencies. 146 MEMORY_DEPS 147 }; 148 149 HWPressureEvent(GenericReason reason, ArrayRef<InstRef> Insts, 150 uint64_t Mask = 0) 151 : Reason(reason), AffectedInstructions(Insts), ResourceMask(Mask) {} 152 153 // Reason for this increase in backend pressure. 154 GenericReason Reason; 155 156 // Instructions affected (i.e. delayed) by this increase in backend pressure. 157 ArrayRef<InstRef> AffectedInstructions; 158 159 // A mask of unavailable processor resources. 160 const uint64_t ResourceMask; 161 }; 162 163 class HWEventListener { 164 public: 165 // Generic events generated by the pipeline. 166 virtual void onCycleBegin() {} 167 virtual void onCycleEnd() {} 168 169 virtual void onEvent(const HWInstructionEvent &Event) {} 170 virtual void onEvent(const HWStallEvent &Event) {} 171 virtual void onEvent(const HWPressureEvent &Event) {} 172 173 virtual void onResourceAvailable(const ResourceRef &RRef) {} 174 175 // Events generated by the Scheduler when buffered resources are 176 // consumed/freed for an instruction. 177 virtual void onReservedBuffers(const InstRef &Inst, 178 ArrayRef<unsigned> Buffers) {} 179 virtual void onReleasedBuffers(const InstRef &Inst, 180 ArrayRef<unsigned> Buffers) {} 181 182 virtual ~HWEventListener() = default; 183 184 private: 185 virtual void anchor(); 186 }; 187 } // namespace mca 188 } // namespace llvm 189 190 #endif // LLVM_MCA_HWEVENTLISTENER_H 191