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/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MCA/SourceMgr.h"
25 
26 namespace llvm {
27 namespace mca {
28 
29 /// Class which can be overriden by targets to modify the
30 /// mca::Instruction objects before the pipeline starts.
31 /// A common usage of this class is to add immediate operands to certain
32 /// instructions or to remove Defs/Uses from an instruction where the
33 /// schedulinng model is incorrect.
34 class InstrPostProcess {
35 protected:
36   const MCSubtargetInfo &STI;
37   const MCInstrInfo &MCII;
38 
39 public:
40   InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
41       : STI(STI), MCII(MCII) {}
42 
43   virtual ~InstrPostProcess() {}
44 
45   virtual void postProcessInstruction(std::unique_ptr<Instruction> &Inst,
46                                       const MCInst &MCI) {}
47 };
48 
49 /// Class which can be overriden by targets to enforce instruction
50 /// dependencies and behaviours that aren't expressed well enough
51 /// within the scheduling model for mca to automatically simulate
52 /// them properly.
53 /// If you implement this class for your target, make sure to also implement
54 /// a target specific InstrPostProcess class as well.
55 class CustomBehaviour {
56 protected:
57   const MCSubtargetInfo &STI;
58   const SourceMgr &SrcMgr;
59   const MCInstrInfo &MCII;
60 
61 public:
62   CustomBehaviour(const MCSubtargetInfo &STI, const SourceMgr &SrcMgr,
63                   const MCInstrInfo &MCII)
64       : STI(STI), SrcMgr(SrcMgr), MCII(MCII) {}
65 
66   virtual ~CustomBehaviour();
67 
68   // Before the llvm-mca pipeline dispatches an instruction, it first checks
69   // for any register or resource dependencies / hazards. If it doesn't find
70   // any, this method will be invoked to determine if there are any custom
71   // hazards that the instruction needs to wait for.
72   // The return value of this method is the number of cycles that the
73   // instruction needs to wait for.
74   // It's safe to underestimate the number of cycles to wait for since these
75   // checks will be invoked again before the intruction gets dispatched.
76   // However, it's not safe (accurate) to overestimate the number of cycles
77   // to wait for since the instruction will wait for AT LEAST that number of
78   // cycles before attempting to be dispatched again.
79   virtual unsigned checkCustomHazard(ArrayRef<InstRef> IssuedInst,
80                                      const InstRef &IR);
81 };
82 
83 } // namespace mca
84 } // namespace llvm
85 
86 #endif /* LLVM_MCA_CUSTOMBEHAVIOUR_H */
87