Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:16

0001 //===---------------------- Stage.h -----------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// This file defines a stage.
0011 /// A chain of stages compose an instruction pipeline.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_MCA_STAGES_STAGE_H
0016 #define LLVM_MCA_STAGES_STAGE_H
0017 
0018 #include "llvm/MCA/HWEventListener.h"
0019 #include "llvm/Support/Error.h"
0020 #include <set>
0021 
0022 namespace llvm {
0023 namespace mca {
0024 
0025 class InstRef;
0026 
0027 class Stage {
0028   Stage *NextInSequence = nullptr;
0029   std::set<HWEventListener *> Listeners;
0030 
0031   Stage(const Stage &Other) = delete;
0032   Stage &operator=(const Stage &Other) = delete;
0033 
0034 protected:
0035   const std::set<HWEventListener *> &getListeners() const { return Listeners; }
0036 
0037 public:
0038   Stage() = default;
0039   virtual ~Stage();
0040 
0041   /// Returns true if it can execute IR during this cycle.
0042   virtual bool isAvailable(const InstRef &IR) const { return true; }
0043 
0044   /// Returns true if some instructions are still executing this stage.
0045   virtual bool hasWorkToComplete() const = 0;
0046 
0047   /// Called once at the start of each cycle.  This can be used as a setup
0048   /// phase to prepare for the executions during the cycle.
0049   virtual Error cycleStart() { return ErrorSuccess(); }
0050 
0051   /// Called after the pipeline is resumed from pausing state.
0052   virtual Error cycleResume() { return ErrorSuccess(); }
0053 
0054   /// Called once at the end of each cycle.
0055   virtual Error cycleEnd() { return ErrorSuccess(); }
0056 
0057   /// The primary action that this stage performs on instruction IR.
0058   virtual Error execute(InstRef &IR) = 0;
0059 
0060   void setNextInSequence(Stage *NextStage) {
0061     assert(!NextInSequence && "This stage already has a NextInSequence!");
0062     NextInSequence = NextStage;
0063   }
0064 
0065   bool checkNextStage(const InstRef &IR) const {
0066     return NextInSequence && NextInSequence->isAvailable(IR);
0067   }
0068 
0069   /// Called when an instruction is ready to move the next pipeline stage.
0070   ///
0071   /// Stages are responsible for moving instructions to their immediate
0072   /// successor stages.
0073   Error moveToTheNextStage(InstRef &IR) {
0074     assert(checkNextStage(IR) && "Next stage is not ready!");
0075     return NextInSequence->execute(IR);
0076   }
0077 
0078   /// Add a listener to receive callbacks during the execution of this stage.
0079   void addListener(HWEventListener *Listener);
0080 
0081   /// Notify listeners of a particular hardware event.
0082   template <typename EventT> void notifyEvent(const EventT &Event) const {
0083     for (HWEventListener *Listener : Listeners)
0084       Listener->onEvent(Event);
0085   }
0086 };
0087 
0088 /// This is actually not an error but a marker to indicate that
0089 /// the instruction stream is paused.
0090 struct InstStreamPause : public ErrorInfo<InstStreamPause> {
0091   static char ID;
0092 
0093   std::error_code convertToErrorCode() const override {
0094     return llvm::inconvertibleErrorCode();
0095   }
0096   void log(raw_ostream &OS) const override { OS << "Stream is paused"; }
0097 };
0098 } // namespace mca
0099 } // namespace llvm
0100 #endif // LLVM_MCA_STAGES_STAGE_H