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 25 namespace llvm { 26 namespace mca { 27 28 class 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 49 public: ExecuteStage(Scheduler & S)50 ExecuteStage(Scheduler &S) : ExecuteStage(S, false) {} ExecuteStage(Scheduler & S,bool ShouldPerformBottleneckAnalysis)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. hasWorkToComplete()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