aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-mca
diff options
context:
space:
mode:
authorMatt Davis <Matthew.Davis@sony.com>2018-06-27 16:09:33 +0000
committerMatt Davis <Matthew.Davis@sony.com>2018-06-27 16:09:33 +0000
commit90b999fed8ffd256f6929345f68bfd3fe6157b06 (patch)
tree1c974eadb3bde0ab31b065159c2c6c860262c387 /tools/llvm-mca
parent966cfbb5c29c8d3d638538214df73e872ef65e19 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335748 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mca')
-rw-r--r--tools/llvm-mca/DispatchStage.cpp15
-rw-r--r--tools/llvm-mca/DispatchStage.h8
-rw-r--r--tools/llvm-mca/ExecuteStage.cpp20
-rw-r--r--tools/llvm-mca/ExecuteStage.h6
-rw-r--r--tools/llvm-mca/Pipeline.cpp29
-rw-r--r--tools/llvm-mca/Pipeline.h5
-rw-r--r--tools/llvm-mca/RetireStage.cpp3
-rw-r--r--tools/llvm-mca/RetireStage.h11
-rw-r--r--tools/llvm-mca/Stage.cpp8
-rw-r--r--tools/llvm-mca/Stage.h9
-rw-r--r--tools/llvm-mca/llvm-mca.cpp6
11 files changed, 49 insertions, 71 deletions
diff --git a/tools/llvm-mca/DispatchStage.cpp b/tools/llvm-mca/DispatchStage.cpp
index 80909188767..70cd28d843a 100644
--- a/tools/llvm-mca/DispatchStage.cpp
+++ b/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<unsigned> 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/tools/llvm-mca/DispatchStage.h b/tools/llvm-mca/DispatchStage.h
index 47e4864a459..9695c3e6854 100644
--- a/tools/llvm-mca/DispatchStage.h
+++ b/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<unsigned> 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/tools/llvm-mca/ExecuteStage.cpp b/tools/llvm-mca/ExecuteStage.cpp
index ebd87150f0a..c446ad67725 100644
--- a/tools/llvm-mca/ExecuteStage.cpp
+++ b/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<uint64_t> Buffers) {
@@ -190,7 +190,8 @@ void ExecuteStage::notifyReservedBuffers(ArrayRef<uint64_t> Buffers) {
SmallVector<unsigned, 4> 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<uint64_t> Buffers) {
@@ -200,7 +201,8 @@ void ExecuteStage::notifyReleasedBuffers(ArrayRef<uint64_t> Buffers) {
SmallVector<unsigned, 4> 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/tools/llvm-mca/ExecuteStage.h b/tools/llvm-mca/ExecuteStage.h
index 82b9369352d..622fa0f983a 100644
--- a/tools/llvm-mca/ExecuteStage.h
+++ b/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/tools/llvm-mca/Pipeline.cpp b/tools/llvm-mca/Pipeline.cpp
index 49cf71e60e3..716c43b7d02 100644
--- a/tools/llvm-mca/Pipeline.cpp
+++ b/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<unsigned> Buffers) {
- for (HWEventListener *Listener : Listeners)
- Listener->onReservedBuffers(Buffers);
-}
-
-void Pipeline::notifyReleasedBuffers(ArrayRef<unsigned> 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/tools/llvm-mca/Pipeline.h b/tools/llvm-mca/Pipeline.h
index 3ff4f152624..399d89e5145 100644
--- a/tools/llvm-mca/Pipeline.h
+++ b/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<unsigned> Buffers);
- void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers);
void notifyCycleEnd(unsigned Cycle);
};
} // namespace mca
diff --git a/tools/llvm-mca/RetireStage.cpp b/tools/llvm-mca/RetireStage.cpp
index cdd0a22fb35..0d1f4e43035 100644
--- a/tools/llvm-mca/RetireStage.cpp
+++ b/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<WriteState> &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/tools/llvm-mca/RetireStage.h b/tools/llvm-mca/RetireStage.h
index 4466890e790..c91e7e2c218 100644
--- a/tools/llvm-mca/RetireStage.h
+++ b/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/tools/llvm-mca/Stage.cpp b/tools/llvm-mca/Stage.cpp
index f4eb8db1881..cfcb3f8bde0 100644
--- a/tools/llvm-mca/Stage.cpp
+++ b/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/tools/llvm-mca/Stage.h b/tools/llvm-mca/Stage.h
index 7e709c8ef61..2719376f757 100644
--- a/tools/llvm-mca/Stage.h
+++ b/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 <set>
namespace mca {
-class HWEventListener;
class InstRef;
class Stage {
- std::set<HWEventListener *> Listeners;
Stage(const Stage &Other) = delete;
Stage &operator=(const Stage &Other) = delete;
+ std::set<HWEventListener *> Listeners;
+
+protected:
+ const std::set<HWEventListener *> &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/tools/llvm-mca/llvm-mca.cpp b/tools/llvm-mca/llvm-mca.cpp
index 380cd3f6adc..a492eb8cc00 100644
--- a/tools/llvm-mca/llvm-mca.cpp
+++ b/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<mca::FetchStage>(IB, S));
P->appendStage(llvm::make_unique<mca::DispatchStage>(
- P.get(), *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS));
- P->appendStage(llvm::make_unique<mca::RetireStage>(P.get(), RCU, PRF));
- P->appendStage(llvm::make_unique<mca::ExecuteStage>(P.get(), RCU, HWS));
+ *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS));
+ P->appendStage(llvm::make_unique<mca::RetireStage>(RCU, PRF));
+ P->appendStage(llvm::make_unique<mca::ExecuteStage>(RCU, HWS));
mca::PipelinePrinter Printer(*P);
if (PrintSummaryView)