diff options
author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2019-05-05 16:07:27 +0000 |
---|---|---|
committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2019-05-05 16:07:27 +0000 |
commit | 0460a3629b2564d9b34702ba05ab3f461533eca9 (patch) | |
tree | c92062168662df2ec543cd6e3a528df54d23cc4c /llvm/lib/MCA | |
parent | 1d0c845d9dce577c2ef14cd7d5fcf0b9c17f9ed2 (diff) | |
download | bcm5719-llvm-0460a3629b2564d9b34702ba05ab3f461533eca9.tar.gz bcm5719-llvm-0460a3629b2564d9b34702ba05ab3f461533eca9.zip |
[MCA] Notify event listeners when instructions transition to the Pending state. NFCI
llvm-svn: 359983
Diffstat (limited to 'llvm/lib/MCA')
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/Scheduler.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/MCA/Stages/ExecuteStage.cpp | 32 |
2 files changed, 35 insertions, 8 deletions
diff --git a/llvm/lib/MCA/HardwareUnits/Scheduler.cpp b/llvm/lib/MCA/HardwareUnits/Scheduler.cpp index 5b2527b886e..9eeea9d0113 100644 --- a/llvm/lib/MCA/HardwareUnits/Scheduler.cpp +++ b/llvm/lib/MCA/HardwareUnits/Scheduler.cpp @@ -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(SmallVectorImpl<InstRef> &Ready) { 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(SmallVectorImpl<InstRef> &RegDeps, 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(SmallVectorImpl<ResourceRef> &Freed, for (InstRef &IR : WaitSet) IR.getInstruction()->cycleEvent(); - promoteToPendingSet(); + promoteToPendingSet(Pending); promoteToReadySet(Ready); NumDispatchedToThePendingSet = 0; @@ -299,6 +302,8 @@ bool Scheduler::dispatch(const InstRef &IR) { 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"); diff --git a/llvm/lib/MCA/Stages/ExecuteStage.cpp b/llvm/lib/MCA/Stages/ExecuteStage.cpp index 49210e06cd4..a2b361fcd1b 100644 --- a/llvm/lib/MCA/Stages/ExecuteStage.cpp +++ b/llvm/lib/MCA/Stages/ExecuteStage.cpp @@ -52,8 +52,10 @@ bool ExecuteStage::isAvailable(const InstRef &IR) const { 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(InstRef &IR) { return S; } + for (const InstRef &I : Pending) + notifyInstructionPending(I); + for (const InstRef &I : Ready) notifyInstructionReady(I); return ErrorSuccess(); @@ -87,9 +92,10 @@ Error ExecuteStage::issueReadyInstructions() { 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::handleInstructionEliminated(InstRef &IR) { #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::notifyInstructionExecuted(const InstRef &IR) const { 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>( |