Stage.h revision 353358
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_STAGE_H 16#define LLVM_MCA_STAGE_H 17 18#include "llvm/MCA/HWEventListener.h" 19#include "llvm/Support/Error.h" 20#include <set> 21 22namespace llvm { 23namespace mca { 24 25class InstRef; 26 27class Stage { 28 Stage *NextInSequence; 29 std::set<HWEventListener *> Listeners; 30 31 Stage(const Stage &Other) = delete; 32 Stage &operator=(const Stage &Other) = delete; 33 34protected: 35 const std::set<HWEventListener *> &getListeners() const { return Listeners; } 36 37public: 38 Stage() : NextInSequence(nullptr) {} 39 virtual ~Stage(); 40 41 /// Returns true if it can execute IR during this cycle. 42 virtual bool isAvailable(const InstRef &IR) const { return true; } 43 44 /// Returns true if some instructions are still executing this stage. 45 virtual bool hasWorkToComplete() const = 0; 46 47 /// Called once at the start of each cycle. This can be used as a setup 48 /// phase to prepare for the executions during the cycle. 49 virtual Error cycleStart() { return ErrorSuccess(); } 50 51 /// Called once at the end of each cycle. 52 virtual Error cycleEnd() { return ErrorSuccess(); } 53 54 /// The primary action that this stage performs on instruction IR. 55 virtual Error execute(InstRef &IR) = 0; 56 57 void setNextInSequence(Stage *NextStage) { 58 assert(!NextInSequence && "This stage already has a NextInSequence!"); 59 NextInSequence = NextStage; 60 } 61 62 bool checkNextStage(const InstRef &IR) const { 63 return NextInSequence && NextInSequence->isAvailable(IR); 64 } 65 66 /// Called when an instruction is ready to move the next pipeline stage. 67 /// 68 /// Stages are responsible for moving instructions to their immediate 69 /// successor stages. 70 Error moveToTheNextStage(InstRef &IR) { 71 assert(checkNextStage(IR) && "Next stage is not ready!"); 72 return NextInSequence->execute(IR); 73 } 74 75 /// Add a listener to receive callbacks during the execution of this stage. 76 void addListener(HWEventListener *Listener); 77 78 /// Notify listeners of a particular hardware event. 79 template <typename EventT> void notifyEvent(const EventT &Event) const { 80 for (HWEventListener *Listener : Listeners) 81 Listener->onEvent(Event); 82 } 83}; 84 85} // namespace mca 86} // namespace llvm 87#endif // LLVM_MCA_STAGE_H 88