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