From 7fccc80ce9b28befc0c161a9c6caede3d78b3257 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Fri, 4 Jan 2019 15:08:38 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350397 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MCA/HardwareUnits/ResourceManager.h | 4 ---- include/llvm/MCA/Instruction.h | 4 ++++ lib/MCA/HardwareUnits/ResourceManager.cpp | 18 ------------------ lib/MCA/HardwareUnits/Scheduler.cpp | 6 ++++-- lib/MCA/InstrBuilder.cpp | 12 +++++++++++- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/include/llvm/MCA/HardwareUnits/ResourceManager.h b/include/llvm/MCA/HardwareUnits/ResourceManager.h index da80c984ba5..9114f7d9bae 100644 --- a/include/llvm/MCA/HardwareUnits/ResourceManager.h +++ b/include/llvm/MCA/HardwareUnits/ResourceManager.h @@ -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( diff --git a/include/llvm/MCA/Instruction.h b/include/llvm/MCA/Instruction.h index 148651b22da..01d08c1916a 100644 --- a/include/llvm/MCA/Instruction.h +++ b/include/llvm/MCA/Instruction.h @@ -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(); } diff --git a/lib/MCA/HardwareUnits/ResourceManager.cpp b/lib/MCA/HardwareUnits/ResourceManager.cpp index c7f45fd9542..b68e996ff9e 100644 --- a/lib/MCA/HardwareUnits/ResourceManager.cpp +++ b/lib/MCA/HardwareUnits/ResourceManager.cpp @@ -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> &Pipes) { diff --git a/lib/MCA/HardwareUnits/Scheduler.cpp b/lib/MCA/HardwareUnits/Scheduler.cpp index 3924ac59910..355ef79d06a 100644 --- a/lib/MCA/HardwareUnits/Scheduler.cpp +++ b/lib/MCA/HardwareUnits/Scheduler.cpp @@ -199,11 +199,13 @@ void Scheduler::cycleEvent(SmallVectorImpl &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) { diff --git a/lib/MCA/InstrBuilder.cpp b/lib/MCA/InstrBuilder.cpp index 8d501dc6b15..d8309b6868e 100644 --- a/lib/MCA/InstrBuilder.cpp +++ b/lib/MCA/InstrBuilder.cpp @@ -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) { -- 2.11.0