aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/include/llvm/MCA/CustomBehaviour.h
blob: b41c5a85a322a780b17c1880810ca585932d8f3b (plain) (blame)
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
187
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===---------------------- CustomBehaviour.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 base class CustomBehaviour which can be inherited from
/// by specific targets (ex. llvm/tools/llvm-mca/lib/X86CustomBehaviour.h).
/// CustomBehaviour is designed to enforce custom behaviour and dependencies
/// within the llvm-mca pipeline simulation that llvm-mca isn't already capable
/// of extracting from the Scheduling Models.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_MCA_CUSTOMBEHAVIOUR_H
#define LLVM_MCA_CUSTOMBEHAVIOUR_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MCA/SourceMgr.h"
#include "llvm/MCA/View.h"

namespace llvm {
namespace mca {

/// Class which can be overriden by targets to modify the
/// mca::Instruction objects before the pipeline starts.
/// A common usage of this class is to add immediate operands to certain
/// instructions or to remove Defs/Uses from an instruction where the
/// schedulinng model is incorrect.
class InstrPostProcess {
protected:
  const MCSubtargetInfo &STI;
  const MCInstrInfo &MCII;

public:
  InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
      : STI(STI), MCII(MCII) {}

  virtual ~InstrPostProcess() = default;

  /// This method can be overriden by targets to modify the mca::Instruction
  /// object after it has been lowered from the MCInst.
  /// This is generally a less disruptive alternative to modifying the
  /// scheduling model.
  virtual void postProcessInstruction(std::unique_ptr<Instruction> &Inst,
                                      const MCInst &MCI) {}

  // The resetState() method gets invoked at the beginning of each code region
  // so that targets that override this function can clear any state that they
  // have left from the previous code region.
  virtual void resetState() {}
};

/// Class which can be overriden by targets to enforce instruction
/// dependencies and behaviours that aren't expressed well enough
/// within the scheduling model for mca to automatically simulate
/// them properly.
/// If you implement this class for your target, make sure to also implement
/// a target specific InstrPostProcess class as well.
class CustomBehaviour {
protected:
  const MCSubtargetInfo &STI;
  const mca::SourceMgr &SrcMgr;
  const MCInstrInfo &MCII;

public:
  CustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr,
                  const MCInstrInfo &MCII)
      : STI(STI), SrcMgr(SrcMgr), MCII(MCII) {}

  virtual ~CustomBehaviour();

  /// Before the llvm-mca pipeline dispatches an instruction, it first checks
  /// for any register or resource dependencies / hazards. If it doesn't find
  /// any, this method will be invoked to determine if there are any custom
  /// hazards that the instruction needs to wait for.
  /// The return value of this method is the number of cycles that the
  /// instruction needs to wait for.
  /// It's safe to underestimate the number of cycles to wait for since these
  /// checks will be invoked again before the intruction gets dispatched.
  /// However, it's not safe (accurate) to overestimate the number of cycles
  /// to wait for since the instruction will wait for AT LEAST that number of
  /// cycles before attempting to be dispatched again.
  virtual unsigned checkCustomHazard(ArrayRef<InstRef> IssuedInst,
                                     const InstRef &IR);

  // Functions that target CBs can override to return a list of
  // target specific Views that need to live within /lib/Target/ so that
  // they can benefit from the target CB or from backend functionality that is
  // not already exposed through MC-layer classes. Keep in mind that how this
  // function is used is that the function is called within llvm-mca.cpp and
  // then each unique_ptr<View> is passed into the PipelinePrinter::addView()
  // function. This function will then std::move the View into its own vector of
  // Views. So any CB that overrides this function needs to make sure that they
  // are not relying on the current address or reference of the View
  // unique_ptrs. If you do need the CB and View to be able to communicate with
  // each other, consider giving the View a reference or pointer to the CB when
  // the View is constructed. Then the View can query the CB for information
  // when it needs it.
  /// Return a vector of Views that will be added before all other Views.
  virtual std::vector<std::unique_ptr<View>>
  getStartViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
  /// Return a vector of Views that will be added after the InstructionInfoView.
  virtual std::vector<std::unique_ptr<View>>
  getPostInstrInfoViews(llvm::MCInstPrinter &IP,
                        llvm::ArrayRef<llvm::MCInst> Insts);
  /// Return a vector of Views that will be added after all other Views.
  virtual std::vector<std::unique_ptr<View>>
  getEndViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
};

class Instrument {
  /// The description of Instrument kind
  const StringRef Desc;

  /// The instrumentation data
  const StringRef Data;

public:
  Instrument(StringRef Desc, StringRef Data) : Desc(Desc), Data(Data) {}

  Instrument() : Instrument("", "") {}

  virtual ~Instrument() = default;

  StringRef getDesc() const { return Desc; }
  StringRef getData() const { return Data; }
};

using SharedInstrument = std::shared_ptr<Instrument>;

/// This class allows targets to optionally customize the logic that resolves
/// scheduling class IDs. Targets can use information encoded in Instrument
/// objects to make more informed scheduling decisions.
class InstrumentManager {
protected:
  const MCSubtargetInfo &STI;
  const MCInstrInfo &MCII;

public:
  InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
      : STI(STI), MCII(MCII) {}

  virtual ~InstrumentManager() = default;

  /// Returns true if llvm-mca should ignore instruments.
  virtual bool shouldIgnoreInstruments() const { return true; }

  // Returns true if this supports processing Instrument with
  // Instrument.Desc equal to Type
  virtual bool supportsInstrumentType(StringRef Type) const { return false; }

  /// Allocate an Instrument, and return a shared pointer to it.
  virtual SharedInstrument createInstrument(StringRef Desc, StringRef Data);

  /// Given an MCInst and a vector of Instrument, a target can
  /// return a SchedClassID. This can be used by a subtarget to return a
  /// PseudoInstruction SchedClassID instead of the one that belongs to the
  /// BaseInstruction This can be useful when a BaseInstruction does not convey
  /// the correct scheduling information without additional data. By default,
  /// it returns the SchedClassID that belongs to MCI.
  virtual unsigned
  getSchedClassID(const MCInstrInfo &MCII, const MCInst &MCI,
                  const SmallVector<SharedInstrument> &IVec) const;
};

} // namespace mca
} // namespace llvm

#endif /* LLVM_MCA_CUSTOMBEHAVIOUR_H */

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif