blob: 2f81b874a62506bc327cb05b8746508aec3fb6a9 [file] [log] [blame]
//===----------------------- HWEventListener.h ------------------*- C++ -*-===//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/// \file
/// This file defines the main interface for hardware event listeners.
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MCA/Instruction.h"
#include "llvm/MCA/Support.h"
namespace llvm {
namespace mca {
// An HWInstructionEvent represents state changes of instructions that
// listeners might be interested in. Listeners can choose to ignore any event
// they are not interested in.
class HWInstructionEvent {
// This is the list of event types that are shared by all targets, that
// generic subtarget-agnostic classes (e.g., Pipeline, HWInstructionEvent,
// ...) and generic Views can manipulate.
// Subtargets are free to define additional event types, that are goin to be
// handled by generic components as opaque values, but can still be
// emitted by subtarget-specific pipeline stages (e.g., ExecuteStage,
// DispatchStage, ...) and interpreted by subtarget-specific EventListener
// implementations.
enum GenericEventType {
Invalid = 0,
// Events generated by the Retire Control Unit.
// Events generated by the Scheduler.
// Events generated by the Dispatch logic.
HWInstructionEvent(unsigned type, const InstRef &Inst)
: Type(type), IR(Inst) {}
// The event type. The exact meaning depends on the subtarget.
const unsigned Type;
// The instruction this event was generated for.
const InstRef &IR;
class HWInstructionIssuedEvent : public HWInstructionEvent {
using ResourceRef = std::pair<uint64_t, uint64_t>;
HWInstructionIssuedEvent(const InstRef &IR,
ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR)
: HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources;
class HWInstructionDispatchedEvent : public HWInstructionEvent {
HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs,
unsigned UOps)
: HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
// Number of physical register allocated for this instruction. There is one
// entry per register file.
ArrayRef<unsigned> UsedPhysRegs;
// Number of micro opcodes dispatched.
// This field is often set to the total number of micro-opcodes specified by
// the instruction descriptor of IR.
// The only exception is when IR declares a number of micro opcodes
// which exceeds the processor DispatchWidth, and - by construction - it
// requires multiple cycles to be fully dispatched. In that particular case,
// the dispatch logic would generate more than one dispatch event (one per
// cycle), and each event would declare how many micro opcodes are effectively
// been dispatched to the schedulers.
unsigned MicroOpcodes;
class HWInstructionRetiredEvent : public HWInstructionEvent {
HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs)
: HWInstructionEvent(HWInstructionEvent::Retired, IR),
FreedPhysRegs(Regs) {}
// Number of register writes that have been architecturally committed. There
// is one entry per register file.
ArrayRef<unsigned> FreedPhysRegs;
// A HWStallEvent represents a pipeline stall caused by the lack of hardware
// resources.
class HWStallEvent {
enum GenericEventType {
Invalid = 0,
// Generic stall events generated by the DispatchStage.
// Generic stall events generated by the Scheduler.
HWStallEvent(unsigned type, const InstRef &Inst) : Type(type), IR(Inst) {}
// The exact meaning of the stall event type depends on the subtarget.
const unsigned Type;
// The instruction this event was generated for.
const InstRef &IR;
// A HWPressureEvent describes an increase in backend pressure caused by
// the presence of data dependencies or unavailability of pipeline resources.
class HWPressureEvent {
enum GenericReason {
// Scheduler was unable to issue all the ready instructions because some
// pipeline resources were unavailable.
// Instructions could not be issued because of register data dependencies.
// Instructions could not be issued because of memory dependencies.
HWPressureEvent(GenericReason reason, ArrayRef<InstRef> Insts,
uint64_t Mask = 0)
: Reason(reason), AffectedInstructions(Insts), ResourceMask(Mask) {}
// Reason for this increase in backend pressure.
GenericReason Reason;
// Instructions affected (i.e. delayed) by this increase in backend pressure.
ArrayRef<InstRef> AffectedInstructions;
// A mask of unavailable processor resources.
const uint64_t ResourceMask;
class HWEventListener {
// Generic events generated by the pipeline.
virtual void onCycleBegin() {}
virtual void onCycleEnd() {}
virtual void onEvent(const HWInstructionEvent &Event) {}
virtual void onEvent(const HWStallEvent &Event) {}
virtual void onEvent(const HWPressureEvent &Event) {}
using ResourceRef = std::pair<uint64_t, uint64_t>;
virtual void onResourceAvailable(const ResourceRef &RRef) {}
// Events generated by the Scheduler when buffered resources are
// consumed/freed for an instruction.
virtual void onReservedBuffers(const InstRef &Inst,
ArrayRef<unsigned> Buffers) {}
virtual void onReleasedBuffers(const InstRef &Inst,
ArrayRef<unsigned> Buffers) {}
virtual ~HWEventListener() {}
virtual void anchor();
} // namespace mca
} // namespace llvm