- //===---------------------- 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 */ 
-