]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MCA/Stages/Stage.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / MCA / Stages / Stage.h
1 //===---------------------- Stage.h -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file defines a stage.
12 /// A chain of stages compose an instruction pipeline.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_MCA_STAGE_H
17 #define LLVM_MCA_STAGE_H
18
19 #include "llvm/MCA/HWEventListener.h"
20 #include "llvm/Support/Error.h"
21 #include <set>
22
23 namespace llvm {
24 namespace mca {
25
26 class InstRef;
27
28 class Stage {
29   Stage *NextInSequence;
30   std::set<HWEventListener *> Listeners;
31
32   Stage(const Stage &Other) = delete;
33   Stage &operator=(const Stage &Other) = delete;
34
35 protected:
36   const std::set<HWEventListener *> &getListeners() const { return Listeners; }
37
38 public:
39   Stage() : NextInSequence(nullptr) {}
40   virtual ~Stage();
41
42   /// Returns true if it can execute IR during this cycle.
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.
50   virtual Error cycleStart() { return ErrorSuccess(); }
51
52   /// Called once at the end of each cycle.
53   virtual Error cycleEnd() { return ErrorSuccess(); }
54
55   /// The primary action that this stage performs on instruction IR.
56   virtual Error execute(InstRef &IR) = 0;
57
58   void setNextInSequence(Stage *NextStage) {
59     assert(!NextInSequence && "This stage already has a NextInSequence!");
60     NextInSequence = NextStage;
61   }
62
63   bool checkNextStage(const InstRef &IR) const {
64     return NextInSequence && NextInSequence->isAvailable(IR);
65   }
66
67   /// Called when an instruction is ready to move the next pipeline stage.
68   ///
69   /// Stages are responsible for moving instructions to their immediate
70   /// successor stages.
71   Error moveToTheNextStage(InstRef &IR) {
72     assert(checkNextStage(IR) && "Next stage is not ready!");
73     return NextInSequence->execute(IR);
74   }
75
76   /// Add a listener to receive callbacks during the execution of this stage.
77   void addListener(HWEventListener *Listener);
78
79   /// Notify listeners of a particular hardware event.
80   template <typename EventT> void notifyEvent(const EventT &Event) const {
81     for (HWEventListener *Listener : Listeners)
82       Listener->onEvent(Event);
83   }
84 };
85
86 } // namespace mca
87 } // namespace llvm
88 #endif // LLVM_MCA_STAGE_H