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/lib/MCA | |
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/lib/MCA')
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/ResourceManager.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/Scheduler.cpp | 3 |
2 files changed, 23 insertions, 10 deletions
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; } } |