Skip to content

Commit b9b1f48

Browse files
committed
Add bit compress and expand IL opcdes
This commit adds opcodes for bit compress compress and expand operations (alternatively referred to as gather/scatter or extract/deposit) for byte, short, int, and long datatypes. Codegen support for Power and x86-64 is implemented with the pdepd/pextd and pdep/pext instructions, respectively. Signed-off-by: Spencer Comin <[email protected]>
1 parent c318529 commit b9b1f48

26 files changed

+860
-4
lines changed

compiler/aarch64/codegen/OMRTreeEvaluator.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -5541,6 +5541,54 @@ OMR::ARM64::TreeEvaluator::lbitpermuteEvaluator(TR::Node *node, TR::CodeGenerato
55415541
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
55425542
}
55435543

5544+
TR::Register*
5545+
OMR::ARM64::TreeEvaluator::bcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5546+
{
5547+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5548+
}
5549+
5550+
TR::Register*
5551+
OMR::ARM64::TreeEvaluator::scompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5552+
{
5553+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5554+
}
5555+
5556+
TR::Register*
5557+
OMR::ARM64::TreeEvaluator::icompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5558+
{
5559+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5560+
}
5561+
5562+
TR::Register*
5563+
OMR::ARM64::TreeEvaluator::lcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5564+
{
5565+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5566+
}
5567+
5568+
TR::Register*
5569+
OMR::ARM64::TreeEvaluator::bexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5570+
{
5571+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5572+
}
5573+
5574+
TR::Register*
5575+
OMR::ARM64::TreeEvaluator::sexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5576+
{
5577+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5578+
}
5579+
5580+
TR::Register*
5581+
OMR::ARM64::TreeEvaluator::iexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5582+
{
5583+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5584+
}
5585+
5586+
TR::Register*
5587+
OMR::ARM64::TreeEvaluator::lexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
5588+
{
5589+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
5590+
}
5591+
55445592
TR::Instruction *loadAddressConstantInSnippet(TR::CodeGenerator *cg, TR::Node *node, intptr_t address, TR::Register *targetRegister, TR_ExternalRelocationTargetKind reloKind, bool isClassUnloadingConst, TR::Instruction *cursor)
55455593
{
55465594
TR::Compilation *comp = cg->comp();

compiler/aarch64/codegen/OMRTreeEvaluator.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,14 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
569569
static TR::Register *sbitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
570570
static TR::Register *ibitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
571571
static TR::Register *lbitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
572+
static TR::Register *bcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
573+
static TR::Register *scompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
574+
static TR::Register *icompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
575+
static TR::Register *lcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
576+
static TR::Register *bexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
577+
static TR::Register *sexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
578+
static TR::Register *iexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
579+
static TR::Register *lexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
572580

573581
static TR::Register *unImpOpEvaluator(TR::Node *node, TR::CodeGenerator *cg);
574582
static TR::Register *badILOpEvaluator(TR::Node *node, TR::CodeGenerator *cg);

compiler/arm/codegen/OMRTreeEvaluator.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -2847,6 +2847,54 @@ OMR::ARM::TreeEvaluator::lbitpermuteEvaluator(TR::Node *node, TR::CodeGenerator
28472847
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
28482848
}
28492849

2850+
TR::Register*
2851+
OMR::ARM::TreeEvaluator::bcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2852+
{
2853+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2854+
}
2855+
2856+
TR::Register*
2857+
OMR::ARM::TreeEvaluator::scompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2858+
{
2859+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2860+
}
2861+
2862+
TR::Register*
2863+
OMR::ARM::TreeEvaluator::icompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2864+
{
2865+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2866+
}
2867+
2868+
TR::Register*
2869+
OMR::ARM::TreeEvaluator::lcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2870+
{
2871+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2872+
}
2873+
2874+
TR::Register*
2875+
OMR::ARM::TreeEvaluator::bexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2876+
{
2877+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2878+
}
2879+
2880+
TR::Register*
2881+
OMR::ARM::TreeEvaluator::sexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2882+
{
2883+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2884+
}
2885+
2886+
TR::Register*
2887+
OMR::ARM::TreeEvaluator::iexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2888+
{
2889+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2890+
}
2891+
2892+
TR::Register*
2893+
OMR::ARM::TreeEvaluator::lexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2894+
{
2895+
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
2896+
}
2897+
28502898
TR::Register*
28512899
OMR::ARM::TreeEvaluator::PrefetchEvaluator(TR::Node *node, TR::CodeGenerator *cg)
28522900
{

compiler/arm/codegen/OMRTreeEvaluator.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,14 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
533533
static TR::Register *sbitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
534534
static TR::Register *ibitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
535535
static TR::Register *lbitpermuteEvaluator(TR::Node *node, TR::CodeGenerator *cg);
536+
static TR::Register *bcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
537+
static TR::Register *scompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
538+
static TR::Register *icompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
539+
static TR::Register *lcompressbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
540+
static TR::Register *bexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
541+
static TR::Register *sexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
542+
static TR::Register *iexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
543+
static TR::Register *lexpandbitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
536544
static TR::Register *PrefetchEvaluator(TR::Node *node, TR::CodeGenerator *cg);
537545

538546
static TR::Register *badILOpEvaluator(TR::Node *node, TR::CodeGenerator *cg);

compiler/env/OMRCPU.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ class OMR_EXTENSIBLE CPU
130130
bool getSupportsHardwareRound() { return false; }
131131
bool getSupportsHardwareCopySign() { return false; }
132132
bool hasPopulationCountInstruction() { return false; }
133+
bool getSupportsHardware32bitCompress() { return false; }
134+
bool getSupportsHardware64bitCompress() { return false; }
135+
bool getSupportsHardware32bitExpand() { return false; }
136+
bool getSupportsHardware64bitExpand() { return false; }
133137
bool supportsDecimalFloatingPoint() { return false; }
134138
bool hasFPU() { return true; }
135139

compiler/il/OMRILOps.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,18 @@ class ILOpCode
17311731
case TR::lnolz:
17321732
vectorOperation = TR::vnolz;
17331733
break;
1734+
case TR::bcompressbits:
1735+
case TR::scompressbits:
1736+
case TR::icompressbits:
1737+
case TR::lcompressbits:
1738+
vectorOperation = TR::vcompressbits;
1739+
break;
1740+
case TR::bexpandbits:
1741+
case TR::sexpandbits:
1742+
case TR::iexpandbits:
1743+
case TR::lexpandbits:
1744+
vectorOperation = TR::vexpandbits;
1745+
break;
17341746
case TR::sbyteswap:
17351747
case TR::ibyteswap:
17361748
case TR::lbyteswap:

compiler/il/OMROpcodes.enum

+128
Original file line numberDiff line numberDiff line change
@@ -8229,6 +8229,134 @@ OPCODE_MACRO(\
82298229
/* .ifCompareOpCode = */ TR::BadILOp, \
82308230
/* .description = */ \
82318231
)
8232+
OPCODE_MACRO(\
8233+
/* .operation = */ bcompressbits, \
8234+
/* .name = */ "bcompressbits", \
8235+
/* .properties1 = */ 0, \
8236+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8237+
/* .properties3 = */ 0, \
8238+
/* .properties4 = */ 0, \
8239+
/* .dataType = */ TR::Int8, \
8240+
/* .typeProperties = */ ILTypeProp::Size_1 | ILTypeProp::Integer, \
8241+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int8), \
8242+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8243+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8244+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8245+
/* .ifCompareOpCode = */ TR::BadILOp, \
8246+
/* .description = compress bits from child1 selected by 1 bits in child2 into low bits of result */
8247+
)
8248+
OPCODE_MACRO(\
8249+
/* .operation = */ scompressbits, \
8250+
/* .name = */ "scompressbits", \
8251+
/* .properties1 = */ 0, \
8252+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8253+
/* .properties3 = */ 0, \
8254+
/* .properties4 = */ 0, \
8255+
/* .dataType = */ TR::Int16, \
8256+
/* .typeProperties = */ ILTypeProp::Size_2 | ILTypeProp::Integer, \
8257+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int16), \
8258+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8259+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8260+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8261+
/* .ifCompareOpCode = */ TR::BadILOp, \
8262+
/* .description = compress bits from child1 selected by 1 bits in child2 into low bits of result */
8263+
)
8264+
OPCODE_MACRO(\
8265+
/* .operation = */ icompressbits, \
8266+
/* .name = */ "icompressbits", \
8267+
/* .properties1 = */ 0, \
8268+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8269+
/* .properties3 = */ 0, \
8270+
/* .properties4 = */ 0, \
8271+
/* .dataType = */ TR::Int32, \
8272+
/* .typeProperties = */ ILTypeProp::Size_4 | ILTypeProp::Integer, \
8273+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int32), \
8274+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8275+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8276+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8277+
/* .ifCompareOpCode = */ TR::BadILOp, \
8278+
/* .description = compress bits from child1 selected by 1 bits in child2 into low bits of result */
8279+
)
8280+
OPCODE_MACRO(\
8281+
/* .operation = */ lcompressbits, \
8282+
/* .name = */ "lcompressbits", \
8283+
/* .properties1 = */ 0, \
8284+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8285+
/* .properties3 = */ 0, \
8286+
/* .properties4 = */ 0, \
8287+
/* .dataType = */ TR::Int64, \
8288+
/* .typeProperties = */ ILTypeProp::Size_8 | ILTypeProp::Integer, \
8289+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int64), \
8290+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8291+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8292+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8293+
/* .ifCompareOpCode = */ TR::BadILOp, \
8294+
/* .description = compress bits from child1 selected by 1 bits in child2 into low bits of result */
8295+
)
8296+
OPCODE_MACRO(\
8297+
/* .operation = */ bexpandbits, \
8298+
/* .name = */ "bexpandbits", \
8299+
/* .properties1 = */ 0, \
8300+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8301+
/* .properties3 = */ 0, \
8302+
/* .properties4 = */ 0, \
8303+
/* .dataType = */ TR::Int8, \
8304+
/* .typeProperties = */ ILTypeProp::Size_1 | ILTypeProp::Integer, \
8305+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int8), \
8306+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8307+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8308+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8309+
/* .ifCompareOpCode = */ TR::BadILOp, \
8310+
/* .description = starting from lowest bit, deposit bits from child1 into bits of result selected by 1 bits in child2 */
8311+
)
8312+
OPCODE_MACRO(\
8313+
/* .operation = */ sexpandbits, \
8314+
/* .name = */ "sexpandbits", \
8315+
/* .properties1 = */ 0, \
8316+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8317+
/* .properties3 = */ 0, \
8318+
/* .properties4 = */ 0, \
8319+
/* .dataType = */ TR::Int16, \
8320+
/* .typeProperties = */ ILTypeProp::Size_2 | ILTypeProp::Integer, \
8321+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int16), \
8322+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8323+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8324+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8325+
/* .ifCompareOpCode = */ TR::BadILOp, \
8326+
/* .description = starting from lowest bit, deposit bits from child1 into bits of result selected by 1 bits in child2 */
8327+
)
8328+
OPCODE_MACRO(\
8329+
/* .operation = */ iexpandbits, \
8330+
/* .name = */ "iexpandbits", \
8331+
/* .properties1 = */ 0, \
8332+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8333+
/* .properties3 = */ 0, \
8334+
/* .properties4 = */ 0, \
8335+
/* .dataType = */ TR::Int32, \
8336+
/* .typeProperties = */ ILTypeProp::Size_4 | ILTypeProp::Integer, \
8337+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int32), \
8338+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8339+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8340+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8341+
/* .ifCompareOpCode = */ TR::BadILOp, \
8342+
/* .description = starting from lowest bit, deposit bits from child1 into bits of result selected by 1 bits in child2 */
8343+
)
8344+
OPCODE_MACRO(\
8345+
/* .operation = */ lexpandbits, \
8346+
/* .name = */ "lexpandbits", \
8347+
/* .properties1 = */ 0, \
8348+
/* .properties2 = */ ILProp2::SupportedForPRE, \
8349+
/* .properties3 = */ 0, \
8350+
/* .properties4 = */ 0, \
8351+
/* .dataType = */ TR::Int64, \
8352+
/* .typeProperties = */ ILTypeProp::Size_8 | ILTypeProp::Integer, \
8353+
/* .childProperties = */ TWO_SAME_CHILD(TR::Int64), \
8354+
/* .swapChildrenOpCode = */ TR::BadILOp, \
8355+
/* .reverseBranchOpCode = */ TR::BadILOp, \
8356+
/* .booleanCompareOpCode = */ TR::BadILOp, \
8357+
/* .ifCompareOpCode = */ TR::BadILOp, \
8358+
/* .description = starting from lowest bit, deposit bits from child1 into bits of result selected by 1 bits in child2 */
8359+
)
82328360
OPCODE_MACRO(\
82338361
/* .opcode = */ sbyteswap, \
82348362
/* .name = */ "sbyteswap", \

compiler/optimizer/OMRSimplifierHandlers.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,7 @@ static bool reduceLongOp(TR::Node * node, TR::Block * block, TR::Simplifier * s,
16521652
case TR::land: newOp = TR::iand; break;
16531653
case TR::lor: newOp = TR::ior; break;
16541654
case TR::lxor: newOp = TR::ixor; break;
1655+
case TR::lexpandbits: newOp = TR::iexpandbits; break;
16551656
case TR::lushr:
16561657
isUnsigned = true;
16571658
case TR::lshr:

compiler/optimizer/OMRSimplifierTable.enum

+8
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,14 @@
682682
#define sbitpermuteSimplifierHandler dftSimplifier
683683
#define ibitpermuteSimplifierHandler dftSimplifier
684684
#define lbitpermuteSimplifierHandler dftSimplifier
685+
#define lcompressbitsSimplifierHandler dftSimplifier
686+
#define icompressbitsSimplifierHandler dftSimplifier
687+
#define scompressbitsSimplifierHandler dftSimplifier
688+
#define bcompressbitsSimplifierHandler dftSimplifier
689+
#define lexpandbitsSimplifierHandler dftSimplifier
690+
#define iexpandbitsSimplifierHandler dftSimplifier
691+
#define sexpandbitsSimplifierHandler dftSimplifier
692+
#define bexpandbitsSimplifierHandler dftSimplifier
685693
#define PrefetchSimplifierHandler dftSimplifier
686694

687695
#endif

compiler/optimizer/ValuePropagationTable.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,14 @@ TR::Node * constrainLongBitCount(OMR::ValuePropagation *vp, TR::Node *node);
820820
#define sbitpermuteVPHandler constrainChildren
821821
#define ibitpermuteVPHandler constrainChildren
822822
#define lbitpermuteVPHandler constrainChildren
823+
#define lcompressbitsVPHandler constrainChildren
824+
#define icompressbitsVPHandler constrainChildren
825+
#define scompressbitsVPHandler constrainChildren
826+
#define bcompressbitsVPHandler constrainChildren
827+
#define lexpandbitsVPHandler constrainChildren
828+
#define iexpandbitsVPHandler constrainChildren
829+
#define sexpandbitsVPHandler constrainChildren
830+
#define bexpandbitsVPHandler constrainChildren
823831
#define PrefetchVPHandler constrainChildren
824832

825833
#ifdef J9_PROJECT_SPECIFIC

0 commit comments

Comments
 (0)