Skip to content

Commit

Permalink
Add env vars to experiment with large method heuristic
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
vijaysun-omr committed Jan 27, 2025
1 parent 24f5138 commit b3b21aa
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
34 changes: 27 additions & 7 deletions runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/optimizer/J9Inliner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class TR_MultipleCallTargetInliner : public TR_InlinerBase
int32_t applyArgumentHeuristics(TR_LinkHead<TR_ParameterMapping> &map, int32_t originalWeight, TR_CallTarget *target);
bool eliminateTailRecursion(TR::ResolvedMethodSymbol *, TR_CallStack *, TR::TreeTop *, TR::Node *, TR::Node *, TR_VirtualGuardSelection *);
void assignArgumentsToParameters(TR::ResolvedMethodSymbol *, TR::TreeTop *, TR::Node *);
bool isLargeCompiledMethod(TR_ResolvedMethod *calleeResolvedMethod, int32_t bytecodeSize, int32_t freq);
bool isLargeCompiledMethod(TR_ResolvedMethod *calleeResolvedMethod, int32_t bytecodeSize, int32_t freq, int32_t exemptionFreqCutoff, int32_t veryLargeCompiledMethodThreshold, int32_t veryLargeCompiledMethodFaninThreshold);
/* \brief
* This API processes the call targets got chopped off from \ref _calltargets
*
Expand Down

0 comments on commit b3b21aa

Please sign in to comment.