From e1e86d0db61c45d8914d39cf8076094dfa2ec266 Mon Sep 17 00:00:00 2001 From: Vijay Sundaresan Date: Mon, 27 Jan 2025 10:45:36 -0500 Subject: [PATCH] Add env vars to experiment with large method heuristic The two callers of isLargeCompiledMethod appear to be inconsistent with the "size" that gets passed in. In one case, the size is the estimated call graph size, whereas in the other case, the size is just the bytecode size. This commit changes isLargeCompiledMethod such that the thresholds to compare against are refactored out and passed in from the caller side, thus allowing different thresholds to be used from the two callers. New env vars have been introduced to do some experiments with passing in different size thresholds, though in principle, we could also vary the other thresholds being passed in at each caller. Signed-off-by: Vijay Sundaresan --- .../compiler/optimizer/InlinerTempForJ9.cpp | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/runtime/compiler/optimizer/InlinerTempForJ9.cpp b/runtime/compiler/optimizer/InlinerTempForJ9.cpp index d5187b6d8e7..0091e872c5d 100644 --- a/runtime/compiler/optimizer/InlinerTempForJ9.cpp +++ b/runtime/compiler/optimizer/InlinerTempForJ9.cpp @@ -4288,8 +4288,19 @@ void TR_MultipleCallTargetInliner::weighCallSite( TR_CallStack * callStack , TR_ if (size > 0) { + int32_t exemptionFreqCutoff = comp()->getOptions()->getLargeCompiledMethodExemptionFreqCutoff(); + int32_t veryLargeCompiledMethodThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodThreshold(); + int32_t veryLargeCompiledMethodFaninThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodFaninThreshold(); + + static const char *cmt = feGetEnv("TR_CompiledMethodCallGraphThreshold"); + if (cmt) + { + static const int32_t callGraphSizeBasedThreshold = atoi(cmt); + veryLargeCompiledMethodThreshold = callGraphSizeBasedThreshold; + } + bool largeCompiledCallee = !comp()->getOption(TR_InlineVeryLargeCompiledMethods) && - isLargeCompiledMethod(calltarget->_calleeMethod, size, frequency2); + isLargeCompiledMethod(calltarget->_calleeMethod, size, frequency2, exemptionFreqCutoff, veryLargeCompiledMethodThreshold, veryLargeCompiledMethodFaninThreshold); if (largeCompiledCallee) { size = size*TR::Options::_inlinerVeryLargeCompiledMethodAdjustFactor; @@ -4650,8 +4661,19 @@ int32_t TR_MultipleCallTargetInliner::scaleSizeBasedOnBlockFrequency(int32_t byt { int32_t maxFrequency = MAX_BLOCK_COUNT + MAX_COLD_BLOCK_COUNT; + int32_t exemptionFreqCutoff = comp()->getOptions()->getLargeCompiledMethodExemptionFreqCutoff(); + int32_t veryLargeCompiledMethodThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodThreshold(); + int32_t veryLargeCompiledMethodFaninThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodFaninThreshold(); + + static const char *bcmt = feGetEnv("TR_CompiledMethodByteCodeThreshold"); + if (bcmt) + { + static const int32_t byteCodeSizeBasedThreshold = atoi(bcmt); + veryLargeCompiledMethodThreshold = byteCodeSizeBasedThreshold; + } + bool largeCompiledCallee = !comp()->getOption(TR_InlineVeryLargeCompiledMethods) && - isLargeCompiledMethod(calleeResolvedMethod, bytecodeSize, frequency); + isLargeCompiledMethod(calleeResolvedMethod, bytecodeSize, frequency, exemptionFreqCutoff, veryLargeCompiledMethodThreshold, veryLargeCompiledMethodFaninThreshold); if (largeCompiledCallee) { bytecodeSize = bytecodeSize * TR::Options::_inlinerVeryLargeCompiledMethodAdjustFactor; @@ -4690,7 +4712,7 @@ int32_t TR_MultipleCallTargetInliner::scaleSizeBasedOnBlockFrequency(int32_t byt } -bool TR_MultipleCallTargetInliner::isLargeCompiledMethod(TR_ResolvedMethod *calleeResolvedMethod, int32_t bytecodeSize, int32_t callerBlockFrequency) +bool TR_MultipleCallTargetInliner::isLargeCompiledMethod(TR_ResolvedMethod *calleeResolvedMethod, int32_t bytecodeSize, int32_t callerBlockFrequency, int32_t exemptionFreqCutoff, int32_t veryLargeCompiledMethodThreshold, int32_t veryLargeCompiledMethodFaninThreshold) { TR_OpaqueMethodBlock* methodCallee = calleeResolvedMethod->getPersistentIdentifier(); if (!calleeResolvedMethod->isInterpreted()) @@ -4708,15 +4730,13 @@ bool TR_MultipleCallTargetInliner::isLargeCompiledMethod(TR_ResolvedMethod *call } // Allow inlining of big methods into high frequency blocks - if (callerBlockFrequency > comp()->getOptions()->getLargeCompiledMethodExemptionFreqCutoff()) + if (callerBlockFrequency > exemptionFreqCutoff) return false; - int32_t veryLargeCompiledMethodThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodThreshold(); - int32_t veryLargeCompiledMethodFaninThreshold = comp()->getOptions()->getInlinerVeryLargeCompiledMethodFaninThreshold(); // Subdue inliner in low frequency blocks if (callerBlockFrequency > 0) { - if ((2 * callerBlockFrequency) < comp()->getOptions()->getLargeCompiledMethodExemptionFreqCutoff()) + if ((2 * callerBlockFrequency) < exemptionFreqCutoff) { veryLargeCompiledMethodThreshold = 100; veryLargeCompiledMethodFaninThreshold = 0;