[llvm] r339885 - [llvm-mca] Small refactoring in preparation for another patch that will improve the modularity of the Pipeline. NFCI
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 16 08:43:09 PDT 2018
Author: adibiagio
Date: Thu Aug 16 08:43:09 2018
New Revision: 339885
URL: http://llvm.org/viewvc/llvm-project?rev=339885&view=rev
Log:
[llvm-mca] Small refactoring in preparation for another patch that will improve the modularity of the Pipeline. NFCI
The main difference is that now `cycleStart()` and `cycleEnd()` return an
llvm::Error.
This patch implements a few minor style changes, and adds missing 'const' to
some methods.
Modified:
llvm/trunk/tools/llvm-mca/DispatchStage.cpp
llvm/trunk/tools/llvm-mca/DispatchStage.h
llvm/trunk/tools/llvm-mca/ExecuteStage.cpp
llvm/trunk/tools/llvm-mca/ExecuteStage.h
llvm/trunk/tools/llvm-mca/FetchStage.cpp
llvm/trunk/tools/llvm-mca/FetchStage.h
llvm/trunk/tools/llvm-mca/Pipeline.cpp
llvm/trunk/tools/llvm-mca/RetireStage.cpp
llvm/trunk/tools/llvm-mca/RetireStage.h
llvm/trunk/tools/llvm-mca/SourceMgr.h
llvm/trunk/tools/llvm-mca/Stage.cpp
llvm/trunk/tools/llvm-mca/Stage.h
Modified: llvm/trunk/tools/llvm-mca/DispatchStage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/DispatchStage.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/DispatchStage.cpp (original)
+++ llvm/trunk/tools/llvm-mca/DispatchStage.cpp Thu Aug 16 08:43:09 2018
@@ -33,7 +33,7 @@ void DispatchStage::notifyInstructionDis
notifyEvent<HWInstructionEvent>(HWInstructionDispatchedEvent(IR, UsedRegs));
}
-bool DispatchStage::checkPRF(const InstRef &IR) {
+bool DispatchStage::checkPRF(const InstRef &IR) const {
SmallVector<unsigned, 4> RegDefs;
for (const std::unique_ptr<WriteState> &RegDef :
IR.getInstruction()->getDefs())
@@ -50,7 +50,7 @@ bool DispatchStage::checkPRF(const InstR
return true;
}
-bool DispatchStage::checkRCU(const InstRef &IR) {
+bool DispatchStage::checkRCU(const InstRef &IR) const {
const unsigned NumMicroOps = IR.getInstruction()->getDesc().NumMicroOps;
if (RCU.isAvailable(NumMicroOps))
return true;
@@ -59,7 +59,7 @@ bool DispatchStage::checkRCU(const InstR
return false;
}
-bool DispatchStage::checkScheduler(const InstRef &IR) {
+bool DispatchStage::checkScheduler(const InstRef &IR) const {
HWStallEvent::GenericEventType Event;
const bool Ready = SC.canBeDispatched(IR, Event);
if (!Ready)
@@ -131,9 +131,10 @@ void DispatchStage::dispatch(InstRef IR)
notifyInstructionDispatched(IR, RegisterFiles);
}
-void DispatchStage::cycleStart() {
+llvm::Error DispatchStage::cycleStart() {
AvailableEntries = CarryOver >= DispatchWidth ? 0 : DispatchWidth - CarryOver;
CarryOver = CarryOver >= DispatchWidth ? CarryOver - DispatchWidth : 0U;
+ return llvm::ErrorSuccess();
}
Stage::Status DispatchStage::execute(InstRef &IR) {
Modified: llvm/trunk/tools/llvm-mca/DispatchStage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/DispatchStage.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/DispatchStage.h (original)
+++ llvm/trunk/tools/llvm-mca/DispatchStage.h Thu Aug 16 08:43:09 2018
@@ -58,9 +58,9 @@ class DispatchStage final : public Stage
RegisterFile &PRF;
Scheduler &SC;
- bool checkRCU(const InstRef &IR);
- bool checkPRF(const InstRef &IR);
- bool checkScheduler(const InstRef &IR);
+ bool checkRCU(const InstRef &IR) const;
+ bool checkPRF(const InstRef &IR) const;
+ bool checkScheduler(const InstRef &IR) const;
void dispatch(InstRef IR);
void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
@@ -93,7 +93,7 @@ public:
// The retire stage, which controls the RCU, might have items to complete but
// RetireStage::hasWorkToComplete will check for that case.
bool hasWorkToComplete() const override { return false; }
- void cycleStart() override;
+ llvm::Error cycleStart() override;
Status execute(InstRef &IR) override;
void notifyDispatchStall(const InstRef &IR, unsigned EventType);
Modified: llvm/trunk/tools/llvm-mca/ExecuteStage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/ExecuteStage.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/ExecuteStage.cpp (original)
+++ llvm/trunk/tools/llvm-mca/ExecuteStage.cpp Thu Aug 16 08:43:09 2018
@@ -35,7 +35,7 @@ void ExecuteStage::reclaimSchedulerResou
}
// Update the scheduler's instruction queues.
-void ExecuteStage::updateSchedulerQueues() {
+Error ExecuteStage::updateSchedulerQueues() {
SmallVector<InstRef, 4> InstructionIDs;
HWS.updateIssuedSet(InstructionIDs);
for (const InstRef &IR : InstructionIDs)
@@ -45,10 +45,11 @@ void ExecuteStage::updateSchedulerQueues
HWS.updatePendingQueue(InstructionIDs);
for (const InstRef &IR : InstructionIDs)
notifyInstructionReady(IR);
+ return ErrorSuccess();
}
// Issue instructions that are waiting in the scheduler's ready queue.
-void ExecuteStage::issueReadyInstructions() {
+Error ExecuteStage::issueReadyInstructions() {
SmallVector<InstRef, 4> InstructionIDs;
InstRef IR = HWS.select();
while (IR.isValid()) {
@@ -75,6 +76,8 @@ void ExecuteStage::issueReadyInstruction
// Select the next instruction to issue.
IR = HWS.select();
}
+
+ return ErrorSuccess();
}
// The following routine is the maintenance routine of the ExecuteStage.
@@ -89,10 +92,11 @@ void ExecuteStage::issueReadyInstruction
// Notifications are issued to this stage's listeners when instructions are
// moved between the HWS's queues. In particular, when an instruction becomes
// ready or executed.
-void ExecuteStage::cycleStart() {
+Error ExecuteStage::cycleStart() {
reclaimSchedulerResources();
- updateSchedulerQueues();
- issueReadyInstructions();
+ if (Error S = updateSchedulerQueues())
+ return S;
+ return issueReadyInstructions();
}
// Schedule the instruction for execution on the hardware.
Modified: llvm/trunk/tools/llvm-mca/ExecuteStage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/ExecuteStage.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/ExecuteStage.h (original)
+++ llvm/trunk/tools/llvm-mca/ExecuteStage.h Thu Aug 16 08:43:09 2018
@@ -33,8 +33,8 @@ class ExecuteStage final : public Stage
// The following routines are used to maintain the HWS.
void reclaimSchedulerResources();
- void updateSchedulerQueues();
- void issueReadyInstructions();
+ llvm::Error updateSchedulerQueues();
+ llvm::Error issueReadyInstructions();
ExecuteStage(const ExecuteStage &Other) = delete;
ExecuteStage &operator=(const ExecuteStage &Other) = delete;
@@ -42,11 +42,15 @@ class ExecuteStage final : public Stage
public:
ExecuteStage(RetireControlUnit &R, Scheduler &S) : Stage(), RCU(R), HWS(S) {}
- // The ExecuteStage will always complete all of its work per call to
- // execute(), so it is never left in a 'to-be-processed' state.
+ // This stage works under the assumption that the Pipeline will eventually
+ // execute a retire stage. We don't need to check if pipelines and/or
+ // schedulers have instructions to process, because those instructions are
+ // also tracked by the retire control unit. That means,
+ // RetireControlUnit::hasWorkToComplete() is responsible for checking if there
+ // are still instructions in-flight in the out-of-order backend.
bool hasWorkToComplete() const override { return false; }
- void cycleStart() override;
+ llvm::Error cycleStart() override;
Status execute(InstRef &IR) override;
void
Modified: llvm/trunk/tools/llvm-mca/FetchStage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/FetchStage.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/FetchStage.cpp (original)
+++ llvm/trunk/tools/llvm-mca/FetchStage.cpp Thu Aug 16 08:43:09 2018
@@ -35,7 +35,7 @@ Stage::Status FetchStage::execute(InstRe
void FetchStage::postExecute() { SM.updateNext(); }
-void FetchStage::cycleEnd() {
+llvm::Error FetchStage::cycleEnd() {
// Find the first instruction which hasn't been retired.
const InstMap::iterator It =
llvm::find_if(Instructions, [](const InstMap::value_type &KeyValuePair) {
@@ -45,6 +45,8 @@ void FetchStage::cycleEnd() {
// Erase instructions up to the first that hasn't been retired.
if (It != Instructions.begin())
Instructions.erase(Instructions.begin(), It);
+
+ return llvm::ErrorSuccess();
}
} // namespace mca
Modified: llvm/trunk/tools/llvm-mca/FetchStage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/FetchStage.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/FetchStage.h (original)
+++ llvm/trunk/tools/llvm-mca/FetchStage.h Thu Aug 16 08:43:09 2018
@@ -38,7 +38,7 @@ public:
bool hasWorkToComplete() const override;
Status execute(InstRef &IR) override;
void postExecute() override;
- void cycleEnd() override;
+ llvm::Error cycleEnd() override;
};
} // namespace mca
Modified: llvm/trunk/tools/llvm-mca/Pipeline.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Pipeline.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Pipeline.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Pipeline.cpp Thu Aug 16 08:43:09 2018
@@ -32,10 +32,9 @@ void Pipeline::addEventListener(HWEventL
}
bool Pipeline::hasWorkToProcess() {
- const auto It = llvm::find_if(Stages, [](const std::unique_ptr<Stage> &S) {
+ return llvm::any_of(Stages, [](const std::unique_ptr<Stage> &S) {
return S->hasWorkToComplete();
});
- return It != Stages.end();
}
// This routine returns early if any stage returns 'false' after execute() is
@@ -62,6 +61,8 @@ void Pipeline::postExecuteStages() {
}
llvm::Error Pipeline::run() {
+ assert(!Stages.empty() && "Unexpected empty pipeline found!");
+
while (hasWorkToProcess()) {
notifyCycleBegin();
if (llvm::Error Err = runCycle())
@@ -73,13 +74,18 @@ llvm::Error Pipeline::run() {
}
llvm::Error Pipeline::runCycle() {
- // Update the stages before we do any processing for this cycle.
- InstRef IR;
- for (auto &S : Stages)
- S->cycleStart();
+ // Update stages before we start processing new instructions.
+ llvm::Error Err = llvm::ErrorSuccess();
+ for (auto I = Stages.begin(), E = Stages.end(); I != E && !Err; ++I) {
+ const std::unique_ptr<Stage> &S = *I;
+ Err = S->cycleStart();
+ }
+
+ if (Err)
+ return Err;
- // Continue executing this cycle until any stage claims it cannot make
- // progress.
+ // Now fetch and execute new instructions.
+ InstRef IR;
while (true) {
preExecuteStages();
Stage::Status Val = executeStages(IR);
@@ -90,9 +96,12 @@ llvm::Error Pipeline::runCycle() {
postExecuteStages();
}
- for (auto &S : Stages)
- S->cycleEnd();
- return llvm::ErrorSuccess();
+ // Update stages in preparation for a new cycle.
+ for (auto I = Stages.begin(), E = Stages.end(); I != E && !Err; ++I) {
+ const std::unique_ptr<Stage> &S = *I;
+ Err = S->cycleEnd();
+ }
+ return Err;
}
void Pipeline::notifyCycleBegin() {
Modified: llvm/trunk/tools/llvm-mca/RetireStage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/RetireStage.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/RetireStage.cpp (original)
+++ llvm/trunk/tools/llvm-mca/RetireStage.cpp Thu Aug 16 08:43:09 2018
@@ -18,15 +18,13 @@
#include "HWEventListener.h"
#include "llvm/Support/Debug.h"
-using namespace llvm;
-
#define DEBUG_TYPE "llvm-mca"
namespace mca {
-void RetireStage::cycleStart() {
+llvm::Error RetireStage::cycleStart() {
if (RCU.isEmpty())
- return;
+ return llvm::ErrorSuccess();
const unsigned MaxRetirePerCycle = RCU.getMaxRetirePerCycle();
unsigned NumRetired = 0;
@@ -40,11 +38,13 @@ void RetireStage::cycleStart() {
notifyInstructionRetired(Current.IR);
NumRetired++;
}
+
+ return llvm::ErrorSuccess();
}
void RetireStage::notifyInstructionRetired(const InstRef &IR) {
- LLVM_DEBUG(dbgs() << "[E] Instruction Retired: #" << IR << '\n');
- SmallVector<unsigned, 4> FreedRegs(PRF.getNumRegisterFiles());
+ LLVM_DEBUG(llvm::dbgs() << "[E] Instruction Retired: #" << IR << '\n');
+ llvm::SmallVector<unsigned, 4> FreedRegs(PRF.getNumRegisterFiles());
const Instruction &Inst = *IR.getInstruction();
const InstrDesc &Desc = Inst.getDesc();
Modified: llvm/trunk/tools/llvm-mca/RetireStage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/RetireStage.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/RetireStage.h (original)
+++ llvm/trunk/tools/llvm-mca/RetireStage.h Thu Aug 16 08:43:09 2018
@@ -36,7 +36,7 @@ public:
: Stage(), RCU(R), PRF(F) {}
bool hasWorkToComplete() const override { return !RCU.isEmpty(); }
- void cycleStart() override;
+ llvm::Error cycleStart() override;
Status execute(InstRef &IR) override { return Stage::Continue; }
void notifyInstructionRetired(const InstRef &IR);
void onInstructionExecuted(unsigned TokenID);
Modified: llvm/trunk/tools/llvm-mca/SourceMgr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/SourceMgr.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/SourceMgr.h (original)
+++ llvm/trunk/tools/llvm-mca/SourceMgr.h Thu Aug 16 08:43:09 2018
@@ -44,6 +44,7 @@ public:
void updateNext() { Current++; }
const SourceRef peekNext() const {
+ assert(hasNext() && "Already at end of sequence!");
unsigned Index = getCurrentInstructionIndex();
return SourceRef(Current, Sequence[Index].get());
}
Modified: llvm/trunk/tools/llvm-mca/Stage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Stage.cpp?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Stage.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Stage.cpp Thu Aug 16 08:43:09 2018
@@ -18,7 +18,7 @@
namespace mca {
// Pin the vtable here in the implementation file.
-Stage::Stage() {}
+Stage::~Stage() = default;
void Stage::addListener(HWEventListener *Listener) {
Listeners.insert(Listener);
Modified: llvm/trunk/tools/llvm-mca/Stage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Stage.h?rev=339885&r1=339884&r2=339885&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Stage.h (original)
+++ llvm/trunk/tools/llvm-mca/Stage.h Thu Aug 16 08:43:09 2018
@@ -25,9 +25,10 @@ namespace mca {
class InstRef;
class Stage {
+ std::set<HWEventListener *> Listeners;
+
Stage(const Stage &Other) = delete;
Stage &operator=(const Stage &Other) = delete;
- std::set<HWEventListener *> Listeners;
public:
/// A Stage's execute() returns Continue, Stop, or an error. Returning
@@ -46,8 +47,8 @@ protected:
const std::set<HWEventListener *> &getListeners() const { return Listeners; }
public:
- Stage();
- virtual ~Stage() = default;
+ Stage() {}
+ virtual ~Stage();
/// Called prior to preExecute to ensure that the stage has items that it
/// is to process. For example, a FetchStage might have more instructions
@@ -57,10 +58,10 @@ public:
/// Called once at the start of each cycle. This can be used as a setup
/// phase to prepare for the executions during the cycle.
- virtual void cycleStart() {}
+ virtual llvm::Error cycleStart() { return llvm::ErrorSuccess(); }
/// Called once at the end of each cycle.
- virtual void cycleEnd() {}
+ virtual llvm::Error cycleEnd() { return llvm::ErrorSuccess(); }
/// Called prior to executing the list of stages.
/// This can be called multiple times per cycle.
@@ -80,7 +81,7 @@ public:
void addListener(HWEventListener *Listener);
/// Notify listeners of a particular hardware event.
- template <typename EventT> void notifyEvent(const EventT &Event) {
+ template <typename EventT> void notifyEvent(const EventT &Event) const {
for (HWEventListener *Listener : Listeners)
Listener->onEvent(Event);
}
More information about the llvm-commits
mailing list