summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca/ResourceManager.cpp
diff options
context:
space:
mode:
authorMatt Davis <Matthew.Davis@sony.com>2018-08-24 22:05:14 +0000
committerMatt Davis <Matthew.Davis@sony.com>2018-08-24 22:05:14 +0000
commite442a8701f7b493dc9e529fa0f491e94f7d67374 (patch)
tree959ee5dde5a2fe95b608695f1a3f8a5e2d1776d1 /llvm/tools/llvm-mca/ResourceManager.cpp
parent006bdad69240670717d0257ef5b7123b65fb12c4 (diff)
downloadbcm5719-llvm-e442a8701f7b493dc9e529fa0f491e94f7d67374.tar.gz
bcm5719-llvm-e442a8701f7b493dc9e529fa0f491e94f7d67374.zip
[llvm-mca] Revert r340659. NFC.
Choosing to revert the change and do it again, hopefully preserving the history of the changes by using svn copy instead of simply creating a new file from the contents within Scheduler. llvm-svn: 340661
Diffstat (limited to 'llvm/tools/llvm-mca/ResourceManager.cpp')
-rw-r--r--llvm/tools/llvm-mca/ResourceManager.cpp309
1 files changed, 0 insertions, 309 deletions
diff --git a/llvm/tools/llvm-mca/ResourceManager.cpp b/llvm/tools/llvm-mca/ResourceManager.cpp
deleted file mode 100644
index 80ea73e631d..00000000000
--- a/llvm/tools/llvm-mca/ResourceManager.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-//===--------------------- ResourceManager.cpp ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// The classes here represent processor resource units and their management
-/// strategy. These classes are managed by the Scheduler.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ResourceManager.h"
-#include "Support.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace mca {
-
-using namespace llvm;
-
-#define DEBUG_TYPE "llvm-mca"
-ResourceStrategy::~ResourceStrategy() = default;
-
-void DefaultResourceStrategy::skipMask(uint64_t Mask) {
- NextInSequenceMask &= (~Mask);
- if (!NextInSequenceMask) {
- NextInSequenceMask = ResourceUnitMask ^ RemovedFromNextInSequence;
- RemovedFromNextInSequence = 0;
- }
-}
-
-uint64_t DefaultResourceStrategy::select(uint64_t ReadyMask) {
- // This method assumes that ReadyMask cannot be zero.
- uint64_t CandidateMask = llvm::PowerOf2Floor(NextInSequenceMask);
- while (!(ReadyMask & CandidateMask)) {
- skipMask(CandidateMask);
- CandidateMask = llvm::PowerOf2Floor(NextInSequenceMask);
- }
- return CandidateMask;
-}
-
-void DefaultResourceStrategy::used(uint64_t Mask) {
- if (Mask > NextInSequenceMask) {
- RemovedFromNextInSequence |= Mask;
- return;
- }
- skipMask(Mask);
-}
-
-ResourceState::ResourceState(const MCProcResourceDesc &Desc, unsigned Index,
- uint64_t Mask)
- : ProcResourceDescIndex(Index), ResourceMask(Mask),
- BufferSize(Desc.BufferSize) {
- if (llvm::countPopulation(ResourceMask) > 1)
- ResourceSizeMask = ResourceMask ^ llvm::PowerOf2Floor(ResourceMask);
- else
- ResourceSizeMask = (1ULL << Desc.NumUnits) - 1;
- ReadyMask = ResourceSizeMask;
- AvailableSlots = BufferSize == -1 ? 0U : static_cast<unsigned>(BufferSize);
- Unavailable = false;
-}
-
-bool ResourceState::isReady(unsigned NumUnits) const {
- return (!isReserved() || isADispatchHazard()) &&
- llvm::countPopulation(ReadyMask) >= NumUnits;
-}
-
-ResourceStateEvent ResourceState::isBufferAvailable() const {
- if (isADispatchHazard() && isReserved())
- return RS_RESERVED;
- if (!isBuffered() || AvailableSlots)
- return RS_BUFFER_AVAILABLE;
- return RS_BUFFER_UNAVAILABLE;
-}
-
-#ifndef NDEBUG
-void ResourceState::dump() const {
- dbgs() << "MASK: " << ResourceMask << ", SIZE_MASK: " << ResourceSizeMask
- << ", RDYMASK: " << ReadyMask << ", BufferSize=" << BufferSize
- << ", AvailableSlots=" << AvailableSlots
- << ", Reserved=" << Unavailable << '\n';
-}
-#endif
-
-static unsigned getResourceStateIndex(uint64_t Mask) {
- return std::numeric_limits<uint64_t>::digits - llvm::countLeadingZeros(Mask);
-}
-
-static std::unique_ptr<ResourceStrategy>
-getStrategyFor(const ResourceState &RS) {
- if (RS.isAResourceGroup() || RS.getNumUnits() > 1)
- return llvm::make_unique<DefaultResourceStrategy>(RS.getReadyMask());
- return std::unique_ptr<ResourceStrategy>(nullptr);
-}
-
-ResourceManager::ResourceManager(const MCSchedModel &SM)
- : ProcResID2Mask(SM.getNumProcResourceKinds()) {
- computeProcResourceMasks(SM, ProcResID2Mask);
- Resources.resize(SM.getNumProcResourceKinds());
- Strategies.resize(SM.getNumProcResourceKinds());
-
- for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
- uint64_t Mask = ProcResID2Mask[I];
- unsigned Index = getResourceStateIndex(Mask);
- Resources[Index] =
- llvm::make_unique<ResourceState>(*SM.getProcResource(I), I, Mask);
- Strategies[Index] = getStrategyFor(*Resources[Index]);
- }
-}
-
-void ResourceManager::setCustomStrategyImpl(std::unique_ptr<ResourceStrategy> S,
- uint64_t ResourceMask) {
- unsigned Index = getResourceStateIndex(ResourceMask);
- assert(Index < Resources.size() && "Invalid processor resource index!");
- assert(S && "Unexpected null strategy in input!");
- Strategies[Index] = std::move(S);
-}
-
-unsigned ResourceManager::resolveResourceMask(uint64_t Mask) const {
- return Resources[getResourceStateIndex(Mask)]->getProcResourceID();
-}
-
-unsigned ResourceManager::getNumUnits(uint64_t ResourceID) const {
- return Resources[getResourceStateIndex(ResourceID)]->getNumUnits();
-}
-
-// Returns the actual resource consumed by this Use.
-// First, is the primary resource ID.
-// Second, is the specific sub-resource ID.
-ResourceRef ResourceManager::selectPipe(uint64_t ResourceID) {
- unsigned Index = getResourceStateIndex(ResourceID);
- ResourceState &RS = *Resources[Index];
- assert(RS.isReady() && "No available units to select!");
-
- // Special case where RS is not a group, and it only declares a single
- // resource unit.
- if (!RS.isAResourceGroup() && RS.getNumUnits() == 1)
- return std::make_pair(ResourceID, RS.getReadyMask());
-
- uint64_t SubResourceID = Strategies[Index]->select(RS.getReadyMask());
- if (RS.isAResourceGroup())
- return selectPipe(SubResourceID);
- return std::make_pair(ResourceID, SubResourceID);
-}
-
-void ResourceManager::use(const ResourceRef &RR) {
- // Mark the sub-resource referenced by RR as used.
- ResourceState &RS = *Resources[getResourceStateIndex(RR.first)];
- RS.markSubResourceAsUsed(RR.second);
- // If there are still available units in RR.first,
- // then we are done.
- if (RS.isReady())
- return;
-
- // Notify to other resources that RR.first is no longer available.
- for (std::unique_ptr<ResourceState> &Res : Resources) {
- ResourceState &Current = *Res;
- if (!Current.isAResourceGroup() || Current.getResourceMask() == RR.first)
- continue;
-
- if (Current.containsResource(RR.first)) {
- unsigned Index = getResourceStateIndex(Current.getResourceMask());
- Current.markSubResourceAsUsed(RR.first);
- Strategies[Index]->used(RR.first);
- }
- }
-}
-
-void ResourceManager::release(const ResourceRef &RR) {
- ResourceState &RS = *Resources[getResourceStateIndex(RR.first)];
- 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;
-
- if (Current.containsResource(RR.first))
- Current.releaseSubResource(RR.first);
- }
-}
-
-ResourceStateEvent
-ResourceManager::canBeDispatched(ArrayRef<uint64_t> Buffers) const {
- ResourceStateEvent Result = ResourceStateEvent::RS_BUFFER_AVAILABLE;
- for (uint64_t Buffer : Buffers) {
- ResourceState &RS = *Resources[getResourceStateIndex(Buffer)];
- Result = RS.isBufferAvailable();
- if (Result != ResourceStateEvent::RS_BUFFER_AVAILABLE)
- break;
- }
- return Result;
-}
-
-void ResourceManager::reserveBuffers(ArrayRef<uint64_t> Buffers) {
- for (const uint64_t Buffer : Buffers) {
- ResourceState &RS = *Resources[getResourceStateIndex(Buffer)];
- assert(RS.isBufferAvailable() == ResourceStateEvent::RS_BUFFER_AVAILABLE);
- RS.reserveBuffer();
-
- if (RS.isADispatchHazard()) {
- assert(!RS.isReserved());
- RS.setReserved();
- }
- }
-}
-
-void ResourceManager::releaseBuffers(ArrayRef<uint64_t> Buffers) {
- for (const uint64_t R : Buffers)
- Resources[getResourceStateIndex(R)]->releaseBuffer();
-}
-
-bool ResourceManager::canBeIssued(const InstrDesc &Desc) const {
- return std::all_of(Desc.Resources.begin(), Desc.Resources.end(),
- [&](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);
- });
-}
-
-// Returns true if all resources are in-order, and there is at least one
-// resource which is a dispatch hazard (BufferSize = 0).
-bool ResourceManager::mustIssueImmediately(const InstrDesc &Desc) const {
- if (!canBeIssued(Desc))
- return false;
- bool AllInOrderResources = all_of(Desc.Buffers, [&](uint64_t BufferMask) {
- unsigned Index = getResourceStateIndex(BufferMask);
- const ResourceState &Resource = *Resources[Index];
- return Resource.isInOrder() || Resource.isADispatchHazard();
- });
- if (!AllInOrderResources)
- return false;
-
- return any_of(Desc.Buffers, [&](uint64_t BufferMask) {
- return Resources[getResourceStateIndex(BufferMask)]->isADispatchHazard();
- });
-}
-
-void ResourceManager::issueInstruction(
- const InstrDesc &Desc,
- SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes) {
- for (const std::pair<uint64_t, ResourceUsage> &R : Desc.Resources) {
- const CycleSegment &CS = R.second.CS;
- if (!CS.size()) {
- releaseResource(R.first);
- continue;
- }
-
- assert(CS.begin() == 0 && "Invalid {Start, End} cycles!");
- if (!R.second.isReserved()) {
- ResourceRef Pipe = selectPipe(R.first);
- use(Pipe);
- BusyResources[Pipe] += CS.size();
- // Replace the resource mask with a valid processor resource index.
- const ResourceState &RS = *Resources[getResourceStateIndex(Pipe.first)];
- Pipe.first = RS.getProcResourceID();
- Pipes.emplace_back(
- std::pair<ResourceRef, double>(Pipe, static_cast<double>(CS.size())));
- } else {
- assert((countPopulation(R.first) > 1) && "Expected a group!");
- // Mark this group as reserved.
- assert(R.second.isReserved());
- reserveResource(R.first);
- BusyResources[ResourceRef(R.first, R.first)] += CS.size();
- }
- }
-}
-
-void ResourceManager::cycleEvent(SmallVectorImpl<ResourceRef> &ResourcesFreed) {
- for (std::pair<ResourceRef, unsigned> &BR : BusyResources) {
- if (BR.second)
- BR.second--;
- if (!BR.second) {
- // Release this resource.
- const ResourceRef &RR = BR.first;
-
- if (countPopulation(RR.first) == 1)
- release(RR);
-
- releaseResource(RR.first);
- ResourcesFreed.push_back(RR);
- }
- }
-
- for (const ResourceRef &RF : ResourcesFreed)
- BusyResources.erase(RF);
-}
-
-void ResourceManager::reserveResource(uint64_t ResourceID) {
- ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)];
- assert(!Resource.isReserved());
- Resource.setReserved();
-}
-
-void ResourceManager::releaseResource(uint64_t ResourceID) {
- ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)];
- Resource.clearReserved();
-}
-
-} // namespace mca
OpenPOWER on IntegriCloud