Skip to content

Commit

Permalink
Refactor prex arg info computation and propagation
Browse files Browse the repository at this point in the history
Part of an effort to refactor prex arg info. This commit contains the
following changes:

- Move two TR_PrexArgInfo functions from OpenJ9 to OMR such that we can
merge prex arg infos in OMR.
- When creating prex arg info for a target, propagate arg info from call
site.
- Add an inliner util to clear arg info for variant argument given a
prex arg info
- `computePrexInfo` will not assume storing the result to `_prexArgInfo`
of a target, instead, the user will take the result and store it to the
place they want.

Part of eclipse-openj9/openj9#11584

Signed-off-by: Liqun Liu <liqunl@ca.ibm.com>
  • Loading branch information
Liqun Liu committed Jan 11, 2021
1 parent 13926a7 commit 71d22eb
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 30 deletions.
67 changes: 47 additions & 20 deletions compiler/optimizer/Inliner.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -1146,7 +1146,8 @@ TR_InlineCall::inlineCall(TR::TreeTop * callNodeTreeTop, TR_OpaqueClassBlock * t
if (comp()->trace(OMR::inlining))
traceMsg(comp(), "inliner: Setting current inline depth=%d\n", currentInlineDepth);

calltarget->_prexArgInfo = new (trHeapMemory()) TR_PrexArgInfo(calltarget->_myCallSite->_callNode->getNumArguments(), trMemory());
TR_PrexArgInfo *callerArgInfo = comp()->getCurrentInlinedCallArgInfo();
calltarget->_prexArgInfo = getUtil()->computePrexInfo(calltarget, callerArgInfo);

// this is called on a case-by-case basis, and can get repeatedly called for recursive
// methods triggering a loop. Unfortunately the callStack is not pervasive
Expand Down Expand Up @@ -2362,7 +2363,7 @@ TR_ParameterToArgumentMapper::initialize(TR_CallStack *callStack)
TR::SymbolReference * symRef = NULL;
const static bool disableUseKnownObjectTempsForParms = feGetEnv("TR_DisableUseKnownObjectTempsForParmsInCallee") ? true: false;
int argOrdinal = argIndex - _callNode->getFirstArgumentIndex();
TR_PrexArgument * prexArgument = _argInfo->get(argOrdinal);
TR_PrexArgument * prexArgument = _argInfo ? _argInfo->get(argOrdinal) : NULL;
// use known object temp if the argument is a known object
if (!disableUseKnownObjectTempsForParms && prexArgument
&& !parmMap->_parmIsModified
Expand Down Expand Up @@ -4600,7 +4601,8 @@ void TR_InlinerBase::inlineFromGraph(TR_CallStack *prevCallStack, TR_CallTarget
for (int32_t i = 0; i < site->numTargets(); i++)
{
TR_CallTarget *target = site->getTarget(i);
getUtil()->computePrexInfo(target, calltarget->_prexArgInfo);
// Compute arg info for target to inline, and propagate caller's arg info into callee
target->_prexArgInfo = getUtil()->computePrexInfo(target, calltarget->_prexArgInfo);
targetsToInline.add(target);
}
}
Expand Down Expand Up @@ -5688,6 +5690,17 @@ TR_CallSite::addTarget(TR_Memory* mem, TR_InlinerBase *inliner, TR_VirtualGuardS
{
TR_PrexArgInfo *myPrexArgInfo = inliner->getUtil()->createPrexArgInfoForCallTarget(guard, implementer);

// Merge call site prex arginfo into `myPrexArgInfo`
if (myPrexArgInfo && _ecsPrexArgInfo)
{
TR_PrexArgInfo::enhance(myPrexArgInfo, _ecsPrexArgInfo, _comp);
}
else if (_ecsPrexArgInfo)
{
// Clone call site prex arg info
myPrexArgInfo = new (comp()->trHeapMemory()) TR_PrexArgInfo(_ecsPrexArgInfo, comp()->trMemory());
}

TR_CallTarget *result = new (mem,allocKind) TR_CallTarget(this,_initialCalleeSymbol,implementer,guard,receiverClass,myPrexArgInfo,ratio);

addTarget(result);
Expand Down Expand Up @@ -6365,15 +6378,9 @@ OMR_InlinerUtil::computePrexInfo(TR_CallTarget *target, TR_PrexArgInfo *callerAr
/**
* \brief
* Clear non-invariant argument arg info for target
*
* \parm target
* Call target whose arg info is to be cleared for non-invariant arguments
*
* \parm tracer
* Inliner tracer used for trace message
*/
void
OMR_InlinerUtil::clearArgInfoForNonInvariantArguments(TR_CallTarget *target, TR_InlinerTracer* tracer)
OMR_InlinerUtil::clearArgInfoForNonInvariantArguments(TR_PrexArgInfo* argInfo, TR::ResolvedMethodSymbol* methodSymbol, TR_InlinerTracer* tracer)
{
if (comp()->getOption(TR_DisableInlinerArgsPropagation))
return;
Expand All @@ -6382,13 +6389,12 @@ OMR_InlinerUtil::clearArgInfoForNonInvariantArguments(TR_CallTarget *target, TR_
if (tracePrex)
traceMsg(comp(), "Clearing arg info for non invariant arguments\n");

TR::ResolvedMethodSymbol* methodSymbol = target->_calleeSymbol;
TR_ASSERT(argInfo, "argInfo can't be NULL");
TR_ASSERT(methodSymbol, "methodSymbol can't be NULL");

TR_PrexArgInfo* argInfo = target->_prexArgInfo;
if (!argInfo)
if (!methodSymbol->getFirstTreeTop() && tracePrex)
{
if (tracePrex)
traceMsg(comp(), "Prex arg info not avaiable\n");
traceMsg(comp(), "IL trees are not generated for method, no arg info is cleared\n");
return;
}

Expand Down Expand Up @@ -6426,15 +6432,36 @@ OMR_InlinerUtil::clearArgInfoForNonInvariantArguments(TR_CallTarget *target, TR_
}
}

if (cleanedAnything)
if (tracePrex)
{
if (tracePrex)
if (cleanedAnything)
{
traceMsg(comp(), "ARGS PROPAGATION: argInfo %p after clear arg info for non-invariant arguments", argInfo);
if (tracer->heuristicLevel())
argInfo->dumpTrace();
if (tracer->heuristicLevel())
argInfo->dumpTrace();
}
else
traceMsg(comp(), "ARGS PROPAGATION: Nothing is cleared\n");
}
}

/**
* \brief
* Clear non-invariant argument arg info for target
*
* \parm target
* Call target whose arg info is to be cleared for non-invariant arguments
*
* \parm tracer
* Inliner tracer used for trace message
*/
void
OMR_InlinerUtil::clearArgInfoForNonInvariantArguments(TR_CallTarget *target, TR_InlinerTracer* tracer)
{
if (target->_prexArgInfo)
clearArgInfoForNonInvariantArguments(target->_prexArgInfo, target->_calleeSymbol, tracer);
}

bool
OMR_InlinerUtil::needTargetedInlining(TR::ResolvedMethodSymbol *callee)
{
Expand Down
3 changes: 2 additions & 1 deletion compiler/optimizer/Inliner.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -554,6 +554,7 @@ class OMR_InlinerUtil : public TR::OptimizationUtil, public OMR_InlinerHelper
virtual TR_PrexArgInfo *computePrexInfo(TR_CallTarget *target);
virtual TR_PrexArgInfo *computePrexInfo(TR_CallTarget *target, TR_PrexArgInfo *callerArgInfo);
virtual void clearArgInfoForNonInvariantArguments(TR_CallTarget *target, TR_InlinerTracer* tracer);
virtual void clearArgInfoForNonInvariantArguments(TR_PrexArgInfo* argInfo, TR::ResolvedMethodSymbol* methodSymbol, TR_InlinerTracer* tracer);
virtual void collectCalleeMethodClassInfo(TR_ResolvedMethod *calleeMethod);
/*
* Implemented by down stream projects to request for certain optimizations based on \parm target
Expand Down
73 changes: 66 additions & 7 deletions compiler/optimizer/PreExistence.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -54,13 +54,17 @@ TR_PrexArgument::TR_PrexArgument(
_knownObjectIndex(knownObjectIndex)
{
#ifdef J9_PROJECT_SPECIFIC
TR::VMAccessCriticalSection prexArgumentCriticalSection(comp,
TR::VMAccessCriticalSection::tryToAcquireVMAccess);

if (prexArgumentCriticalSection.hasVMAccess())
auto knot = comp->getKnownObjectTable();
if (knot && !knot->isNull(knownObjectIndex))
{
_class = TR::Compiler->cls.objectClass(comp, comp->getKnownObjectTable()->getPointer(knownObjectIndex));
_classKind = ClassIsFixed;
TR::VMAccessCriticalSection prexArgumentCriticalSection(comp,
TR::VMAccessCriticalSection::tryToAcquireVMAccess);

if (prexArgumentCriticalSection.hasVMAccess())
{
_class = TR::Compiler->cls.objectClass(comp, comp->getKnownObjectTable()->getPointer(knownObjectIndex));
_classKind = ClassIsFixed;
}
}
#endif
}
Expand All @@ -84,3 +88,58 @@ void TR_PrexArgInfo::dumpTrace() {
}
traceMsg(comp, "</argInfo>\n");
}

/**
* \brief
* Given two `TR_PrexArgument`, return the one with more concrete argument info
*/
static TR_PrexArgument *strongerArgumentInfo(TR_PrexArgument *left, TR_PrexArgument *right, TR::Compilation *comp)
{
if (TR_PrexArgument::knowledgeLevel(left) > TR_PrexArgument::knowledgeLevel(right))
return left;
else if (TR_PrexArgument::knowledgeLevel(right) > TR_PrexArgument::knowledgeLevel(left))
return right;
else if (left && right)
{
if (left->getClass() && right->getClass())
{
if (comp->fe()->isInstanceOf(left->getClass(), right->getClass(), true, true, false))
return left;
else if (comp->fe()->isInstanceOf(right->getClass(), left->getClass(), true, true, false))
return right;
}
else if (left->getClass())
return left;
else if (right->getClass())
return right;

return NULL;
}
else
return left ? left : right; // Return non-null prex argument when possible
}

TR_PrexArgInfo *
TR_PrexArgInfo::enhance(TR_PrexArgInfo *dest, TR_PrexArgInfo *source, TR::Compilation *comp)
{
// If dest is NULL, we can't simply return source, as TR_PrexArgInfo is mutable, any
// future change to dest will change source. Thus return a copy of source
//
if (!dest && source)
return new (comp->trHeapMemory()) TR_PrexArgInfo(source, comp->trMemory());
else if (!source)
return dest;

TR_ASSERT(dest->getNumArgs() == source->getNumArgs(), "Number of arguments don't match: dest %p %d arguments and source %p %d arguments", dest, dest->getNumArgs(), source, source->getNumArgs());

auto numArgsToEnhance = dest->getNumArgs();
for (int32_t i = 0; i < numArgsToEnhance; i++)
{
TR_PrexArgument* result = strongerArgumentInfo(dest->get(i), source->get(i), comp);
if (result)
dest->set(i, result);
}

return dest;
}

22 changes: 20 additions & 2 deletions compiler/optimizer/PreExistence.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -34,6 +34,7 @@ class TR_OpaqueClassBlock;
class TR_VirtualGuard;
namespace TR { class Compilation; }
namespace TR { class Node; }
namespace TR { class TreeTop; }
namespace TR { class ResolvedMethodSymbol; }

enum PrexKnowledgeLevel { NONE, PREEXISTENT, FIXED_CLASS, KNOWN_OBJECT };
Expand Down Expand Up @@ -106,8 +107,15 @@ class TR_PrexArgInfo
{
public:

#ifdef J9_PROJECT_SPECIFIC
/**
* \brief
* Improve prex arg info `dest` with `source`
*
* \return
* TR_PrexArgInfo The improved prex arg info
*/
static TR_PrexArgInfo* enhance(TR_PrexArgInfo *dest, TR_PrexArgInfo *source, TR::Compilation *comp);
#ifdef J9_PROJECT_SPECIFIC

static void propagateReceiverInfoIfAvailable (TR::ResolvedMethodSymbol* methodSymbol, TR_CallSite* callsite,
TR_PrexArgInfo* argInfo, TR_LogTracer* tracer);
Expand Down Expand Up @@ -136,12 +144,22 @@ class TR_PrexArgInfo
memset(_args, 0, sizeof(TR_PrexArgument*) * numArgs);
}

// Construct TR_PrexArgInfo from another TR_PrexArgInfo
TR_PrexArgInfo(TR_PrexArgInfo* other, TR_Memory * m)
{
TR_ASSERT(other, "other can't be NULL");
_numArgs = other->_numArgs;
_args = (TR_PrexArgument **) m->allocateHeapMemory(sizeof(TR_PrexArgument*) * _numArgs);
memcpy(_args, other->_args, sizeof(TR_PrexArgument*) * _numArgs);
}

void set(int32_t index, TR_PrexArgument *info) { _args[index] = info; }
TR_PrexArgument *get(int32_t index) { return _args[index]; }

int32_t getNumArgs() { return _numArgs; }

void dumpTrace();
static TR::TreeTop* getCallTree(TR::ResolvedMethodSymbol* methodSymbol, TR_CallSite* callsite, TR_LogTracer* tracer);

private:

Expand Down

0 comments on commit 71d22eb

Please sign in to comment.