diff options
Diffstat (limited to 'lib/MCA/HardwareUnits/ResourceManager.cpp')
-rw-r--r-- | lib/MCA/HardwareUnits/ResourceManager.cpp | 98 |
1 files changed, 60 insertions, 38 deletions
diff --git a/lib/MCA/HardwareUnits/ResourceManager.cpp b/lib/MCA/HardwareUnits/ResourceManager.cpp index 2039b58e8ee5..06f2476353d6 100644 --- a/lib/MCA/HardwareUnits/ResourceManager.cpp +++ b/lib/MCA/HardwareUnits/ResourceManager.cpp @@ -1,9 +1,8 @@ //===--------------------- ResourceManager.cpp ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -24,16 +23,10 @@ namespace mca { #define DEBUG_TYPE "llvm-mca" ResourceStrategy::~ResourceStrategy() = default; -// Returns the index of the highest bit set. For resource masks, the position of -// the highest bit set can be used to construct a resource mask identifier. -static unsigned getResourceStateIndex(uint64_t Mask) { - return std::numeric_limits<uint64_t>::digits - countLeadingZeros(Mask); -} - static uint64_t selectImpl(uint64_t CandidateMask, uint64_t &NextInSequenceMask) { // The upper bit set in CandidateMask identifies our next candidate resource. - CandidateMask = 1ULL << (getResourceStateIndex(CandidateMask) - 1); + CandidateMask = 1ULL << getResourceStateIndex(CandidateMask); NextInSequenceMask &= (CandidateMask | (CandidateMask - 1)); return CandidateMask; } @@ -75,7 +68,7 @@ ResourceState::ResourceState(const MCProcResourceDesc &Desc, unsigned Index, BufferSize(Desc.BufferSize), IsAGroup(countPopulation(ResourceMask) > 1) { if (IsAGroup) { ResourceSizeMask = - ResourceMask ^ 1ULL << (getResourceStateIndex(ResourceMask) - 1); + ResourceMask ^ 1ULL << getResourceStateIndex(ResourceMask); } else { ResourceSizeMask = (1ULL << Desc.NumUnits) - 1; } @@ -116,13 +109,21 @@ getStrategyFor(const ResourceState &RS) { } ResourceManager::ResourceManager(const MCSchedModel &SM) - : Resources(SM.getNumProcResourceKinds()), - Strategies(SM.getNumProcResourceKinds()), - Resource2Groups(SM.getNumProcResourceKinds(), 0), - ProcResID2Mask(SM.getNumProcResourceKinds()) { + : Resources(SM.getNumProcResourceKinds() - 1), + Strategies(SM.getNumProcResourceKinds() - 1), + Resource2Groups(SM.getNumProcResourceKinds() - 1, 0), + ProcResID2Mask(SM.getNumProcResourceKinds(), 0), + ResIndex2ProcResID(SM.getNumProcResourceKinds() - 1, 0), + ProcResUnitMask(0), ReservedResourceGroups(0) { computeProcResourceMasks(SM, ProcResID2Mask); - for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) { + // initialize vector ResIndex2ProcResID. + for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { + unsigned Index = getResourceStateIndex(ProcResID2Mask[I]); + ResIndex2ProcResID[Index] = I; + } + + for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { uint64_t Mask = ProcResID2Mask[I]; unsigned Index = getResourceStateIndex(Mask); Resources[Index] = @@ -130,14 +131,16 @@ ResourceManager::ResourceManager(const MCSchedModel &SM) Strategies[Index] = getStrategyFor(*Resources[Index]); } - for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) { + for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { 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); + uint64_t GroupMaskIdx = 1ULL << Index; Mask -= GroupMaskIdx; while (Mask) { // Extract lowest set isolated bit. @@ -147,6 +150,8 @@ ResourceManager::ResourceManager(const MCSchedModel &SM) Mask ^= Unit; } } + + AvailableProcResUnits = ProcResUnitMask; } void ResourceManager::setCustomStrategyImpl(std::unique_ptr<ResourceStrategy> S, @@ -158,7 +163,7 @@ void ResourceManager::setCustomStrategyImpl(std::unique_ptr<ResourceStrategy> S, } unsigned ResourceManager::resolveResourceMask(uint64_t Mask) const { - return Resources[getResourceStateIndex(Mask)]->getProcResourceID(); + return ResIndex2ProcResID[getResourceStateIndex(Mask)]; } unsigned ResourceManager::getNumUnits(uint64_t ResourceID) const { @@ -200,6 +205,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) { @@ -214,19 +221,22 @@ void ResourceManager::use(const ResourceRef &RR) { } void ResourceManager::release(const ResourceRef &RR) { - ResourceState &RS = *Resources[getResourceStateIndex(RR.first)]; + unsigned RSID = getResourceStateIndex(RR.first); + ResourceState &RS = *Resources[RSID]; bool WasFullyUsed = !RS.isReady(); RS.releaseSubResource(RR.second); if (!WasFullyUsed) return; - for (std::unique_ptr<ResourceState> &Res : Resources) { - ResourceState &Current = *Res; - if (!Current.isAResourceGroup() || Current.getResourceMask() == RR.first) - continue; + AvailableProcResUnits ^= RR.first; - if (Current.containsResource(RR.first)) - Current.releaseSubResource(RR.first); + // Notify groups that RR.first is now available again. + uint64_t Users = Resource2Groups[RSID]; + while (Users) { + unsigned GroupIndex = getResourceStateIndex(Users & (-Users)); + ResourceState &CurrentUser = *Resources[GroupIndex]; + CurrentUser.releaseSubResource(RR.first); + Users &= Users - 1; } } @@ -260,13 +270,19 @@ 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; + } + + BusyResourceMask &= ProcResUnitMask; + if (BusyResourceMask) + return BusyResourceMask; + return Desc.UsedProcResGroups & ReservedResourceGroups; } void ResourceManager::issueInstruction( @@ -317,14 +333,20 @@ void ResourceManager::cycleEvent(SmallVectorImpl<ResourceRef> &ResourcesFreed) { } void ResourceManager::reserveResource(uint64_t ResourceID) { - ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)]; - assert(!Resource.isReserved()); + const unsigned Index = getResourceStateIndex(ResourceID); + ResourceState &Resource = *Resources[Index]; + assert(Resource.isAResourceGroup() && !Resource.isReserved() && + "Unexpected resource found!"); Resource.setReserved(); + ReservedResourceGroups ^= 1ULL << Index; } void ResourceManager::releaseResource(uint64_t ResourceID) { - ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)]; + const unsigned Index = getResourceStateIndex(ResourceID); + ResourceState &Resource = *Resources[Index]; Resource.clearReserved(); + if (Resource.isAResourceGroup()) + ReservedResourceGroups ^= 1ULL << Index; } } // namespace mca |