diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -26,6 +26,7 @@ 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 --- 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 #include @@ -45,7 +46,7 @@ // // 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 getNonRedundantWriteProcRes(const MCSchedClassDesc &SCDesc, const MCSubtargetInfo &STI) { @@ -53,12 +54,33 @@ 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 ProcResUnitUsage(NumProcRes); + // Collect resource masks. + SmallVector ProcResourceMasks(NumProcRes); + mca::computeProcResourceMasks(SM, ProcResourceMasks); + + // Sort entries by smaller resources for (basic) topological ordering. + using ResourceMaskAndEntry = std::pair; + SmallVector 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 ProcResUnitUsage(NumProcRes); + for (const ResourceMaskAndEntry &Entry : ResourceMaskAndEntries) { + const MCWriteProcResEntry *WPR = Entry.second; const MCProcResourceDesc *const ProcResDesc = SM.getProcResource(WPR->ProcResourceIdx); if (ProcResDesc->SubUnitsIdxBegin == nullptr) {