forked from OSchip/llvm-project
[MCA] Improved handling of in-order issue/dispatch resources.
Added field 'MustIssueImmediately' to the instruction descriptor of instructions that only consume in-order issue/dispatch processor resources. This speeds up queries from the hardware Scheduler, and gives an average ~5% speedup on a release build. No functional change intended. llvm-svn: 350397
This commit is contained in:
parent
7ee2285625
commit
3f4b54850f
|
@ -389,10 +389,6 @@ public:
|
|||
// Release a previously reserved processor resource.
|
||||
void releaseResource(uint64_t ResourceID);
|
||||
|
||||
// Returns true if all resources are in-order, and there is at least one
|
||||
// resource which is a dispatch hazard (BufferSize = 0).
|
||||
bool mustIssueImmediately(const InstrDesc &Desc) const;
|
||||
|
||||
bool canBeIssued(const InstrDesc &Desc) const;
|
||||
|
||||
void issueInstruction(
|
||||
|
|
|
@ -337,6 +337,10 @@ struct InstrDesc {
|
|||
bool BeginGroup;
|
||||
bool EndGroup;
|
||||
|
||||
// True if all buffered resources are in-order, and there is at least one
|
||||
// buffer which is a dispatch hazard (BufferSize = 0).
|
||||
bool MustIssueImmediately;
|
||||
|
||||
// A zero latency instruction doesn't consume any scheduler resources.
|
||||
bool isZeroLatency() const { return !MaxLatency && Resources.empty(); }
|
||||
|
||||
|
|
|
@ -267,24 +267,6 @@ bool ResourceManager::canBeIssued(const InstrDesc &Desc) const {
|
|||
});
|
||||
}
|
||||
|
||||
// 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, ResourceCycles>> &Pipes) {
|
||||
|
|
|
@ -199,11 +199,13 @@ void Scheduler::cycleEvent(SmallVectorImpl<ResourceRef> &Freed,
|
|||
}
|
||||
|
||||
bool Scheduler::mustIssueImmediately(const InstRef &IR) const {
|
||||
const InstrDesc &Desc = IR.getInstruction()->getDesc();
|
||||
if (Desc.isZeroLatency())
|
||||
return true;
|
||||
// Instructions that use an in-order dispatch/issue processor resource must be
|
||||
// issued immediately to the pipeline(s). Any other in-order buffered
|
||||
// resources (i.e. BufferSize=1) is consumed.
|
||||
const InstrDesc &Desc = IR.getInstruction()->getDesc();
|
||||
return Desc.isZeroLatency() || Resources->mustIssueImmediately(Desc);
|
||||
return Desc.MustIssueImmediately;
|
||||
}
|
||||
|
||||
void Scheduler::dispatch(const InstRef &IR) {
|
||||
|
|
|
@ -59,12 +59,20 @@ static void initializeUsedResources(InstrDesc &ID,
|
|||
unsigned NumProcResources = SM.getNumProcResourceKinds();
|
||||
APInt Buffers(NumProcResources, 0);
|
||||
|
||||
bool AllInOrderResources = true;
|
||||
bool AnyDispatchHazards = false;
|
||||
for (unsigned I = 0, E = SCDesc.NumWriteProcResEntries; I < E; ++I) {
|
||||
const MCWriteProcResEntry *PRE = STI.getWriteProcResBegin(&SCDesc) + I;
|
||||
const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx);
|
||||
uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx];
|
||||
if (PR.BufferSize != -1)
|
||||
if (PR.BufferSize < 0) {
|
||||
AllInOrderResources = false;
|
||||
} else {
|
||||
Buffers.setBit(PRE->ProcResourceIdx);
|
||||
AnyDispatchHazards |= (PR.BufferSize == 0);
|
||||
AllInOrderResources &= (PR.BufferSize <= 1);
|
||||
}
|
||||
|
||||
CycleSegment RCy(0, PRE->Cycles, false);
|
||||
Worklist.emplace_back(ResourcePlusCycles(Mask, ResourceUsage(RCy)));
|
||||
if (PR.SuperIdx) {
|
||||
|
@ -73,6 +81,8 @@ static void initializeUsedResources(InstrDesc &ID,
|
|||
}
|
||||
}
|
||||
|
||||
ID.MustIssueImmediately = AllInOrderResources && AnyDispatchHazards;
|
||||
|
||||
// Sort elements by mask popcount, so that we prioritize resource units over
|
||||
// resource groups, and smaller groups over larger groups.
|
||||
sort(Worklist, [](const ResourcePlusCycles &A, const ResourcePlusCycles &B) {
|
||||
|
|
Loading…
Reference in New Issue