--- old/src/hotspot/share/adlc/forms.cpp 2020-04-02 14:11:51.000000000 +0300 +++ new/src/hotspot/share/adlc/forms.cpp 2020-04-02 14:11:51.000000000 +0300 @@ -268,6 +268,7 @@ if( strcmp(opType,"LoadRange")==0 ) return Form::idealI; if( strcmp(opType,"LoadS")==0 ) return Form::idealS; if( strcmp(opType,"LoadVector")==0 ) return Form::idealV; + if( strcmp(opType,"LoadVectorGather")==0 ) return Form::idealV; assert( strcmp(opType,"Load") != 0, "Must type Loads" ); return Form::none; } @@ -284,6 +285,7 @@ if( strcmp(opType,"StoreN")==0) return Form::idealN; if( strcmp(opType,"StoreNKlass")==0) return Form::idealNKlass; if( strcmp(opType,"StoreVector")==0 ) return Form::idealV; + if( strcmp(opType,"StoreVectorScatter")==0 ) return Form::idealV; assert( strcmp(opType,"Store") != 0, "Must type Stores" ); return Form::none; } --- old/src/hotspot/share/adlc/formssel.cpp 2020-04-02 14:11:52.000000000 +0300 +++ new/src/hotspot/share/adlc/formssel.cpp 2020-04-02 14:11:52.000000000 +0300 @@ -3492,7 +3492,7 @@ "StoreB","StoreC","Store" ,"StoreFP", "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" , "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" , - "StoreVector", "LoadVector", + "StoreVector", "LoadVector", "LoadVectorGather", "StoreVectorScatter", "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned", "LoadPLocked", "StorePConditional", "StoreIConditional", "StoreLConditional", @@ -3809,6 +3809,7 @@ "MaxV", "MinV", "MulI","MulL","MulF","MulD", "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD", + "MinV","MaxV", "OrI","OrL", "OrV", "XorI","XorL", @@ -4059,8 +4060,8 @@ strcmp(opType,"MulReductionVL")==0 || strcmp(opType,"MulReductionVF")==0 || strcmp(opType,"MulReductionVD")==0 || - strcmp(opType,"MinReductionV")==0 || - strcmp(opType,"MaxReductionV")==0 || + strcmp(opType,"MinReductionV")== 0 || + strcmp(opType,"MaxReductionV")== 0 || strcmp(opType,"AndReductionV")==0 || strcmp(opType,"OrReductionV")==0 || strcmp(opType,"XorReductionV")==0 || @@ -4157,24 +4158,31 @@ "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD", "CMoveVD", "CMoveVF", "DivVF","DivVD", + "MinV","MaxV", "AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD", - "NegVF","NegVD", + "NegVF","NegVD","NegVI", "SqrtVD","SqrtVF", - "AndV" ,"XorV" ,"OrV", + "AndV" ,"XorV" ,"OrV", "NotV", "MaxV", "MinV", "AddReductionVI", "AddReductionVL", "AddReductionVF", "AddReductionVD", "MulReductionVI", "MulReductionVL", "MulReductionVF", "MulReductionVD", + "MulAddVS2VI", "MaxReductionV", "MinReductionV", "AndReductionV", "OrReductionV", "XorReductionV", - "MulAddVS2VI", "LShiftCntV","RShiftCntV", "LShiftVB","LShiftVS","LShiftVI","LShiftVL", "RShiftVB","RShiftVS","RShiftVI","RShiftVL", "URShiftVB","URShiftVS","URShiftVI","URShiftVL", + "VLShiftV","VRShiftV","VURShiftV", "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD", - "RoundDoubleModeV","LoadVector","StoreVector", + "RoundDoubleModeV","LoadVector","StoreVector","LoadVectorGather", "StoreVectorScatter", + "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert", + "VectorRearrange","VectorLoadShuffle", "VectorLoadConst", + "VectorCastB2X", "VectorCastS2X", "VectorCastI2X", + "VectorCastL2X", "VectorCastF2X", "VectorCastD2X", + "VectorMaskWrapper", "VectorMaskCmp", "VectorReinterpret", "FmaVD", "FmaVF","PopCountVI", // Next are not supported currently. "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D", --- old/src/hotspot/share/opto/addnode.hpp 2020-04-02 14:11:52.000000000 +0300 +++ new/src/hotspot/share/opto/addnode.hpp 2020-04-02 14:11:52.000000000 +0300 @@ -249,6 +249,30 @@ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); }; +//------------------------------MaxLNode--------------------------------------- +// MAXimum of 2 longs. +class MaxLNode : public MaxNode { +public: + MaxLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {} + virtual int Opcode() const; + virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; } + virtual const Type *add_id() const { return TypeLong::make(min_jlong); } + virtual const Type *bottom_type() const { return TypeLong::LONG; } + virtual uint ideal_reg() const { return Op_RegL; } +}; + +//------------------------------MinLNode--------------------------------------- +// MINimum of 2 longs. +class MinLNode : public MaxNode { +public: + MinLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {} + virtual int Opcode() const; + virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; } + virtual const Type *add_id() const { return TypeLong::make(max_jlong); } + virtual const Type *bottom_type() const { return TypeLong::LONG; } + virtual uint ideal_reg() const { return Op_RegL; } +}; + //------------------------------MaxFNode--------------------------------------- // Maximum of 2 floats. class MaxFNode : public MaxNode { --- old/src/hotspot/share/opto/classes.hpp 2020-04-02 14:11:53.000000000 +0300 +++ new/src/hotspot/share/opto/classes.hpp 2020-04-02 14:11:52.000000000 +0300 @@ -199,9 +199,10 @@ macro(Mach) macro(MachProj) macro(MulAddS2I) +macro(MaxI) +macro(MaxL) macro(MaxD) macro(MaxF) -macro(MaxI) macro(MemBarAcquire) macro(LoadFence) macro(SetVectMaskI) @@ -213,9 +214,10 @@ macro(MemBarVolatile) macro(MemBarStoreStore) macro(MergeMem) -macro(MinD) -macro(MinF) macro(MinI) +macro(MinL) +macro(MinF) +macro(MinD) macro(ModD) macro(ModF) macro(ModI) @@ -230,8 +232,11 @@ macro(MulI) macro(MulL) macro(Multi) +macro(NegI) +macro(NegL) macro(NegD) macro(NegF) +macro(Not) macro(NeverBranch) macro(OnSpinWait) macro(Opaque1) @@ -314,6 +319,8 @@ macro(TailJump) macro(ThreadLocal) macro(Unlock) +macro(URShiftB) +macro(URShiftS) macro(URShiftI) macro(URShiftL) macro(XorI) @@ -346,16 +353,19 @@ macro(MulVD) macro(MulReductionVD) macro(MulAddVS2VI) +macro(NotV) macro(FmaVD) macro(FmaVF) macro(DivVF) macro(DivVD) +macro(AbsV) macro(AbsVB) macro(AbsVS) macro(AbsVI) macro(AbsVL) macro(AbsVF) macro(AbsVD) +macro(NegVI) macro(NegVF) macro(NegVD) macro(SqrtVD) @@ -374,6 +384,9 @@ macro(URShiftVS) macro(URShiftVI) macro(URShiftVL) +macro(VLShiftV) +macro(VRShiftV) +macro(VURShiftV) macro(AndV) macro(AndReductionV) macro(OrV) @@ -385,7 +398,9 @@ macro(MinReductionV) macro(MaxReductionV) macro(LoadVector) +macro(LoadVectorGather) macro(StoreVector) +macro(StoreVectorScatter) macro(Pack) macro(PackB) macro(PackS) @@ -414,3 +429,21 @@ macro(LowerCase) macro(UpperCase) macro(Whitespace) +macro(VectorMaskWrapper) +macro(VectorMaskCmp) +macro(VectorTest) +macro(VectorBlend) +macro(VectorRearrange) +macro(VectorLoadMask) +macro(VectorLoadShuffle) +macro(VectorLoadConst) +macro(VectorStoreMask) +macro(VectorReinterpret) +macro(VectorCast) +macro(VectorCastB2X) +macro(VectorCastS2X) +macro(VectorCastI2X) +macro(VectorCastL2X) +macro(VectorCastF2X) +macro(VectorCastD2X) +macro(VectorInsert) --- old/src/hotspot/share/opto/compile.cpp 2020-04-02 14:11:53.000000000 +0300 +++ new/src/hotspot/share/opto/compile.cpp 2020-04-02 14:11:53.000000000 +0300 @@ -2460,7 +2460,8 @@ // Check for commutative opcode switch( nop ) { case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL: - case Op_MaxI: case Op_MinI: + case Op_MaxI: case Op_MaxL: case Op_MaxF: case Op_MaxD: + case Op_MinI: case Op_MinL: case Op_MinF: case Op_MinD: case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL: case Op_AndL: case Op_XorL: case Op_OrL: case Op_AndI: case Op_XorI: case Op_OrI: { @@ -3025,6 +3026,8 @@ case Op_LoadVector: case Op_StoreVector: + case Op_LoadVectorGather: + case Op_StoreVectorScatter: break; case Op_AddReductionVI: --- old/src/hotspot/share/opto/lcm.cpp 2020-04-02 14:11:54.000000000 +0300 +++ new/src/hotspot/share/opto/lcm.cpp 2020-04-02 14:11:53.000000000 +0300 @@ -687,6 +687,7 @@ case Op_StoreP: case Op_StoreN: case Op_StoreVector: + case Op_StoreVectorScatter: case Op_StoreNKlass: for (uint k = 1; k < m->req(); k++) { Node *in = m->in(k); --- old/src/hotspot/share/opto/matcher.cpp 2020-04-02 14:11:54.000000000 +0300 +++ new/src/hotspot/share/opto/matcher.cpp 2020-04-02 14:11:54.000000000 +0300 @@ -2358,6 +2358,20 @@ n->del_req(3); break; } + case Op_VectorBlend: + case Op_VectorInsert: { + Node* pair = new BinaryNode(n->in(1), n->in(2)); + n->set_req(1, pair); + n->set_req(2, n->in(3)); + n->del_req(3); + break; + } + case Op_StoreVectorScatter: { + Node* pair = new BinaryNode(n->in(MemNode::ValueIn), n->in(MemNode::ValueIn+1)); + n->set_req(MemNode::ValueIn, pair); + n->del_req(MemNode::ValueIn+1); + break; + } case Op_MulAddS2I: { Node* pair1 = new BinaryNode(n->in(1), n->in(2)); Node* pair2 = new BinaryNode(n->in(3), n->in(4)); @@ -2367,6 +2381,14 @@ n->del_req(3); break; } +#ifdef X86 + case Op_VectorMaskCmp: { + n->set_req(1, new BinaryNode(n->in(1), n->in(2))); + n->set_req(2, n->in(3)); + n->del_req(3); + break; + } +#endif default: break; } --- old/src/hotspot/share/opto/memnode.cpp 2020-04-02 14:11:55.000000000 +0300 +++ new/src/hotspot/share/opto/memnode.cpp 2020-04-02 14:11:54.000000000 +0300 @@ -2539,6 +2539,8 @@ assert(Opcode() == st->Opcode() || st->Opcode() == Op_StoreVector || Opcode() == Op_StoreVector || + st->Opcode() == Op_StoreVectorScatter || + Opcode() == Op_StoreVectorScatter || phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw || (Opcode() == Op_StoreL && st->Opcode() == Op_StoreI) || // expanded ClearArrayNode (Opcode() == Op_StoreI && st->Opcode() == Op_StoreL) || // initialization by arraycopy --- old/src/hotspot/share/opto/movenode.cpp 2020-04-02 14:11:55.000000000 +0300 +++ new/src/hotspot/share/opto/movenode.cpp 2020-04-02 14:11:55.000000000 +0300 @@ -361,6 +361,14 @@ return TypeD::make( v.get_jdouble() ); } +//------------------------------Identity---------------------------------------- +Node* MoveL2DNode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_MoveD2L) { + return in(1)->in(1); + } + return this; +} + //------------------------------Value------------------------------------------ const Type* MoveI2FNode::Value(PhaseGVN* phase) const { const Type *t = phase->type( in(1) ); @@ -372,6 +380,14 @@ return TypeF::make( v.get_jfloat() ); } +//------------------------------Identity---------------------------------------- +Node* MoveI2FNode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_MoveF2I) { + return in(1)->in(1); + } + return this; +} + //------------------------------Value------------------------------------------ const Type* MoveF2INode::Value(PhaseGVN* phase) const { const Type *t = phase->type( in(1) ); @@ -383,6 +399,14 @@ return TypeInt::make( v.get_jint() ); } +//------------------------------Identity---------------------------------------- +Node* MoveF2INode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_MoveI2F) { + return in(1)->in(1); + } + return this; +} + //------------------------------Value------------------------------------------ const Type* MoveD2LNode::Value(PhaseGVN* phase) const { const Type *t = phase->type( in(1) ); @@ -394,6 +418,14 @@ return TypeLong::make( v.get_jlong() ); } +//------------------------------Identity---------------------------------------- +Node* MoveD2LNode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_MoveL2D) { + return in(1)->in(1); + } + return this; +} + #ifndef PRODUCT //----------------------------BinaryNode--------------------------------------- // The set of related nodes for a BinaryNode is all data inputs and all outputs --- old/src/hotspot/share/opto/movenode.hpp 2020-04-02 14:11:56.000000000 +0300 +++ new/src/hotspot/share/opto/movenode.hpp 2020-04-02 14:11:55.000000000 +0300 @@ -105,6 +105,7 @@ virtual const Type *bottom_type() const { return Type::FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Identity(PhaseGVN* phase); }; class MoveL2DNode : public Node { @@ -114,6 +115,7 @@ virtual const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Identity(PhaseGVN* phase); }; class MoveF2INode : public Node { @@ -123,6 +125,7 @@ virtual const Type *bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Identity(PhaseGVN* phase); }; class MoveD2LNode : public Node { @@ -132,6 +135,7 @@ virtual const Type *bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Identity(PhaseGVN* phase); }; //------------------------------BinaryNode------------------------------------- --- old/src/hotspot/share/opto/mulnode.hpp 2020-04-02 14:11:56.000000000 +0300 +++ new/src/hotspot/share/opto/mulnode.hpp 2020-04-02 14:11:56.000000000 +0300 @@ -236,6 +236,25 @@ virtual uint ideal_reg() const { return Op_RegL; } }; +//------------------------------URShiftBNode----------------------------------- +// Logical shift right +class URShiftBNode : public Node { +public: + URShiftBNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { + ShouldNotReachHere(); // only vector variant is used + } + virtual int Opcode() const; +}; + +//------------------------------URShiftSNode----------------------------------- +// Logical shift right +class URShiftSNode : public Node { +public: + URShiftSNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { + ShouldNotReachHere(); // only vector variant is used + } + virtual int Opcode() const; +}; //------------------------------URShiftINode----------------------------------- // Logical shift right --- old/src/hotspot/share/opto/node.hpp 2020-04-02 14:11:56.000000000 +0300 +++ new/src/hotspot/share/opto/node.hpp 2020-04-02 14:11:56.000000000 +0300 @@ -152,7 +152,10 @@ class UnlockNode; class VectorNode; class LoadVectorNode; +class LoadVectorGatherNode; class StoreVectorNode; +class StoreVectorScatterNode; +class VectorMaskCmpNode; class VectorSet; typedef void (*NFunc)(Node&,void*); extern "C" { @@ -690,8 +693,10 @@ DEFINE_CLASS_ID(Mem, Node, 4) DEFINE_CLASS_ID(Load, Mem, 0) DEFINE_CLASS_ID(LoadVector, Load, 0) + DEFINE_CLASS_ID(LoadVectorGather, LoadVector, 0) DEFINE_CLASS_ID(Store, Mem, 1) DEFINE_CLASS_ID(StoreVector, Store, 0) + DEFINE_CLASS_ID(StoreVectorScatter, StoreVector, 0) DEFINE_CLASS_ID(LoadStore, Mem, 2) DEFINE_CLASS_ID(LoadStoreConditional, LoadStore, 0) DEFINE_CLASS_ID(CompareAndSwap, LoadStoreConditional, 0) @@ -716,6 +721,7 @@ DEFINE_CLASS_ID(Add, Node, 11) DEFINE_CLASS_ID(Mul, Node, 12) DEFINE_CLASS_ID(Vector, Node, 13) + DEFINE_CLASS_ID(VectorMaskCmp, Vector, 0) DEFINE_CLASS_ID(ClearArray, Node, 14) DEFINE_CLASS_ID(Halt, Node, 15) @@ -882,7 +888,10 @@ DEFINE_CLASS_QUERY(Type) DEFINE_CLASS_QUERY(Vector) DEFINE_CLASS_QUERY(LoadVector) + DEFINE_CLASS_QUERY(LoadVectorGather) DEFINE_CLASS_QUERY(StoreVector) + DEFINE_CLASS_QUERY(StoreVectorScatter) + DEFINE_CLASS_QUERY(VectorMaskCmp) DEFINE_CLASS_QUERY(Unlock) #undef DEFINE_CLASS_QUERY --- old/src/hotspot/share/opto/subnode.hpp 2020-04-02 14:11:57.000000000 +0300 +++ new/src/hotspot/share/opto/subnode.hpp 2020-04-02 14:11:57.000000000 +0300 @@ -403,6 +403,28 @@ NegNode( Node *in1 ) : Node(0,in1) {} }; +//------------------------------NegINode--------------------------------------- +// Negate value an int. For int values, negation is the same as subtraction +// from zero +class NegINode : public NegNode { +public: + NegINode(Node *in1) : NegNode(in1) {} + virtual int Opcode() const; + const Type *bottom_type() const { return TypeInt::INT; } + virtual uint ideal_reg() const { return Op_RegI; } +}; + +//------------------------------NegLNode--------------------------------------- +// Negate value an int. For int values, negation is the same as subtraction +// from zero +class NegLNode : public NegNode { +public: + NegLNode(Node *in1) : NegNode(in1) {} + virtual int Opcode() const; + const Type *bottom_type() const { return TypeLong::LONG; } + virtual uint ideal_reg() const { return Op_RegL; } +}; + //------------------------------NegFNode--------------------------------------- // Negate value a float. Negating 0.0 returns -0.0, but subtracting from // zero returns +0.0 (per JVM spec on 'fneg' bytecode). As subtraction @@ -473,6 +495,14 @@ virtual const Type* Value(PhaseGVN* phase) const; }; +//--------------------------------NotNode----------------------------------------- +// not for byte, short, int and long +class NotNode : public Node { +public: + NotNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {} + virtual int Opcode() const; +}; + //-------------------------------ReverseBytesINode-------------------------------- // reverse bytes of an integer class ReverseBytesINode : public Node { --- old/src/hotspot/share/opto/superword.cpp 2020-04-02 14:11:57.000000000 +0300 +++ new/src/hotspot/share/opto/superword.cpp 2020-04-02 14:11:57.000000000 +0300 @@ -2742,7 +2742,7 @@ } } // Move shift count into vector register. - cnt = VectorNode::shift_count(p0, cnt, vlen, velt_basic_type(p0)); + cnt = VectorNode::shift_count(p0->Opcode(), cnt, vlen, velt_basic_type(p0)); _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); return cnt; --- old/src/hotspot/share/opto/type.cpp 2020-04-02 14:11:58.000000000 +0300 +++ new/src/hotspot/share/opto/type.cpp 2020-04-02 14:11:57.000000000 +0300 @@ -442,16 +442,22 @@ BOTTOM = make(Bottom); // Everything HALF = make(Half); // Placeholder half of doublewide type + TypeF::MAX = TypeF::make(max_jfloat); // Float MAX + TypeF::MIN = TypeF::make(min_jfloat); // Float MIN TypeF::ZERO = TypeF::make(0.0); // Float 0 (positive zero) TypeF::ONE = TypeF::make(1.0); // Float 1 TypeF::POS_INF = TypeF::make(jfloat_cast(POSITIVE_INFINITE_F)); TypeF::NEG_INF = TypeF::make(-jfloat_cast(POSITIVE_INFINITE_F)); + TypeD::MAX = TypeD::make(max_jdouble); // Double MAX + TypeD::MIN = TypeD::make(min_jdouble); // Double MIN TypeD::ZERO = TypeD::make(0.0); // Double 0 (positive zero) TypeD::ONE = TypeD::make(1.0); // Double 1 TypeD::POS_INF = TypeD::make(jdouble_cast(POSITIVE_INFINITE_D)); TypeD::NEG_INF = TypeD::make(-jdouble_cast(POSITIVE_INFINITE_D)); + TypeInt::MAX = TypeInt::make(max_jint); // Int MAX + TypeInt::MIN = TypeInt::make(min_jint); // Int MIN TypeInt::MINUS_1 = TypeInt::make(-1); // -1 TypeInt::ZERO = TypeInt::make( 0); // 0 TypeInt::ONE = TypeInt::make( 1); // 1 @@ -480,6 +486,8 @@ assert( TypeInt::CC_GE == TypeInt::BOOL, "types must match for CmpL to work" ); assert( (juint)(TypeInt::CC->_hi - TypeInt::CC->_lo) <= SMALLINT, "CC is truly small"); + TypeLong::MAX = TypeLong::make(max_jlong); // Long MAX + TypeLong::MIN = TypeLong::make(min_jlong); // Long MIN TypeLong::MINUS_1 = TypeLong::make(-1); // -1 TypeLong::ZERO = TypeLong::make( 0); // 0 TypeLong::ONE = TypeLong::make( 1); // 1 @@ -859,6 +867,7 @@ #ifdef ASSERT if (isa_narrowoop() || t->isa_narrowoop()) return mt; if (isa_narrowklass() || t->isa_narrowklass()) return mt; + if (isa_vect() || t->isa_vect()) return mt; Compile* C = Compile::current(); if (!C->_type_verify_symmetry) { return mt; @@ -1115,6 +1124,8 @@ //============================================================================= // Convenience common pre-built types. +const TypeF *TypeF::MAX; // Floating point max +const TypeF *TypeF::MIN; // Floating point min const TypeF *TypeF::ZERO; // Floating point zero const TypeF *TypeF::ONE; // Floating point one const TypeF *TypeF::POS_INF; // Floating point positive infinity @@ -1225,6 +1236,8 @@ //============================================================================= // Convenience common pre-built types. +const TypeD *TypeD::MAX; // Floating point max +const TypeD *TypeD::MIN; // Floating point min const TypeD *TypeD::ZERO; // Floating point zero const TypeD *TypeD::ONE; // Floating point one const TypeD *TypeD::POS_INF; // Floating point positive infinity @@ -1331,6 +1344,8 @@ //============================================================================= // Convience common pre-built types. +const TypeInt *TypeInt::MAX; // INT_MAX +const TypeInt *TypeInt::MIN; // INT_MIN const TypeInt *TypeInt::MINUS_1;// -1 const TypeInt *TypeInt::ZERO; // 0 const TypeInt *TypeInt::ONE; // 1 @@ -1600,6 +1615,8 @@ //============================================================================= // Convenience common pre-built types. +const TypeLong *TypeLong::MAX; +const TypeLong *TypeLong::MIN; const TypeLong *TypeLong::MINUS_1;// -1 const TypeLong *TypeLong::ZERO; // 0 const TypeLong *TypeLong::ONE; // 1 --- old/src/hotspot/share/opto/type.hpp 2020-04-02 14:11:58.000000000 +0300 +++ new/src/hotspot/share/opto/type.hpp 2020-04-02 14:11:58.000000000 +0300 @@ -481,6 +481,8 @@ virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. // Convenience common pre-built types. + static const TypeF *MAX; + static const TypeF *MIN; static const TypeF *ZERO; // positive zero only static const TypeF *ONE; static const TypeF *POS_INF; @@ -510,6 +512,8 @@ virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. // Convenience common pre-built types. + static const TypeD *MAX; + static const TypeD *MIN; static const TypeD *ZERO; // positive zero only static const TypeD *ONE; static const TypeD *POS_INF; @@ -553,6 +557,8 @@ virtual const Type *narrow( const Type *t ) const; // Do not kill _widen bits. // Convenience common pre-built types. + static const TypeInt *MAX; + static const TypeInt *MIN; static const TypeInt *MINUS_1; static const TypeInt *ZERO; static const TypeInt *ONE; @@ -618,6 +624,8 @@ virtual const Type *widen( const Type *t, const Type* limit_type ) const; virtual const Type *narrow( const Type *t ) const; // Convenience common pre-built types. + static const TypeLong *MAX; + static const TypeLong *MIN; static const TypeLong *MINUS_1; static const TypeLong *ZERO; static const TypeLong *ONE; --- old/src/hotspot/share/opto/vectornode.cpp 2020-04-02 14:11:59.000000000 +0300 +++ new/src/hotspot/share/opto/vectornode.cpp 2020-04-02 14:11:58.000000000 +0300 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/connode.hpp" +#include "opto/subnode.hpp" #include "opto/vectornode.hpp" #include "utilities/powerOfTwo.hpp" @@ -117,12 +118,51 @@ case Op_AbsL: assert(bt == T_LONG, "must be"); return Op_AbsVL; + case Op_MinI: + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: return Op_MinV; + default: ShouldNotReachHere(); return 0; + } + case Op_MinL: + assert(bt == T_LONG, "must be"); + return Op_MinV; + case Op_MinF: + assert(bt == T_FLOAT, "must be"); + return Op_MinV; + case Op_MinD: + assert(bt == T_DOUBLE, "must be"); + return Op_MinV; + case Op_MaxI: + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: return Op_MaxV; + default: ShouldNotReachHere(); return 0; + } + case Op_MaxL: + assert(bt == T_LONG, "must be"); + return Op_MaxV; + case Op_MaxF: + assert(bt == T_FLOAT, "must be"); + return Op_MaxV; + case Op_MaxD: + assert(bt == T_DOUBLE, "must be"); + return Op_MaxV; case Op_AbsF: assert(bt == T_FLOAT, "must be"); return Op_AbsVF; case Op_AbsD: assert(bt == T_DOUBLE, "must be"); return Op_AbsVD; + case Op_NegI: + assert(bt == T_INT, "must be"); + return Op_NegVI; case Op_NegF: assert(bt == T_FLOAT, "must be"); return Op_NegVF; @@ -138,6 +178,8 @@ case Op_SqrtD: assert(bt == T_DOUBLE, "must be"); return Op_SqrtVD; + case Op_Not: + return Op_NotV; case Op_PopCountI: if (bt == T_INT) { return Op_PopCountVI; @@ -169,6 +211,12 @@ case Op_RShiftL: assert(bt == T_LONG, "must be"); return Op_RShiftVL; + case Op_URShiftB: + assert(bt == T_BYTE, "must be"); + return Op_URShiftVB; + case Op_URShiftS: + assert(bt == T_SHORT, "must be"); + return Op_URShiftVS; case Op_URShiftI: switch (bt) { case T_BOOLEAN:return Op_URShiftVB; @@ -194,18 +242,6 @@ case Op_XorI: case Op_XorL: return Op_XorV; - case Op_MinF: - assert(bt == T_FLOAT, "must be"); - return Op_MinV; - case Op_MinD: - assert(bt == T_DOUBLE, "must be"); - return Op_MinV; - case Op_MaxF: - assert(bt == T_FLOAT, "must be"); - return Op_MaxV; - case Op_MaxD: - assert(bt == T_DOUBLE, "must be"); - return Op_MaxV; case Op_LoadB: case Op_LoadUB: @@ -232,6 +268,29 @@ } } +int VectorNode::replicate_opcode(BasicType bt) { + switch(bt) { + case T_BOOLEAN: + case T_BYTE: + return Op_ReplicateB; + case T_SHORT: + case T_CHAR: + return Op_ReplicateS; + case T_INT: + return Op_ReplicateI; + case T_LONG: + return Op_ReplicateL; + case T_FLOAT: + return Op_ReplicateF; + case T_DOUBLE: + return Op_ReplicateD; + default: + break; + } + + return 0; +} + // Also used to check if the code generator // supports the vector operation. bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { @@ -284,6 +343,38 @@ } } +bool VectorNode::is_vshift(Node* n) { + switch (n->Opcode()) { + case Op_LShiftVB: + case Op_LShiftVS: + case Op_LShiftVI: + case Op_LShiftVL: + + case Op_RShiftVB: + case Op_RShiftVS: + case Op_RShiftVI: + case Op_RShiftVL: + + case Op_URShiftVB: + case Op_URShiftVS: + case Op_URShiftVI: + case Op_URShiftVL: + return true; + default: + return false; + } +} + +bool VectorNode::is_vshift_cnt(Node* n) { + switch (n->Opcode()) { + case Op_LShiftCntV: + case Op_RShiftCntV: + return true; + default: + return false; + } +} + // Check if input is loop invariant vector. bool VectorNode::is_invariant_vector(Node* n) { // Only Replicate vector nodes are loop invariant for now. @@ -350,12 +441,10 @@ } } -// Return the vector version of a scalar operation node. -VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { - const TypeVect* vt = TypeVect::make(bt, vlen); - int vopc = VectorNode::opcode(opc, bt); +// Make a vector node for binary operation +VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt) { // This method should not be called for unimplemented vectors. - guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]); + guarantee(vopc > 0, "vopc must be > 0"); switch (vopc) { case Op_AddVB: return new AddVBNode(n1, n2, vt); case Op_AddVS: return new AddVSNode(n1, n2, vt); @@ -381,13 +470,18 @@ case Op_DivVF: return new DivVFNode(n1, n2, vt); case Op_DivVD: return new DivVDNode(n1, n2, vt); + case Op_MinV: return new MinVNode(n1, n2, vt); + case Op_MaxV: return new MaxVNode(n1, n2, vt); + + case Op_AbsV: return new AbsVNode(n1, vt); + case Op_AbsVF: return new AbsVFNode(n1, vt); + case Op_AbsVD: return new AbsVDNode(n1, vt); case Op_AbsVB: return new AbsVBNode(n1, vt); case Op_AbsVS: return new AbsVSNode(n1, vt); case Op_AbsVI: return new AbsVINode(n1, vt); case Op_AbsVL: return new AbsVLNode(n1, vt); - case Op_AbsVF: return new AbsVFNode(n1, vt); - case Op_AbsVD: return new AbsVDNode(n1, vt); + case Op_NegVI: return new NegVINode(n1, vt); case Op_NegVF: return new NegVFNode(n1, vt); case Op_NegVD: return new NegVDNode(n1, vt); @@ -395,6 +489,7 @@ case Op_SqrtVD: return new SqrtVDNode(n1, vt); case Op_PopCountVI: return new PopCountVINode(n1, vt); + case Op_NotV: return new NotVNode(n1, vt); case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt); case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt); @@ -411,13 +506,15 @@ case Op_URShiftVI: return new URShiftVINode(n1, n2, vt); case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt); + // Variable shift left + case Op_VLShiftV: return new VLShiftVNode(n1, n2, vt); + case Op_VRShiftV: return new VRShiftVNode(n1, n2, vt); + case Op_VURShiftV: return new VURShiftVNode(n1, n2, vt); + case Op_AndV: return new AndVNode(n1, n2, vt); case Op_OrV: return new OrVNode (n1, n2, vt); case Op_XorV: return new XorVNode(n1, n2, vt); - case Op_MinV: return new MinVNode(n1, n2, vt); - case Op_MaxV: return new MaxVNode(n1, n2, vt); - case Op_RoundDoubleModeV: return new RoundDoubleModeVNode(n1, n2, vt); case Op_MulAddVS2VI: return new MulAddVS2VINode(n1, n2, vt); @@ -427,11 +524,19 @@ } } -VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) { +// Return the vector version of a scalar binary operation node. +VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { const TypeVect* vt = TypeVect::make(bt, vlen); int vopc = VectorNode::opcode(opc, bt); // This method should not be called for unimplemented vectors. guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]); + return make(vopc, n1, n2, vt); +} + +// Make a vector node for ternary operation +VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt) { + // This method should not be called for unimplemented vectors. + guarantee(vopc > 0, "vopc must be > 0"); switch (vopc) { case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt); case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt); @@ -441,6 +546,15 @@ } } +// Return the vector version of a scalar ternary operation node. +VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) { + const TypeVect* vt = TypeVect::make(bt, vlen); + int vopc = VectorNode::opcode(opc, bt); + // This method should not be called for unimplemented vectors. + guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]); + return make(vopc, n1, n2, n3, vt); +} + // Scalar promotion VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) { BasicType bt = opd_t->array_element_basic_type(); @@ -467,21 +581,22 @@ } } -VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) { - assert(VectorNode::is_shift(shift), "sanity"); +VectorNode* VectorNode::shift_count(int opc, Node* cnt, uint vlen, BasicType bt) { // Match shift count type with shift vector type. const TypeVect* vt = TypeVect::make(bt, vlen); - switch (shift->Opcode()) { + switch (opc) { case Op_LShiftI: case Op_LShiftL: return new LShiftCntVNode(cnt, vt); case Op_RShiftI: case Op_RShiftL: + case Op_URShiftB: + case Op_URShiftS: case Op_URShiftI: case Op_URShiftL: return new RShiftCntVNode(cnt, vt); default: - fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]); + fatal("Missed vector creation for '%s'", NodeClassNames[opc]); return NULL; } } @@ -595,6 +710,30 @@ return new StoreVectorNode(ctl, mem, adr, atyp, val); } +int ExtractNode::opcode(BasicType bt) { + switch (bt) { + case T_BOOLEAN: + return Op_ExtractUB; + case T_BYTE: + return Op_ExtractB; + case T_CHAR: + return Op_ExtractC; + case T_SHORT: + return Op_ExtractS; + case T_INT: + return Op_ExtractI; + case T_LONG: + return Op_ExtractL; + case T_FLOAT: + return Op_ExtractF; + case T_DOUBLE: + return Op_ExtractD; + default: + fatal("Type '%s' is not supported for vectors", type2name(bt)); + return 0; + } +} + // Extract a scalar element of vector. Node* ExtractNode::make(Node* v, uint position, BasicType bt) { assert((int)position < Matcher::max_vector_size(bt), "pos in range"); @@ -626,8 +765,16 @@ int vopc = opc; switch (opc) { case Op_AddI: - assert(bt == T_INT, "must be"); - vopc = Op_AddReductionVI; + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_AddReductionVI; + break; + default: ShouldNotReachHere(); return 0; + } break; case Op_AddL: assert(bt == T_LONG, "must be"); @@ -642,8 +789,16 @@ vopc = Op_AddReductionVD; break; case Op_MulI: - assert(bt == T_INT, "must be"); - vopc = Op_MulReductionVI; + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_MulReductionVI; + break; + default: ShouldNotReachHere(); return 0; + } break; case Op_MulL: assert(bt == T_LONG, "must be"); @@ -657,6 +812,22 @@ assert(bt == T_DOUBLE, "must be"); vopc = Op_MulReductionVD; break; + case Op_MinI: + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_MinReductionV; + break; + default: ShouldNotReachHere(); return 0; + } + break; + case Op_MinL: + assert(bt == T_LONG, "must be"); + vopc = Op_MinReductionV; + break; case Op_MinF: assert(bt == T_FLOAT, "must be"); vopc = Op_MinReductionV; @@ -665,6 +836,22 @@ assert(bt == T_DOUBLE, "must be"); vopc = Op_MinReductionV; break; + case Op_MaxI: + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_MaxReductionV; + break; + default: ShouldNotReachHere(); return 0; + } + break; + case Op_MaxL: + assert(bt == T_LONG, "must be"); + vopc = Op_MaxReductionV; + break; case Op_MaxF: assert(bt == T_FLOAT, "must be"); vopc = Op_MaxReductionV; @@ -674,24 +861,48 @@ vopc = Op_MaxReductionV; break; case Op_AndI: - assert(bt == T_INT, "must be"); - vopc = Op_AndReductionV; + switch (bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_AndReductionV; + break; + default: ShouldNotReachHere(); return 0; + } break; case Op_AndL: assert(bt == T_LONG, "must be"); vopc = Op_AndReductionV; break; case Op_OrI: - assert(bt == T_INT, "must be"); - vopc = Op_OrReductionV; + switch(bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_OrReductionV; + break; + default: ShouldNotReachHere(); return 0; + } break; case Op_OrL: assert(bt == T_LONG, "must be"); vopc = Op_OrReductionV; break; case Op_XorI: - assert(bt == T_INT, "must be"); - vopc = Op_XorReductionV; + switch(bt) { + case T_BOOLEAN: + case T_CHAR: return 0; + case T_BYTE: + case T_SHORT: + case T_INT: + vopc = Op_XorReductionV; + break; + default: ShouldNotReachHere(); return 0; + } break; case Op_XorL: assert(bt == T_LONG, "must be"); @@ -731,6 +942,102 @@ } } +VectorCastNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) { + const TypeVect* vt = TypeVect::make(bt, vlen); + switch (vopc) { + case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt); + case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt); + case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt); + case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt); + case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt); + case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt); + default: fatal("unknown node: %s", NodeClassNames[vopc]); + } + return NULL; +} + +int VectorCastNode::opcode(BasicType bt) { + switch (bt) { + case T_BYTE: return Op_VectorCastB2X; + case T_SHORT: return Op_VectorCastS2X; + case T_INT: return Op_VectorCastI2X; + case T_LONG: return Op_VectorCastL2X; + case T_FLOAT: return Op_VectorCastF2X; + case T_DOUBLE: return Op_VectorCastD2X; + default: Unimplemented(); + } + return 0; +} + +Node* ReductionNode::make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt) { + int vopc = opcode(opc, bt); + guarantee(vopc != opc, "Vector reduction for '%s' is not implemented", NodeClassNames[opc]); + + switch (vopc) { + case Op_AndReductionV: + switch (bt) { + case T_BYTE: + case T_SHORT: + case T_INT: + return gvn.makecon(TypeInt::MINUS_1); + case T_LONG: + return gvn.makecon(TypeLong::MINUS_1); + default: + fatal("Missed vector creation for '%s' as the basic type is not correct.", NodeClassNames[vopc]); + return NULL; + } + break; + case Op_AddReductionVI: // fallthrough + case Op_AddReductionVL: // fallthrough + case Op_AddReductionVF: // fallthrough + case Op_AddReductionVD: + case Op_OrReductionV: + case Op_XorReductionV: + return gvn.zerocon(bt); + case Op_MulReductionVI: + return gvn.makecon(TypeInt::ONE); + case Op_MulReductionVL: + return gvn.makecon(TypeLong::ONE); + case Op_MulReductionVF: + return gvn.makecon(TypeF::ONE); + case Op_MulReductionVD: + return gvn.makecon(TypeD::ONE); + case Op_MinReductionV: + switch (bt) { + case T_BYTE: + case T_SHORT: + case T_INT: + return gvn.makecon(TypeInt::MAX); + case T_LONG: + return gvn.makecon(TypeLong::MAX); + case T_FLOAT: + return gvn.makecon(TypeF::POS_INF); + case T_DOUBLE: + return gvn.makecon(TypeD::POS_INF); + default: Unimplemented(); return NULL; + } + break; + case Op_MaxReductionV: + switch (bt) { + case T_BYTE: + case T_SHORT: + case T_INT: + return gvn.makecon(TypeInt::MIN); + case T_LONG: + return gvn.makecon(TypeLong::MIN); + case T_FLOAT: + return gvn.makecon(TypeF::NEG_INF); + case T_DOUBLE: + return gvn.makecon(TypeD::NEG_INF); + default: Unimplemented(); return NULL; + } + break; + default: + fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); + return NULL; + } +} + bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) { if (is_java_primitive(bt) && (vlen > 1) && is_power_of_2(vlen) && @@ -740,3 +1047,26 @@ } return false; } + +#ifndef PRODUCT +void VectorMaskCmpNode::dump_spec(outputStream *st) const { + st->print(" %d #", _predicate); _type->dump_on(st); +} +#endif // PRODUCT + +Node* VectorReinterpretNode::Identity(PhaseGVN *phase) { + Node* n = in(1); + if (n->Opcode() == Op_VectorReinterpret) { + if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0) { + return n->in(1); + } + } + return this; +} + +Node* VectorInsertNode::make(Node* vec, Node* new_val, int position) { + assert(position < (int)vec->bottom_type()->is_vect()->length(), "pos in range"); + ConINode* pos = ConINode::make(position); + return new VectorInsertNode(vec, new_val, pos, vec->bottom_type()->is_vect()); +} + --- old/src/hotspot/share/opto/vectornode.hpp 2020-04-02 14:11:59.000000000 +0300 +++ new/src/hotspot/share/opto/vectornode.hpp 2020-04-02 14:11:59.000000000 +0300 @@ -60,13 +60,18 @@ virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); } static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t); - static VectorNode* shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt); + static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt); static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt); + static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt); static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt); + static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt); static int opcode(int opc, BasicType bt); + static int replicate_opcode(BasicType bt); static bool implemented(int opc, uint vlen, BasicType bt); static bool is_shift(Node* n); + static bool is_vshift(Node* n); + static bool is_vshift_cnt(Node* n); static bool is_type_transition_short_to_int(Node* n); static bool is_type_transition_to_int(Node* n); static bool is_muladds2i(Node* n); @@ -145,9 +150,10 @@ static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt); static int opcode(int opc, BasicType bt); static bool implemented(int opc, uint vlen, BasicType bt); + static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt); virtual const Type* bottom_type() const { - BasicType vbt = in(2)->bottom_type()->is_vect()->element_basic_type(); + BasicType vbt = in(1)->bottom_type()->basic_type(); return Type::get_const_basic_type(vbt); } @@ -157,12 +163,11 @@ }; //------------------------------AddReductionVINode-------------------------------------- -// Vector add int as a reduction +// Vector add byte, short and int as a reduction class AddReductionVINode : public ReductionNode { public: AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; - virtual const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -333,12 +338,11 @@ }; //------------------------------MulReductionVINode-------------------------------------- -// Vector multiply int as a reduction +// Vector multiply byte, short and int as a reduction class MulReductionVINode : public ReductionNode { public: MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; - virtual const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -349,7 +353,7 @@ MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; virtual const Type* bottom_type() const { return TypeLong::LONG; } - virtual uint ideal_reg() const { return Op_RegI; } + virtual uint ideal_reg() const { return Op_RegL; } }; //------------------------------MulReductionVFNode-------------------------------------- @@ -404,6 +408,30 @@ virtual int Opcode() const; }; +//------------------------------MinVNode-------------------------------------- +// Vector Min +class MinVNode : public VectorNode { +public: + MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} + virtual int Opcode() const; +}; + +//------------------------------MaxVNode-------------------------------------- +// Vector Max +class MaxVNode : public VectorNode { +public: + MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} + virtual int Opcode() const; +}; + +//------------------------------AbsVNode-------------------------------------- +// Vector Abs +class AbsVNode : public VectorNode { +public: + AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} + virtual int Opcode() const; +}; + //------------------------------AbsVINode-------------------------------------- // Vector Abs int class AbsVINode : public VectorNode { @@ -436,6 +464,14 @@ virtual int Opcode() const; }; +//------------------------------NegVINode-------------------------------------- +// Vector Neg int +class NegVINode : public VectorNode { +public: + NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} + virtual int Opcode() const; +}; + //------------------------------NegVFNode-------------------------------------- // Vector Neg float class NegVFNode : public VectorNode { @@ -483,6 +519,14 @@ virtual int Opcode() const; }; +//------------------------------NotVNode-------------------------------------- +// Vector Not +class NotVNode : public VectorNode { +public: + NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} + virtual int Opcode() const; +}; + //------------------------------LShiftVBNode----------------------------------- // Vector left shift bytes class LShiftVBNode : public VectorNode { @@ -598,40 +642,56 @@ }; -//------------------------------AndVNode--------------------------------------- -// Vector and integer -class AndVNode : public VectorNode { +//------------------------------VLShiftVNode----------------------------------- +// Variable vector left shift bytes +class VLShiftVNode : public VectorNode { public: - AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} + VLShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; }; -//------------------------------OrVNode--------------------------------------- -// Vector or integer -class OrVNode : public VectorNode { +//------------------------------VRShiftVNode----------------------------------- +// Variable vector right shift bytes +class VRShiftVNode : public VectorNode { public: - OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} + VRShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; }; -//------------------------------XorVNode--------------------------------------- -// Vector xor integer -class XorVNode : public VectorNode { +//------------------------------VURShiftVNode----------------------------------- +// Variable vector unsigned right shift bytes +class VURShiftVNode : public VectorNode { public: - XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} + VURShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} + virtual int Opcode() const; +}; + +//------------------------------AndVNode--------------------------------------- +// Vector and integer +class AndVNode : public VectorNode { + public: + AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; }; //------------------------------AndReductionVNode-------------------------------------- -// Vector and int, long as a reduction +// Vector and byte, short, int, long as a reduction class AndReductionVNode : public ReductionNode { public: AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; }; +//------------------------------OrVNode--------------------------------------- +// Vector or byte, short, int, long as a reduction +class OrVNode : public VectorNode { + public: + OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} + virtual int Opcode() const; +}; + //------------------------------OrReductionVNode-------------------------------------- -// Vector or int, long as a reduction +// Vector xor byte, short, int, long as a reduction class OrReductionVNode : public ReductionNode { public: OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} @@ -639,31 +699,23 @@ }; //------------------------------XorReductionVNode-------------------------------------- -// Vector xor int, long as a reduction +// Vector and int, long as a reduction class XorReductionVNode : public ReductionNode { public: XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; }; -//------------------------------MinVNode-------------------------------------- -// Vector min -class MinVNode : public VectorNode { -public: - MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} - virtual int Opcode() const; -}; - -//------------------------------MaxVNode-------------------------------------- -// Vector max -class MaxVNode : public VectorNode { -public: - MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} +//------------------------------XorVNode--------------------------------------- +// Vector xor integer +class XorVNode : public VectorNode { + public: + XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; }; //------------------------------MinReductionVNode-------------------------------------- -// Vector min as a reduction +// Vector min byte, short, int, long, float, double as a reduction class MinReductionVNode : public ReductionNode { public: MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} @@ -671,7 +723,7 @@ }; //------------------------------MaxReductionVNode-------------------------------------- -// Vector max as a reduction +// Vector min byte, short, int, long, float, double as a reduction class MaxReductionVNode : public ReductionNode { public: MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} @@ -708,13 +760,28 @@ uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } }; +//------------------------------LoadVectorGatherNode------------------------------ +// Load Vector from memory via index map +class LoadVectorGatherNode : public LoadVectorNode { + public: + LoadVectorGatherNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, Node* indices) + : LoadVectorNode(c, mem, adr, at, vt) { + init_class_id(Class_LoadVectorGather); + assert(indices->bottom_type()->is_vect(), "indices must be in vector"); + add_req(indices); + assert(req() == MemNode::ValueIn + 1, "match_edge expects that last input is in MemNode::ValueIn"); + } + + virtual int Opcode() const; + virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } +}; + //------------------------------StoreVectorNode-------------------------------- // Store Vector to memory class StoreVectorNode : public StoreNode { public: StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val) : StoreNode(c, mem, adr, at, val, MemNode::unordered) { - assert(val->is_Vector() || val->is_LoadVector(), "sanity"); init_class_id(Class_StoreVector); set_mismatched_access(); } @@ -735,6 +802,23 @@ uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } }; +//------------------------------StoreVectorScatterNode------------------------------ +// Store Vector into memory via index map + + class StoreVectorScatterNode : public StoreVectorNode { + public: + StoreVectorScatterNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices) + : StoreVectorNode(c, mem, adr, at, val) { + init_class_id(Class_StoreVectorScatter); + assert(indices->bottom_type()->is_vect(), "indices must be in vector"); + add_req(indices); + assert(req() == MemNode::ValueIn + 2, "match_edge expects that last input is in MemNode::ValueIn+1"); + } + virtual int Opcode() const; + virtual uint match_edge(uint idx) const { return idx == MemNode::Address || + idx == MemNode::ValueIn || + idx == MemNode::ValueIn + 1; } +}; //=========================Promote_Scalar_to_Vector============================ @@ -876,6 +960,12 @@ }; +class VectorLoadConstNode : public VectorNode { + public: + VectorLoadConstNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} + virtual int Opcode() const; +}; + //========================Extract_Scalar_from_Vector=========================== //------------------------------ExtractNode------------------------------------ @@ -889,6 +979,7 @@ uint pos() const { return in(2)->get_int(); } static Node* make(Node* v, uint position, BasicType bt); + static int opcode(BasicType bt); }; //------------------------------ExtractBNode----------------------------------- @@ -917,7 +1008,7 @@ public: ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} virtual int Opcode() const; - virtual const Type *bottom_type() const { return TypeInt::INT; } + virtual const Type *bottom_type() const { return TypeInt::CHAR; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -927,7 +1018,7 @@ public: ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} virtual int Opcode() const; - virtual const Type *bottom_type() const { return TypeInt::INT; } + virtual const Type *bottom_type() const { return TypeInt::SHORT; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -982,4 +1073,237 @@ virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } }; +class VectorMaskCmpNode : public VectorNode { + private: + BoolTest::mask _predicate; + + protected: + uint size_of() const { return sizeof(*this); } + + public: + VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, ConINode* predicate_node, const TypeVect* vt) : +#ifdef X86 + VectorNode(in1, in2, predicate_node, vt), +#else + VectorNode(in1, in2, vt), +#endif + _predicate(predicate) { + assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), + "VectorMaskCmp inputs must have same type for elements"); + assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), + "VectorMaskCmp inputs must have same number of elements"); + init_class_id(Class_VectorMaskCmp); + } + + virtual int Opcode() const; + virtual uint hash() const { return VectorNode::hash() + _predicate; } + virtual bool cmp( const Node &n ) const { + return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; + } + BoolTest::mask get_predicate() { return _predicate; } +#ifndef PRODUCT + virtual void dump_spec(outputStream *st) const; +#endif // PRODUCT +}; + +// Used to wrap other vector nodes in order to add masking functionality. +class VectorMaskWrapperNode : public VectorNode { +public: + VectorMaskWrapperNode(Node* vector, Node* mask) + : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { + assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); + } + + virtual int Opcode() const; + Node* vector_val() const { return in(1); } + Node* vector_mask() const { return in(2); } +}; + +class VectorTestNode : public Node { + private: + BoolTest::mask _predicate; + + protected: + uint size_of() const { return sizeof(*this); } + + public: + VectorTestNode( Node *in1, Node *in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) { + assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector"); + assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector"); + assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), + "same type elements are needed"); + assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), + "same number of elements is needed"); + } + virtual int Opcode() const; + virtual uint hash() const { return Node::hash() + _predicate; } + virtual bool cmp( const Node &n ) const { + return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; + } + virtual const Type *bottom_type() const { return TypeInt::BOOL; } + virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest + // in middle-end, we make it boolean result directly. + BoolTest::mask get_predicate() const { return _predicate; } +}; + +class VectorBlendNode : public VectorNode { +public: + VectorBlendNode(Node* vec1, Node* vec2, Node* mask) + : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { + // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); + } + + virtual int Opcode() const; + Node* vec1() const { return in(1); } + Node* vec2() const { return in(2); } + Node* vec_mask() const { return in(3); } +}; + +class VectorRearrangeNode : public VectorNode { +public: + VectorRearrangeNode(Node* vec1, Node* shuffle) + : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) { + // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); + } + + virtual int Opcode() const; + Node* vec1() const { return in(1); } + Node* vec_shuffle() const { return in(2); } +}; + + +class VectorLoadMaskNode : public VectorNode { + public: + VectorLoadMaskNode(Node* in, const TypeVect* vt) + : VectorNode(in, vt) { + assert(in->is_LoadVector(), "expected load vector"); + assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean"); + } + + int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); } + virtual int Opcode() const; +}; + +class VectorLoadShuffleNode : public VectorNode { +public: + VectorLoadShuffleNode(Node* in, const TypeVect* vt) + : VectorNode(in, vt) { + assert(in->is_LoadVector(), "expected load vector"); + assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BYTE, "must be BYTE"); + } + + int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); } + virtual int Opcode() const; +}; + +class VectorStoreMaskNode : public VectorNode { + private: + int _mask_size; + protected: + uint size_of() const { return sizeof(*this); } + + public: + VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem) + : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) { + _mask_size = type2aelembytes(in_type); + } + + virtual uint hash() const { return VectorNode::hash() + _mask_size; } + virtual bool cmp( const Node &n ) const { + return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size; + } + int GetInputMaskSize() const { return _mask_size; } + virtual int Opcode() const; +}; + +// This is intended for use as a simple reinterpret node that has no cast. +class VectorReinterpretNode : public VectorNode { + private: + const TypeVect* _src_vt; + protected: + uint size_of() const { return sizeof(*this); } + public: + VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) + : VectorNode(in, dst_vt), _src_vt(src_vt) { } + + virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } + virtual bool cmp( const Node &n ) const { + return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); + } + virtual Node *Identity(PhaseGVN *phase); + + virtual int Opcode() const; +}; + +class VectorCastNode : public VectorNode { + public: + VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} + virtual int Opcode() const; + + static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); + static int opcode(BasicType bt); + static bool implemented(BasicType bt, uint vlen); +}; + +class VectorCastB2XNode : public VectorCastNode { +public: + VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); + } + virtual int Opcode() const; +}; + +class VectorCastS2XNode : public VectorCastNode { +public: + VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); + } + virtual int Opcode() const; +}; + +class VectorCastI2XNode : public VectorCastNode { +public: + VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); + } + virtual int Opcode() const; +}; + +class VectorCastL2XNode : public VectorCastNode { +public: + VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long"); + } + virtual int Opcode() const; +}; + +class VectorCastF2XNode : public VectorCastNode { +public: + VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); + } + virtual int Opcode() const; +}; + +class VectorCastD2XNode : public VectorCastNode { +public: + VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); + } + virtual int Opcode() const; +}; + +class VectorInsertNode : public VectorNode { + public: + VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { + assert(pos->get_int() >= 0, "positive constants"); + assert(pos->get_int() < (int)vt->length(), "index must be less than vector length"); + assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type"); + } + virtual int Opcode() const; + uint pos() const { return in(3)->get_int(); } + + static Node* make(Node* vec, Node* new_val, int position); +}; + #endif // SHARE_OPTO_VECTORNODE_HPP --- old/src/hotspot/share/runtime/vmStructs.cpp 2020-04-02 14:11:59.000000000 +0300 +++ new/src/hotspot/share/runtime/vmStructs.cpp 2020-04-02 14:11:59.000000000 +0300 @@ -1519,6 +1519,8 @@ declare_c2_type(MaxNode, AddNode) \ declare_c2_type(MaxINode, MaxNode) \ declare_c2_type(MinINode, MaxNode) \ + declare_c2_type(MaxLNode, MaxNode) \ + declare_c2_type(MinLNode, MaxNode) \ declare_c2_type(MaxFNode, MaxNode) \ declare_c2_type(MinFNode, MaxNode) \ declare_c2_type(MaxDNode, MaxNode) \ @@ -1754,19 +1756,25 @@ declare_c2_type(AbsDNode, AbsNode) \ declare_c2_type(CmpLTMaskNode, Node) \ declare_c2_type(NegNode, Node) \ + declare_c2_type(NegINode, NegNode) \ + declare_c2_type(NegLNode, NegNode) \ declare_c2_type(NegFNode, NegNode) \ declare_c2_type(NegDNode, NegNode) \ declare_c2_type(AtanDNode, Node) \ declare_c2_type(SqrtFNode, Node) \ declare_c2_type(SqrtDNode, Node) \ + declare_c2_type(NotNode, Node) \ declare_c2_type(ReverseBytesINode, Node) \ declare_c2_type(ReverseBytesLNode, Node) \ declare_c2_type(ReductionNode, Node) \ declare_c2_type(VectorNode, Node) \ - declare_c2_type(AbsVBNode, VectorNode) \ - declare_c2_type(AbsVSNode, VectorNode) \ - declare_c2_type(AbsVINode, VectorNode) \ - declare_c2_type(AbsVLNode, VectorNode) \ + declare_c2_type(AbsVNode, VectorNode) \ + declare_c2_type(AbsVFNode, VectorNode) \ + declare_c2_type(AbsVDNode, VectorNode) \ + declare_c2_type(AbsVBNode, VectorNode) \ + declare_c2_type(AbsVSNode, VectorNode) \ + declare_c2_type(AbsVINode, VectorNode) \ + declare_c2_type(AbsVLNode, VectorNode) \ declare_c2_type(AddVBNode, VectorNode) \ declare_c2_type(AddVSNode, VectorNode) \ declare_c2_type(AddVINode, VectorNode) \ @@ -1792,8 +1800,10 @@ declare_c2_type(MulVFNode, VectorNode) \ declare_c2_type(MulReductionVFNode, ReductionNode) \ declare_c2_type(MulVDNode, VectorNode) \ + declare_c2_type(NegVINode, VectorNode) \ declare_c2_type(NegVFNode, VectorNode) \ declare_c2_type(NegVDNode, VectorNode) \ + declare_c2_type(NotVNode, VectorNode) \ declare_c2_type(FmaVDNode, VectorNode) \ declare_c2_type(FmaVFNode, VectorNode) \ declare_c2_type(CMoveVFNode, VectorNode) \ @@ -1814,6 +1824,11 @@ declare_c2_type(URShiftVSNode, VectorNode) \ declare_c2_type(URShiftVINode, VectorNode) \ declare_c2_type(URShiftVLNode, VectorNode) \ + declare_c2_type(VLShiftVNode, VectorNode) \ + declare_c2_type(VRShiftVNode, VectorNode) \ + declare_c2_type(VURShiftVNode, VectorNode) \ + declare_c2_type(MinReductionVNode, ReductionNode) \ + declare_c2_type(MaxReductionVNode, ReductionNode) \ declare_c2_type(AndVNode, VectorNode) \ declare_c2_type(AndReductionVNode, ReductionNode) \ declare_c2_type(OrVNode, VectorNode) \ @@ -1822,8 +1837,6 @@ declare_c2_type(XorReductionVNode, ReductionNode) \ declare_c2_type(MaxVNode, VectorNode) \ declare_c2_type(MinVNode, VectorNode) \ - declare_c2_type(MaxReductionVNode, ReductionNode) \ - declare_c2_type(MinReductionVNode, ReductionNode) \ declare_c2_type(LoadVectorNode, LoadNode) \ declare_c2_type(StoreVectorNode, StoreNode) \ declare_c2_type(ReplicateBNode, VectorNode) \ @@ -1861,6 +1874,24 @@ declare_c2_type(OverflowMulLNode, OverflowLNode) \ declare_c2_type(FmaDNode, Node) \ declare_c2_type(FmaFNode, Node) \ + declare_c2_type(LoadVectorGatherNode, LoadVectorNode) \ + declare_c2_type(StoreVectorScatterNode, StoreVectorNode) \ + declare_c2_type(VectorLoadMaskNode, VectorNode) \ + declare_c2_type(VectorLoadShuffleNode, VectorNode) \ + declare_c2_type(VectorStoreMaskNode, VectorNode) \ + declare_c2_type(VectorBlendNode, VectorNode) \ + declare_c2_type(VectorRearrangeNode, VectorNode) \ + declare_c2_type(VectorMaskWrapperNode, VectorNode) \ + declare_c2_type(VectorMaskCmpNode, VectorNode) \ + declare_c2_type(VectorCastB2XNode, VectorNode) \ + declare_c2_type(VectorCastS2XNode, VectorNode) \ + declare_c2_type(VectorCastI2XNode, VectorNode) \ + declare_c2_type(VectorCastL2XNode, VectorNode) \ + declare_c2_type(VectorCastF2XNode, VectorNode) \ + declare_c2_type(VectorCastD2XNode, VectorNode) \ + declare_c2_type(VectorInsertNode, VectorNode) \ + declare_c2_type(VectorReinterpretNode, VectorNode) \ + declare_c2_type(VectorTestNode, Node) \ \ /*********************/ \ /* Adapter Blob Entries */ \ --- old/src/hotspot/share/utilities/globalDefinitions.hpp 2020-04-02 14:12:00.000000000 +0300 +++ new/src/hotspot/share/utilities/globalDefinitions.hpp 2020-04-02 14:12:00.000000000 +0300 @@ -233,6 +233,9 @@ return (byte_size + (HeapWordSize-1)) >> LogHeapWordSize; } +inline jfloat jfloat_cast(jint x); +inline jdouble jdouble_cast(jlong x); + //------------------------------------------- // Constant for jlong (standardized by C++11) @@ -243,6 +246,13 @@ const jlong min_jlong = CONST64(0x8000000000000000); const jlong max_jlong = CONST64(0x7fffffffffffffff); +//------------------------------------------- +// Constant for jdouble +const jlong min_jlongDouble = CONST64(0x0000000000000001); +const jdouble min_jdouble = jdouble_cast(min_jlongDouble); +const jlong max_jlongDouble = CONST64(0x7fefffffffffffff); +const jdouble max_jdouble = jdouble_cast(max_jlongDouble); + const size_t K = 1024; const size_t M = K*K; const size_t G = M*K; @@ -460,6 +470,11 @@ const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint const jint max_jint = (juint)min_jint - 1; // 0x7FFFFFFF == largest jint +const jint min_jintFloat = (jint)(0x00000001); +const jfloat min_jfloat = jfloat_cast(min_jintFloat); +const jint max_jintFloat = (jint)(0x7f7fffff); +const jfloat max_jfloat = jfloat_cast(max_jintFloat); + //---------------------------------------------------------------------------------------------------- // JVM spec restrictions @@ -664,6 +679,10 @@ return (t == T_OBJECT || t == T_ARRAY); } +inline bool is_integral_type(BasicType t) { + return is_subword_type(t) || t == T_INT || t == T_LONG; +} + extern char type2char_tab[T_CONFLICT+1]; // Map a BasicType to a jchar inline char type2char(BasicType t) { return (uint)t < T_CONFLICT+1 ? type2char_tab[t] : 0; } extern int type2size[T_CONFLICT+1]; // Map BasicType to result stack elements