xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MCA/Stages/Stage.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===---------------------- Stage.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 a stage.
11 /// A chain of stages compose an instruction pipeline.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_MCA_STAGES_STAGE_H
16 #define LLVM_MCA_STAGES_STAGE_H
17 
18 #include "llvm/MCA/HWEventListener.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/Error.h"
21 #include <set>
22 
23 namespace llvm {
24 namespace mca {
25 
26 class InstRef;
27 
28 class LLVM_ABI Stage {
29   Stage *NextInSequence = nullptr;
30   std::set<HWEventListener *> Listeners;
31 
32   Stage(const Stage &Other) = delete;
33   Stage &operator=(const Stage &Other) = delete;
34 
35 protected:
getListeners()36   const std::set<HWEventListener *> &getListeners() const { return Listeners; }
37 
38 public:
39   Stage() = default;
40   virtual ~Stage();
41 
42   /// Returns true if it can execute IR during this cycle.
isAvailable(const InstRef & IR)43   virtual bool isAvailable(const InstRef &IR) const { return true; }
44 
45   /// Returns true if some instructions are still executing this stage.
46   virtual bool hasWorkToComplete() const = 0;
47 
48   /// Called once at the start of each cycle.  This can be used as a setup
49   /// phase to prepare for the executions during the cycle.
cycleStart()50   virtual Error cycleStart() { return ErrorSuccess(); }
51 
52   /// Called after the pipeline is resumed from pausing state.
cycleResume()53   virtual Error cycleResume() { return ErrorSuccess(); }
54 
55   /// Called once at the end of each cycle.
cycleEnd()56   virtual Error cycleEnd() { return ErrorSuccess(); }
57 
58   /// The primary action that this stage performs on instruction IR.
59   virtual Error execute(InstRef &IR) = 0;
60 
setNextInSequence(Stage * NextStage)61   void setNextInSequence(Stage *NextStage) {
62     assert(!NextInSequence && "This stage already has a NextInSequence!");
63     NextInSequence = NextStage;
64   }
65 
checkNextStage(const InstRef & IR)66   bool checkNextStage(const InstRef &IR) const {
67     return NextInSequence && NextInSequence->isAvailable(IR);
68   }
69 
70   /// Called when an instruction is ready to move the next pipeline stage.
71   ///
72   /// Stages are responsible for moving instructions to their immediate
73   /// successor stages.
moveToTheNextStage(InstRef & IR)74   Error moveToTheNextStage(InstRef &IR) {
75     assert(checkNextStage(IR) && "Next stage is not ready!");
76     return NextInSequence->execute(IR);
77   }
78 
79   /// Add a listener to receive callbacks during the execution of this stage.
80   void addListener(HWEventListener *Listener);
81 
82   /// Notify listeners of a particular hardware event.
notifyEvent(const EventT & Event)83   template <typename EventT> void notifyEvent(const EventT &Event) const {
84     for (HWEventListener *Listener : Listeners)
85       Listener->onEvent(Event);
86   }
87 };
88 
89 /// This is actually not an error but a marker to indicate that
90 /// the instruction stream is paused.
91 struct InstStreamPause : public ErrorInfo<InstStreamPause> {
92   LLVM_ABI static char ID;
93 
convertToErrorCodeInstStreamPause94   std::error_code convertToErrorCode() const override {
95     return llvm::inconvertibleErrorCode();
96   }
logInstStreamPause97   void log(raw_ostream &OS) const override { OS << "Stream is paused"; }
98 };
99 } // namespace mca
100 } // namespace llvm
101 #endif // LLVM_MCA_STAGES_STAGE_H
102