Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:16

0001 //===---------------------- CustomBehaviour.h -------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// This file defines the base class CustomBehaviour which can be inherited from
0011 /// by specific targets (ex. llvm/tools/llvm-mca/lib/X86CustomBehaviour.h).
0012 /// CustomBehaviour is designed to enforce custom behaviour and dependencies
0013 /// within the llvm-mca pipeline simulation that llvm-mca isn't already capable
0014 /// of extracting from the Scheduling Models.
0015 ///
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_MCA_CUSTOMBEHAVIOUR_H
0019 #define LLVM_MCA_CUSTOMBEHAVIOUR_H
0020 
0021 #include "llvm/ADT/SmallVector.h"
0022 #include "llvm/MC/MCInst.h"
0023 #include "llvm/MC/MCInstrInfo.h"
0024 #include "llvm/MC/MCSubtargetInfo.h"
0025 #include "llvm/MCA/SourceMgr.h"
0026 #include "llvm/MCA/View.h"
0027 
0028 namespace llvm {
0029 namespace mca {
0030 
0031 /// Class which can be overriden by targets to modify the
0032 /// mca::Instruction objects before the pipeline starts.
0033 /// A common usage of this class is to add immediate operands to certain
0034 /// instructions or to remove Defs/Uses from an instruction where the
0035 /// schedulinng model is incorrect.
0036 class InstrPostProcess {
0037 protected:
0038   const MCSubtargetInfo &STI;
0039   const MCInstrInfo &MCII;
0040 
0041 public:
0042   InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
0043       : STI(STI), MCII(MCII) {}
0044 
0045   virtual ~InstrPostProcess() = default;
0046 
0047   /// This method can be overriden by targets to modify the mca::Instruction
0048   /// object after it has been lowered from the MCInst.
0049   /// This is generally a less disruptive alternative to modifying the
0050   /// scheduling model.
0051   virtual void postProcessInstruction(std::unique_ptr<Instruction> &Inst,
0052                                       const MCInst &MCI) {}
0053 
0054   // The resetState() method gets invoked at the beginning of each code region
0055   // so that targets that override this function can clear any state that they
0056   // have left from the previous code region.
0057   virtual void resetState() {}
0058 };
0059 
0060 /// Class which can be overriden by targets to enforce instruction
0061 /// dependencies and behaviours that aren't expressed well enough
0062 /// within the scheduling model for mca to automatically simulate
0063 /// them properly.
0064 /// If you implement this class for your target, make sure to also implement
0065 /// a target specific InstrPostProcess class as well.
0066 class CustomBehaviour {
0067 protected:
0068   const MCSubtargetInfo &STI;
0069   const mca::SourceMgr &SrcMgr;
0070   const MCInstrInfo &MCII;
0071 
0072 public:
0073   CustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr,
0074                   const MCInstrInfo &MCII)
0075       : STI(STI), SrcMgr(SrcMgr), MCII(MCII) {}
0076 
0077   virtual ~CustomBehaviour();
0078 
0079   /// Before the llvm-mca pipeline dispatches an instruction, it first checks
0080   /// for any register or resource dependencies / hazards. If it doesn't find
0081   /// any, this method will be invoked to determine if there are any custom
0082   /// hazards that the instruction needs to wait for.
0083   /// The return value of this method is the number of cycles that the
0084   /// instruction needs to wait for.
0085   /// It's safe to underestimate the number of cycles to wait for since these
0086   /// checks will be invoked again before the intruction gets dispatched.
0087   /// However, it's not safe (accurate) to overestimate the number of cycles
0088   /// to wait for since the instruction will wait for AT LEAST that number of
0089   /// cycles before attempting to be dispatched again.
0090   virtual unsigned checkCustomHazard(ArrayRef<InstRef> IssuedInst,
0091                                      const InstRef &IR);
0092 
0093   // Functions that target CBs can override to return a list of
0094   // target specific Views that need to live within /lib/Target/ so that
0095   // they can benefit from the target CB or from backend functionality that is
0096   // not already exposed through MC-layer classes. Keep in mind that how this
0097   // function is used is that the function is called within llvm-mca.cpp and
0098   // then each unique_ptr<View> is passed into the PipelinePrinter::addView()
0099   // function. This function will then std::move the View into its own vector of
0100   // Views. So any CB that overrides this function needs to make sure that they
0101   // are not relying on the current address or reference of the View
0102   // unique_ptrs. If you do need the CB and View to be able to communicate with
0103   // each other, consider giving the View a reference or pointer to the CB when
0104   // the View is constructed. Then the View can query the CB for information
0105   // when it needs it.
0106   /// Return a vector of Views that will be added before all other Views.
0107   virtual std::vector<std::unique_ptr<View>>
0108   getStartViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
0109   /// Return a vector of Views that will be added after the InstructionInfoView.
0110   virtual std::vector<std::unique_ptr<View>>
0111   getPostInstrInfoViews(llvm::MCInstPrinter &IP,
0112                         llvm::ArrayRef<llvm::MCInst> Insts);
0113   /// Return a vector of Views that will be added after all other Views.
0114   virtual std::vector<std::unique_ptr<View>>
0115   getEndViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
0116 };
0117 
0118 class Instrument {
0119   /// The description of Instrument kind
0120   const StringRef Desc;
0121 
0122   /// The instrumentation data
0123   const StringRef Data;
0124 
0125 public:
0126   Instrument(StringRef Desc, StringRef Data) : Desc(Desc), Data(Data) {}
0127 
0128   Instrument() : Instrument("", "") {}
0129 
0130   virtual ~Instrument() = default;
0131 
0132   StringRef getDesc() const { return Desc; }
0133   StringRef getData() const { return Data; }
0134 };
0135 
0136 using UniqueInstrument = std::unique_ptr<Instrument>;
0137 
0138 /// This class allows targets to optionally customize the logic that resolves
0139 /// scheduling class IDs. Targets can use information encoded in Instrument
0140 /// objects to make more informed scheduling decisions.
0141 class InstrumentManager {
0142 protected:
0143   const MCSubtargetInfo &STI;
0144   const MCInstrInfo &MCII;
0145 
0146 public:
0147   InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
0148       : STI(STI), MCII(MCII) {}
0149 
0150   virtual ~InstrumentManager() = default;
0151 
0152   /// Returns true if llvm-mca should ignore instruments.
0153   virtual bool shouldIgnoreInstruments() const { return true; }
0154 
0155   // Returns true if this supports processing Instrument with
0156   // Instrument.Desc equal to Type
0157   virtual bool supportsInstrumentType(StringRef Type) const { return false; }
0158 
0159   /// Allocate an Instrument, and return a unique pointer to it. This function
0160   /// may be useful to create instruments coming from comments in the assembly.
0161   /// See createInstruments to create Instruments from MCInst
0162   virtual UniqueInstrument createInstrument(StringRef Desc, StringRef Data);
0163 
0164   /// Return a list of unique pointers to Instruments, where each Instrument
0165   /// is allocated by this function. See createInstrument to create Instrument
0166   /// from a description and data.
0167   virtual SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst);
0168 
0169   /// Given an MCInst and a vector of Instrument, a target can
0170   /// return a SchedClassID. This can be used by a subtarget to return a
0171   /// PseudoInstruction SchedClassID instead of the one that belongs to the
0172   /// BaseInstruction This can be useful when a BaseInstruction does not convey
0173   /// the correct scheduling information without additional data. By default,
0174   /// it returns the SchedClassID that belongs to MCI.
0175   virtual unsigned getSchedClassID(const MCInstrInfo &MCII, const MCInst &MCI,
0176                                    const SmallVector<Instrument *> &IVec) const;
0177 };
0178 
0179 } // namespace mca
0180 } // namespace llvm
0181 
0182 #endif /* LLVM_MCA_CUSTOMBEHAVIOUR_H */