reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
//===----------------------- HWEventListener.h ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file defines the main interface for hardware event listeners.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_MCA_HWEVENTLISTENER_H
#define LLVM_MCA_HWEVENTLISTENER_H

#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 {
public:
  // 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.
    Retired,
    // Events generated by the Scheduler.
    Pending,
    Ready,
    Issued,
    Executed,
    // Events generated by the Dispatch logic.
    Dispatched,

    LastGenericEventType,
  };

  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 {
public:
  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 {
public:
  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 {
public:
  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 {
public:
  enum GenericEventType {
    Invalid = 0,
    // Generic stall events generated by the DispatchStage.
    RegisterFileStall,
    RetireControlUnitStall,
    // Generic stall events generated by the Scheduler.
    DispatchGroupStall,
    SchedulerQueueFull,
    LoadQueueFull,
    StoreQueueFull,
    LastGenericEvent
  };

  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 {
public:
  enum GenericReason {
    INVALID = 0,
    // Scheduler was unable to issue all the ready instructions because some
    // pipeline resources were unavailable.
    RESOURCES,
    // Instructions could not be issued because of register data dependencies.
    REGISTER_DEPS,
    // Instructions could not be issued because of memory dependencies.
    MEMORY_DEPS
  };

  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 {
public:
  // 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() {}

private:
  virtual void anchor();
};
} // namespace mca
} // namespace llvm

#endif // LLVM_MCA_HWEVENTLISTENER_H