mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-30 21:18:25 +00:00
8341784: Refactor TypeVect to use a BasicType instead of a const Type*
Reviewed-by: kvn, jkarthikeyan
This commit is contained in:
parent
6133866150
commit
7276a1bec0
@ -2307,10 +2307,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return &_PR_REG_mask;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return new TypeVectMask(elemTy, length);
|
||||
}
|
||||
|
||||
// Vector calling convention not yet implemented.
|
||||
bool Matcher::supports_vector_calling_convention(void) {
|
||||
return false;
|
||||
|
||||
@ -1003,10 +1003,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Vector calling convention not yet implemented.
|
||||
bool Matcher::supports_vector_calling_convention(void) {
|
||||
return false;
|
||||
|
||||
@ -2154,10 +2154,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Vector calling convention not yet implemented.
|
||||
bool Matcher::supports_vector_calling_convention(void) {
|
||||
return false;
|
||||
|
||||
@ -1966,10 +1966,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return &_VMASK_REG_mask;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return new TypeVectMask(elemTy, length);
|
||||
}
|
||||
|
||||
// Vector calling convention not yet implemented.
|
||||
bool Matcher::supports_vector_calling_convention(void) {
|
||||
return EnableVectorSupport && UseVectorStubs;
|
||||
|
||||
@ -1477,10 +1477,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Vector calling convention not yet implemented.
|
||||
bool Matcher::supports_vector_calling_convention(void) {
|
||||
return false;
|
||||
|
||||
@ -2231,10 +2231,6 @@ const RegMask* Matcher::predicate_reg_mask(void) {
|
||||
return &_VECTMASK_REG_mask;
|
||||
}
|
||||
|
||||
const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
|
||||
return new TypeVectMask(elemTy, length);
|
||||
}
|
||||
|
||||
// Max vector size in bytes. 0 if not supported.
|
||||
int Matcher::vector_width_in_bytes(BasicType bt) {
|
||||
assert(is_java_primitive(bt), "only primitive type vectors");
|
||||
|
||||
@ -4548,7 +4548,6 @@ void PhaseIdealLoop::move_unordered_reduction_out_of_loop(IdealLoopTree* loop) {
|
||||
const TypeVect* vec_t = last_ur->vect_type();
|
||||
uint vector_length = vec_t->length();
|
||||
BasicType bt = vec_t->element_basic_type();
|
||||
const Type* bt_t = Type::get_const_basic_type(bt);
|
||||
|
||||
// Convert opcode from vector-reduction -> scalar -> normal-vector-op
|
||||
const int sopc = VectorNode::scalar_opcode(last_ur->Opcode(), bt);
|
||||
@ -4628,7 +4627,7 @@ void PhaseIdealLoop::move_unordered_reduction_out_of_loop(IdealLoopTree* loop) {
|
||||
|
||||
Node* identity_scalar = ReductionNode::make_identity_con_scalar(_igvn, sopc, bt);
|
||||
set_ctrl(identity_scalar, C->root());
|
||||
VectorNode* identity_vector = VectorNode::scalar2vector(identity_scalar, vector_length, bt_t);
|
||||
VectorNode* identity_vector = VectorNode::scalar2vector(identity_scalar, vector_length, bt);
|
||||
register_new_node(identity_vector, C->root());
|
||||
assert(vec_t == identity_vector->vect_type(), "matching vector type");
|
||||
VectorNode::trace_new_vector(identity_vector, "Unordered Reduction");
|
||||
|
||||
@ -342,7 +342,6 @@ public:
|
||||
static bool vector_needs_partial_operations(Node* node, const TypeVect* vt);
|
||||
|
||||
static const RegMask* predicate_reg_mask(void);
|
||||
static const TypeVectMask* predicate_reg_type(const Type* elemTy, int length);
|
||||
|
||||
// Vector width in bytes
|
||||
static int vector_width_in_bytes(BasicType bt);
|
||||
|
||||
@ -228,8 +228,8 @@ VTransformNode* SuperWordVTransformBuilder::get_or_make_vtnode_vector_input_at_i
|
||||
return shift_count;
|
||||
} else {
|
||||
// Replicate the scalar same_input to every vector element.
|
||||
const Type* element_type = _vloop_analyzer.types().velt_type(p0);
|
||||
if (index == 2 && VectorNode::is_scalar_rotate(p0) && element_type->isa_long()) {
|
||||
BasicType element_type = _vloop_analyzer.types().velt_basic_type(p0);
|
||||
if (index == 2 && VectorNode::is_scalar_rotate(p0) && element_type == T_LONG) {
|
||||
// Scalar rotate has int rotation value, but the scalar rotate expects longs.
|
||||
assert(same_input->bottom_type()->isa_int(), "scalar rotate expects int rotation");
|
||||
VTransformNode* conv = new (_vtransform.arena()) VTransformConvI2LNode(_vtransform);
|
||||
|
||||
@ -679,7 +679,7 @@ void Type::Initialize_shared(Compile* current) {
|
||||
// get_zero_type() should not happen for T_CONFLICT
|
||||
_zero_type[T_CONFLICT]= nullptr;
|
||||
|
||||
TypeVect::VECTMASK = (TypeVect*)(new TypeVectMask(TypeInt::BOOL, MaxVectorSize))->hashcons();
|
||||
TypeVect::VECTMASK = (TypeVect*)(new TypeVectMask(T_BOOLEAN, MaxVectorSize))->hashcons();
|
||||
mreg2type[Op_RegVectMask] = TypeVect::VECTMASK;
|
||||
|
||||
if (Matcher::supports_scalable_vector()) {
|
||||
@ -687,20 +687,20 @@ void Type::Initialize_shared(Compile* current) {
|
||||
}
|
||||
|
||||
// Vector predefined types, it needs initialized _const_basic_type[].
|
||||
if (Matcher::vector_size_supported(T_BYTE,4)) {
|
||||
TypeVect::VECTS = TypeVect::make(T_BYTE,4);
|
||||
if (Matcher::vector_size_supported(T_BYTE, 4)) {
|
||||
TypeVect::VECTS = TypeVect::make(T_BYTE, 4);
|
||||
}
|
||||
if (Matcher::vector_size_supported(T_FLOAT,2)) {
|
||||
TypeVect::VECTD = TypeVect::make(T_FLOAT,2);
|
||||
if (Matcher::vector_size_supported(T_FLOAT, 2)) {
|
||||
TypeVect::VECTD = TypeVect::make(T_FLOAT, 2);
|
||||
}
|
||||
if (Matcher::vector_size_supported(T_FLOAT,4)) {
|
||||
TypeVect::VECTX = TypeVect::make(T_FLOAT,4);
|
||||
if (Matcher::vector_size_supported(T_FLOAT, 4)) {
|
||||
TypeVect::VECTX = TypeVect::make(T_FLOAT, 4);
|
||||
}
|
||||
if (Matcher::vector_size_supported(T_FLOAT,8)) {
|
||||
TypeVect::VECTY = TypeVect::make(T_FLOAT,8);
|
||||
if (Matcher::vector_size_supported(T_FLOAT, 8)) {
|
||||
TypeVect::VECTY = TypeVect::make(T_FLOAT, 8);
|
||||
}
|
||||
if (Matcher::vector_size_supported(T_FLOAT,16)) {
|
||||
TypeVect::VECTZ = TypeVect::make(T_FLOAT,16);
|
||||
if (Matcher::vector_size_supported(T_FLOAT, 16)) {
|
||||
TypeVect::VECTZ = TypeVect::make(T_FLOAT, 16);
|
||||
}
|
||||
|
||||
mreg2type[Op_VecA] = TypeVect::VECTA;
|
||||
@ -2482,58 +2482,59 @@ bool TypeAry::ary_must_be_exact() const {
|
||||
|
||||
//==============================TypeVect=======================================
|
||||
// Convenience common pre-built types.
|
||||
const TypeVect *TypeVect::VECTA = nullptr; // vector length agnostic
|
||||
const TypeVect *TypeVect::VECTS = nullptr; // 32-bit vectors
|
||||
const TypeVect *TypeVect::VECTD = nullptr; // 64-bit vectors
|
||||
const TypeVect *TypeVect::VECTX = nullptr; // 128-bit vectors
|
||||
const TypeVect *TypeVect::VECTY = nullptr; // 256-bit vectors
|
||||
const TypeVect *TypeVect::VECTZ = nullptr; // 512-bit vectors
|
||||
const TypeVect *TypeVect::VECTMASK = nullptr; // predicate/mask vector
|
||||
const TypeVect* TypeVect::VECTA = nullptr; // vector length agnostic
|
||||
const TypeVect* TypeVect::VECTS = nullptr; // 32-bit vectors
|
||||
const TypeVect* TypeVect::VECTD = nullptr; // 64-bit vectors
|
||||
const TypeVect* TypeVect::VECTX = nullptr; // 128-bit vectors
|
||||
const TypeVect* TypeVect::VECTY = nullptr; // 256-bit vectors
|
||||
const TypeVect* TypeVect::VECTZ = nullptr; // 512-bit vectors
|
||||
const TypeVect* TypeVect::VECTMASK = nullptr; // predicate/mask vector
|
||||
|
||||
//------------------------------make-------------------------------------------
|
||||
const TypeVect* TypeVect::make(const Type *elem, uint length, bool is_mask) {
|
||||
const TypeVect* TypeVect::make(BasicType elem_bt, uint length, bool is_mask) {
|
||||
if (is_mask) {
|
||||
return makemask(elem, length);
|
||||
return makemask(elem_bt, length);
|
||||
}
|
||||
BasicType elem_bt = elem->array_element_basic_type();
|
||||
assert(is_java_primitive(elem_bt), "only primitive types in vector");
|
||||
assert(Matcher::vector_size_supported(elem_bt, length), "length in range");
|
||||
int size = length * type2aelembytes(elem_bt);
|
||||
switch (Matcher::vector_ideal_reg(size)) {
|
||||
case Op_VecA:
|
||||
return (TypeVect*)(new TypeVectA(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectA(elem_bt, length))->hashcons();
|
||||
case Op_VecS:
|
||||
return (TypeVect*)(new TypeVectS(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectS(elem_bt, length))->hashcons();
|
||||
case Op_RegL:
|
||||
case Op_VecD:
|
||||
case Op_RegD:
|
||||
return (TypeVect*)(new TypeVectD(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectD(elem_bt, length))->hashcons();
|
||||
case Op_VecX:
|
||||
return (TypeVect*)(new TypeVectX(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectX(elem_bt, length))->hashcons();
|
||||
case Op_VecY:
|
||||
return (TypeVect*)(new TypeVectY(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectY(elem_bt, length))->hashcons();
|
||||
case Op_VecZ:
|
||||
return (TypeVect*)(new TypeVectZ(elem, length))->hashcons();
|
||||
return (TypeVect*)(new TypeVectZ(elem_bt, length))->hashcons();
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const TypeVect *TypeVect::makemask(const Type* elem, uint length) {
|
||||
BasicType elem_bt = elem->array_element_basic_type();
|
||||
const TypeVect* TypeVect::makemask(BasicType elem_bt, uint length) {
|
||||
if (Matcher::has_predicated_vectors() &&
|
||||
Matcher::match_rule_supported_vector_masked(Op_VectorLoadMask, length, elem_bt)) {
|
||||
return TypeVectMask::make(elem, length);
|
||||
return TypeVectMask::make(elem_bt, length);
|
||||
} else {
|
||||
return make(elem, length);
|
||||
return make(elem_bt, length);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------meet-------------------------------------------
|
||||
// Compute the MEET of two types. It returns a new Type object.
|
||||
const Type *TypeVect::xmeet( const Type *t ) const {
|
||||
// Compute the MEET of two types. Since each TypeVect is the only instance of
|
||||
// its species, meeting often returns itself
|
||||
const Type* TypeVect::xmeet(const Type* t) const {
|
||||
// Perform a fast test for common case; meeting the same types together.
|
||||
if( this == t ) return this; // Meeting same type-rep?
|
||||
if (this == t) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Current "this->_base" is Vector
|
||||
switch (t->base()) { // switch on original type
|
||||
@ -2543,13 +2544,7 @@ const Type *TypeVect::xmeet( const Type *t ) const {
|
||||
|
||||
default: // All else is a mistake
|
||||
typerr(t);
|
||||
case VectorMask: {
|
||||
const TypeVectMask* v = t->is_vectmask();
|
||||
assert( base() == v->base(), "");
|
||||
assert(length() == v->length(), "");
|
||||
assert(element_basic_type() == v->element_basic_type(), "");
|
||||
return TypeVect::makemask(_elem->xmeet(v->_elem), _length);
|
||||
}
|
||||
case VectorMask:
|
||||
case VectorA:
|
||||
case VectorS:
|
||||
case VectorD:
|
||||
@ -2557,10 +2552,10 @@ const Type *TypeVect::xmeet( const Type *t ) const {
|
||||
case VectorY:
|
||||
case VectorZ: { // Meeting 2 vectors?
|
||||
const TypeVect* v = t->is_vect();
|
||||
assert( base() == v->base(), "");
|
||||
assert(base() == v->base(), "");
|
||||
assert(length() == v->length(), "");
|
||||
assert(element_basic_type() == v->element_basic_type(), "");
|
||||
return TypeVect::make(_elem->xmeet(v->_elem), _length);
|
||||
return this;
|
||||
}
|
||||
case Top:
|
||||
break;
|
||||
@ -2569,26 +2564,26 @@ const Type *TypeVect::xmeet( const Type *t ) const {
|
||||
}
|
||||
|
||||
//------------------------------xdual------------------------------------------
|
||||
// Dual: compute field-by-field dual
|
||||
const Type *TypeVect::xdual() const {
|
||||
return new TypeVect(base(), _elem->dual(), _length);
|
||||
// Since each TypeVect is the only instance of its species, it is self-dual
|
||||
const Type* TypeVect::xdual() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------eq---------------------------------------------
|
||||
// Structural equality check for Type representations
|
||||
bool TypeVect::eq(const Type *t) const {
|
||||
const TypeVect *v = t->is_vect();
|
||||
return (_elem == v->_elem) && (_length == v->_length);
|
||||
bool TypeVect::eq(const Type* t) const {
|
||||
const TypeVect* v = t->is_vect();
|
||||
return (element_basic_type() == v->element_basic_type()) && (length() == v->length());
|
||||
}
|
||||
|
||||
//------------------------------hash-------------------------------------------
|
||||
// Type-specific hashing function.
|
||||
uint TypeVect::hash(void) const {
|
||||
return (uint)(uintptr_t)_elem + (uint)(uintptr_t)_length;
|
||||
return (uint)base() + (uint)(uintptr_t)_elem_bt + (uint)(uintptr_t)_length;
|
||||
}
|
||||
|
||||
//------------------------------singleton--------------------------------------
|
||||
// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
|
||||
// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
|
||||
// constants (Ldi nodes). Vector is singleton if all elements are the same
|
||||
// constant value (when vector is created with Replicate code).
|
||||
bool TypeVect::singleton(void) const {
|
||||
@ -2598,52 +2593,36 @@ bool TypeVect::singleton(void) const {
|
||||
}
|
||||
|
||||
bool TypeVect::empty(void) const {
|
||||
return _elem->empty();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeVect::dump2(Dict &d, uint depth, outputStream *st) const {
|
||||
void TypeVect::dump2(Dict& d, uint depth, outputStream* st) const {
|
||||
switch (base()) {
|
||||
case VectorA:
|
||||
st->print("vectora["); break;
|
||||
st->print("vectora"); break;
|
||||
case VectorS:
|
||||
st->print("vectors["); break;
|
||||
st->print("vectors"); break;
|
||||
case VectorD:
|
||||
st->print("vectord["); break;
|
||||
st->print("vectord"); break;
|
||||
case VectorX:
|
||||
st->print("vectorx["); break;
|
||||
st->print("vectorx"); break;
|
||||
case VectorY:
|
||||
st->print("vectory["); break;
|
||||
st->print("vectory"); break;
|
||||
case VectorZ:
|
||||
st->print("vectorz["); break;
|
||||
st->print("vectorz"); break;
|
||||
case VectorMask:
|
||||
st->print("vectormask["); break;
|
||||
st->print("vectormask"); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
st->print("%d]:{", _length);
|
||||
_elem->dump2(d, depth, st);
|
||||
st->print("}");
|
||||
st->print("<%c,%u>", type2char(element_basic_type()), length());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TypeVectMask::eq(const Type *t) const {
|
||||
const TypeVectMask *v = t->is_vectmask();
|
||||
return (element_type() == v->element_type()) && (length() == v->length());
|
||||
}
|
||||
|
||||
const Type *TypeVectMask::xdual() const {
|
||||
return new TypeVectMask(element_type()->dual(), length());
|
||||
}
|
||||
|
||||
const TypeVectMask *TypeVectMask::make(const BasicType elem_bt, uint length) {
|
||||
return make(get_const_basic_type(elem_bt), length);
|
||||
}
|
||||
|
||||
const TypeVectMask *TypeVectMask::make(const Type* elem, uint length) {
|
||||
const TypeVectMask* mtype = Matcher::predicate_reg_type(elem, length);
|
||||
return (TypeVectMask*) const_cast<TypeVectMask*>(mtype)->hashcons();
|
||||
const TypeVectMask* TypeVectMask::make(const BasicType elem_bt, uint length) {
|
||||
return (TypeVectMask*) (new TypeVectMask(elem_bt, length))->hashcons();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@ -784,94 +784,79 @@ public:
|
||||
//------------------------------TypeVect---------------------------------------
|
||||
// Class of Vector Types
|
||||
class TypeVect : public Type {
|
||||
const Type* _elem; // Vector's element type
|
||||
const uint _length; // Elements in vector (power of 2)
|
||||
const BasicType _elem_bt; // Vector's element type
|
||||
const uint _length; // Elements in vector (power of 2)
|
||||
|
||||
protected:
|
||||
TypeVect(TYPES t, const Type* elem, uint length) : Type(t),
|
||||
_elem(elem), _length(length) {}
|
||||
TypeVect(TYPES t, BasicType elem_bt, uint length) : Type(t),
|
||||
_elem_bt(elem_bt), _length(length) {}
|
||||
|
||||
public:
|
||||
const Type* element_type() const { return _elem; }
|
||||
BasicType element_basic_type() const { return _elem->array_element_basic_type(); }
|
||||
BasicType element_basic_type() const { return _elem_bt; }
|
||||
uint length() const { return _length; }
|
||||
uint length_in_bytes() const {
|
||||
return _length * type2aelembytes(element_basic_type());
|
||||
return _length * type2aelembytes(element_basic_type());
|
||||
}
|
||||
|
||||
virtual bool eq(const Type *t) const;
|
||||
virtual bool eq(const Type* t) const;
|
||||
virtual uint hash() const; // Type specific hashing
|
||||
virtual bool singleton(void) const; // TRUE if type is a singleton
|
||||
virtual bool empty(void) const; // TRUE if type is vacuous
|
||||
|
||||
static const TypeVect *make(const BasicType elem_bt, uint length, bool is_mask = false) {
|
||||
// Use bottom primitive type.
|
||||
return make(get_const_basic_type(elem_bt), length, is_mask);
|
||||
}
|
||||
// Used directly by Replicate nodes to construct singleton vector.
|
||||
static const TypeVect *make(const Type* elem, uint length, bool is_mask = false);
|
||||
static const TypeVect* make(const BasicType elem_bt, uint length, bool is_mask = false);
|
||||
static const TypeVect* makemask(const BasicType elem_bt, uint length);
|
||||
|
||||
static const TypeVect *makemask(const BasicType elem_bt, uint length) {
|
||||
// Use bottom primitive type.
|
||||
return makemask(get_const_basic_type(elem_bt), length);
|
||||
}
|
||||
static const TypeVect *makemask(const Type* elem, uint length);
|
||||
virtual const Type* xmeet( const Type *t) const;
|
||||
virtual const Type* xdual() const; // Compute dual right now.
|
||||
|
||||
|
||||
virtual const Type *xmeet( const Type *t) const;
|
||||
virtual const Type *xdual() const; // Compute dual right now.
|
||||
|
||||
static const TypeVect *VECTA;
|
||||
static const TypeVect *VECTS;
|
||||
static const TypeVect *VECTD;
|
||||
static const TypeVect *VECTX;
|
||||
static const TypeVect *VECTY;
|
||||
static const TypeVect *VECTZ;
|
||||
static const TypeVect *VECTMASK;
|
||||
static const TypeVect* VECTA;
|
||||
static const TypeVect* VECTS;
|
||||
static const TypeVect* VECTD;
|
||||
static const TypeVect* VECTX;
|
||||
static const TypeVect* VECTY;
|
||||
static const TypeVect* VECTZ;
|
||||
static const TypeVect* VECTMASK;
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump2(Dict &d, uint, outputStream *st) const; // Specialized per-Type dumping
|
||||
virtual void dump2(Dict& d, uint, outputStream* st) const; // Specialized per-Type dumping
|
||||
#endif
|
||||
};
|
||||
|
||||
class TypeVectA : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectA(const Type* elem, uint length) : TypeVect(VectorA, elem, length) {}
|
||||
TypeVectA(BasicType elem_bt, uint length) : TypeVect(VectorA, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectS : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectS(const Type* elem, uint length) : TypeVect(VectorS, elem, length) {}
|
||||
TypeVectS(BasicType elem_bt, uint length) : TypeVect(VectorS, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectD : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectD(const Type* elem, uint length) : TypeVect(VectorD, elem, length) {}
|
||||
TypeVectD(BasicType elem_bt, uint length) : TypeVect(VectorD, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectX : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectX(const Type* elem, uint length) : TypeVect(VectorX, elem, length) {}
|
||||
TypeVectX(BasicType elem_bt, uint length) : TypeVect(VectorX, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectY : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectY(const Type* elem, uint length) : TypeVect(VectorY, elem, length) {}
|
||||
TypeVectY(BasicType elem_bt, uint length) : TypeVect(VectorY, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectZ : public TypeVect {
|
||||
friend class TypeVect;
|
||||
TypeVectZ(const Type* elem, uint length) : TypeVect(VectorZ, elem, length) {}
|
||||
TypeVectZ(BasicType elem_bt, uint length) : TypeVect(VectorZ, elem_bt, length) {}
|
||||
};
|
||||
|
||||
class TypeVectMask : public TypeVect {
|
||||
public:
|
||||
friend class TypeVect;
|
||||
TypeVectMask(const Type* elem, uint length) : TypeVect(VectorMask, elem, length) {}
|
||||
virtual bool eq(const Type *t) const;
|
||||
virtual const Type *xdual() const;
|
||||
TypeVectMask(BasicType elem_bt, uint length) : TypeVect(VectorMask, elem_bt, length) {}
|
||||
static const TypeVectMask* make(const BasicType elem_bt, uint length);
|
||||
static const TypeVectMask* make(const Type* elem, uint length);
|
||||
};
|
||||
|
||||
// Set of implemented interfaces. Referenced from TypeOopPtr and TypeKlassPtr.
|
||||
|
||||
@ -524,17 +524,16 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
Node* LibraryCallKit::partially_wrap_indexes(Node* index_vec, int num_elem, BasicType elem_bt) {
|
||||
assert(elem_bt == T_BYTE, "Shuffles use byte array based backing storage.");
|
||||
const TypeVect* vt = TypeVect::make(elem_bt, num_elem);
|
||||
const Type* type_bt = Type::get_const_basic_type(elem_bt);
|
||||
|
||||
Node* mod_mask = gvn().makecon(TypeInt::make(num_elem-1));
|
||||
Node* bcast_mod_mask = gvn().transform(VectorNode::scalar2vector(mod_mask, num_elem, type_bt));
|
||||
Node* bcast_mod_mask = gvn().transform(VectorNode::scalar2vector(mod_mask, num_elem, elem_bt));
|
||||
|
||||
BoolTest::mask pred = BoolTest::ugt;
|
||||
ConINode* pred_node = (ConINode*)gvn().makecon(TypeInt::make(pred));
|
||||
Node* lane_cnt = gvn().makecon(TypeInt::make(num_elem));
|
||||
Node* bcast_lane_cnt = gvn().transform(VectorNode::scalar2vector(lane_cnt, num_elem, type_bt));
|
||||
const TypeVect* vmask_type = TypeVect::makemask(type_bt, num_elem);
|
||||
Node* mask = gvn().transform(new VectorMaskCmpNode(pred, bcast_lane_cnt, index_vec, pred_node, vmask_type));
|
||||
Node* bcast_lane_cnt = gvn().transform(VectorNode::scalar2vector(lane_cnt, num_elem, elem_bt));
|
||||
const TypeVect* vmask_type = TypeVect::makemask(elem_bt, num_elem);
|
||||
Node* mask = gvn().transform(new VectorMaskCmpNode(pred, bcast_lane_cnt, index_vec, pred_node, vmask_type));
|
||||
|
||||
// Make the indices greater than lane count as -ve values to match the java side implementation.
|
||||
index_vec = gvn().transform(VectorNode::make(Op_AndV, index_vec, bcast_mod_mask, vt));
|
||||
@ -600,8 +599,7 @@ bool LibraryCallKit::inline_vector_shuffle_iota() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Type * type_bt = Type::get_const_basic_type(elem_bt);
|
||||
const TypeVect * vt = TypeVect::make(type_bt, num_elem);
|
||||
const TypeVect* vt = TypeVect::make(elem_bt, num_elem);
|
||||
|
||||
Node* res = gvn().transform(new VectorLoadConstNode(gvn().makecon(TypeInt::ZERO), vt));
|
||||
|
||||
@ -609,7 +607,7 @@ bool LibraryCallKit::inline_vector_shuffle_iota() {
|
||||
Node* step = argument(5);
|
||||
|
||||
if (step_multiply) {
|
||||
Node* bcast_step = gvn().transform(VectorNode::scalar2vector(step, num_elem, type_bt));
|
||||
Node* bcast_step = gvn().transform(VectorNode::scalar2vector(step, num_elem, elem_bt));
|
||||
res = gvn().transform(VectorNode::make(Op_MulVB, res, bcast_step, vt));
|
||||
} else if (step_val->get_con() > 1) {
|
||||
Node* cnt = gvn().makecon(TypeInt::make(log2i_exact(step_val->get_con())));
|
||||
@ -618,12 +616,12 @@ bool LibraryCallKit::inline_vector_shuffle_iota() {
|
||||
}
|
||||
|
||||
if (!start_val->is_con() || start_val->get_con() != 0) {
|
||||
Node* bcast_start = gvn().transform(VectorNode::scalar2vector(start, num_elem, type_bt));
|
||||
Node* bcast_start = gvn().transform(VectorNode::scalar2vector(start, num_elem, elem_bt));
|
||||
res = gvn().transform(VectorNode::make(Op_AddVB, res, bcast_start, vt));
|
||||
}
|
||||
|
||||
Node * mod_val = gvn().makecon(TypeInt::make(num_elem-1));
|
||||
Node * bcast_mod = gvn().transform(VectorNode::scalar2vector(mod_val, num_elem, type_bt));
|
||||
Node* mod_val = gvn().makecon(TypeInt::make(num_elem-1));
|
||||
Node* bcast_mod = gvn().transform(VectorNode::scalar2vector(mod_val, num_elem, elem_bt));
|
||||
|
||||
if (do_wrap) {
|
||||
// Wrap the indices greater than lane count.
|
||||
@ -802,9 +800,8 @@ bool LibraryCallKit::inline_vector_wrap_shuffle_indexes() {
|
||||
Node* shuffle_vec = unbox_vector(shuffle, shuffle_box_type, shuffle_bt, num_elem, true);
|
||||
|
||||
const TypeVect* vt = TypeVect::make(shuffle_bt, num_elem);
|
||||
const Type* shuffle_type_bt = Type::get_const_basic_type(shuffle_bt);
|
||||
Node* mod_mask = gvn().makecon(TypeInt::make(num_elem-1));
|
||||
Node* bcast_mod_mask = gvn().transform(VectorNode::scalar2vector(mod_mask, num_elem, shuffle_type_bt));
|
||||
Node* mod_mask = gvn().makecon(TypeInt::make(num_elem - 1));
|
||||
Node* bcast_mod_mask = gvn().transform(VectorNode::scalar2vector(mod_mask, num_elem, shuffle_bt));
|
||||
// Wrap the indices greater than lane count.
|
||||
Node* res = gvn().transform(VectorNode::make(Op_AndV, shuffle_vec, bcast_mod_mask, vt));
|
||||
|
||||
@ -908,7 +905,7 @@ bool LibraryCallKit::inline_vector_frombits_coerced() {
|
||||
}
|
||||
default: fatal("%s", type2name(elem_bt));
|
||||
}
|
||||
broadcast = VectorNode::scalar2vector(elem, num_elem, Type::get_const_basic_type(elem_bt), is_mask);
|
||||
broadcast = VectorNode::scalar2vector(elem, num_elem, elem_bt, is_mask);
|
||||
broadcast = gvn().transform(broadcast);
|
||||
}
|
||||
|
||||
@ -1352,7 +1349,7 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) {
|
||||
} else {
|
||||
// Use the vector blend to implement the masked load vector. The biased elements are zeros.
|
||||
Node* zero = gvn().transform(gvn().zerocon(mem_elem_bt));
|
||||
zero = gvn().transform(VectorNode::scalar2vector(zero, mem_num_elem, Type::get_const_basic_type(mem_elem_bt)));
|
||||
zero = gvn().transform(VectorNode::scalar2vector(zero, mem_num_elem, mem_elem_bt));
|
||||
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, mem_num_elem, mem_elem_bt));
|
||||
vload = gvn().transform(new VectorBlendNode(zero, vload, mask));
|
||||
}
|
||||
@ -1678,7 +1675,7 @@ bool LibraryCallKit::inline_vector_reduction() {
|
||||
|
||||
assert(mask != nullptr || !is_masked_op, "Masked op needs the mask value never null");
|
||||
if (mask != nullptr && !use_predicate) {
|
||||
Node* reduce_identity = gvn().transform(VectorNode::scalar2vector(init, num_elem, Type::get_const_basic_type(elem_bt)));
|
||||
Node* reduce_identity = gvn().transform(VectorNode::scalar2vector(init, num_elem, elem_bt));
|
||||
value = gvn().transform(new VectorBlendNode(reduce_identity, value, mask));
|
||||
}
|
||||
|
||||
@ -2059,7 +2056,7 @@ bool LibraryCallKit::inline_vector_rearrange() {
|
||||
const TypeVect* vt = v1->bottom_type()->is_vect();
|
||||
rearrange = gvn().transform(rearrange);
|
||||
Node* zero = gvn().makecon(Type::get_zero_type(elem_bt));
|
||||
Node* zerovec = gvn().transform(VectorNode::scalar2vector(zero, num_elem, Type::get_const_basic_type(elem_bt)));
|
||||
Node* zerovec = gvn().transform(VectorNode::scalar2vector(zero, num_elem, elem_bt));
|
||||
rearrange = new VectorBlendNode(zerovec, rearrange, mask);
|
||||
}
|
||||
}
|
||||
@ -2215,18 +2212,17 @@ bool LibraryCallKit::inline_vector_select_from() {
|
||||
}
|
||||
|
||||
// cast index vector from elem_bt vector to byte vector
|
||||
const Type * byte_bt = Type::get_const_basic_type(T_BYTE);
|
||||
const TypeVect * byte_vt = TypeVect::make(byte_bt, num_elem);
|
||||
const TypeVect* byte_vt = TypeVect::make(T_BYTE, num_elem);
|
||||
Node* byte_shuffle = gvn().transform(VectorCastNode::make(cast_vopc, v1, T_BYTE, num_elem));
|
||||
|
||||
// wrap the byte vector lanes to (num_elem - 1) to form the shuffle vector where num_elem is vector length
|
||||
// this is a simple AND operation as we come here only for power of two vector length
|
||||
Node* mod_val = gvn().makecon(TypeInt::make(num_elem-1));
|
||||
Node* bcast_mod = gvn().transform(VectorNode::scalar2vector(mod_val, num_elem, byte_bt));
|
||||
Node* bcast_mod = gvn().transform(VectorNode::scalar2vector(mod_val, num_elem, T_BYTE));
|
||||
byte_shuffle = gvn().transform(VectorNode::make(Op_AndV, byte_shuffle, bcast_mod, byte_vt));
|
||||
|
||||
// load the shuffle to use in rearrange
|
||||
const TypeVect * shuffle_vt = TypeVect::make(elem_bt, num_elem);
|
||||
const TypeVect* shuffle_vt = TypeVect::make(elem_bt, num_elem);
|
||||
Node* load_shuffle = gvn().transform(new VectorLoadShuffleNode(byte_shuffle, shuffle_vt));
|
||||
|
||||
// and finally rearrange
|
||||
@ -2243,7 +2239,7 @@ bool LibraryCallKit::inline_vector_select_from() {
|
||||
|
||||
// create a zero vector with each lane element set as zero
|
||||
Node* zero = gvn().makecon(Type::get_zero_type(elem_bt));
|
||||
Node* zerovec = gvn().transform(VectorNode::scalar2vector(zero, num_elem, Type::get_const_basic_type(elem_bt)));
|
||||
Node* zerovec = gvn().transform(VectorNode::scalar2vector(zero, num_elem, elem_bt));
|
||||
|
||||
// For each lane for which mask is set, blend in the rearranged lane into zero vector
|
||||
rearrange = new VectorBlendNode(zerovec, rearrange, mask);
|
||||
@ -2391,9 +2387,8 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
|
||||
} else {
|
||||
assert(is_rotate, "unexpected operation");
|
||||
if (!is_const_rotate) {
|
||||
const Type * type_bt = Type::get_const_basic_type(elem_bt);
|
||||
cnt = elem_bt == T_LONG ? gvn().transform(new ConvI2LNode(cnt)) : cnt;
|
||||
opd2 = gvn().transform(VectorNode::scalar2vector(cnt, num_elem, type_bt));
|
||||
opd2 = gvn().transform(VectorNode::scalar2vector(cnt, num_elem, elem_bt));
|
||||
} else {
|
||||
// Constant shift value.
|
||||
opd2 = cnt;
|
||||
@ -3051,7 +3046,7 @@ bool LibraryCallKit::inline_index_vector() {
|
||||
}
|
||||
default: fatal("%s", type2name(elem_bt));
|
||||
}
|
||||
scale = gvn().transform(VectorNode::scalar2vector(scale, num_elem, Type::get_const_basic_type(elem_bt)));
|
||||
scale = gvn().transform(VectorNode::scalar2vector(scale, num_elem, elem_bt));
|
||||
index = gvn().transform(VectorNode::make(vmul_op, index, scale, vt));
|
||||
}
|
||||
|
||||
@ -3164,7 +3159,7 @@ bool LibraryCallKit::inline_index_partially_in_upper_range() {
|
||||
}
|
||||
default: fatal("%s", type2name(elem_bt));
|
||||
}
|
||||
indexLimit = gvn().transform(VectorNode::scalar2vector(indexLimit, num_elem, Type::get_const_basic_type(elem_bt)));
|
||||
indexLimit = gvn().transform(VectorNode::scalar2vector(indexLimit, num_elem, elem_bt));
|
||||
|
||||
// Load the "iota" vector.
|
||||
const TypeVect* vt = TypeVect::make(elem_bt, num_elem);
|
||||
|
||||
@ -799,15 +799,13 @@ VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, B
|
||||
}
|
||||
|
||||
// Scalar promotion
|
||||
VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t, bool is_mask) {
|
||||
BasicType bt = opd_t->array_element_basic_type();
|
||||
VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, BasicType bt, bool is_mask) {
|
||||
if (is_mask && Matcher::match_rule_supported_vector(Op_MaskAll, vlen, bt)) {
|
||||
const TypeVect* vt = TypeVect::make(opd_t, vlen, true);
|
||||
const TypeVect* vt = TypeVect::make(bt, vlen, true);
|
||||
return new MaskAllNode(s, vt);
|
||||
}
|
||||
|
||||
const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
|
||||
: TypeVect::make(bt, vlen);
|
||||
const TypeVect* vt = TypeVect::make(bt, vlen);
|
||||
return new ReplicateNode(s, vt);
|
||||
}
|
||||
|
||||
@ -1626,8 +1624,6 @@ Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_
|
||||
Node* const_one_node = nullptr;
|
||||
|
||||
assert(cnt->bottom_type()->isa_vect(), "Unexpected shift");
|
||||
const Type* elem_ty = Type::get_const_basic_type(bt);
|
||||
|
||||
if (bt == T_LONG) {
|
||||
shift_mask_node = phase->longcon(shift_mask);
|
||||
const_one_node = phase->longcon(1L);
|
||||
@ -1639,8 +1635,8 @@ Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_
|
||||
subVopc = VectorNode::opcode(Op_SubI, bt);
|
||||
addVopc = VectorNode::opcode(Op_AddI, bt);
|
||||
}
|
||||
Node* vector_mask = phase->transform(VectorNode::scalar2vector(shift_mask_node, vlen, elem_ty));
|
||||
Node* vector_one = phase->transform(VectorNode::scalar2vector(const_one_node, vlen, elem_ty));
|
||||
Node* vector_mask = phase->transform(VectorNode::scalar2vector(shift_mask_node, vlen, bt));
|
||||
Node* vector_one = phase->transform(VectorNode::scalar2vector(const_one_node, vlen, bt));
|
||||
|
||||
shiftRCnt = cnt;
|
||||
shiftRCnt = phase->transform(VectorNode::make(Op_AndV, shiftRCnt, vector_mask, vt));
|
||||
@ -1882,12 +1878,12 @@ Node* NegVNode::degenerate_integral_negate(PhaseGVN* phase, bool is_predicated)
|
||||
const_one = phase->intcon(1);
|
||||
add_opc = Op_AddI;
|
||||
}
|
||||
const_minus_one = phase->transform(VectorNode::scalar2vector(const_minus_one, vlen, Type::get_const_basic_type(bt)));
|
||||
const_minus_one = phase->transform(VectorNode::scalar2vector(const_minus_one, vlen, bt));
|
||||
Node* xorv = VectorNode::make(Op_XorV, in(1), const_minus_one, vt);
|
||||
xorv->add_req(in(2));
|
||||
xorv->add_flag(Node::Flag_is_predicated_vector);
|
||||
phase->transform(xorv);
|
||||
const_one = phase->transform(VectorNode::scalar2vector(const_one, vlen, Type::get_const_basic_type(bt)));
|
||||
const_one = phase->transform(VectorNode::scalar2vector(const_one, vlen, bt));
|
||||
Node* addv = VectorNode::make(VectorNode::opcode(add_opc, bt), xorv, const_one, vt);
|
||||
addv->add_req(in(2));
|
||||
addv->add_flag(Node::Flag_is_predicated_vector);
|
||||
@ -1904,7 +1900,7 @@ Node* NegVNode::degenerate_integral_negate(PhaseGVN* phase, bool is_predicated)
|
||||
const_zero = phase->intcon(0);
|
||||
sub_opc = Op_SubI;
|
||||
}
|
||||
const_zero = phase->transform(VectorNode::scalar2vector(const_zero, vlen, Type::get_const_basic_type(bt)));
|
||||
const_zero = phase->transform(VectorNode::scalar2vector(const_zero, vlen, bt));
|
||||
return VectorNode::make(VectorNode::opcode(sub_opc, bt), const_zero, in(1), vt);
|
||||
}
|
||||
|
||||
@ -2069,8 +2065,7 @@ Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
if (!is_predicated_vector() && (in(1) == in(2))) {
|
||||
BasicType bt = vect_type()->element_basic_type();
|
||||
Node* zero = phase->transform(phase->zerocon(bt));
|
||||
return VectorNode::scalar2vector(zero, length(), Type::get_const_basic_type(bt),
|
||||
bottom_type()->isa_vectmask() != nullptr);
|
||||
return VectorNode::scalar2vector(zero, length(), bt, bottom_type()->isa_vectmask() != nullptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ class VectorNode : public TypeNode {
|
||||
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
|
||||
static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t, bool is_mask = false);
|
||||
static VectorNode* scalar2vector(Node* s, uint vlen, BasicType bt, bool is_mask = false);
|
||||
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, bool is_var_shift = false);
|
||||
static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask = false, bool is_var_shift = false);
|
||||
|
||||
@ -422,8 +422,7 @@ void VTransformScalarNode::print_spec() const {
|
||||
}
|
||||
|
||||
void VTransformReplicateNode::print_spec() const {
|
||||
tty->print("vlen=%d element_type=", _vlen);
|
||||
_element_type->dump();
|
||||
tty->print("vlen=%d element_type=%s", _vlen, type2name(_element_type));
|
||||
}
|
||||
|
||||
void VTransformShiftCountNode::print_spec() const {
|
||||
|
||||
@ -354,9 +354,9 @@ public:
|
||||
class VTransformReplicateNode : public VTransformNode {
|
||||
private:
|
||||
int _vlen;
|
||||
const Type* _element_type;
|
||||
BasicType _element_type;
|
||||
public:
|
||||
VTransformReplicateNode(VTransform& vtransform, int vlen, const Type* element_type) :
|
||||
VTransformReplicateNode(VTransform& vtransform, int vlen, BasicType element_type) :
|
||||
VTransformNode(vtransform, 2), _vlen(vlen), _element_type(element_type) {}
|
||||
virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer,
|
||||
const GrowableArray<Node*>& vnode_idx_to_transformed_node) const override;
|
||||
|
||||
@ -119,13 +119,13 @@ public class IRNode {
|
||||
public static final String VECTOR_SIZE_32 = VECTOR_SIZE + "32";
|
||||
public static final String VECTOR_SIZE_64 = VECTOR_SIZE + "64";
|
||||
|
||||
private static final String TYPE_BYTE = "byte";
|
||||
private static final String TYPE_CHAR = "char";
|
||||
private static final String TYPE_SHORT = "short";
|
||||
private static final String TYPE_INT = "int";
|
||||
private static final String TYPE_LONG = "long";
|
||||
private static final String TYPE_FLOAT = "float";
|
||||
private static final String TYPE_DOUBLE = "double";
|
||||
private static final String TYPE_BYTE = "B";
|
||||
private static final String TYPE_CHAR = "C";
|
||||
private static final String TYPE_SHORT = "S";
|
||||
private static final String TYPE_INT = "I";
|
||||
private static final String TYPE_LONG = "J";
|
||||
private static final String TYPE_FLOAT = "F";
|
||||
private static final String TYPE_DOUBLE = "D";
|
||||
|
||||
/**
|
||||
* IR placeholder string to regex-for-compile-phase map.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -133,7 +133,6 @@ public class RawIRNode {
|
||||
}
|
||||
}
|
||||
String sizeRegex = IRNode.parseVectorNodeSize(size, type, vmInfo);
|
||||
return nodeRegex.replaceAll(IRNode.IS_REPLACED,
|
||||
"vector[A-Za-z]\\\\[" + sizeRegex + "\\\\]:\\\\{" + type + "\\\\}");
|
||||
return nodeRegex.replaceAll(IRNode.IS_REPLACED, "vector[A-Za-z]<" + type + "," + sizeRegex + ">");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user