forked from OSchip/llvm-project
[llvm-mca] Simplify eventing by adding an onEvent templated method.
Summary: This patch eliminates some redundancy in iterating across Listeners for the Instruction and Stall HWEvents, by introducing a template onEvent routine. This change was suggested by @courbet in https://reviews.llvm.org/D48576. I hope that this patch addresses that suggestion appropriately. I do like this change better than what we had previously. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb, courbet Subscribers: javed.absar, tschuett, gbedwell, llvm-commits, courbet Differential Revision: https://reviews.llvm.org/D48672 llvm-svn: 336916
This commit is contained in:
parent
c2c0138a04
commit
0906a7fc53
|
@ -30,12 +30,7 @@ namespace mca {
|
|||
void DispatchStage::notifyInstructionDispatched(const InstRef &IR,
|
||||
ArrayRef<unsigned> UsedRegs) {
|
||||
LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: " << IR << '\n');
|
||||
notifyInstructionEvent(HWInstructionDispatchedEvent(IR, UsedRegs));
|
||||
}
|
||||
|
||||
void DispatchStage::notifyStallEvent(const HWStallEvent &Event) {
|
||||
for (HWEventListener *Listener : getListeners())
|
||||
Listener->onStallEvent(Event);
|
||||
notifyEvent<HWInstructionEvent>(HWInstructionDispatchedEvent(IR, UsedRegs));
|
||||
}
|
||||
|
||||
bool DispatchStage::checkPRF(const InstRef &IR) {
|
||||
|
@ -47,7 +42,8 @@ bool DispatchStage::checkPRF(const InstRef &IR) {
|
|||
const unsigned RegisterMask = PRF.isAvailable(RegDefs);
|
||||
// A mask with all zeroes means: register files are available.
|
||||
if (RegisterMask) {
|
||||
notifyStallEvent(HWStallEvent(HWStallEvent::RegisterFileStall, IR));
|
||||
notifyEvent<HWStallEvent>(
|
||||
HWStallEvent(HWStallEvent::RegisterFileStall, IR));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -58,7 +54,8 @@ bool DispatchStage::checkRCU(const InstRef &IR) {
|
|||
const unsigned NumMicroOps = IR.getInstruction()->getDesc().NumMicroOps;
|
||||
if (RCU.isAvailable(NumMicroOps))
|
||||
return true;
|
||||
notifyStallEvent(HWStallEvent(HWStallEvent::RetireControlUnitStall, IR));
|
||||
notifyEvent<HWStallEvent>(
|
||||
HWStallEvent(HWStallEvent::RetireControlUnitStall, IR));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -66,7 +63,7 @@ bool DispatchStage::checkScheduler(const InstRef &IR) {
|
|||
HWStallEvent::GenericEventType Event;
|
||||
const bool Ready = SC.canBeDispatched(IR, Event);
|
||||
if (!Ready)
|
||||
notifyStallEvent(HWStallEvent(Event, IR));
|
||||
notifyEvent<HWStallEvent>(HWStallEvent(Event, IR));
|
||||
return Ready;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ 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);
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@ using namespace llvm;
|
|||
|
||||
namespace mca {
|
||||
|
||||
void DispatchStatistics::onStallEvent(const HWStallEvent &Event) {
|
||||
void DispatchStatistics::onEvent(const HWStallEvent &Event) {
|
||||
if (Event.Type < HWStallEvent::LastGenericEvent)
|
||||
HWStalls[Event.Type]++;
|
||||
}
|
||||
|
||||
void DispatchStatistics::onInstructionEvent(const HWInstructionEvent &Event) {
|
||||
void DispatchStatistics::onEvent(const HWInstructionEvent &Event) {
|
||||
if (Event.Type == HWInstructionEvent::Dispatched)
|
||||
++NumDispatched;
|
||||
}
|
||||
|
|
|
@ -66,14 +66,14 @@ public:
|
|||
: NumDispatched(0), NumCycles(0),
|
||||
HWStalls(HWStallEvent::LastGenericEvent) {}
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWStallEvent &Event) override;
|
||||
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void onCycleBegin() override { NumCycles++; }
|
||||
|
||||
void onCycleEnd() override { updateHistograms(); }
|
||||
|
||||
void onStallEvent(const HWStallEvent &Event) override;
|
||||
|
||||
void printView(llvm::raw_ostream &OS) const override {
|
||||
printDispatchStalls(OS);
|
||||
printDispatchHistogram(OS);
|
||||
|
|
|
@ -154,13 +154,15 @@ bool ExecuteStage::execute(InstRef &IR) {
|
|||
void ExecuteStage::notifyInstructionExecuted(const InstRef &IR) {
|
||||
HWS.onInstructionExecuted(IR);
|
||||
LLVM_DEBUG(dbgs() << "[E] Instruction Executed: " << IR << '\n');
|
||||
notifyInstructionEvent(HWInstructionEvent(HWInstructionEvent::Executed, IR));
|
||||
notifyEvent<HWInstructionEvent>(
|
||||
HWInstructionEvent(HWInstructionEvent::Executed, IR));
|
||||
RCU.onInstructionExecuted(IR.getInstruction()->getRCUTokenID());
|
||||
}
|
||||
|
||||
void ExecuteStage::notifyInstructionReady(const InstRef &IR) {
|
||||
LLVM_DEBUG(dbgs() << "[E] Instruction Ready: " << IR << '\n');
|
||||
notifyInstructionEvent(HWInstructionEvent(HWInstructionEvent::Ready, IR));
|
||||
notifyEvent<HWInstructionEvent>(
|
||||
HWInstructionEvent(HWInstructionEvent::Ready, IR));
|
||||
}
|
||||
|
||||
void ExecuteStage::notifyResourceAvailable(const ResourceRef &RR) {
|
||||
|
@ -180,7 +182,7 @@ void ExecuteStage::notifyInstructionIssued(
|
|||
dbgs() << " cycles: " << Resource.second << '\n';
|
||||
}
|
||||
});
|
||||
notifyInstructionEvent(HWInstructionIssuedEvent(IR, Used));
|
||||
notifyEvent<HWInstructionEvent>(HWInstructionIssuedEvent(IR, Used));
|
||||
}
|
||||
|
||||
void ExecuteStage::notifyReservedBuffers(ArrayRef<uint64_t> Buffers) {
|
||||
|
|
|
@ -120,8 +120,8 @@ public:
|
|||
virtual void onCycleBegin() {}
|
||||
virtual void onCycleEnd() {}
|
||||
|
||||
virtual void onInstructionEvent(const HWInstructionEvent &Event) {}
|
||||
virtual void onStallEvent(const HWStallEvent &Event) {}
|
||||
virtual void onEvent(const HWInstructionEvent &Event) {}
|
||||
virtual void onEvent(const HWStallEvent &Event) {}
|
||||
|
||||
using ResourceRef = std::pair<uint64_t, uint64_t>;
|
||||
virtual void onResourceAvailable(const ResourceRef &RRef) {}
|
||||
|
|
|
@ -39,9 +39,8 @@ void InstructionTables::run() {
|
|||
if (!Resource.second.size())
|
||||
continue;
|
||||
double Cycles = static_cast<double>(Resource.second.size());
|
||||
unsigned Index =
|
||||
std::distance(Masks.begin(), std::find(Masks.begin(), Masks.end(),
|
||||
Resource.first));
|
||||
unsigned Index = std::distance(
|
||||
Masks.begin(), std::find(Masks.begin(), Masks.end(), Resource.first));
|
||||
const MCProcResourceDesc &ProcResource = *SM.getProcResource(Index);
|
||||
unsigned NumUnits = ProcResource.NumUnits;
|
||||
if (!ProcResource.SubUnitsIdxBegin) {
|
||||
|
@ -73,7 +72,7 @@ void InstructionTables::run() {
|
|||
InstRef IR(SR.first, Inst.get());
|
||||
HWInstructionIssuedEvent Event(IR, UsedResources);
|
||||
for (std::unique_ptr<View> &Listener : Views)
|
||||
Listener->onInstructionEvent(Event);
|
||||
Listener->onEvent(Event);
|
||||
S.updateNext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@ void RegisterFileStatistics::initializeRegisterFileInfo() {
|
|||
std::fill(RegisterFiles.begin(), RegisterFiles.end(), Empty);
|
||||
}
|
||||
|
||||
void RegisterFileStatistics::onInstructionEvent(
|
||||
const HWInstructionEvent &Event) {
|
||||
void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) {
|
||||
switch (Event.Type) {
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
initializeRegisterFileInfo();
|
||||
}
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void printView(llvm::raw_ostream &OS) const override;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ void ResourcePressureView::initialize() {
|
|||
std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0.0);
|
||||
}
|
||||
|
||||
void ResourcePressureView::onInstructionEvent(const HWInstructionEvent &Event) {
|
||||
void ResourcePressureView::onEvent(const HWInstructionEvent &Event) {
|
||||
// We're only interested in Issue events.
|
||||
if (Event.Type != HWInstructionEvent::Issued)
|
||||
return;
|
||||
|
|
|
@ -96,7 +96,7 @@ public:
|
|||
initialize();
|
||||
}
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void printView(llvm::raw_ostream &OS) const override {
|
||||
unsigned Executions = Source.getNumIterations();
|
||||
|
|
|
@ -19,8 +19,7 @@ using namespace llvm;
|
|||
|
||||
namespace mca {
|
||||
|
||||
void RetireControlUnitStatistics::onInstructionEvent(
|
||||
const HWInstructionEvent &Event) {
|
||||
void RetireControlUnitStatistics::onEvent(const HWInstructionEvent &Event) {
|
||||
if (Event.Type == HWInstructionEvent::Retired)
|
||||
++NumRetired;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class RetireControlUnitStatistics : public View {
|
|||
public:
|
||||
RetireControlUnitStatistics() : NumRetired(0), NumCycles(0) {}
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void onCycleBegin() override { NumCycles++; }
|
||||
|
||||
|
|
|
@ -49,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());
|
||||
notifyInstructionEvent(HWInstructionRetiredEvent(IR, FreedRegs));
|
||||
notifyEvent<HWInstructionEvent>(HWInstructionRetiredEvent(IR, FreedRegs));
|
||||
}
|
||||
|
||||
} // namespace mca
|
||||
|
|
|
@ -19,7 +19,7 @@ using namespace llvm;
|
|||
|
||||
namespace mca {
|
||||
|
||||
void SchedulerStatistics::onInstructionEvent(const HWInstructionEvent &Event) {
|
||||
void SchedulerStatistics::onEvent(const HWInstructionEvent &Event) {
|
||||
if (Event.Type == HWInstructionEvent::Issued)
|
||||
++NumIssued;
|
||||
}
|
||||
|
|
|
@ -65,9 +65,9 @@ class SchedulerStatistics : public View {
|
|||
|
||||
public:
|
||||
SchedulerStatistics(const llvm::MCSubtargetInfo &STI)
|
||||
: SM(STI.getSchedModel()), NumIssued(0), NumCycles(0) { }
|
||||
: SM(STI.getSchedModel()), NumIssued(0), NumCycles(0) {}
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void onCycleBegin() override { NumCycles++; }
|
||||
|
||||
|
|
|
@ -24,9 +24,4 @@ void Stage::addListener(HWEventListener *Listener) {
|
|||
Listeners.insert(Listener);
|
||||
}
|
||||
|
||||
void Stage::notifyInstructionEvent(const HWInstructionEvent &Event) {
|
||||
for (HWEventListener *Listener : Listeners)
|
||||
Listener->onInstructionEvent(Event);
|
||||
}
|
||||
|
||||
} // namespace mca
|
||||
|
|
|
@ -55,7 +55,11 @@ public:
|
|||
/// Add a listener to receive callbacks during the execution of this stage.
|
||||
void addListener(HWEventListener *Listener);
|
||||
|
||||
virtual void notifyInstructionEvent(const HWInstructionEvent &Event);
|
||||
/// Notify listeners of a particular hardware event.
|
||||
template <typename EventT> void notifyEvent(const EventT &Event) {
|
||||
for (HWEventListener *Listener : Listeners)
|
||||
Listener->onEvent(Event);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mca
|
||||
|
|
|
@ -32,7 +32,7 @@ SummaryView::SummaryView(const llvm::MCSchedModel &Model, const SourceMgr &S,
|
|||
computeProcResourceMasks(SM, ProcResourceMasks);
|
||||
}
|
||||
|
||||
void SummaryView::onInstructionEvent(const HWInstructionEvent &Event) {
|
||||
void SummaryView::onEvent(const HWInstructionEvent &Event) {
|
||||
// We are only interested in the "instruction dispatched" events generated by
|
||||
// the dispatch stage for instructions that are part of iteration #0.
|
||||
if (Event.Type != HWInstructionEvent::Dispatched)
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
void onCycleEnd() override { ++TotalCycles; }
|
||||
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
void printView(llvm::raw_ostream &OS) const override;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ void TimelineView::initialize(unsigned MaxIterations) {
|
|||
std::fill(WaitTime.begin(), WaitTime.end(), NullWTEntry);
|
||||
}
|
||||
|
||||
void TimelineView::onInstructionEvent(const HWInstructionEvent &Event) {
|
||||
void TimelineView::onEvent(const HWInstructionEvent &Event) {
|
||||
const unsigned Index = Event.IR.getSourceIndex();
|
||||
if (CurrentCycle >= MaxCycle || Index >= Timeline.size())
|
||||
return;
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
|
||||
// Event handlers.
|
||||
void onCycleEnd() override { ++CurrentCycle; }
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
void onEvent(const HWInstructionEvent &Event) override;
|
||||
|
||||
// print functionalities.
|
||||
void printTimeline(llvm::raw_ostream &OS) const;
|
||||
|
|
Loading…
Reference in New Issue