Skip to content

Commit

Permalink
Merge pull request #13442 from gita-omr/pr_mixed_mode
Browse files Browse the repository at this point in the history
  • Loading branch information
fjeremic committed Sep 3, 2021
2 parents 3c4cb51 + 93b06ef commit b4f9d6e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 36 deletions.
148 changes: 117 additions & 31 deletions runtime/compiler/optimizer/VectorAPIExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,16 +284,50 @@ TR_VectorAPIExpansion::visitNodeToBuildVectorAliases(TR::Node *node)
// check if VectorAPI method is supported
TR::RecognizedMethod index = methodSymbol->getRecognizedMethod();
int handlerIndex = index - _firstMethod;
//TODO: support mode per class

if (methodElementType == TR::NoType ||
methodNumLanes == 0 ||
!methodTable[handlerIndex]._methodHandler(this, NULL, node, methodElementType, methodNumLanes, defaultCheckMode))
methodNumLanes == 0)
{
if (_trace)
traceMsg(comp(), "Invalidating #%d due to unsupported elementType=%d, numLanes=%d, or opcode in node %p\n",
traceMsg(comp(), "Invalidating #%d due to unknown elementType=%d, numLanes=%d in node %p\n",
node->getSymbolReference()->getReferenceNumber(), (int)methodElementType, methodNumLanes, node);
invalidateSymRef(node->getSymbolReference());
}
else
{
int32_t elementSize = OMR::DataType::getSize(methodElementType);
vec_sz_t vectorLength = methodNumLanes*8*elementSize;

bool canVectorize = methodTable[handlerIndex]._methodHandler(this, NULL, node, methodElementType, vectorLength,
checkVectorization);
bool canScalarize = methodTable[handlerIndex]._methodHandler(this, NULL, node, methodElementType, vectorLength,
checkScalarization);
if (!canVectorize)
{
if (_trace)
traceMsg(comp(), "Can't vectorize #%d due to unsupported opcode in node %p\n",
node->getSymbolReference()->getReferenceNumber(), node);

_aliasTable[methodRefNum]._cantVectorize = true;

if (!canScalarize)
{
_aliasTable[methodRefNum]._cantScalarize = true;
if (_trace)
traceMsg(comp(), "Invalidating #%d due to unsupported opcode in node %p\n",
node->getSymbolReference()->getReferenceNumber(), node);
invalidateSymRef(node->getSymbolReference());
}
}
else if (!canScalarize)
{
if (_trace)
traceMsg(comp(), "Can't scalarize #%d due to unsupported opcode in node %p\n",
node->getSymbolReference()->getReferenceNumber(), node);

_aliasTable[methodRefNum]._cantScalarize = true;
}
}
}
else if (opCode.isLoadAddr())
{
Expand Down Expand Up @@ -602,6 +636,21 @@ TR_VectorAPIExpansion::validateVectorAliasClasses()
vectorClass = validateSymRef(id, i, classLength, classType);
if (!vectorClass)
break;

if (_aliasTable[i]._cantVectorize)
{
if (_trace)
traceMsg(comp(), "Class #%d can't be vectorized due to #%d\n", id, i);

_aliasTable[id]._cantVectorize = true;
}

if (_aliasTable[i]._cantScalarize)
{
if (_trace)
traceMsg(comp(), "Class #%d can't be scalarized due to #%d\n", id, i);
_aliasTable[id]._cantScalarize = true;
}
}
}

Expand Down Expand Up @@ -684,13 +733,27 @@ TR_VectorAPIExpansion::expandVectorAPI()
if (_aliasTable[classId]._classId == -1) // class was invalidated
continue;

handlerMode checkMode = checkVectorization;
handlerMode doMode = doVectorization;

if (_aliasTable[classId]._cantVectorize)
{
TR_ASSERT_FATAL(!_aliasTable[classId]._cantScalarize, "Class %d should be either vectorizable or scalarizable",
classId);
checkMode = checkScalarization;
doMode = doScalarization;
}

