summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2019-02-11 14:53:04 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2019-02-11 14:53:04 +0000
commit83e68854d54509e7536f32e4b4aa07e1ad25ec19 (patch)
tree0f0477f0caeb4630ebc3873b66536a3a8080e3c2 /llvm
parent756ecb8e44dca8cc629987be3411fc2a0b6c9f31 (diff)
downloadbcm5719-llvm-83e68854d54509e7536f32e4b4aa07e1ad25ec19.tar.gz
bcm5719-llvm-83e68854d54509e7536f32e4b4aa07e1ad25ec19.zip
[MCA] Return a mask of busy resources from method ResourceManager::checkAvailability(). NFCI
In case of bottlenecks caused by pipeline pressure, we want to be able to correctly report the set of problematic pipelines. This is a first step towards adding support for bottleneck hints in llvm-mca (see PR37494). No functional change intended. llvm-svn: 353706
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h15
-rw-r--r--llvm/include/llvm/MCA/HardwareUnits/Scheduler.h6
-rw-r--r--llvm/lib/MCA/HardwareUnits/ResourceManager.cpp30
-rw-r--r--llvm/lib/MCA/HardwareUnits/Scheduler.cpp3
4 files changed, 43 insertions, 11 deletions
diff --git a/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h b/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
index bf78dec86a9..66272af8a9f 100644
--- a/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
+++ b/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
@@ -341,6 +341,12 @@ class ResourceManager {
// before those become usable again.
SmallDenseMap<ResourceRef, unsigned> BusyResources;
+ // Set of processor resource units available on the target.
+ uint64_t ProcResUnitMask;
+
+ // Set of processor resource units that are available during this cycle.
+ uint64_t AvailableProcResUnits;
+
// Returns the actual resource unit that will be used.
ResourceRef selectPipe(uint64_t ResourceID);
@@ -388,7 +394,14 @@ public:
// Release a previously reserved processor resource.
void releaseResource(uint64_t ResourceID);
- bool canBeIssued(const InstrDesc &Desc) const;
+ // Returns a zero mask if resources requested by Desc are all available during
+ // this cycle. It returns a non-zero mask value only if there are unavailable
+ // processor resources; each bit set in the mask represents a busy processor
+ // resource unit.
+ uint64_t checkAvailability(const InstrDesc &Desc) const;
+
+ uint64_t getProcResUnitMask() const { return ProcResUnitMask; }
+ uint64_t getAvailableProcResUnits() const { return AvailableProcResUnits; }
void issueInstruction(
const InstrDesc &Desc,
diff --git a/llvm/include/llvm/MCA/HardwareUnits/Scheduler.h b/llvm/include/llvm/MCA/HardwareUnits/Scheduler.h
index ae09aef13ff..53e416b1643 100644
--- a/llvm/include/llvm/MCA/HardwareUnits/Scheduler.h
+++ b/llvm/include/llvm/MCA/HardwareUnits/Scheduler.h
@@ -194,6 +194,12 @@ public:
/// resources are not available.
InstRef select();
+ bool arePipelinesFullyUsed() const {
+ return !Resources->getAvailableProcResUnits();
+ }
+ bool isReadySetEmpty() const { return ReadySet.empty(); }
+ bool isWaitSetEmpty() const { return WaitSet.empty(); }
+
#ifndef NDEBUG
// Update the ready queues.
void dump() const;
diff --git a/llvm/lib/MCA/HardwareUnits/ResourceManager.cpp b/llvm/lib/MCA/HardwareUnits/ResourceManager.cpp
index 4cad4f40013..da6bfd55339 100644
--- a/llvm/lib/MCA/HardwareUnits/ResourceManager.cpp
+++ b/llvm/lib/MCA/HardwareUnits/ResourceManager.cpp
@@ -118,7 +118,8 @@ ResourceManager::ResourceManager(const MCSchedModel &SM)
: Resources(SM.getNumProcResourceKinds()),
Strategies(SM.getNumProcResourceKinds()),
Resource2Groups(SM.getNumProcResourceKinds(), 0),
- ProcResID2Mask(SM.getNumProcResourceKinds()) {
+ ProcResID2Mask(SM.getNumProcResourceKinds()),
+ ProcResUnitMask(0) {
computeProcResourceMasks(SM, ProcResID2Mask);
for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
@@ -133,8 +134,10 @@ ResourceManager::ResourceManager(const MCSchedModel &SM)
uint64_t Mask = ProcResID2Mask[I];
unsigned Index = getResourceStateIndex(Mask);
const ResourceState &RS = *Resources[Index];
- if (!RS.isAResourceGroup())
+ if (!RS.isAResourceGroup()) {
+ ProcResUnitMask |= Mask;
continue;
+ }
uint64_t GroupMaskIdx = 1ULL << (Index - 1);
Mask -= GroupMaskIdx;
@@ -146,6 +149,8 @@ ResourceManager::ResourceManager(const MCSchedModel &SM)
Mask ^= Unit;
}
}
+
+ AvailableProcResUnits = ProcResUnitMask;
}
void ResourceManager::setCustomStrategyImpl(std::unique_ptr<ResourceStrategy> S,
@@ -199,6 +204,8 @@ void ResourceManager::use(const ResourceRef &RR) {
if (RS.isReady())
return;
+ AvailableProcResUnits ^= RR.first;
+
// Notify groups that RR.first is no longer available.
uint64_t Users = Resource2Groups[RSID];
while (Users) {
@@ -220,6 +227,8 @@ void ResourceManager::release(const ResourceRef &RR) {
if (!WasFullyUsed)
return;
+ AvailableProcResUnits ^= RR.first;
+
// Notify groups that RR.first is now available again.
uint64_t Users = Resource2Groups[RSID];
while (Users) {
@@ -260,13 +269,16 @@ void ResourceManager::releaseBuffers(ArrayRef<uint64_t> Buffers) {
Resources[getResourceStateIndex(R)]->releaseBuffer();
}
-bool ResourceManager::canBeIssued(const InstrDesc &Desc) const {
- return all_of(
- Desc.Resources, [&](const std::pair<uint64_t, const ResourceUsage> &E) {
- unsigned NumUnits = E.second.isReserved() ? 0U : E.second.NumUnits;
- unsigned Index = getResourceStateIndex(E.first);
- return Resources[Index]->isReady(NumUnits);
- });
+uint64_t ResourceManager::checkAvailability(const InstrDesc &Desc) const {
+ uint64_t BusyResourceMask = 0;
+ for (const std::pair<uint64_t, const ResourceUsage> &E : Desc.Resources) {
+ unsigned NumUnits = E.second.isReserved() ? 0U : E.second.NumUnits;
+ unsigned Index = getResourceStateIndex(E.first);
+ if (!Resources[Index]->isReady(NumUnits))
+ BusyResourceMask |= E.first;
+ }
+
+ return BusyResourceMask & ProcResUnitMask;
}
void ResourceManager::issueInstruction(
diff --git a/llvm/lib/MCA/HardwareUnits/Scheduler.cpp b/llvm/lib/MCA/HardwareUnits/Scheduler.cpp
index 45a43ecb002..fb1080dc02c 100644
--- a/llvm/lib/MCA/HardwareUnits/Scheduler.cpp
+++ b/llvm/lib/MCA/HardwareUnits/Scheduler.cpp
@@ -139,7 +139,8 @@ InstRef Scheduler::select() {
if (QueueIndex == ReadySet.size() ||
Strategy->compare(IR, ReadySet[QueueIndex])) {
const InstrDesc &D = IR.getInstruction()->getDesc();
- if (Resources->canBeIssued(D))
+ uint64_t BusyResourceMask = Resources->checkAvailability(D);
+ if (!BusyResourceMask)
QueueIndex = I;
}
}
OpenPOWER on IntegriCloud