1//===---------------------- ExecuteStage.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 the execution stage of a default instruction pipeline.
11///
12/// The ExecuteStage is responsible for managing the hardware scheduler
13/// and issuing notifications that an instruction has been executed.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_MCA_STAGES_EXECUTESTAGE_H
18#define LLVM_MCA_STAGES_EXECUTESTAGE_H
19
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/MCA/HardwareUnits/Scheduler.h"
22#include "llvm/MCA/Instruction.h"
23#include "llvm/MCA/Stages/Stage.h"
24
25namespace llvm {
26namespace mca {
27
28class ExecuteStage final : public Stage {
29  Scheduler &HWS;
30
31  unsigned NumDispatchedOpcodes;
32  unsigned NumIssuedOpcodes;
33
34  // True if this stage should notify listeners of HWPressureEvents.
35  bool EnablePressureEvents;
36
37  Error issueInstruction(InstRef &IR);
38
39  // Called at the beginning of each cycle to issue already dispatched
40  // instructions to the underlying pipelines.
41  Error issueReadyInstructions();
42
43  // Used to notify instructions eliminated at register renaming stage.
44  Error handleInstructionEliminated(InstRef &IR);
45
46  ExecuteStage(const ExecuteStage &Other) = delete;
47  ExecuteStage &operator=(const ExecuteStage &Other) = delete;
48
49public:
50  ExecuteStage(Scheduler &S) : ExecuteStage(S, false) {}
51  ExecuteStage(Scheduler &S, bool ShouldPerformBottleneckAnalysis)
52      : HWS(S), NumDispatchedOpcodes(0), NumIssuedOpcodes(0),
53        EnablePressureEvents(ShouldPerformBottleneckAnalysis) {}
54
55  // This stage works under the assumption that the Pipeline will eventually
56  // execute a retire stage. We don't need to check if pipelines and/or
57  // schedulers have instructions to process, because those instructions are
58  // also tracked by the retire control unit. That means,
59  // RetireControlUnit::hasWorkToComplete() is responsible for checking if there
60  // are still instructions in-flight in the out-of-order backend.
61  bool hasWorkToComplete() const override { return false; }
62  bool isAvailable(const InstRef &IR) const override;
63
64  // Notifies the scheduler that a new cycle just started.
65  //
66  // This method notifies the scheduler that a new cycle started.
67  // This method is also responsible for notifying listeners about instructions
68  // state changes, and processor resources freed by the scheduler.
69  // Instructions that transitioned to the 'Executed' state are automatically
70  // moved to the next stage (i.e. RetireStage).
71  Error cycleStart() override;
72  Error cycleEnd() override;
73  Error execute(InstRef &IR) override;
74
75  void notifyInstructionIssued(const InstRef &IR,
76                               MutableArrayRef<ResourceUse> Used) const;
77  void notifyInstructionExecuted(const InstRef &IR) const;
78  void notifyInstructionPending(const InstRef &IR) const;
79  void notifyInstructionReady(const InstRef &IR) const;
80  void notifyResourceAvailable(const ResourceRef &RR) const;
81
82  // Notify listeners that buffered resources have been consumed or freed.
83  void notifyReservedOrReleasedBuffers(const InstRef &IR, bool Reserved) const;
84};
85
86} // namespace mca
87} // namespace llvm
88
89#endif // LLVM_MCA_STAGES_EXECUTESTAGE_H
90