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