diff options
author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2019-02-11 14:53:04 +0000 |
---|---|---|
committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2019-02-11 14:53:04 +0000 |
commit | 83e68854d54509e7536f32e4b4aa07e1ad25ec19 (patch) | |
tree | 0f0477f0caeb4630ebc3873b66536a3a8080e3c2 /llvm | |
parent | 756ecb8e44dca8cc629987be3411fc2a0b6c9f31 (diff) | |
download | bcm5719-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.h | 15 | ||||
-rw-r--r-- | llvm/include/llvm/MCA/HardwareUnits/Scheduler.h | 6 | ||||
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/ResourceManager.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/Scheduler.cpp | 3 |
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; } } |