From a70253443303a2cf9957a199eca4fc8a06dfae87 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 9 Feb 2023 12:17:48 -0800 Subject: [PATCH] JIT: add option to use interlocked add for PGO edge count updates Mainly intended for use in determining what is leading to some consistency issues with our current edge profiles. We might consider enabling this in some of our static PGO collections. Enabled via JitInterlockedProfile=1. --- src/coreclr/jit/fgprofile.cpp | 34 +++++++++++++++++++++++-------- src/coreclr/jit/jitconfigvalues.h | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index d50a0f1b7b7e12..16f5f8a92dd6bb 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -1716,18 +1716,34 @@ void EfficientEdgeCountInstrumentor::Instrument(BasicBlock* block, Schema& schem var_types typ = entry.InstrumentationKind == ICorJitInfo::PgoInstrumentationKind::EdgeIntCount ? TYP_INT : TYP_LONG; - // Read Basic-Block count value - GenTree* valueNode = - m_comp->gtNewIndOfIconHandleNode(typ, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); - // Increment value by 1 - GenTree* rhsNode = m_comp->gtNewOperNode(GT_ADD, typ, valueNode, m_comp->gtNewIconNode(1, typ)); + if (JitConfig.JitInterlockedProfiling() > 0) + { + // Form counter address + GenTree* addressNode = m_comp->gtNewIconHandleNode(addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR); + + // Interlocked increment + GenTree* xAddNode = m_comp->gtNewOperNode(GT_XADD, typ, addressNode, m_comp->gtNewIconNode(1, typ)); + + // Ignore result. + m_comp->fgNewStmtAtBeg(instrumentedBlock, xAddNode); + } + else + { + // Read Basic-Block count value + GenTree* valueNode = + m_comp->gtNewIndOfIconHandleNode(typ, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); - // Write new Basic-Block count value - GenTree* lhsNode = m_comp->gtNewIndOfIconHandleNode(typ, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); - GenTree* asgNode = m_comp->gtNewAssignNode(lhsNode, rhsNode); + // Increment value by 1 + GenTree* rhsNode = m_comp->gtNewOperNode(GT_ADD, typ, valueNode, m_comp->gtNewIconNode(1, typ)); - m_comp->fgNewStmtAtBeg(instrumentedBlock, asgNode); + // Write new Basic-Block count value + GenTree* lhsNode = + m_comp->gtNewIndOfIconHandleNode(typ, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); + GenTree* asgNode = m_comp->gtNewAssignNode(lhsNode, rhsNode); + + m_comp->fgNewStmtAtBeg(instrumentedBlock, asgNode); + } if (probe->kind != EdgeKind::Duplicate) { diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index edc9ccdb1bd172..484241a306e87a 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -567,6 +567,7 @@ CONFIG_STRING(JitEnablePatchpointRange, W("JitEnablePatchpointRange")) #endif // Profile instrumentation options +CONFIG_INTEGER(JitInterlockedProfiling, W("JitInterlockedProfiling"), 0) CONFIG_INTEGER(JitMinimalJitProfiling, W("JitMinimalJitProfiling"), 1) CONFIG_INTEGER(JitMinimalPrejitProfiling, W("JitMinimalPrejitProfiling"), 0)