[llvm] r359983 - [MCA] Notify event listeners when instructions transition to the Pending state. NFCI
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Sun May 5 09:07:27 PDT 2019
Author: adibiagio
Date: Sun May 5 09:07:27 2019
New Revision: 359983
URL: http://llvm.org/viewvc/llvm-project?rev=359983&view=rev
Log:
[MCA] Notify event listeners when instructions transition to the Pending state. NFCI
Modified:
llvm/trunk/include/llvm/MCA/HWEventListener.h
llvm/trunk/include/llvm/MCA/HardwareUnits/Scheduler.h
llvm/trunk/include/llvm/MCA/Stages/ExecuteStage.h
llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp
llvm/trunk/lib/MCA/Stages/ExecuteStage.cpp
Modified: llvm/trunk/include/llvm/MCA/HWEventListener.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MCA/HWEventListener.h?rev=359983&r1=359982&r2=359983&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MCA/HWEventListener.h (original)
+++ llvm/trunk/include/llvm/MCA/HWEventListener.h Sun May 5 09:07:27 2019
@@ -39,6 +39,7 @@ public:
// Events generated by the Retire Control Unit.
Retired,
// Events generated by the Scheduler.
+ Pending,
Ready,
Issued,
Executed,
Modified: llvm/trunk/include/llvm/MCA/HardwareUnits/Scheduler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MCA/HardwareUnits/Scheduler.h?rev=359983&r1=359982&r2=359983&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MCA/HardwareUnits/Scheduler.h (original)
+++ llvm/trunk/include/llvm/MCA/HardwareUnits/Scheduler.h Sun May 5 09:07:27 2019
@@ -149,8 +149,9 @@ class Scheduler : public HardwareUnit {
bool promoteToReadySet(SmallVectorImpl<InstRef> &Ready);
// Try to promote instructions from the WaitSet to the PendingSet.
+ // Add promoted instructions to the 'Pending' vector in input.
// Returns true if at least one instruction was promoted.
- bool promoteToPendingSet();
+ bool promoteToPendingSet(SmallVectorImpl<InstRef> &Pending);
public:
Scheduler(const MCSchedModel &Model, LSUnit &Lsu)
@@ -198,6 +199,7 @@ public:
void issueInstruction(
InstRef &IR,
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Used,
+ SmallVectorImpl<InstRef> &Pending,
SmallVectorImpl<InstRef> &Ready);
/// Returns true if IR has to be issued immediately, or if IR is a zero
@@ -211,9 +213,15 @@ public:
/// have changed in state, and that are now available to new instructions.
/// Instructions executed are added to vector Executed, while vector Ready is
/// populated with instructions that have become ready in this new cycle.
+ /// Vector Pending is popluated by instructions that have transitioned through
+ /// the pending stat during this cycle. The Pending and Ready sets may not be
+ /// disjoint. An instruction is allowed to transition from the WAIT state to
+ /// the READY state (going through the PENDING state) within a single cycle.
+ /// That means, instructions may appear in both the Pending and Ready set.
void cycleEvent(SmallVectorImpl<ResourceRef> &Freed,
- SmallVectorImpl<InstRef> &Ready,
- SmallVectorImpl<InstRef> &Executed);
+ SmallVectorImpl<InstRef> &Executed,
+ SmallVectorImpl<InstRef> &Pending,
+ SmallVectorImpl<InstRef> &Ready);
/// Convert a resource mask into a valid llvm processor resource identifier.
unsigned getResourceID(uint64_t Mask) const {
Modified: llvm/trunk/include/llvm/MCA/Stages/ExecuteStage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MCA/Stages/ExecuteStage.h?rev=359983&r1=359982&r2=359983&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MCA/Stages/ExecuteStage.h (original)
+++ llvm/trunk/include/llvm/MCA/Stages/ExecuteStage.h Sun May 5 09:07:27 2019
@@ -76,6 +76,7 @@ public:
const InstRef &IR,
MutableArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const;
void notifyInstructionExecuted(const InstRef &IR) const;
+ void notifyInstructionPending(const InstRef &IR) const;
void notifyInstructionReady(const InstRef &IR) const;
void notifyResourceAvailable(const ResourceRef &RR) const;
Modified: llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp?rev=359983&r1=359982&r2=359983&view=diff
==============================================================================
--- llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp (original)
+++ llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp Sun May 5 09:07:27 2019
@@ -92,6 +92,7 @@ void Scheduler::issueInstructionImpl(
void Scheduler::issueInstruction(
InstRef &IR,
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &UsedResources,
+ SmallVectorImpl<InstRef> &PendingInstructions,
SmallVectorImpl<InstRef> &ReadyInstructions) {
const Instruction &Inst = *IR.getInstruction();
bool HasDependentUsers = Inst.hasDependentUsers();
@@ -102,7 +103,7 @@ void Scheduler::issueInstruction(
// other dependent instructions. Dependent instructions may be issued during
// this same cycle if operands have ReadAdvance entries. Promote those
// instructions to the ReadySet and notify the caller that those are ready.
- if (HasDependentUsers && promoteToPendingSet())
+ if (HasDependentUsers && promoteToPendingSet(PendingInstructions))
promoteToReadySet(ReadyInstructions);
}
@@ -147,7 +148,7 @@ bool Scheduler::promoteToReadySet(SmallV
return PromotedElements;
}
-bool Scheduler::promoteToPendingSet() {
+bool Scheduler::promoteToPendingSet(SmallVectorImpl<InstRef> &Pending) {
// Scan the set of waiting instructions and promote them to the
// pending set if operands are all ready.
unsigned RemovedElements = 0;
@@ -166,6 +167,7 @@ bool Scheduler::promoteToPendingSet() {
LLVM_DEBUG(dbgs() << "[SCHEDULER]: Instruction #" << IR
<< " promoted to the PENDING set.\n");
+ Pending.emplace_back(IR);
PendingSet.emplace_back(IR);
IR.invalidate();
@@ -251,6 +253,7 @@ void Scheduler::analyzeDataDependencies(
void Scheduler::cycleEvent(SmallVectorImpl<ResourceRef> &Freed,
SmallVectorImpl<InstRef> &Executed,
+ SmallVectorImpl<InstRef> &Pending,
SmallVectorImpl<InstRef> &Ready) {
// Release consumed resources.
Resources->cycleEvent(Freed);
@@ -265,7 +268,7 @@ void Scheduler::cycleEvent(SmallVectorIm
for (InstRef &IR : WaitSet)
IR.getInstruction()->cycleEvent();
- promoteToPendingSet();
+ promoteToPendingSet(Pending);
promoteToReadySet(Ready);
NumDispatchedToThePendingSet = 0;
@@ -299,6 +302,8 @@ bool Scheduler::dispatch(const InstRef &
return false;
}
+ // Memory operations that are not in a ready state are initially assigned to
+ // the WaitSet.
if (!IS.isReady() ||
(IS.isMemOp() && LSU.isReady(IR) != IR.getSourceIndex())) {
LLVM_DEBUG(dbgs() << "[SCHEDULER] Adding #" << IR << " to the WaitSet\n");
Modified: llvm/trunk/lib/MCA/Stages/ExecuteStage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MCA/Stages/ExecuteStage.cpp?rev=359983&r1=359982&r2=359983&view=diff
==============================================================================
--- llvm/trunk/lib/MCA/Stages/ExecuteStage.cpp (original)
+++ llvm/trunk/lib/MCA/Stages/ExecuteStage.cpp Sun May 5 09:07:27 2019
@@ -52,8 +52,10 @@ bool ExecuteStage::isAvailable(const Ins
Error ExecuteStage::issueInstruction(InstRef &IR) {
SmallVector<std::pair<ResourceRef, ResourceCycles>, 4> Used;
+ SmallVector<InstRef, 4> Pending;
SmallVector<InstRef, 4> Ready;
- HWS.issueInstruction(IR, Used, Ready);
+
+ HWS.issueInstruction(IR, Used, Pending, Ready);
NumIssuedOpcodes += IR.getInstruction()->getDesc().NumMicroOps;
notifyReservedOrReleasedBuffers(IR, /* Reserved */ false);
@@ -66,6 +68,9 @@ Error ExecuteStage::issueInstruction(Ins
return S;
}
+ for (const InstRef &I : Pending)
+ notifyInstructionPending(I);
+
for (const InstRef &I : Ready)
notifyInstructionReady(I);
return ErrorSuccess();
@@ -87,9 +92,10 @@ Error ExecuteStage::issueReadyInstructio
Error ExecuteStage::cycleStart() {
SmallVector<ResourceRef, 8> Freed;
SmallVector<InstRef, 4> Executed;
+ SmallVector<InstRef, 4> Pending;
SmallVector<InstRef, 4> Ready;
- HWS.cycleEvent(Freed, Executed, Ready);
+ HWS.cycleEvent(Freed, Executed, Pending, Ready);
NumDispatchedOpcodes = 0;
NumIssuedOpcodes = 0;
@@ -103,6 +109,9 @@ Error ExecuteStage::cycleStart() {
return S;
}
+ for (const InstRef &IR : Pending)
+ notifyInstructionPending(IR);
+
for (const InstRef &IR : Ready)
notifyInstructionReady(IR);
@@ -126,7 +135,6 @@ Error ExecuteStage::cycleEnd() {
<< format_hex(Mask, 16) << '\n');
HWPressureEvent Ev(HWPressureEvent::RESOURCES, Insts, Mask);
notifyEvent(Ev);
- return ErrorSuccess();
}
SmallVector<InstRef, 8> RegDeps;
@@ -165,6 +173,7 @@ Error ExecuteStage::handleInstructionEli
#ifndef NDEBUG
verifyInstructionEliminated(IR);
#endif
+ notifyInstructionPending(IR);
notifyInstructionReady(IR);
notifyInstructionIssued(IR, {});
IR.getInstruction()->forceExecuted();
@@ -189,10 +198,17 @@ Error ExecuteStage::execute(InstRef &IR)
// be released after MCIS is issued, and all the ResourceCycles for those
// units have been consumed.
bool IsReadyInstruction = HWS.dispatch(IR);
- NumDispatchedOpcodes += IR.getInstruction()->getDesc().NumMicroOps;
+ const Instruction &Inst = *IR.getInstruction();
+ NumDispatchedOpcodes += Inst.getDesc().NumMicroOps;
notifyReservedOrReleasedBuffers(IR, /* Reserved */ true);
- if (!IsReadyInstruction)
+
+ if (!IsReadyInstruction) {
+ if (Inst.isPending())
+ notifyInstructionPending(IR);
return ErrorSuccess();
+ }
+
+ notifyInstructionPending(IR);
// If we did not return early, then the scheduler is ready for execution.
notifyInstructionReady(IR);
@@ -212,6 +228,12 @@ void ExecuteStage::notifyInstructionExec
HWInstructionEvent(HWInstructionEvent::Executed, IR));
}
+void ExecuteStage::notifyInstructionPending(const InstRef &IR) const {
+ LLVM_DEBUG(dbgs() << "[E] Instruction Pending: #" << IR << '\n');
+ notifyEvent<HWInstructionEvent>(
+ HWInstructionEvent(HWInstructionEvent::Pending, IR));
+}
+
void ExecuteStage::notifyInstructionReady(const InstRef &IR) const {
LLVM_DEBUG(dbgs() << "[E] Instruction Ready: #" << IR << '\n');
notifyEvent<HWInstructionEvent>(
More information about the llvm-commits
mailing list