From 7b5a36ec72571607f6af3d12f72703fb27ad5677 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Wed, 27 Jun 2018 16:09:33 +0000 Subject: [PATCH] [llvm-mca] Register listeners with stages; remove Pipeline dependency from Stage. Summary: This patch removes a few callbacks from Pipeline. It comes at the cost of registering Listeners with all Stages. Not all stages need listeners or issue callbacks, this registration is a bit redundant. However, as we build-out the API, this redundancy can disappear. The main purpose here is to move callback code from the Pipeline and into the stages that actually issue those callbacks. This removes the back-pointer to the Pipeline that was put into a few Stage subclasses. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb, courbet Subscribers: tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D48576 llvm-svn: 335748 --- llvm/tools/llvm-mca/DispatchStage.cpp | 15 +++++++++------ llvm/tools/llvm-mca/DispatchStage.h | 8 ++++---- llvm/tools/llvm-mca/ExecuteStage.cpp | 20 +++++++++++--------- llvm/tools/llvm-mca/ExecuteStage.h | 6 +----- llvm/tools/llvm-mca/Pipeline.cpp | 29 ++--------------------------- llvm/tools/llvm-mca/Pipeline.h | 5 ----- llvm/tools/llvm-mca/RetireStage.cpp | 3 +-- llvm/tools/llvm-mca/RetireStage.h | 11 +++++------ llvm/tools/llvm-mca/Stage.cpp | 8 ++++++-- llvm/tools/llvm-mca/Stage.h | 9 +++++++-- llvm/tools/llvm-mca/llvm-mca.cpp | 6 +++--- 11 files changed, 49 insertions(+), 71 deletions(-) diff --git a/llvm/tools/llvm-mca/DispatchStage.cpp b/llvm/tools/llvm-mca/DispatchStage.cpp index 8090918..70cd28d 100644 --- a/llvm/tools/llvm-mca/DispatchStage.cpp +++ b/llvm/tools/llvm-mca/DispatchStage.cpp @@ -18,7 +18,6 @@ #include "DispatchStage.h" #include "HWEventListener.h" -#include "Pipeline.h" #include "Scheduler.h" #include "llvm/Support/Debug.h" @@ -31,7 +30,12 @@ namespace mca { void DispatchStage::notifyInstructionDispatched(const InstRef &IR, ArrayRef UsedRegs) { LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: " << IR << '\n'); - Owner->notifyInstructionEvent(HWInstructionDispatchedEvent(IR, UsedRegs)); + notifyInstructionEvent(HWInstructionDispatchedEvent(IR, UsedRegs)); +} + +void DispatchStage::notifyStallEvent(const HWStallEvent &Event) { + for (HWEventListener *Listener : getListeners()) + Listener->onStallEvent(Event); } bool DispatchStage::checkPRF(const InstRef &IR) { @@ -43,7 +47,7 @@ bool DispatchStage::checkPRF(const InstRef &IR) { const unsigned RegisterMask = PRF.isAvailable(RegDefs); // A mask with all zeroes means: register files are available. if (RegisterMask) { - Owner->notifyStallEvent(HWStallEvent(HWStallEvent::RegisterFileStall, IR)); + notifyStallEvent(HWStallEvent(HWStallEvent::RegisterFileStall, IR)); return false; } @@ -54,8 +58,7 @@ bool DispatchStage::checkRCU(const InstRef &IR) { const unsigned NumMicroOps = IR.getInstruction()->getDesc().NumMicroOps; if (RCU.isAvailable(NumMicroOps)) return true; - Owner->notifyStallEvent( - HWStallEvent(HWStallEvent::RetireControlUnitStall, IR)); + notifyStallEvent(HWStallEvent(HWStallEvent::RetireControlUnitStall, IR)); return false; } @@ -63,7 +66,7 @@ bool DispatchStage::checkScheduler(const InstRef &IR) { HWStallEvent::GenericEventType Event; const bool Ready = SC.canBeDispatched(IR, Event); if (!Ready) - Owner->notifyStallEvent(HWStallEvent(Event, IR)); + notifyStallEvent(HWStallEvent(Event, IR)); return Ready; } diff --git a/llvm/tools/llvm-mca/DispatchStage.h b/llvm/tools/llvm-mca/DispatchStage.h index 47e4864..9695c3e 100644 --- a/llvm/tools/llvm-mca/DispatchStage.h +++ b/llvm/tools/llvm-mca/DispatchStage.h @@ -19,6 +19,7 @@ #ifndef LLVM_TOOLS_LLVM_MCA_DISPATCH_STAGE_H #define LLVM_TOOLS_LLVM_MCA_DISPATCH_STAGE_H +#include "HWEventListener.h" #include "Instruction.h" #include "RegisterFile.h" #include "RetireControlUnit.h" @@ -30,7 +31,6 @@ namespace mca { class WriteState; class Scheduler; -class Pipeline; // Implements the hardware dispatch logic. // @@ -54,7 +54,6 @@ class DispatchStage : public Stage { unsigned DispatchWidth; unsigned AvailableEntries; unsigned CarryOver; - Pipeline *Owner; const llvm::MCSubtargetInfo &STI; RetireControlUnit &RCU; RegisterFile &PRF; @@ -66,6 +65,7 @@ class DispatchStage : public Stage { void dispatch(InstRef IR); void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI); + void notifyStallEvent(const HWStallEvent &Event); void notifyInstructionDispatched(const InstRef &IR, llvm::ArrayRef UsedPhysRegs); @@ -84,12 +84,12 @@ class DispatchStage : public Stage { } public: - DispatchStage(Pipeline *P, const llvm::MCSubtargetInfo &Subtarget, + DispatchStage(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCRegisterInfo &MRI, unsigned RegisterFileSize, unsigned MaxDispatchWidth, RetireControlUnit &R, RegisterFile &F, Scheduler &Sched) : DispatchWidth(MaxDispatchWidth), AvailableEntries(MaxDispatchWidth), - CarryOver(0U), Owner(P), STI(Subtarget), RCU(R), PRF(F), SC(Sched) {} + CarryOver(0U), STI(Subtarget), RCU(R), PRF(F), SC(Sched) {} // We can always try to dispatch, so returning false is okay in this case. // The retire stage, which controls the RCU, might have items to complete but diff --git a/llvm/tools/llvm-mca/ExecuteStage.cpp b/llvm/tools/llvm-mca/ExecuteStage.cpp index ebd8715..c446ad6 100644 --- a/llvm/tools/llvm-mca/ExecuteStage.cpp +++ b/llvm/tools/llvm-mca/ExecuteStage.cpp @@ -16,7 +16,6 @@ //===----------------------------------------------------------------------===// #include "ExecuteStage.h" -#include "Pipeline.h" #include "Scheduler.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" @@ -155,19 +154,20 @@ bool ExecuteStage::execute(InstRef &IR) { void ExecuteStage::notifyInstructionExecuted(const InstRef &IR) { HWS.onInstructionExecuted(IR); LLVM_DEBUG(dbgs() << "[E] Instruction Executed: " << IR << '\n'); - Owner->notifyInstructionEvent( - HWInstructionEvent(HWInstructionEvent::Executed, IR)); + notifyInstructionEvent(HWInstructionEvent(HWInstructionEvent::Executed, IR)); RCU.onInstructionExecuted(IR.getInstruction()->getRCUTokenID()); } void ExecuteStage::notifyInstructionReady(const InstRef &IR) { LLVM_DEBUG(dbgs() << "[E] Instruction Ready: " << IR << '\n'); - Owner->notifyInstructionEvent( - HWInstructionEvent(HWInstructionEvent::Ready, IR)); + notifyInstructionEvent(HWInstructionEvent(HWInstructionEvent::Ready, IR)); } void ExecuteStage::notifyResourceAvailable(const ResourceRef &RR) { - Owner->notifyResourceAvailable(RR); + LLVM_DEBUG(dbgs() << "[E] Resource Available: [" << RR.first << '.' + << RR.second << "]\n"); + for (HWEventListener *Listener : getListeners()) + Listener->onResourceAvailable(RR); } void ExecuteStage::notifyInstructionIssued( @@ -180,7 +180,7 @@ void ExecuteStage::notifyInstructionIssued( dbgs() << " cycles: " << Resource.second << '\n'; } }); - Owner->notifyInstructionEvent(HWInstructionIssuedEvent(IR, Used)); + notifyInstructionEvent(HWInstructionIssuedEvent(IR, Used)); } void ExecuteStage::notifyReservedBuffers(ArrayRef Buffers) { @@ -190,7 +190,8 @@ void ExecuteStage::notifyReservedBuffers(ArrayRef Buffers) { SmallVector BufferIDs(Buffers.begin(), Buffers.end()); std::transform(Buffers.begin(), Buffers.end(), BufferIDs.begin(), [&](uint64_t Op) { return HWS.getResourceID(Op); }); - Owner->notifyReservedBuffers(BufferIDs); + for (HWEventListener *Listener : getListeners()) + Listener->onReservedBuffers(BufferIDs); } void ExecuteStage::notifyReleasedBuffers(ArrayRef Buffers) { @@ -200,7 +201,8 @@ void ExecuteStage::notifyReleasedBuffers(ArrayRef Buffers) { SmallVector BufferIDs(Buffers.begin(), Buffers.end()); std::transform(Buffers.begin(), Buffers.end(), BufferIDs.begin(), [&](uint64_t Op) { return HWS.getResourceID(Op); }); - Owner->notifyReleasedBuffers(BufferIDs); + for (HWEventListener *Listener : getListeners()) + Listener->onReleasedBuffers(BufferIDs); } } // namespace mca diff --git a/llvm/tools/llvm-mca/ExecuteStage.h b/llvm/tools/llvm-mca/ExecuteStage.h index 82b9369..622fa0f 100644 --- a/llvm/tools/llvm-mca/ExecuteStage.h +++ b/llvm/tools/llvm-mca/ExecuteStage.h @@ -26,11 +26,8 @@ namespace mca { -class Pipeline; - class ExecuteStage : public Stage { // Owner will go away when we move listeners/eventing to the stages. - Pipeline *Owner; RetireControlUnit &RCU; Scheduler &HWS; @@ -40,8 +37,7 @@ class ExecuteStage : public Stage { void issueReadyInstructions(); public: - ExecuteStage(Pipeline *P, RetireControlUnit &R, Scheduler &S) - : Stage(), Owner(P), RCU(R), HWS(S) {} + ExecuteStage(RetireControlUnit &R, Scheduler &S) : Stage(), RCU(R), HWS(S) {} ExecuteStage(const ExecuteStage &Other) = delete; ExecuteStage &operator=(const ExecuteStage &Other) = delete; diff --git a/llvm/tools/llvm-mca/Pipeline.cpp b/llvm/tools/llvm-mca/Pipeline.cpp index 49cf71e..716c43b 100644 --- a/llvm/tools/llvm-mca/Pipeline.cpp +++ b/llvm/tools/llvm-mca/Pipeline.cpp @@ -27,6 +27,8 @@ using namespace llvm; void Pipeline::addEventListener(HWEventListener *Listener) { if (Listener) Listeners.insert(Listener); + for (auto &S : Stages) + S->addListener(Listener); } bool Pipeline::hasWorkToProcess() { @@ -77,33 +79,6 @@ void Pipeline::notifyCycleBegin(unsigned Cycle) { Listener->onCycleBegin(); } -void Pipeline::notifyInstructionEvent(const HWInstructionEvent &Event) { - for (HWEventListener *Listener : Listeners) - Listener->onInstructionEvent(Event); -} - -void Pipeline::notifyStallEvent(const HWStallEvent &Event) { - for (HWEventListener *Listener : Listeners) - Listener->onStallEvent(Event); -} - -void Pipeline::notifyResourceAvailable(const ResourceRef &RR) { - LLVM_DEBUG(dbgs() << "[E] Resource Available: [" << RR.first << '.' - << RR.second << "]\n"); - for (HWEventListener *Listener : Listeners) - Listener->onResourceAvailable(RR); -} - -void Pipeline::notifyReservedBuffers(ArrayRef Buffers) { - for (HWEventListener *Listener : Listeners) - Listener->onReservedBuffers(Buffers); -} - -void Pipeline::notifyReleasedBuffers(ArrayRef Buffers) { - for (HWEventListener *Listener : Listeners) - Listener->onReleasedBuffers(Buffers); -} - void Pipeline::notifyCycleEnd(unsigned Cycle) { LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycle << "\n\n"); for (HWEventListener *Listener : Listeners) diff --git a/llvm/tools/llvm-mca/Pipeline.h b/llvm/tools/llvm-mca/Pipeline.h index 3ff4f15..399d89e 100644 --- a/llvm/tools/llvm-mca/Pipeline.h +++ b/llvm/tools/llvm-mca/Pipeline.h @@ -70,11 +70,6 @@ public: void run(); void addEventListener(HWEventListener *Listener); void notifyCycleBegin(unsigned Cycle); - void notifyInstructionEvent(const HWInstructionEvent &Event); - void notifyStallEvent(const HWStallEvent &Event); - void notifyResourceAvailable(const ResourceRef &RR); - void notifyReservedBuffers(llvm::ArrayRef Buffers); - void notifyReleasedBuffers(llvm::ArrayRef Buffers); void notifyCycleEnd(unsigned Cycle); }; } // namespace mca diff --git a/llvm/tools/llvm-mca/RetireStage.cpp b/llvm/tools/llvm-mca/RetireStage.cpp index cdd0a22..0d1f4e4 100644 --- a/llvm/tools/llvm-mca/RetireStage.cpp +++ b/llvm/tools/llvm-mca/RetireStage.cpp @@ -16,7 +16,6 @@ #include "RetireStage.h" #include "HWEventListener.h" -#include "Pipeline.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -50,7 +49,7 @@ void RetireStage::notifyInstructionRetired(const InstRef &IR) { for (const std::unique_ptr &WS : IR.getInstruction()->getDefs()) PRF.removeRegisterWrite(*WS.get(), FreedRegs, !Desc.isZeroLatency()); - Owner->notifyInstructionEvent(HWInstructionRetiredEvent(IR, FreedRegs)); + notifyInstructionEvent(HWInstructionRetiredEvent(IR, FreedRegs)); } } // namespace mca diff --git a/llvm/tools/llvm-mca/RetireStage.h b/llvm/tools/llvm-mca/RetireStage.h index 4466890..c91e7e2 100644 --- a/llvm/tools/llvm-mca/RetireStage.h +++ b/llvm/tools/llvm-mca/RetireStage.h @@ -23,21 +23,20 @@ namespace mca { -class Pipeline; - class RetireStage : public Stage { // Owner will go away when we move listeners/eventing to the stages. - Pipeline *Owner; RetireControlUnit &RCU; RegisterFile &PRF; public: - RetireStage(Pipeline *P, RetireControlUnit &R, RegisterFile &F) - : Stage(), Owner(P), RCU(R), PRF(F) {} + RetireStage(RetireControlUnit &R, RegisterFile &F) + : Stage(), RCU(R), PRF(F) {} RetireStage(const RetireStage &Other) = delete; RetireStage &operator=(const RetireStage &Other) = delete; - virtual bool hasWorkToComplete() const override final { return !RCU.isEmpty(); } + virtual bool hasWorkToComplete() const override final { + return !RCU.isEmpty(); + } virtual void preExecute(const InstRef &IR) override final; virtual bool execute(InstRef &IR) override final { return true; } void notifyInstructionRetired(const InstRef &IR); diff --git a/llvm/tools/llvm-mca/Stage.cpp b/llvm/tools/llvm-mca/Stage.cpp index f4eb8db..cfcb3f8 100644 --- a/llvm/tools/llvm-mca/Stage.cpp +++ b/llvm/tools/llvm-mca/Stage.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "Stage.h" -#include "llvm/Support/ErrorHandling.h" namespace mca { @@ -22,7 +21,12 @@ namespace mca { Stage::Stage() {} void Stage::addListener(HWEventListener *Listener) { - llvm_unreachable("Stage-based eventing is not implemented."); + Listeners.insert(Listener); +} + +void Stage::notifyInstructionEvent(const HWInstructionEvent &Event) { + for (HWEventListener *Listener : Listeners) + Listener->onInstructionEvent(Event); } } // namespace mca diff --git a/llvm/tools/llvm-mca/Stage.h b/llvm/tools/llvm-mca/Stage.h index 7e709c8..2719376 100644 --- a/llvm/tools/llvm-mca/Stage.h +++ b/llvm/tools/llvm-mca/Stage.h @@ -16,17 +16,20 @@ #ifndef LLVM_TOOLS_LLVM_MCA_STAGE_H #define LLVM_TOOLS_LLVM_MCA_STAGE_H +#include "HWEventListener.h" #include namespace mca { -class HWEventListener; class InstRef; class Stage { - std::set Listeners; Stage(const Stage &Other) = delete; Stage &operator=(const Stage &Other) = delete; + std::set Listeners; + +protected: + const std::set &getListeners() const { return Listeners; } public: Stage(); @@ -51,6 +54,8 @@ public: /// Add a listener to receive callbacks during the execution of this stage. void addListener(HWEventListener *Listener); + + virtual void notifyInstructionEvent(const HWInstructionEvent &Event); }; } // namespace mca diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp index 380cd3f..a492eb8 100644 --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -511,9 +511,9 @@ int main(int argc, char **argv) { Width, RegisterFileSize, LoadQueueSize, StoreQueueSize, AssumeNoAlias); P->appendStage(llvm::make_unique(IB, S)); P->appendStage(llvm::make_unique( - P.get(), *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS)); - P->appendStage(llvm::make_unique(P.get(), RCU, PRF)); - P->appendStage(llvm::make_unique(P.get(), RCU, HWS)); + *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS)); + P->appendStage(llvm::make_unique(RCU, PRF)); + P->appendStage(llvm::make_unique(RCU, HWS)); mca::PipelinePrinter Printer(*P); if (PrintSummaryView) -- 2.7.4