xref: /llvm-project/llvm/include/llvm/MCA/CustomBehaviour.h (revision ecf372f993fa0f1ae417a3159e5c397f36c2d48c)
1ef16c8eaSPatrick Holland //===---------------------- CustomBehaviour.h -------------------*- C++ -*-===//
2ef16c8eaSPatrick Holland //
3ef16c8eaSPatrick Holland // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ef16c8eaSPatrick Holland // See https://llvm.org/LICENSE.txt for license information.
5ef16c8eaSPatrick Holland // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef16c8eaSPatrick Holland //
7ef16c8eaSPatrick Holland //===----------------------------------------------------------------------===//
8ef16c8eaSPatrick Holland /// \file
9ef16c8eaSPatrick Holland ///
10ef16c8eaSPatrick Holland /// This file defines the base class CustomBehaviour which can be inherited from
11ef16c8eaSPatrick Holland /// by specific targets (ex. llvm/tools/llvm-mca/lib/X86CustomBehaviour.h).
12ef16c8eaSPatrick Holland /// CustomBehaviour is designed to enforce custom behaviour and dependencies
13ef16c8eaSPatrick Holland /// within the llvm-mca pipeline simulation that llvm-mca isn't already capable
14ef16c8eaSPatrick Holland /// of extracting from the Scheduling Models.
15ef16c8eaSPatrick Holland ///
16ef16c8eaSPatrick Holland //===----------------------------------------------------------------------===//
17ef16c8eaSPatrick Holland 
18ef16c8eaSPatrick Holland #ifndef LLVM_MCA_CUSTOMBEHAVIOUR_H
19ef16c8eaSPatrick Holland #define LLVM_MCA_CUSTOMBEHAVIOUR_H
20ef16c8eaSPatrick Holland 
2198e342dcSMichael Maitland #include "llvm/ADT/SmallVector.h"
22ef16c8eaSPatrick Holland #include "llvm/MC/MCInst.h"
23ef16c8eaSPatrick Holland #include "llvm/MC/MCInstrInfo.h"
24ef16c8eaSPatrick Holland #include "llvm/MC/MCSubtargetInfo.h"
25ef16c8eaSPatrick Holland #include "llvm/MCA/SourceMgr.h"
26fe01014fSPatrick Holland #include "llvm/MCA/View.h"
27ef16c8eaSPatrick Holland 
28ef16c8eaSPatrick Holland namespace llvm {
29ef16c8eaSPatrick Holland namespace mca {
30ef16c8eaSPatrick Holland 
31ef16c8eaSPatrick Holland /// Class which can be overriden by targets to modify the
32ef16c8eaSPatrick Holland /// mca::Instruction objects before the pipeline starts.
33ef16c8eaSPatrick Holland /// A common usage of this class is to add immediate operands to certain
34ef16c8eaSPatrick Holland /// instructions or to remove Defs/Uses from an instruction where the
35ef16c8eaSPatrick Holland /// schedulinng model is incorrect.
36ef16c8eaSPatrick Holland class InstrPostProcess {
37ef16c8eaSPatrick Holland protected:
38ef16c8eaSPatrick Holland   const MCSubtargetInfo &STI;
39ef16c8eaSPatrick Holland   const MCInstrInfo &MCII;
40ef16c8eaSPatrick Holland 
41ef16c8eaSPatrick Holland public:
InstrPostProcess(const MCSubtargetInfo & STI,const MCInstrInfo & MCII)42ef16c8eaSPatrick Holland   InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
43ef16c8eaSPatrick Holland       : STI(STI), MCII(MCII) {}
44ef16c8eaSPatrick Holland 
45152d61a8SKazu Hirata   virtual ~InstrPostProcess() = default;
46ef16c8eaSPatrick Holland 
4785e6e748SPatrick Holland   /// This method can be overriden by targets to modify the mca::Instruction
4885e6e748SPatrick Holland   /// object after it has been lowered from the MCInst.
4985e6e748SPatrick Holland   /// This is generally a less disruptive alternative to modifying the
5085e6e748SPatrick Holland   /// scheduling model.
postProcessInstruction(std::unique_ptr<Instruction> & Inst,const MCInst & MCI)51ef16c8eaSPatrick Holland   virtual void postProcessInstruction(std::unique_ptr<Instruction> &Inst,
52ef16c8eaSPatrick Holland                                       const MCInst &MCI) {}
5355cedf9cSPatrick Holland 
5455cedf9cSPatrick Holland   // The resetState() method gets invoked at the beginning of each code region
5555cedf9cSPatrick Holland   // so that targets that override this function can clear any state that they
5655cedf9cSPatrick Holland   // have left from the previous code region.
resetState()5755cedf9cSPatrick Holland   virtual void resetState() {}
58ef16c8eaSPatrick Holland };
59ef16c8eaSPatrick Holland 
60ef16c8eaSPatrick Holland /// Class which can be overriden by targets to enforce instruction
61ef16c8eaSPatrick Holland /// dependencies and behaviours that aren't expressed well enough
62ef16c8eaSPatrick Holland /// within the scheduling model for mca to automatically simulate
63ef16c8eaSPatrick Holland /// them properly.
64ef16c8eaSPatrick Holland /// If you implement this class for your target, make sure to also implement
65ef16c8eaSPatrick Holland /// a target specific InstrPostProcess class as well.
66ef16c8eaSPatrick Holland class CustomBehaviour {
67ef16c8eaSPatrick Holland protected:
68ef16c8eaSPatrick Holland   const MCSubtargetInfo &STI;
69dbed061bSPatrick Holland   const mca::SourceMgr &SrcMgr;
70ef16c8eaSPatrick Holland   const MCInstrInfo &MCII;
71ef16c8eaSPatrick Holland 
72ef16c8eaSPatrick Holland public:
CustomBehaviour(const MCSubtargetInfo & STI,const mca::SourceMgr & SrcMgr,const MCInstrInfo & MCII)73dbed061bSPatrick Holland   CustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr,
74ef16c8eaSPatrick Holland                   const MCInstrInfo &MCII)
75ef16c8eaSPatrick Holland       : STI(STI), SrcMgr(SrcMgr), MCII(MCII) {}
76ef16c8eaSPatrick Holland 
77c2955534SMin-Yih Hsu   virtual ~CustomBehaviour();
78ef16c8eaSPatrick Holland 
79fe01014fSPatrick Holland   /// Before the llvm-mca pipeline dispatches an instruction, it first checks
80fe01014fSPatrick Holland   /// for any register or resource dependencies / hazards. If it doesn't find
81fe01014fSPatrick Holland   /// any, this method will be invoked to determine if there are any custom
82fe01014fSPatrick Holland   /// hazards that the instruction needs to wait for.
83fe01014fSPatrick Holland   /// The return value of this method is the number of cycles that the
84fe01014fSPatrick Holland   /// instruction needs to wait for.
85fe01014fSPatrick Holland   /// It's safe to underestimate the number of cycles to wait for since these
86fe01014fSPatrick Holland   /// checks will be invoked again before the intruction gets dispatched.
87fe01014fSPatrick Holland   /// However, it's not safe (accurate) to overestimate the number of cycles
88fe01014fSPatrick Holland   /// to wait for since the instruction will wait for AT LEAST that number of
89fe01014fSPatrick Holland   /// cycles before attempting to be dispatched again.
90ef16c8eaSPatrick Holland   virtual unsigned checkCustomHazard(ArrayRef<InstRef> IssuedInst,
91ef16c8eaSPatrick Holland                                      const InstRef &IR);
92fe01014fSPatrick Holland 
93fe01014fSPatrick Holland   // Functions that target CBs can override to return a list of
94fe01014fSPatrick Holland   // target specific Views that need to live within /lib/Target/ so that
95fe01014fSPatrick Holland   // they can benefit from the target CB or from backend functionality that is
96fe01014fSPatrick Holland   // not already exposed through MC-layer classes. Keep in mind that how this
97fe01014fSPatrick Holland   // function is used is that the function is called within llvm-mca.cpp and
98fe01014fSPatrick Holland   // then each unique_ptr<View> is passed into the PipelinePrinter::addView()
99fe01014fSPatrick Holland   // function. This function will then std::move the View into its own vector of
100fe01014fSPatrick Holland   // Views. So any CB that overrides this function needs to make sure that they
101fe01014fSPatrick Holland   // are not relying on the current address or reference of the View
102fe01014fSPatrick Holland   // unique_ptrs. If you do need the CB and View to be able to communicate with
103fe01014fSPatrick Holland   // each other, consider giving the View a reference or pointer to the CB when
104fe01014fSPatrick Holland   // the View is constructed. Then the View can query the CB for information
105fe01014fSPatrick Holland   // when it needs it.
106fe01014fSPatrick Holland   /// Return a vector of Views that will be added before all other Views.
107fe01014fSPatrick Holland   virtual std::vector<std::unique_ptr<View>>
108fe01014fSPatrick Holland   getStartViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
109fe01014fSPatrick Holland   /// Return a vector of Views that will be added after the InstructionInfoView.
110fe01014fSPatrick Holland   virtual std::vector<std::unique_ptr<View>>
111fe01014fSPatrick Holland   getPostInstrInfoViews(llvm::MCInstPrinter &IP,
112fe01014fSPatrick Holland                         llvm::ArrayRef<llvm::MCInst> Insts);
113fe01014fSPatrick Holland   /// Return a vector of Views that will be added after all other Views.
114fe01014fSPatrick Holland   virtual std::vector<std::unique_ptr<View>>
115fe01014fSPatrick Holland   getEndViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
116ef16c8eaSPatrick Holland };
117ef16c8eaSPatrick Holland 
11898e342dcSMichael Maitland class Instrument {
11998e342dcSMichael Maitland   /// The description of Instrument kind
12098e342dcSMichael Maitland   const StringRef Desc;
12198e342dcSMichael Maitland 
12298e342dcSMichael Maitland   /// The instrumentation data
12398e342dcSMichael Maitland   const StringRef Data;
12498e342dcSMichael Maitland 
12598e342dcSMichael Maitland public:
Instrument(StringRef Desc,StringRef Data)12698e342dcSMichael Maitland   Instrument(StringRef Desc, StringRef Data) : Desc(Desc), Data(Data) {}
12798e342dcSMichael Maitland 
Instrument()12898e342dcSMichael Maitland   Instrument() : Instrument("", "") {}
12998e342dcSMichael Maitland 
13098e342dcSMichael Maitland   virtual ~Instrument() = default;
13198e342dcSMichael Maitland 
getDesc()13298e342dcSMichael Maitland   StringRef getDesc() const { return Desc; }
getData()13398e342dcSMichael Maitland   StringRef getData() const { return Data; }
13498e342dcSMichael Maitland };
13598e342dcSMichael Maitland 
13656674e8eSMichael Maitland using UniqueInstrument = std::unique_ptr<Instrument>;
13798e342dcSMichael Maitland 
13898e342dcSMichael Maitland /// This class allows targets to optionally customize the logic that resolves
13998e342dcSMichael Maitland /// scheduling class IDs. Targets can use information encoded in Instrument
14098e342dcSMichael Maitland /// objects to make more informed scheduling decisions.
14198e342dcSMichael Maitland class InstrumentManager {
14298e342dcSMichael Maitland protected:
14398e342dcSMichael Maitland   const MCSubtargetInfo &STI;
14498e342dcSMichael Maitland   const MCInstrInfo &MCII;
14598e342dcSMichael Maitland 
14698e342dcSMichael Maitland public:
InstrumentManager(const MCSubtargetInfo & STI,const MCInstrInfo & MCII)14798e342dcSMichael Maitland   InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
14898e342dcSMichael Maitland       : STI(STI), MCII(MCII) {}
14998e342dcSMichael Maitland 
15098e342dcSMichael Maitland   virtual ~InstrumentManager() = default;
15198e342dcSMichael Maitland 
15298e342dcSMichael Maitland   /// Returns true if llvm-mca should ignore instruments.
shouldIgnoreInstruments()15398e342dcSMichael Maitland   virtual bool shouldIgnoreInstruments() const { return true; }
15498e342dcSMichael Maitland 
15598e342dcSMichael Maitland   // Returns true if this supports processing Instrument with
15698e342dcSMichael Maitland   // Instrument.Desc equal to Type
supportsInstrumentType(StringRef Type)15798e342dcSMichael Maitland   virtual bool supportsInstrumentType(StringRef Type) const { return false; }
15898e342dcSMichael Maitland 
159*ecf372f9SMichael Maitland   /// Allocate an Instrument, and return a unique pointer to it. This function
160*ecf372f9SMichael Maitland   /// may be useful to create instruments coming from comments in the assembly.
161*ecf372f9SMichael Maitland   /// See createInstruments to create Instruments from MCInst
16256674e8eSMichael Maitland   virtual UniqueInstrument createInstrument(StringRef Desc, StringRef Data);
16398e342dcSMichael Maitland 
164*ecf372f9SMichael Maitland   /// Return a list of unique pointers to Instruments, where each Instrument
165*ecf372f9SMichael Maitland   /// is allocated by this function. See createInstrument to create Instrument
166*ecf372f9SMichael Maitland   /// from a description and data.
167*ecf372f9SMichael Maitland   virtual SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst);
168*ecf372f9SMichael Maitland 
16998e342dcSMichael Maitland   /// Given an MCInst and a vector of Instrument, a target can
17098e342dcSMichael Maitland   /// return a SchedClassID. This can be used by a subtarget to return a
17198e342dcSMichael Maitland   /// PseudoInstruction SchedClassID instead of the one that belongs to the
17298e342dcSMichael Maitland   /// BaseInstruction This can be useful when a BaseInstruction does not convey
17398e342dcSMichael Maitland   /// the correct scheduling information without additional data. By default,
17498e342dcSMichael Maitland   /// it returns the SchedClassID that belongs to MCI.
17556674e8eSMichael Maitland   virtual unsigned getSchedClassID(const MCInstrInfo &MCII, const MCInst &MCI,
17656674e8eSMichael Maitland                                    const SmallVector<Instrument *> &IVec) const;
17798e342dcSMichael Maitland };
17898e342dcSMichael Maitland 
179ef16c8eaSPatrick Holland } // namespace mca
180ef16c8eaSPatrick Holland } // namespace llvm
181ef16c8eaSPatrick Holland 
182ef16c8eaSPatrick Holland #endif /* LLVM_MCA_CUSTOMBEHAVIOUR_H */
183