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 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 62 class HWInstructionIssuedEvent : public HWInstructionEvent { 63 public: 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 72 class HWInstructionDispatchedEvent : public HWInstructionEvent { 73 public: 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 93 class HWInstructionRetiredEvent : public HWInstructionEvent { 94 public: 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. 105 class HWStallEvent { 106 public: 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. 131 class HWPressureEvent { 132 public: 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 158 class HWEventListener { 159 public: 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 180 private: 181 virtual void anchor(); 182 }; 183 } // namespace mca 184 } // namespace llvm 185 186 #endif // LLVM_MCA_HWEVENTLISTENER_H 187