1//===---------------------- CustomBehaviour.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 base class CustomBehaviour which can be inherited from
11/// by specific targets (ex. llvm/tools/llvm-mca/lib/X86CustomBehaviour.h).
12/// CustomBehaviour is designed to enforce custom behaviour and dependencies
13/// within the llvm-mca pipeline simulation that llvm-mca isn't already capable
14/// of extracting from the Scheduling Models.
15///
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_MCA_CUSTOMBEHAVIOUR_H
19#define LLVM_MCA_CUSTOMBEHAVIOUR_H
20
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/MCA/SourceMgr.h"
26#include "llvm/MCA/View.h"
27
28namespace llvm {
29namespace mca {
30
31/// Class which can be overriden by targets to modify the
32/// mca::Instruction objects before the pipeline starts.
33/// A common usage of this class is to add immediate operands to certain
34/// instructions or to remove Defs/Uses from an instruction where the
35/// schedulinng model is incorrect.
36class InstrPostProcess {
37protected:
38 const MCSubtargetInfo &STI;
39 const MCInstrInfo &MCII;
40
41public:
42 InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
43 : STI(STI), MCII(MCII) {}
44
45 virtual ~InstrPostProcess() = default;
46
47 /// This method can be overriden by targets to modify the mca::Instruction
48 /// object after it has been lowered from the MCInst.
49 /// This is generally a less disruptive alternative to modifying the
50 /// scheduling model.
51 virtual void postProcessInstruction(std::unique_ptr<Instruction> &Inst,
52 const MCInst &MCI) {}
53
54 // The resetState() method gets invoked at the beginning of each code region
55 // so that targets that override this function can clear any state that they
56 // have left from the previous code region.
57 virtual void resetState() {}
58};
59
60/// Class which can be overriden by targets to enforce instruction
61/// dependencies and behaviours that aren't expressed well enough
62/// within the scheduling model for mca to automatically simulate
63/// them properly.
64/// If you implement this class for your target, make sure to also implement
65/// a target specific InstrPostProcess class as well.
66class CustomBehaviour {
67protected:
68 const MCSubtargetInfo &STI;
69 const mca::SourceMgr &SrcMgr;
70 const MCInstrInfo &MCII;
71
72public:
73 CustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr,
74 const MCInstrInfo &MCII)
75 : STI(STI), SrcMgr(SrcMgr), MCII(MCII) {}
76
77 virtual ~CustomBehaviour();
78
79 /// Before the llvm-mca pipeline dispatches an instruction, it first checks
80 /// for any register or resource dependencies / hazards. If it doesn't find
81 /// any, this method will be invoked to determine if there are any custom
82 /// hazards that the instruction needs to wait for.
83 /// The return value of this method is the number of cycles that the
84 /// instruction needs to wait for.
85 /// It's safe to underestimate the number of cycles to wait for since these
86 /// checks will be invoked again before the intruction gets dispatched.
87 /// However, it's not safe (accurate) to overestimate the number of cycles
88 /// to wait for since the instruction will wait for AT LEAST that number of
89 /// cycles before attempting to be dispatched again.
90 virtual unsigned checkCustomHazard(ArrayRef<InstRef> IssuedInst,
91 const InstRef &IR);
92
93 // Functions that target CBs can override to return a list of
94 // target specific Views that need to live within /lib/Target/ so that
95 // they can benefit from the target CB or from backend functionality that is
96 // not already exposed through MC-layer classes. Keep in mind that how this
97 // function is used is that the function is called within llvm-mca.cpp and
98 // then each unique_ptr<View> is passed into the PipelinePrinter::addView()
99 // function. This function will then std::move the View into its own vector of
100 // Views. So any CB that overrides this function needs to make sure that they
101 // are not relying on the current address or reference of the View
102 // unique_ptrs. If you do need the CB and View to be able to communicate with
103 // each other, consider giving the View a reference or pointer to the CB when
104 // the View is constructed. Then the View can query the CB for information
105 // when it needs it.
106 /// Return a vector of Views that will be added before all other Views.
107 virtual std::vector<std::unique_ptr<View>>
108 getStartViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
109 /// Return a vector of Views that will be added after the InstructionInfoView.
110 virtual std::vector<std::unique_ptr<View>>
111 getPostInstrInfoViews(llvm::MCInstPrinter &IP,
112 llvm::ArrayRef<llvm::MCInst> Insts);
113 /// Return a vector of Views that will be added after all other Views.
114 virtual std::vector<std::unique_ptr<View>>
115 getEndViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
116};
117
118class Instrument {
119 /// The description of Instrument kind
120 const StringRef Desc;
121
122 /// The instrumentation data
123 const StringRef Data;
124
125public:
126 Instrument(StringRef Desc, StringRef Data) : Desc(Desc), Data(Data) {}
127
128 Instrument() : Instrument("", "") {}
129
130 virtual ~Instrument() = default;
131
132 StringRef getDesc() const { return Desc; }
133 StringRef getData() const { return Data; }
134};
135
136using UniqueInstrument = std::unique_ptr<Instrument>;
137
138/// This class allows targets to optionally customize the logic that resolves
139/// scheduling class IDs. Targets can use information encoded in Instrument
140/// objects to make more informed scheduling decisions.
141class InstrumentManager {
142protected:
143 const MCSubtargetInfo &STI;
144 const MCInstrInfo &MCII;
145
146public:
147 InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
148 : STI(STI), MCII(MCII) {}
149
150 virtual ~InstrumentManager() = default;
151
152 /// Returns true if llvm-mca should ignore instruments.
153 virtual bool shouldIgnoreInstruments() const { return true; }
154
155 // Returns true if this supports processing Instrument with
156 // Instrument.Desc equal to Type
157 virtual bool supportsInstrumentType(StringRef Type) const { return false; }
158
159 /// Allocate an Instrument, and return a unique pointer to it. This function
160 /// may be useful to create instruments coming from comments in the assembly.
161 /// See createInstruments to create Instruments from MCInst
162 virtual UniqueInstrument createInstrument(StringRef Desc, StringRef Data);
163
164 /// Return a list of unique pointers to Instruments, where each Instrument
165 /// is allocated by this function. See createInstrument to create Instrument
166 /// from a description and data.
167 virtual SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst);
168
169 /// Given an MCInst and a vector of Instrument, a target can
170 /// return a SchedClassID. This can be used by a subtarget to return a
171 /// PseudoInstruction SchedClassID instead of the one that belongs to the
172 /// BaseInstruction This can be useful when a BaseInstruction does not convey
173 /// the correct scheduling information without additional data. By default,
174 /// it returns the SchedClassID that belongs to MCI.
175 virtual unsigned getSchedClassID(const MCInstrInfo &MCII, const MCInst &MCI,
176 const SmallVector<Instrument *> &IVec) const;
177};
178
179} // namespace mca
180} // namespace llvm
181
182#endif /* LLVM_MCA_CUSTOMBEHAVIOUR_H */
183

source code of llvm/include/llvm/MCA/CustomBehaviour.h