diff options
Diffstat (limited to 'llvm/tools/llvm-mca/Scheduler.h')
-rw-r--r-- | llvm/tools/llvm-mca/Scheduler.h | 120 |
1 files changed, 74 insertions, 46 deletions
diff --git a/llvm/tools/llvm-mca/Scheduler.h b/llvm/tools/llvm-mca/Scheduler.h index f8dce3c2e9b..d6da6c08a1c 100644 --- a/llvm/tools/llvm-mca/Scheduler.h +++ b/llvm/tools/llvm-mca/Scheduler.h @@ -15,17 +15,18 @@ #ifndef LLVM_TOOLS_LLVM_MCA_SCHEDULER_H #define LLVM_TOOLS_LLVM_MCA_SCHEDULER_H +#include "HWEventListener.h" #include "Instruction.h" #include "LSUnit.h" #include "RetireControlUnit.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSubtargetInfo.h" #include <map> namespace mca { -class Backend; - /// Used to notify the internal state of a processor resource. /// /// A processor resource is available if it is not reserved, and there are @@ -402,68 +403,52 @@ public: /// An Instruction leaves the IssuedQueue when it reaches the write-back stage. class Scheduler { const llvm::MCSchedModel &SM; - RetireControlUnit &RCU; // Hardware resources that are managed by this scheduler. std::unique_ptr<ResourceManager> Resources; std::unique_ptr<LSUnit> LSU; - // The Backend gets notified when instructions are ready/issued/executed. - Backend *const Owner; - using QueueEntryTy = std::pair<unsigned, Instruction *>; std::map<unsigned, Instruction *> WaitQueue; std::map<unsigned, Instruction *> ReadyQueue; std::map<unsigned, Instruction *> IssuedQueue; - void - notifyInstructionIssued(const InstRef &IR, - llvm::ArrayRef<std::pair<ResourceRef, double>> Used); - void notifyInstructionExecuted(const InstRef &IR); - void notifyInstructionReady(const InstRef &IR); - void notifyResourceAvailable(const ResourceRef &RR); - - // Notify the Backend that buffered resources were consumed. - void notifyReservedBuffers(llvm::ArrayRef<uint64_t> Buffers); - // Notify the Backend that buffered resources were freed. - void notifyReleasedBuffers(llvm::ArrayRef<uint64_t> Buffers); - - /// Select the next instruction to issue from the ReadyQueue. - /// This method gives priority to older instructions. - InstRef select(); - - /// Move instructions from the WaitQueue to the ReadyQueue if input operands - /// are all available. - void promoteToReadyQueue(llvm::SmallVectorImpl<InstRef> &Ready); - /// Issue an instruction without updating the ready queue. void issueInstructionImpl( InstRef &IR, llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes); - void updatePendingQueue(llvm::SmallVectorImpl<InstRef> &Ready); - void updateIssuedQueue(llvm::SmallVectorImpl<InstRef> &Executed); - public: - Scheduler(Backend *B, const llvm::MCSchedModel &Model, RetireControlUnit &R, - unsigned LoadQueueSize, unsigned StoreQueueSize, bool AssumeNoAlias) - : SM(Model), RCU(R), Resources(llvm::make_unique<ResourceManager>(SM)), + Scheduler(const llvm::MCSchedModel &Model, unsigned LoadQueueSize, + unsigned StoreQueueSize, bool AssumeNoAlias) + : SM(Model), Resources(llvm::make_unique<ResourceManager>(SM)), LSU(llvm::make_unique<LSUnit>(LoadQueueSize, StoreQueueSize, - AssumeNoAlias)), - Owner(B) {} + AssumeNoAlias)) {} /// Check if the instruction in 'IR' can be dispatched. /// /// The DispatchStage is responsible for querying the Scheduler before - /// dispatching new instructions. Queries are performed through method - /// `Scheduler::canBeDispatched`. If scheduling resources are available, - /// and the instruction can be dispatched, then this method returns true. - /// Otherwise, a generic HWStallEvent is notified to the listeners. - bool canBeDispatched(const InstRef &IR) const; - void scheduleInstruction(InstRef &IR); + /// dispatching new instructions. This routine is used for performing such + /// a query. If the instruction 'IR' can be dispatched, then true is + /// returned, otherwise false is returned with Event set to the stall type. + bool canBeDispatched(const InstRef &IR, + HWStallEvent::GenericEventType &Event) const; + + /// Returns true if there is availibility for IR in the LSU. + bool isReady(const InstRef &IR) const { return LSU->isReady(IR); } - /// Issue an instruction. - void issueInstruction(InstRef &IR); + /// Issue an instruction. The Used container is populated with + /// the resource objects consumed on behalf of issuing this instruction. + void + issueInstruction(InstRef &IR, + llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Used); + + /// This routine will attempt to issue an instruction immediately (for + /// zero-latency instructions). + /// + /// Returns true if the instruction is issued immediately. If this does not + /// occur, then the instruction will be added to the Scheduler's ReadyQueue. + bool issueImmediately(InstRef &IR); /// Reserve one entry in each buffered resource. void reserveBuffers(llvm::ArrayRef<uint64_t> Buffers) { @@ -475,12 +460,55 @@ public: Resources->releaseBuffers(Buffers); } - void cycleEvent(); + /// Update the resources managed by the scheduler. + /// This routine is to be called at the start of a new cycle, and is + /// responsible for updating scheduler resources. Resources are released + /// once they have been fully consumed. + void reclaimSimulatedResources(llvm::SmallVectorImpl<ResourceRef> &Freed); + + /// Move instructions from the WaitQueue to the ReadyQueue if input operands + /// are all available. + void promoteToReadyQueue(llvm::SmallVectorImpl<InstRef> &Ready); + + /// Update the ready queue. + void updatePendingQueue(llvm::SmallVectorImpl<InstRef> &Ready); + + /// Update the issued queue. + void updateIssuedQueue(llvm::SmallVectorImpl<InstRef> &Executed); + + /// Updates the Scheduler's resources to reflect that an instruction has just + /// been executed. + void onInstructionExecuted(const InstRef &IR); + + /// Obtain the processor's resource identifier for the given + /// resource mask. + unsigned getResourceID(uint64_t Mask) { + return Resources->resolveResourceMask(Mask); + } + + /// Reserve resources necessary to issue the instruction. + /// Returns true if the resources are ready and the (LSU) can + /// execute the given instruction immediately. + bool reserveResources(InstRef &IR); + + /// Select the next instruction to issue from the ReadyQueue. + /// This method gives priority to older instructions. + InstRef select(); #ifndef NDEBUG + // Update the ready queues. void dump() const; -#endif + + // This routine performs a sanity check. This routine should only be called + // when we know that 'IR' is not in the scheduler's instruction queues. + void sanityCheck(const InstRef &IR) const { + const unsigned Idx = IR.getSourceIndex(); + assert(WaitQueue.find(Idx) == WaitQueue.end()); + assert(ReadyQueue.find(Idx) == ReadyQueue.end()); + assert(IssuedQueue.find(Idx) == IssuedQueue.end()); + } +#endif // !NDEBUG }; -} // Namespace mca +} // namespace mca -#endif +#endif // LLVM_TOOLS_LLVM_MCA_SCHEDULER_H |