Skip to content

Commit 18a9d83

Browse files
committed
Fix Vector API boxing defects
- support boxing of children of convert intrinsic - make getting intrinsic object type more general
1 parent 2ad6b24 commit 18a9d83

File tree

2 files changed

+156
-67
lines changed

2 files changed

+156
-67
lines changed

runtime/compiler/optimizer/VectorAPIExpansion.cpp

Lines changed: 112 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ void
247247
TR_VectorAPIExpansion::buildVectorAliases(bool verifyMode)
248248
{
249249
if (_trace)
250-
traceMsg(comp(), "%s Aliasing symrefs verifyMode=%\n", OPT_DETAILS_VECTOR, verifyMode);
250+
traceMsg(comp(), "%s Aliasing symrefs verifyMode=%d\n", OPT_DETAILS_VECTOR, verifyMode);
251251

252252
_visitedNodes.empty();
253253

@@ -409,14 +409,7 @@ TR_VectorAPIExpansion::visitNodeToBuildVectorAliases(TR::Node *node, bool verify
409409
if (getSecondClassIndex(methodSymbol) != -1)
410410
getObjectTypeFromClassNode(comp(), node->getChild(getSecondClassIndex(methodSymbol)));
411411

412-
if (methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_load ||
413-
methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_store ||
414-
methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_fromBitsCoerced ||
415-
methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_binaryOp)
416-
{
417-
objectType = objectTypeFromClass;
418-
}
419-
else if (methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_compressExpandOp)
412+
if (methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_compressExpandOp)
420413
{
421414
if (!node->getFirstChild()->getOpCode().isLoadConst())
422415
{
@@ -431,9 +424,9 @@ TR_VectorAPIExpansion::visitNodeToBuildVectorAliases(TR::Node *node, bool verify
431424
objectType = Vector;
432425
}
433426
}
434-
else
427+
else if (objectType == Unknown)
435428
{
436-
TR_ASSERT_FATAL (objectType != Unknown, "Object type should be known");
429+
objectType = objectTypeFromClass;
437430
}
438431
}
439432

@@ -674,7 +667,8 @@ TR_VectorAPIExpansion::visitNodeToBuildVectorAliases(TR::Node *node, bool verify
674667
}
675668
else if (boxingAllowed() &&
676669
(node->getOpCodeValue() == TR::checkcast ||
677-
node->getOpCodeValue() == TR::athrow))
670+
node->getOpCodeValue() == TR::athrow ||
671+
node->getOpCodeValue() == TR::awrtbar))
678672
{
679673
// do nothing here to allow this treetop when boxing is enabled
680674
}
@@ -1054,7 +1048,7 @@ TR_VectorAPIExpansion::getObjectTypeFromClassNode(TR::Compilation *comp, TR::Nod
10541048

10551049
if ((*(*_boxingClasses[objectType - 1])[vectorLength - 1])[elementType - 1] == NULL)
10561050
{
1057-
traceMsg(comp, "Caching class for boxing: %d %d %d", objectType, vectorLength, elementType);
1051+
traceMsg(comp, "Caching class for boxing: %d %d %d\n", objectType, vectorLength, elementType);
10581052

10591053
(*(*_boxingClasses[objectType - 1])[vectorLength - 1])[elementType - 1] = clazz;
10601054
}
@@ -1427,8 +1421,8 @@ TR_VectorAPIExpansion::dontVectorizeNode(TR::Node *node)
14271421

14281422

14291423
bool
1430-
TR_VectorAPIExpansion::isVectorizedOrScalarizedNode(TR::Node *node, TR::DataType &elementType, int32_t &bitsLength,
1431-
vapiObjType &objectType, bool &scalarized)
1424+
TR_VectorAPIExpansion::isVectorizedOrScalarizedNode(TR::Node *node, TR::DataType &elementType, vec_sz_t &bitsLength,
1425+
vapiObjType &objectType, bool &scalarized, bool sourceType)
14321426
{
14331427
// TODO: do not override if not vectorized
14341428
elementType = TR::NoType;
@@ -1482,10 +1476,24 @@ TR_VectorAPIExpansion::isVectorizedOrScalarizedNode(TR::Node *node, TR::DataType
14821476
if (_aliasTable[classId]._classId <= 0)
14831477
return false;
14841478

1485-
elementType = _nodeTable[nodeIndex]._elementType;
1486-
bitsLength = _nodeTable[nodeIndex]._vecLen;
14871479
objectType = _nodeTable[nodeIndex]._objectType;
14881480

1481+
TR::MethodSymbol *methodSymbol = node->getSymbolReference()->getSymbol()->castToMethodSymbol();
1482+
1483+
if (sourceType &&
1484+
methodSymbol->getRecognizedMethod() == TR::jdk_internal_vm_vector_VectorSupport_convert)
1485+
{
1486+
// source type of two-type opcodes is not stored in the _nodeTable
1487+
// so we need to analyze the node again
1488+
bool result = getConvertSourceType(this, node, elementType, bitsLength);
1489+
TR_ASSERT_FATAL(result, "Conversion source type should be known\n");
1490+
}
1491+
else
1492+
{
1493+
elementType = _nodeTable[nodeIndex]._elementType;
1494+
bitsLength = _nodeTable[nodeIndex]._vecLen;
1495+
}
1496+
14891497
if (!_nodeTable[nodeIndex]._canVectorize)
14901498
scalarized = true;
14911499

@@ -1502,9 +1510,16 @@ TR_VectorAPIExpansion::isVectorizedOrScalarizedNode(TR::Node *node, TR::DataType
15021510
{
15031511
ncount_t nodeIndex = node->getGlobalIndex();
15041512

1513+
objectType = _nodeTable[nodeIndex]._objectType;
1514+
1515+
TR::MethodSymbol *methodSymbol = origSymRef->getSymbol()->castToMethodSymbol();
1516+
1517+
1518+
TR_ASSERT_FATAL(!sourceType, "Node could not be vectorized if we are asking for its source type\n");
1519+
15051520
elementType = _nodeTable[nodeIndex]._elementType;
15061521
bitsLength = _nodeTable[nodeIndex]._vecLen;
1507-
objectType = _nodeTable[nodeIndex]._objectType;
1522+
15081523
return true;
15091524
}
15101525

@@ -1558,7 +1573,7 @@ TR_VectorAPIExpansion::boxChild(TR::TreeTop *treeTop, TR::Node *node, uint32_t i
15581573
TR::Node *child = node->getChild(i);
15591574

15601575
TR::DataType elementType;
1561-
int32_t bitsLength;
1576+
vec_sz_t bitsLength;
15621577
vapiObjType objectType;
15631578
bool scalarized;
15641579
TR::ILOpCodes maskStoreOpCode;
@@ -1590,7 +1605,12 @@ TR_VectorAPIExpansion::boxChild(TR::TreeTop *treeTop, TR::Node *node, uint32_t i
15901605
{
15911606
vecClass = getClassForBoxing(child, elementType, bitsLength, objectType);
15921607
if (!vecClass)
1608+
{
1609+
if (_trace)
1610+
traceMsg(comp(), "Missing class for boxing of %d child of node %p\n", i, node);
1611+
15931612
boxingSupported = false;
1613+
}
15941614
}
15951615

15961616
if (!boxingSupported ||
@@ -1603,8 +1623,7 @@ TR_VectorAPIExpansion::boxChild(TR::TreeTop *treeTop, TR::Node *node, uint32_t i
16031623
_aliasTable[classId]._classId = -1;
16041624

16051625
if (_trace)
1606-
traceMsg(comp(), "Invalidated class #%d due to unsupported boxing of %d child of node %p in %s\n",
1607-
classId, i, node, comp()->signature());
1626+
traceMsg(comp(), "Invalidated class #%d due to unsupported boxing of %d child of node %p\n", classId, i, node);
16081627
return false;
16091628
}
16101629

@@ -1677,7 +1696,9 @@ TR_VectorAPIExpansion::boxChild(TR::TreeTop *treeTop, TR::Node *node, uint32_t i
16771696
treeTop->insertBefore(TR::TreeTop::create(comp(), fence));
16781697

16791698
if (_trace)
1680-
traceMsg(comp(), "Boxed child %d of node %p into %p\n", i, node, newObject);
1699+
traceMsg(comp(), "Boxed %s%d%s child %d of node %p into %p\n",
1700+
objectType == Vector ? "Vector" : "Mask", bitsLength, TR::DataType::getName(elementType),
1701+
i, node, newObject);
16811702

16821703
if (TR::Options::getVerboseOption(TR_VerboseVectorAPI))
16831704
{
@@ -1695,11 +1716,11 @@ TR_VectorAPIExpansion::unboxNode(TR::Node *parentNode, TR::Node *operand, vapiOb
16951716
bool checkBoxing)
16961717
{
16971718
TR::DataType elementType;
1698-
int32_t bitsLength;
1719+
vec_sz_t bitsLength;
16991720
vapiObjType parentType;
17001721
bool parentScalarized;
17011722
bool parentVectorizedOrScalarized = isVectorizedOrScalarizedNode(parentNode, elementType, bitsLength,
1702-
parentType, parentScalarized);
1723+
parentType, parentScalarized, true);
17031724

17041725
TR_ASSERT_FATAL(parentVectorizedOrScalarized, "Node %p should be vectorized or scalarized since we are trying to unbox its operand %p",
17051726
parentNode, operand);
@@ -1728,7 +1749,12 @@ TR_VectorAPIExpansion::unboxNode(TR::Node *parentNode, TR::Node *operand, vapiOb
17281749
{
17291750
vecClass = getClassForBoxing(operand, elementType, bitsLength, operandObjectType);
17301751
if (!vecClass)
1752+
{
1753+
if (_trace)
1754+
traceMsg(comp(), "Missing class for unboxing of operand %p of node %p\n", operand, parentNode);
1755+
17311756
unboxingSupported = false;
1757+
}
17321758
}
17331759

17341760
if (!unboxingSupported)
@@ -1741,8 +1767,8 @@ TR_VectorAPIExpansion::unboxNode(TR::Node *parentNode, TR::Node *operand, vapiOb
17411767
_aliasTable[classId]._classId = -1;
17421768

17431769
if (_trace)
1744-
traceMsg(comp(), "Invalidated class #%d due to unsupported unboxing of operand %p of node %p in %s\n",
1745-
classId, operand, parentNode, comp()->signature());
1770+
traceMsg(comp(), "Invalidated class #%d due to unsupported unboxing of operand %p of node %p\n",
1771+
classId, operand, parentNode);
17461772

17471773
return NULL;
17481774
}
@@ -1784,7 +1810,9 @@ TR_VectorAPIExpansion::unboxNode(TR::Node *parentNode, TR::Node *operand, vapiOb
17841810
}
17851811

17861812
if (_trace)
1787-
traceMsg(comp(), "Unboxed node %p into new node %p for parent %p\n", operand, newOperand, parentNode);
1813+
traceMsg(comp(), "Unboxed %s%d%s node %p into new node %p for parent %p\n",
1814+
operandObjectType == Vector ? "Vector" : "Mask", bitsLength, TR::DataType::getName(elementType),
1815+
operand, newOperand, parentNode);
17881816

17891817
if (TR::Options::getVerboseOption(TR_VerboseVectorAPI))
17901818
{
@@ -1857,11 +1885,14 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
18571885

18581886
bool scalarized;
18591887
TR::DataType elementType;
1860-
int32_t bitsLength;
1888+
vec_sz_t bitsLength;
18611889
vapiObjType objectType;
1862-
18631890
bool vectorizedOrScalarizedNode = isVectorizedOrScalarizedNode(node, elementType, bitsLength, objectType, scalarized);
18641891

1892+
if (_trace)
1893+
traceMsg(comp(), "Node %p (%s) vectorizedOrScalarized=%d elementType=%d bitsLength=%d objectType=%d scalarized=%d\n",
1894+
node, opCode.getName(), vectorizedOrScalarizedNode, elementType.getDataType(), bitsLength, objectType, scalarized);
1895+
18651896
// Vectorize intrinsic if its operands are known
18661897
if (boxingAllowed() &&
18671898
!vectorizedOrScalarizedNode &&
@@ -1879,7 +1910,7 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
18791910

18801911
bool operandScalarized;
18811912
TR::DataType operandElementType;
1882-
int32_t operandBitsLength;
1913+
vec_sz_t operandBitsLength;
18831914
vapiObjType operandObjectType;
18841915

18851916
bool operandVectorizedOrScalarized = isVectorizedOrScalarizedNode(operand, operandElementType, operandBitsLength,
@@ -1935,7 +1966,8 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
19351966
opCodeValue == TR::areturn ||
19361967
opCodeValue == TR::aRegStore ||
19371968
opCodeValue == TR::checkcast ||
1938-
opCodeValue == TR::athrow))
1969+
opCodeValue == TR::athrow ||
1970+
opCodeValue == TR::awrtbar))
19391971
{
19401972
if (_trace)
19411973
traceMsg(comp(), "Checking if children of non-vector node %p need to be boxed\n", node);
@@ -2028,7 +2060,7 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
20282060
if (boxingAllowed())
20292061
{
20302062
TR::DataType rhsElementType;
2031-
int32_t rhsBitsLength;
2063+
vec_sz_t rhsBitsLength;
20322064
vapiObjType rhsObjectType;
20332065
bool rhsScalarized;
20342066
bool rhsVectorizedOrScalarized = isVectorizedOrScalarizedNode(node->getFirstChild(), rhsElementType, rhsBitsLength,
@@ -2079,7 +2111,7 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
20792111
bool vectorizedOrScalarized = false;
20802112

20812113
TR::DataType operandElementType;
2082-
int32_t operandBitsLength;
2114+
vec_sz_t operandBitsLength;
20832115
vapiObjType operandObjectType;
20842116
bool operandScalarized;
20852117

@@ -2088,8 +2120,10 @@ TR_VectorAPIExpansion::transformIL(bool checkBoxing)
20882120

20892121
if (!vectorizedOrScalarized)
20902122
{
2091-
TR_ASSERT_FATAL(operand->getOpCodeValue() == TR::aload || operand->getOpCodeValue() == TR::acall,
2092-
"Operand can only be aload or acall");
2123+
TR_ASSERT_FATAL(operand->getOpCodeValue() == TR::aload ||
2124+
operand->getOpCodeValue() == TR::acall ||
2125+
operand->getOpCodeValue() == TR::New,
2126+
"Operand can only be aload, acall, or New (child %d)", i);
20932127
vapiObjType operandObjectType = Vector;
20942128

20952129
if (getArgumentType(methodSymbol, i) == Mask)
@@ -2874,6 +2908,41 @@ TR::Node *TR_VectorAPIExpansion::transformRORtoROL(TR_VectorAPIExpansion *opt, T
28742908
return subNode;
28752909
}
28762910

2911+
bool
2912+
TR_VectorAPIExpansion::getConvertSourceType(TR_VectorAPIExpansion *opt, TR::Node *node,
2913+
TR::DataType &sourceElementType, vec_sz_t &bitsLength)
2914+
{
2915+
TR::Compilation *comp = opt->comp();
2916+
bitsLength = vec_len_default;
2917+
2918+
// For convert, source vector type info is in children 2 and 3
2919+
TR::Node *sourceElementTypeNode = node->getChild(2);
2920+
sourceElementType = getDataTypeFromClassNode(comp, sourceElementTypeNode);
2921+
2922+
TR::Node *sourceNumLanesNode = node->getChild(3);
2923+
2924+
if (sourceNumLanesNode->getOpCode().isLoadConst())
2925+
{
2926+
int32_t elementSize = OMR::DataType::getSize(sourceElementType);
2927+
bitsLength = sourceNumLanesNode->get32bitIntegralValue()*8*elementSize;
2928+
2929+
if (supportedOnPlatform(comp, bitsLength) == TR::NoVectorLength)
2930+
{
2931+
traceMsg(comp, "Platform does not support conversion source length %d in node %p\n",
2932+
bitsLength, node);
2933+
return false;
2934+
}
2935+
}
2936+
2937+
if (sourceElementType == TR::NoType || bitsLength == vec_len_default)
2938+
{
2939+
traceMsg(comp, "Unknown conversion source type in node %p\n", node);
2940+
return false;
2941+
}
2942+
2943+
return true;
2944+
}
2945+
28772946

28782947
TR::Node *TR_VectorAPIExpansion::naryIntrinsicHandler(TR_VectorAPIExpansion *opt, TR::TreeTop *treeTop, TR::Node *node,
28792948
TR::DataType elementType, TR::VectorLength vectorLength, vapiObjType objectType,
@@ -2964,32 +3033,12 @@ TR::Node *TR_VectorAPIExpansion::naryIntrinsicHandler(TR_VectorAPIExpansion *opt
29643033

29653034
if (opCodeType == Convert)
29663035
{
2967-
// source vector type info is in children 2 and 3
2968-
TR::Node *sourceElementTypeNode = node->getChild(2);
2969-
sourceElementType = getDataTypeFromClassNode(comp, sourceElementTypeNode);
3036+
vec_sz_t bitsLength = vec_len_default;
29703037

2971-
TR::Node *sourceNumLanesNode = node->getChild(3);
2972-
2973-
if (sourceNumLanesNode->getOpCode().isLoadConst())
2974-
{
2975-
int32_t elementSize = OMR::DataType::getSize(sourceElementType);
2976-
vec_sz_t bitsLength = sourceNumLanesNode->get32bitIntegralValue()*8*elementSize;
2977-
2978-
if (supportedOnPlatform(comp, bitsLength) == TR::NoVectorLength)
2979-
{
2980-
traceMsg(comp, "Platform does not support conversion source length %d in node %p",
2981-
bitsLength, node);
2982-
return NULL;
2983-
}
2984-
2985-
sourceVectorLength = OMR::DataType::bitsToVectorLength(bitsLength);
2986-
}
2987-
2988-
if (sourceElementType == TR::NoType || sourceVectorLength == TR::NoVectorLength)
2989-
{
2990-
traceMsg(comp, "Unknown conversion source type in node %p", node);
3038+
if (!getConvertSourceType(opt, node, sourceElementType, bitsLength))
29913039
return NULL;
2992-
}
3040+
3041+
sourceVectorLength = OMR::DataType::bitsToVectorLength(bitsLength);
29933042
}
29943043
else if (opCodeType == Compare)
29953044
{
@@ -3249,6 +3298,8 @@ TR::ILOpCodes TR_VectorAPIExpansion::ILOpcodeFromVectorAPIOpcode(TR::Compilation
32493298
{
32503299
if (scalar) return TR::BadILOp;
32513300

3301+
if (objectType == Mask) return reportMissingOpCode(comp, vectorAPIOpCode, objectType, opCodeType, withMask);
3302+
32523303
switch (vectorAPIOpCode)
32533304
{
32543305
case VECTOR_OP_CAST:
@@ -3674,12 +3725,12 @@ TR_VectorAPIExpansion::vapiObjTypeNames[] =
36743725
{
36753726
"Unknown",
36763727
"Vector",
3728+
"Mask",
3729+
"Shuffle",
36773730
"Species",
36783731
"ElementType",
36793732
"NumLanes",
3680-
"Mask",
36813733
"Scalar",
3682-
"Shuffle",
36833734
"Invalid"
36843735
};
36853736

0 commit comments

Comments
 (0)