[llvm] 97bd44f - [llvm-exegesis] getNonRedundantWriteProcRes - perform basic toplogical sorting (PR58500)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 24 02:46:25 PDT 2022


Author: Simon Pilgrim
Date: 2022-10-24T10:46:04+01:00
New Revision: 97bd44f436ea81381d14aa108363941ecb82f544

URL: https://github.com/llvm/llvm-project/commit/97bd44f436ea81381d14aa108363941ecb82f544
DIFF: https://github.com/llvm/llvm-project/commit/97bd44f436ea81381d14aa108363941ecb82f544.diff

LOG: [llvm-exegesis] getNonRedundantWriteProcRes - perform basic toplogical sorting (PR58500)

getNonRedundantWriteProcRes was assuming that tblgen topologically sorted the cpu ModelProcResources[] arrays so that resource units were declared before the resource groups that used them, but unfortunately that doesn't appear to be true - in most cases it was just getting lucky based off the alphanumeric sorting that was being performed and the choice of the resource pipe names in most scheduler models (Intel models in particular).

This patch adds an explicit sort, based off llvm-mca's initializeUsedResources, that sorts by resource mask - I'm hoping this basic sorting is enough, I don't think overlapping groups or Super resources are a problem.

I'd like to take this further in the future and start sharing more code between llvm-mca and llvm-exegesis - while triaging this bug I saw how similar both approaches are, but are just dissimilar enough that any refactor isn't going to be trivial :(

Working with @courbet on a follow up unit test

Fixes #58500
Fixes #37045

Differential Revision: https://reviews.llvm.org/D136351

Added: 
    

Modified: 
    llvm/tools/llvm-exegesis/lib/CMakeLists.txt
    llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
index 922162f77d60c..c92b6ab42acf8 100644
--- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
+++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
@@ -26,6 +26,7 @@ set(LLVM_LINK_COMPONENTS
   ExecutionEngine
   GlobalISel
   MC
+  MCA
   MCDisassembler
   MCJIT
   MCParser

diff  --git a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
index 03386cf2384f8..024e511ce7ea4 100644
--- a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
@@ -10,6 +10,7 @@
 #include "BenchmarkResult.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MCA/Support.h"
 #include "llvm/Support/FormatVariadic.h"
 #include <limits>
 #include <unordered_set>
@@ -45,7 +46,7 @@ namespace exegesis {
 //
 // Note that in this case, P016 does not contribute any cycles, so it would
 // be removed by this function.
-// FIXME: Move this to MCSubtargetInfo and use it in llvm-mca.
+// FIXME: Merge this with the equivalent in llvm-mca.
 static SmallVector<MCWriteProcResEntry, 8>
 getNonRedundantWriteProcRes(const MCSchedClassDesc &SCDesc,
                             const MCSubtargetInfo &STI) {
@@ -53,12 +54,33 @@ getNonRedundantWriteProcRes(const MCSchedClassDesc &SCDesc,
   const auto &SM = STI.getSchedModel();
   const unsigned NumProcRes = SM.getNumProcResourceKinds();
 
-  // This assumes that the ProcResDescs are sorted in topological order, which
-  // is guaranteed by the tablegen backend.
-  SmallVector<float, 32> ProcResUnitUsage(NumProcRes);
+  // Collect resource masks.
+  SmallVector<uint64_t> ProcResourceMasks(NumProcRes);
+  mca::computeProcResourceMasks(SM, ProcResourceMasks);
+
+  // Sort entries by smaller resources for (basic) topological ordering.
+  using ResourceMaskAndEntry = std::pair<uint64_t, const MCWriteProcResEntry *>;
+  SmallVector<ResourceMaskAndEntry, 8> ResourceMaskAndEntries;
   for (const auto *WPR = STI.getWriteProcResBegin(&SCDesc),
                   *const WPREnd = STI.getWriteProcResEnd(&SCDesc);
        WPR != WPREnd; ++WPR) {
+    uint64_t Mask = ProcResourceMasks[WPR->ProcResourceIdx];
+    ResourceMaskAndEntries.push_back({Mask, WPR});
+  }
+  sort(ResourceMaskAndEntries,
+       [](const ResourceMaskAndEntry &A, const ResourceMaskAndEntry &B) {
+         unsigned popcntA = countPopulation(A.first);
+         unsigned popcntB = countPopulation(B.first);
+         if (popcntA < popcntB)
+           return true;
+         if (popcntA > popcntB)
+           return false;
+         return A.first < B.first;
+       });
+
+  SmallVector<float, 32> ProcResUnitUsage(NumProcRes);
+  for (const ResourceMaskAndEntry &Entry : ResourceMaskAndEntries) {
+    const MCWriteProcResEntry *WPR = Entry.second;
     const MCProcResourceDesc *const ProcResDesc =
         SM.getProcResource(WPR->ProcResourceIdx);
     if (ProcResDesc->SubUnitsIdxBegin == nullptr) {


        


More information about the llvm-commits mailing list