if (!_seenClasses.isSet(classId))
{
_seenClasses.set(classId);

//printf("Expanding class %d in %s\n", classId, comp()->signature());

if (!performTransformation(comp(), "%s Starting to transform class #%d\n", optDetailString(), classId))
//printf("%s Starting to %s class #%d\n", optDetailString(), doMode == doVectorization ? "vectorize" : "scalarize", classId);

if (!performTransformation(comp(), "%s Starting to %s class #%d\n", optDetailString(),
doMode == doVectorization ? "vectorize" : "scalarize",
classId))
{
_aliasTable[classId]._classId = -1; // invalidate the whole class
continue;
Expand All @@ -703,10 +766,6 @@ TR_VectorAPIExpansion::expandVectorAPI()
TR::DataType elementType = _aliasTable[classId]._elementType;
int32_t vectorLength = _aliasTable[classId]._vecLen;

// TODO: make it per class
handlerMode checkMode = defaultCheckMode;
handlerMode doMode = defaultDoMode;

if (opCodeValue == TR::astore)
{
if (_trace)
Expand Down Expand Up @@ -989,7 +1048,8 @@ TR::Node *TR_VectorAPIExpansion::fromArrayHandler(TR_VectorAPIExpansion *opt, TR
TR::Compilation *comp = opt->comp();

if (mode == checkScalarization) return node;
if (mode == checkVectorization) return node;
if (mode == checkVectorization)
return supportedOnPlatform(comp, vectorLength) ? node : NULL;

if (opt->_trace)
traceMsg(comp, "fromArrayHandler for node %p\n", node);
Expand All @@ -1009,7 +1069,8 @@ TR::Node *TR_VectorAPIExpansion::intoArrayHandler(TR_VectorAPIExpansion *opt, TR
TR::Compilation *comp = opt->comp();

if (mode == checkScalarization) return node;
if (mode == checkVectorization) return node;
if (mode == checkVectorization)
return supportedOnPlatform(comp, vectorLength) ? node : NULL;

if (opt->_trace)
traceMsg(comp, "intoArrayHandler for node %p\n", node);
Expand All @@ -1027,10 +1088,15 @@ TR::Node *TR_VectorAPIExpansion::intoArrayHandler(TR_VectorAPIExpansion *opt, TR
TR::Node *TR_VectorAPIExpansion::addHandler(TR_VectorAPIExpansion *opt, TR::TreeTop *treeTop, TR::Node *node,
TR::DataType elementType, vec_sz_t vectorLength, handlerMode mode)
{
// This handler is not for intrinsic and is currently disabled

TR::Compilation *comp = opt->comp();

if (mode == checkScalarization) return node;
if (mode == checkVectorization) return NULL; // TODO: check type and platform
if (mode == checkVectorization)
return supportedOnPlatform(comp, vectorLength) ? node : NULL;

// TODO: The above does not check the actual opcode and type

if (opt->_trace)
traceMsg(comp, "addHandler for node %p\n", node);
Expand All @@ -1050,7 +1116,8 @@ TR::Node *TR_VectorAPIExpansion::loadIntrinsicHandler(TR_VectorAPIExpansion *opt
TR::Compilation *comp = opt->comp();

if (mode == checkScalarization) return node;
if (mode == checkVectorization) return node;
if (mode == checkVectorization)
return supportedOnPlatform(comp, vectorLength) ? node : NULL;

if (opt->_trace)
traceMsg(comp, "loadIntrinsicHandler for node %p\n", node);
Expand Down Expand Up @@ -1125,7 +1192,8 @@ TR::Node *TR_VectorAPIExpansion::storeIntrinsicHandler(TR_VectorAPIExpansion *op
TR::Compilation *comp = opt->comp();

if (mode == checkScalarization) return node;
if (mode == checkVectorization) return node;
if (mode == checkVectorization)
return supportedOnPlatform(comp, vectorLength) ? node : NULL;

if (opt->_trace)
traceMsg(comp, "storeIntrinsicHandler for node %p\n", node);
Expand Down Expand Up @@ -1237,7 +1305,20 @@ TR::Node *TR_VectorAPIExpansion::binaryIntrinsicHandler(TR_VectorAPIExpansion *o
return (scalarOpCode != TR::BadILOp) ? node : NULL;

if (mode == checkVectorization)
return NULL; // TODO: check opcode and platform
{
if (!supportedOnPlatform(comp, vectorLength)) return NULL;

TR::ILOpCodes vectorOpCode = TR::ILOpCode::convertScalarToVector(scalarOpCode);

if (vectorOpCode == TR::BadILOp)
return NULL;

if (!comp->cg()->getSupportsOpCodeForAutoSIMD(vectorOpCode, elementType))
return NULL;

return node;
}


if (opt->_trace)
traceMsg(comp, "binaryIntrinsicHandler for node %p\n", node);
Expand Down Expand Up @@ -1290,14 +1371,11 @@ TR::ILOpCodes TR_VectorAPIExpansion::ILOpcodeFromVectorAPIOpcode(int vectorOpCod
TR::Node *TR_VectorAPIExpansion::transformBinary(TR_VectorAPIExpansion *opt, TR::TreeTop *treeTop, TR::Node *node,
TR::DataType elementType, vec_sz_t vectorLength, handlerMode mode,
TR::Node *firstChild, TR::Node *secondChild,
TR::ILOpCodes opcode)
TR::ILOpCodes scalarOpCode)
{
TR::Compilation *comp = opt->comp();

anchorOldChildren(opt, treeTop, node);
node->setAndIncChild(0, firstChild);
node->setAndIncChild(1, secondChild);
node->setNumChildren(2);

if (mode == doScalarization)
{
Expand All @@ -1307,11 +1385,14 @@ TR::Node *TR_VectorAPIExpansion::transformBinary(TR_VectorAPIExpansion *opt, TR:
if (firstChild->getOpCodeValue() == TR::aload) aloadHandler(opt, treeTop, firstChild, elementType, vectorLength, mode);
if (secondChild->getOpCodeValue() == TR::aload) aloadHandler(opt, treeTop, secondChild, elementType, vectorLength, mode);

TR::Node::recreate(node, opcode);
node->setAndIncChild(0, firstChild);
node->setAndIncChild(1, secondChild);
node->setNumChildren(2);
TR::Node::recreate(node, scalarOpCode);

for (int i = 1; i < numLanes; i++)
{
TR::Node *newAddNode = TR::Node::create(node, opcode, 2);
TR::Node *newAddNode = TR::Node::create(node, scalarOpCode, 2);
addScalarNode(opt, node, numLanes, i, newAddNode);
newAddNode->setAndIncChild(0, getScalarNode(opt, firstChild, i));
newAddNode->setAndIncChild(1, getScalarNode(opt, secondChild, i));
Expand All @@ -1324,7 +1405,19 @@ TR::Node *TR_VectorAPIExpansion::transformBinary(TR_VectorAPIExpansion *opt, TR:
if (firstChild->getOpCodeValue() == TR::aload) vectorizeLoadOrStore(opt, firstChild, vectorType);
if (secondChild->getOpCodeValue() == TR::aload) vectorizeLoadOrStore(opt, secondChild, vectorType);

TR::Node::recreate(node, TR::vcall);
TR::ILOpCodes vectorOpCode = TR::ILOpCode::convertScalarToVector(scalarOpCode);

if (vectorOpCode != TR::BadILOp)
{
node->setAndIncChild(0, firstChild);
node->setAndIncChild(1, secondChild);
node->setNumChildren(2);
TR::Node::recreate(node, vectorOpCode);
}
else
{
TR::Node::recreate(node, TR::vcall);
}
}

return node;
Expand All @@ -1342,7 +1435,7 @@ TR_VectorAPIExpansion::methodTable[] =
{unsupportedHandler /*intoArrayHandler*/, TR::Float, Unknown, {Vector}}, // jdk_incubator_vector_FloatVector_intoArray,
{unsupportedHandler, TR::Float, Vector, {Species}}, // jdk_incubator_vector_FloatVector_fromArray_mask
{unsupportedHandler, TR::Float, Unknown, {}}, // jdk_incubator_vector_FloatVector_intoArray_mask
{addHandler, TR::Float, Vector, {Vector, Vector}}, // jdk_incubator_vector_FloatVector_add
{unsupportedHandler /*addHandler*/, TR::Float, Vector, {Vector, Vector}}, // jdk_incubator_vector_FloatVector_add
{unsupportedHandler, TR::Float, Vector, {}} // jdk_incubator_vector_VectorSpecies_indexInRange
};

Expand All @@ -1358,11 +1451,7 @@ TR_VectorAPIExpansion::TR_VectorAPIExpansion(TR::OptimizationManager *manager)


//TODOs:
// 1) disable inlining of recognized intrinsics
// 2) add disable and trace command line options
// 3) enable inlining of all vector methods
// 4) handle OSR guards
// 5) make scalarization and vectorization per web
// 6) make scalarization and vectorization coexist in one web
// 7) handle all intrinsics
// 8) box vector objects if passed to unvectorized methods
Expand All @@ -1371,10 +1460,7 @@ TR_VectorAPIExpansion::TR_VectorAPIExpansion(TR::OptimizationManager *manager)
// 11) implement useDef based approach
// 12) handle methods that return vector type different from the argument
// 13) OPT: optimize java/util/Objects.checkIndex
// 14) OPT: getClass() issue in FloatVector.binaryOp
// 15) OPT: too many aliased temps (reused privatized args) that cause over-aliasing after GVP
// 16) OPT: add to other opt levels
// 17) OPT: second pass of GVP still needed to propagate opcode
// 18) OPT: jdk/incubator/vector/VectorOperators.opCode() is not inlined with Byte,Short,Long add
// 19) OPT: don't insert OSR guards for intrinsics
// 20) Fix TR_ALLOC
30 changes: 25 additions & 5 deletions runtime/compiler/optimizer/VectorAPIExpansion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ class TR_VectorAPIExpansion : public TR::Optimization
static const vec_sz_t vec_len_unknown = -1;
static const vec_sz_t vec_len_default = 0;

static const handlerMode defaultCheckMode = checkScalarization;
static const handlerMode defaultDoMode = doScalarization;


/** \brief
* Element of the alias table.
* -# After a call to \c buildVectorAliases():
Expand All @@ -182,7 +178,8 @@ class TR_VectorAPIExpansion : public TR::Optimization
TR_ALLOC(TR_Memory::Inliner); // TODO: add new type

vectorAliasTableElement() : _symRef(NULL), _vecSymRef(NULL),
_vecLen(vec_len_default), _elementType(TR::NoType), _aliases(NULL), _classId(0) {}
_vecLen(vec_len_default), _elementType(TR::NoType), _aliases(NULL), _classId(0),
_cantVectorize(false), _cantScalarize(false) {}

TR::SymbolReference *_symRef;
union
Expand All @@ -198,6 +195,8 @@ class TR_VectorAPIExpansion : public TR::Optimization
TR::DataType _elementType;
TR_BitVector *_aliases;
int32_t _classId;
bool _cantVectorize;
bool _cantScalarize;
};


Expand Down Expand Up @@ -225,6 +224,27 @@ class TR_VectorAPIExpansion : public TR::Optimization
TR_BitVector _visitedNodes;
TR_BitVector _seenClasses;

/** \brief
* Checks if vector length is supported on current platform
*
* \param comp
* Compilation
*
* \param vectorLength
* Vector length in bits
*
* \return
* \c true if plaform supports \c vectorLength
* \c false otherwise
*/
static bool supportedOnPlatform(TR::Compilation *comp, vec_sz_t vectorLength)
{
if (comp->target().cpu.isPower() && vectorLength == 128)
return true;
else
return false;
}

/** \brief
* Checks if the method being compiled contains any recognized Vector API methods
*
Expand Down

0 comments on commit b4f9d6e

Please sign in to comment.