From 87d6bbaa59aeeb9bfdca08a01e12bd87e4f2fbdd Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Fri, 26 May 2023 21:39:48 +0200 Subject: [PATCH] JIT: Pick some low-hanging fruit in physical promotion throughput (#86792) * Skip any IR traversals entirely if there are no candidates locals for physical promotion * During accounting, do a quick pre-check for candidates in each statement using the linked locals list, before doing the tree walk. Result: ``` Collection PDIFF aspnet.run.windows.x64.checked.mch -0.59% benchmarks.run.windows.x64.checked.mch -0.65% benchmarks.run_pgo.windows.x64.checked.mch -0.65% benchmarks.run_tiered.windows.x64.checked.mch -0.65% coreclr_tests.run.windows.x64.checked.mch -0.66% libraries.crossgen2.windows.x64.checked.mch -0.61% libraries.pmi.windows.x64.checked.mch -0.63% libraries_tests.pmi.windows.x64.checked.mch -0.68% ``` --- src/coreclr/jit/promotion.cpp | 45 ++++++++++++++++++++++++++++++++++++++++--- src/coreclr/jit/promotion.h | 4 ++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/promotion.cpp b/src/coreclr/jit/promotion.cpp index 5aa4bb2..f2f32da 100644 --- a/src/coreclr/jit/promotion.cpp +++ b/src/coreclr/jit/promotion.cpp @@ -573,7 +573,7 @@ public: { GenTreeLclVarCommon* lcl = tree->AsLclVarCommon(); LclVarDsc* dsc = m_compiler->lvaGetDesc(lcl); - if (!dsc->lvPromoted && (dsc->TypeGet() == TYP_STRUCT) && !dsc->IsAddressExposed()) + if (Promotion::IsCandidateForPhysicalPromotion(dsc)) { var_types accessType; ClassLayout* accessLayout; @@ -1665,7 +1665,7 @@ bool ReplaceVisitor::MarkForReadBack(unsigned lcl, unsigned offs, unsigned size) // PhaseStatus Promotion::Run() { - if (m_compiler->lvaCount <= 0) + if (!HaveCandidateLocals()) { return PhaseStatus::MODIFIED_NOTHING; } @@ -1678,7 +1678,14 @@ PhaseStatus Promotion::Run() for (Statement* stmt : bb->Statements()) { - localsUse.WalkTree(stmt->GetRootNodePointer(), nullptr); + for (GenTreeLclVarCommon* lcl : stmt->LocalsTreeList()) + { + if (Promotion::IsCandidateForPhysicalPromotion(m_compiler->lvaGetDesc(lcl))) + { + localsUse.WalkTree(stmt->GetRootNodePointer(), nullptr); + break; + } + } } } @@ -1818,6 +1825,38 @@ PhaseStatus Promotion::Run() } //------------------------------------------------------------------------ +// Promotion::HaveCandidateLocals: +// Check if there are any locals that are candidates for physical promotion. +// +// Returns: +// True if so. +// +bool Promotion::HaveCandidateLocals() +{ + for (unsigned lclNum = 0; lclNum < m_compiler->lvaCount; lclNum++) + { + if (IsCandidateForPhysicalPromotion(m_compiler->lvaGetDesc(lclNum))) + { + return true; + } + } + + return false; +} + +//------------------------------------------------------------------------ +// Promotion::IsCandidateForPhysicalPromotion: +// Check if a specified local is a candidate for physical promotion. +// +// Returns: +// True if so. +// +bool Promotion::IsCandidateForPhysicalPromotion(LclVarDsc* dsc) +{ + return (dsc->TypeGet() == TYP_STRUCT) && !dsc->lvPromoted && !dsc->IsAddressExposed(); +} + +//------------------------------------------------------------------------ // Promotion::InsertInitialReadBack: // Insert IR to initially read a struct local's value into its promoted field locals. // diff --git a/src/coreclr/jit/promotion.h b/src/coreclr/jit/promotion.h index 7f64613..24ebffe 100644 --- a/src/coreclr/jit/promotion.h +++ b/src/coreclr/jit/promotion.h @@ -169,6 +169,10 @@ class Promotion return ~min; } + bool HaveCandidateLocals(); + + static bool IsCandidateForPhysicalPromotion(LclVarDsc* dsc); + public: explicit Promotion(Compiler* compiler) : m_compiler(compiler) { -- 2.7.4