Stage.h revision 343171
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
23namespace llvm {
24namespace mca {
25
26class InstRef;
27
28class Stage {
29  Stage *NextInSequence;
30  std::set<HWEventListener *> Listeners;
31
32  Stage(const Stage &Other) = delete;
33  Stage &operator=(const Stage &Other) = delete;
34
35protected:
36  const std::set<HWEventListener *> &getListeners() const { return Listeners; }
37
38public:
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
89