From ed5e79f740ee0a8a47df736a16a5ffef6694f22b Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Tue, 16 Dec 2025 09:12:22 +0000 Subject: [PATCH 1/4] 8370666: VectorAPI: Add clear comments for vector mask relative code in c2 --- src/hotspot/share/opto/matcher.hpp | 4 +- src/hotspot/share/opto/node.hpp | 5 +- src/hotspot/share/opto/type.cpp | 9 +- src/hotspot/share/opto/type.hpp | 17 +++- src/hotspot/share/opto/vectornode.hpp | 132 +++++++++++++++++++++++--- 5 files changed, 147 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index a071cff9e3cb1..9579af84f24b7 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, 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 @@ -327,6 +327,8 @@ class Matcher : public PhaseTransform { // e.g. Op_ vector nodes and other intrinsics while guarding with vlen static bool match_rule_supported_vector(int opcode, int vlen, BasicType bt); + // Returns true if the platform efficiently implements the given masked vector + // operation using predicate features, false otherwise. static bool match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt); // Determines if a vector operation needs to be partially implemented with a mask diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 0adb20721000f..8448cf4380e1a 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, 2025, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -843,7 +843,8 @@ class Node { Flag_has_swapped_edges = 1ULL << 11, Flag_is_scheduled = 1ULL << 12, Flag_is_expensive = 1ULL << 13, - Flag_is_predicated_vector = 1ULL << 14, + Flag_is_predicated_vector = 1ULL << 14, // Marked on a vector node that has an additional + // mask input controlling the lane operations. Flag_for_post_loop_opts_igvn = 1ULL << 15, Flag_for_merge_stores_igvn = 1ULL << 16, Flag_is_removed_by_peephole = 1ULL << 17, diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index ecb8c2c1cd825..ccfdd755a8997 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, 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 @@ -2443,6 +2443,13 @@ const TypeVect* TypeVect::make(BasicType elem_bt, uint length, bool is_mask) { return nullptr; } +// Create the type for a vector mask with the given element basic type and lane +// count. +// - Returns "TypeVectMask" for platforms that support the predicate feature and +// it is implemented properly in the backend, allowing the vector mask to be +// stored in a predicate/mask register. +// - Returns a normal vector type (i.e. TypeVectA ~ TypeVectZ) otherwise, where +// the vector mask is stored in a vector register. 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)) { diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index 73e2ba0045a90..4ceae2387bd14 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, 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 @@ -1012,7 +1012,7 @@ class TypeAry : public Type { }; //------------------------------TypeVect--------------------------------------- -// Class of Vector Types +// Basic class of vector (mask) types. class TypeVect : public Type { const BasicType _elem_bt; // Vector's element type const uint _length; // Elements in vector (power of 2) @@ -1052,6 +1052,16 @@ class TypeVect : public Type { #endif }; +// TypeVect subclasses representing vectors or vector masks with "BVectMask" or "NVectMask" +// layout (see vectornode.hpp for detailed notes on vector mask representations), mapped +// to vector registers and distinguished by vector register size: +// +// - TypeVectA: Scalable vector type (variable size, e.g., AArch64 SVE, RISC-V RVV) +// - TypeVectS: 32-bit vector type +// - TypeVectD: 64-bit vector type +// - TypeVectX: 128-bit vector type +// - TypeVectY: 256-bit vector type +// - TypeVectZ: 512-bit vector type class TypeVectA : public TypeVect { friend class TypeVect; TypeVectA(BasicType elem_bt, uint length) : TypeVect(VectorA, elem_bt, length) {} @@ -1082,6 +1092,9 @@ class TypeVectZ : public TypeVect { TypeVectZ(BasicType elem_bt, uint length) : TypeVect(VectorZ, elem_bt, length) {} }; +// Class of TypeVectMask, representing vector masks with "PVectMask" layout (see +// vectornode.hpp for detailed notes on vector mask representations), mapped to +// dedicated hardware predicate/mask registers. class TypeVectMask : public TypeVect { public: friend class TypeVect; diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index dc7aa13cf3683..b28f59b8a0e94 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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 @@ -33,6 +33,62 @@ #include "opto/opcodes.hpp" #include "prims/vectorSupport.hpp" +//=======================Notes-for-VectorMask-Representation======================= +// +// There are three distinct representations for vector masks based on platform and +// use scenarios: +// +// - BVectMask: Platform-independent mask stored in a vector register with 8-bit +// lanes containing 1/0 values. The corresponding type is TypeVectA ~ TypeVectZ. +// +// - NVectMask: Platform-specific mask stored in vector registers with N-bit lanes, +// where all bits in each lane are either set (true) or unset (false). Generated +// on architectures without predicate/mask feature, such as AArch64 NEON, x86 +// AVX2, etc. The corresponding type is TypeVectA ~ TypeVectZ. +// +// - PVectMask: Platform-specific mask stored in predicate/mask registers. Generated +// on architectures with predicate/mask feature, such as AArch64 SVE, x86 AVX-512, +// and RISC-V Vector Extension (RVV). The corresponding type is TypeVectMask. +// +// NVectMask and PVectMask encode element data type and vector length information. +// They are the primary mask representations used in most mask and masked vector +// operations. While BVectMask primarily represents mask values loaded from or +// stored to Java boolean memory, and is currently used in certain mask operations +// (i.e. VectorMaskOpNode). +// +//=========================Notes-for-Masked-Vector-Nodes=========================== +// +// Each lane-wise and cross-lane (reduction) ALU node supports both non-masked +// and masked operations. +// +// Currently masked vector nodes are only used to implement the Vector API's masked +// operations (which might also be used for auto-vectorization in future), such as: +// Vector lanewise(VectorOperators.Binary op, Vector v, VectorMask m) +// +// They are generated during intrinsification for Vector API, only on architectures +// that support the relevant predicated instructions. The compiler uses +// "Matcher::match_rule_supported_vector_masked()" to check whether the current +// platform supports the predicated/masked vector instructions for an operation. It +// generates the masked vector node for the operation if supported. Otherwise, it +// generates the unpredicated vector node and implements the masked operation with +// the help of a VectorBlendNode. Please see more details from API intrinsification +// in vectorIntrinsics.cpp. +// +// To differentiate the masked and non-masked nodes, flag "Flag_is_predicated_vector" +// is set for the masked version. Meanwhile, there is an additional mask input for +// the masked nodes. +// +// For example, "AddVBNode" might have two versions: +// - Non-masked version: +// in1 in2 +// \ / +// AddVBNode +// +// - Masked version (with "Flag_is_predicated_vector" being set): +// in1 in2 mask +// \ | / +// AddVBNode + //------------------------------VectorNode------------------------------------- // Vector Operation class VectorNode : public TypeNode { @@ -103,6 +159,8 @@ class VectorNode : public TypeNode { static bool implemented(int opc, uint vlen, BasicType bt); static bool is_shift(Node* n); static bool is_vshift_cnt(Node* n); + // Returns true if the lower vlen bits (bits [0, vlen-1]) of the long value + // are all 1s or all 0s, indicating a "mask all" or "mask none" pattern. static bool is_maskall_type(const TypeLong* type, int vlen); static bool is_muladds2i(const Node* n); static bool is_roundopD(Node* n); @@ -1051,6 +1109,7 @@ class CompressVNode: public VectorNode { virtual int Opcode() const; }; +// Vector mask compress class CompressMNode: public VectorNode { public: CompressMNode(Node* mask, const TypeVect* vt) : @@ -1326,6 +1385,8 @@ class VectorCmpMaskedNode : public TypeNode { }; //------------------------------VectorMaskGenNode---------------------------------- +// Generate a vector mask based on the given length. Lanes with indices in +// [0, length) are set to true, while the remaining lanes are set to false. class VectorMaskGenNode : public TypeNode { public: VectorMaskGenNode(Node* length, const Type* ty): TypeNode(ty, 2) { @@ -1339,6 +1400,8 @@ class VectorMaskGenNode : public TypeNode { }; //------------------------------VectorMaskOpNode----------------------------------- +// Base class for certain vector mask operations. The supported input mask can be +// either "BVectMask" or "PVectMask" depending on the platform. class VectorMaskOpNode : public TypeNode { private: int _mopc; @@ -1359,6 +1422,7 @@ class VectorMaskOpNode : public TypeNode { static Node* make(Node* mask, const Type* ty, int mopc); }; +// Count the number of true (set) lanes in the vector mask. class VectorMaskTrueCountNode : public VectorMaskOpNode { public: VectorMaskTrueCountNode(Node* mask, const Type* ty): @@ -1366,6 +1430,8 @@ class VectorMaskTrueCountNode : public VectorMaskOpNode { virtual int Opcode() const; }; +// Returns the index of the first true (set) lane in the vector mask. +// If no lanes are set, returns the vector length. class VectorMaskFirstTrueNode : public VectorMaskOpNode { public: VectorMaskFirstTrueNode(Node* mask, const Type* ty): @@ -1373,6 +1439,8 @@ class VectorMaskFirstTrueNode : public VectorMaskOpNode { virtual int Opcode() const; }; +// Returns the index of the last true (set) lane in the vector mask. +// If no lanes are set, returns -1 . class VectorMaskLastTrueNode : public VectorMaskOpNode { public: VectorMaskLastTrueNode(Node* mask, const Type* ty): @@ -1380,6 +1448,10 @@ class VectorMaskLastTrueNode : public VectorMaskOpNode { virtual int Opcode() const; }; +// Pack the mask lane values into a long value, supporting at most the +// first 64 lanes. Each mask lane is packed into one bit in the long +// value, ordered from the least significant bit to the most significant +// bit. class VectorMaskToLongNode : public VectorMaskOpNode { public: VectorMaskToLongNode(Node* mask, const Type* ty): @@ -1391,6 +1463,9 @@ class VectorMaskToLongNode : public VectorMaskOpNode { virtual Node* Identity(PhaseGVN* phase); }; +// Unpack bits from a long value into vector mask lane values. Each bit +// in the long value is unpacked into one mask lane, ordered from the +// least significant bit to the sign bit. class VectorLongToMaskNode : public VectorNode { public: VectorLongToMaskNode(Node* mask, const TypeVect* ty): @@ -1400,28 +1475,37 @@ class VectorLongToMaskNode : public VectorNode { virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; -//-------------------------- Vector mask broadcast ----------------------------------- +//-------------------------- Vector mask broadcast ------------------------------ +// Broadcast a scalar value to all lanes of a vector mask. All lanes are set +// to true if the input value is non-zero, or false if the input value is zero. +// This node is only used to generate a mask with "PVectMask" layout. class MaskAllNode : public VectorNode { public: MaskAllNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical and -------------------------------- +//--------------------------- Vector mask logical and --------------------------- +// Perform a bitwise AND operation between two vector masks. This node is only +// used for vector masks with "PVectMask" layout. class AndVMaskNode : public AndVNode { public: AndVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : AndVNode(in1, in2, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical or --------------------------------- +//--------------------------- Vector mask logical or ---------------------------- +// Perform a bitwise OR operation between two vector masks. This node is only +// used for vector masks with "PVectMask" layout. class OrVMaskNode : public OrVNode { public: OrVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : OrVNode(in1, in2, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical xor -------------------------------- +//--------------------------- Vector mask logical xor --------------------------- +// Perform a bitwise XOR operation between two vector masks. This node is only +// used for vector masks with "PVectMask" layout. class XorVMaskNode : public XorVNode { public: XorVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : XorVNode(in1, in2, vt) {} @@ -1653,6 +1737,9 @@ class MacroLogicVNode : public VectorNode { Node* mask, uint truth_table, const TypeVect* vt); }; +//------------------------------VectorMaskCmpNode------------------------------- +// Compare two vectors lane-wise using the specified predicate and produce a +// vector mask. class VectorMaskCmpNode : public VectorNode { private: BoolTest::mask _predicate; @@ -1697,6 +1784,9 @@ class VectorMaskWrapperNode : public VectorNode { Node* vector_mask() const { return in(2); } }; +//------------------------------VectorTestNode------------------------------- +// Test whether all or any lanes in the first input vector mask is true, +// based on the specified predicate. class VectorTestNode : public CmpNode { private: BoolTest::mask _predicate; @@ -1719,6 +1809,10 @@ class VectorTestNode : public CmpNode { } }; +//------------------------------VectorBlendNode------------------------------- +// Blend two vectors based on a vector mask. For each lane, select the value +// from the first input vector (vec1) if the corresponding mask lane is set, +// otherwise select from the second input vector (vec2). class VectorBlendNode : public VectorNode { public: VectorBlendNode(Node* vec1, Node* vec2, Node* mask) @@ -1736,7 +1830,6 @@ 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; @@ -1744,7 +1837,6 @@ class VectorRearrangeNode : public VectorNode { Node* vec_shuffle() const { return in(2); } }; - // Select elements from two source vectors based on the wrapped indexes held in // the first vector. class SelectFromTwoVectorNode : public VectorNode { @@ -1758,13 +1850,16 @@ class SelectFromTwoVectorNode : public VectorNode { virtual int Opcode() const; }; -// The target may not directly support the rearrange operation for an element type. In those cases, -// we can transform the rearrange into a different element type. For example, on x86 before AVX512, -// there is no rearrange instruction for short elements, what we will then do is to transform the -// shuffle vector into one that we can do byte rearrange such that it would provide the same -// result. This could have been done in VectorRearrangeNode during code emission but we eagerly -// expand this out because it is often the case that an index vector is reused in many rearrange -// operations. This allows the index preparation to be GVN-ed as well as hoisted out of loops, etc. +//------------------------------VectorLoadShuffleNode------------------------------ +// The target may not directly support the rearrange operation for an element type. +// In those cases, we can transform the rearrange into a different element type. +// For example, on x86 before AVX512, there is no rearrange instruction for short +// elements, what we will then do is to transform the shuffle vector into one that +// we can do byte rearrange such that it would provide the same result. This could +// have been done in VectorRearrangeNode during code emission but we eagerly expand +// this out because it is often the case that an index vector is reused in many +// rearrange operations. This allows the index preparation to be GVN-ed as well as +// hoisted out of loops, etc. class VectorLoadShuffleNode : public VectorNode { public: VectorLoadShuffleNode(Node* in, const TypeVect* vt) @@ -1773,6 +1868,9 @@ class VectorLoadShuffleNode : public VectorNode { virtual int Opcode() const; }; +//------------------------------VectorLoadMaskNode--------------------------------- +// Convert a "BVectMask" into a platform-specific vector mask (either "NVectMask" +// or "PVectMask"). class VectorLoadMaskNode : public VectorNode { public: VectorLoadMaskNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { @@ -1784,6 +1882,9 @@ class VectorLoadMaskNode : public VectorNode { Node* Ideal(PhaseGVN* phase, bool can_reshape); }; +//------------------------------VectorStoreMaskNode-------------------------------- +// Convert a platform-specific vector mask (either "NVectMask" or "PVectMask") +// into a "BVectMask". class VectorStoreMaskNode : public VectorNode { protected: VectorStoreMaskNode(Node* in1, ConINode* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} @@ -1795,6 +1896,9 @@ class VectorStoreMaskNode : public VectorNode { static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem); }; +//------------------------------VectorMaskCastNode---------------------------------- +// Lane-wise type cast a vector mask to the given vector type. The vector length +// of the input and output must be the same. class VectorMaskCastNode : public VectorNode { public: VectorMaskCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { From 6782b7f6ce16d111ab77f1723d30ee3d2c506792 Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Tue, 13 Jan 2026 08:43:19 +0000 Subject: [PATCH 2/4] Add more comments for vector nodes --- src/hotspot/share/opto/vectornode.hpp | 270 +++++++++----------------- 1 file changed, 97 insertions(+), 173 deletions(-) diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index b28f59b8a0e94..9f2715a8871e8 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -78,7 +78,7 @@ // is set for the masked version. Meanwhile, there is an additional mask input for // the masked nodes. // -// For example, "AddVBNode" might have two versions: +// For example: // - Non-masked version: // in1 in2 // \ / @@ -89,7 +89,6 @@ // \ | / // AddVBNode -//------------------------------VectorNode------------------------------------- // Vector Operation class VectorNode : public TypeNode { public: @@ -234,7 +233,6 @@ class SaturatingVectorNode : public VectorNode { bool is_unsigned() { return _is_unsigned; } }; -//------------------------------AddVBNode-------------------------------------- // Vector add byte class AddVBNode : public VectorNode { public: @@ -242,7 +240,6 @@ class AddVBNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVSNode-------------------------------------- // Vector add char/short class AddVSNode : public VectorNode { public: @@ -250,7 +247,6 @@ class AddVSNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVINode-------------------------------------- // Vector add int class AddVINode : public VectorNode { public: @@ -258,7 +254,6 @@ class AddVINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVLNode-------------------------------------- // Vector add long class AddVLNode : public VectorNode { public: @@ -266,7 +261,6 @@ class AddVLNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVHFNode-------------------------------------- // Vector add float class AddVHFNode : public VectorNode { public: @@ -274,7 +268,6 @@ class AddVHFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVFNode-------------------------------------- // Vector add float class AddVFNode : public VectorNode { public: @@ -282,7 +275,6 @@ class AddVFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AddVDNode-------------------------------------- // Vector add double class AddVDNode : public VectorNode { public: @@ -290,7 +282,6 @@ class AddVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------ReductionNode------------------------------------ // Perform reduction of a vector class ReductionNode : public Node { private: @@ -352,7 +343,6 @@ class ReductionNode : public Node { #endif }; -//------------------------------AddReductionVINode-------------------------------------- // Vector add byte, short and int as a reduction class AddReductionVINode : public ReductionNode { public: @@ -360,7 +350,6 @@ class AddReductionVINode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------AddReductionVLNode-------------------------------------- // Vector add long as a reduction class AddReductionVLNode : public ReductionNode { public: @@ -368,7 +357,6 @@ class AddReductionVLNode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------AddReductionVFNode-------------------------------------- // Vector add float as a reduction class AddReductionVFNode : public ReductionNode { private: @@ -395,7 +383,6 @@ class AddReductionVFNode : public ReductionNode { virtual uint size_of() const { return sizeof(*this); } }; -//------------------------------AddReductionVDNode-------------------------------------- // Vector add double as a reduction class AddReductionVDNode : public ReductionNode { private: @@ -422,7 +409,6 @@ class AddReductionVDNode : public ReductionNode { virtual uint size_of() const { return sizeof(*this); } }; -//------------------------------SubVBNode-------------------------------------- // Vector subtract byte class SubVBNode : public VectorNode { public: @@ -430,7 +416,6 @@ class SubVBNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SubVSNode-------------------------------------- // Vector subtract short class SubVSNode : public VectorNode { public: @@ -438,7 +423,6 @@ class SubVSNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SubVINode-------------------------------------- // Vector subtract int class SubVINode : public VectorNode { public: @@ -446,7 +430,6 @@ class SubVINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SubVLNode-------------------------------------- // Vector subtract long class SubVLNode : public VectorNode { public: @@ -454,7 +437,6 @@ class SubVLNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SaturatingAddVNode----------------------------- // Vector saturating addition. class SaturatingAddVNode : public SaturatingVectorNode { public: @@ -462,7 +444,6 @@ class SaturatingAddVNode : public SaturatingVectorNode { virtual int Opcode() const; }; -//------------------------------SaturatingSubVNode----------------------------- // Vector saturating subtraction. class SaturatingSubVNode : public SaturatingVectorNode { public: @@ -470,7 +451,6 @@ class SaturatingSubVNode : public SaturatingVectorNode { virtual int Opcode() const; }; -//------------------------------SubVHFNode-------------------------------------- // Vector subtract half float class SubVHFNode : public VectorNode { public: @@ -478,8 +458,6 @@ class SubVHFNode : public VectorNode { virtual int Opcode() const; }; - -//------------------------------SubVFNode-------------------------------------- // Vector subtract float class SubVFNode : public VectorNode { public: @@ -487,7 +465,6 @@ class SubVFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SubVDNode-------------------------------------- // Vector subtract double class SubVDNode : public VectorNode { public: @@ -495,7 +472,6 @@ class SubVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVBNode-------------------------------------- // Vector multiply byte class MulVBNode : public VectorNode { public: @@ -503,7 +479,6 @@ class MulVBNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVSNode-------------------------------------- // Vector multiply short class MulVSNode : public VectorNode { public: @@ -511,7 +486,6 @@ class MulVSNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVINode-------------------------------------- // Vector multiply int class MulVINode : public VectorNode { public: @@ -519,7 +493,6 @@ class MulVINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVLNode-------------------------------------- // Vector multiply long class MulVLNode : public VectorNode { public: @@ -531,7 +504,6 @@ class MulVLNode : public VectorNode { bool has_uint_inputs() const; }; -//------------------------------MulVFNode-------------------------------------- // Vector multiply half float class MulVHFNode : public VectorNode { public: @@ -539,7 +511,6 @@ class MulVHFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVFNode-------------------------------------- // Vector multiply float class MulVFNode : public VectorNode { public: @@ -547,7 +518,6 @@ class MulVFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulVDNode-------------------------------------- // Vector multiply double class MulVDNode : public VectorNode { public: @@ -555,7 +525,6 @@ class MulVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MulAddVS2VINode-------------------------------- // Vector multiply shorts to int and add adjacent ints. class MulAddVS2VINode : public VectorNode { public: @@ -563,7 +532,6 @@ class MulAddVS2VINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------FmaVNode-------------------------------------- // Vector fused-multiply-add class FmaVNode : public VectorNode { public: @@ -573,7 +541,6 @@ class FmaVNode : public VectorNode { virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; -//------------------------------FmaVDNode-------------------------------------- // Vector fused-multiply-add double class FmaVDNode : public FmaVNode { public: @@ -581,7 +548,6 @@ class FmaVDNode : public FmaVNode { virtual int Opcode() const; }; -//------------------------------FmaVFNode-------------------------------------- // Vector fused-multiply-add float class FmaVFNode : public FmaVNode { public: @@ -589,7 +555,6 @@ class FmaVFNode : public FmaVNode { virtual int Opcode() const; }; -//------------------------------FmaVHFNode------------------------------------- // Vector fused-multiply-add half-precision float class FmaVHFNode : public FmaVNode { public: @@ -597,7 +562,6 @@ class FmaVHFNode : public FmaVNode { virtual int Opcode() const; }; -//------------------------------MulReductionVINode-------------------------------------- // Vector multiply byte, short and int as a reduction class MulReductionVINode : public ReductionNode { public: @@ -605,7 +569,6 @@ class MulReductionVINode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------MulReductionVLNode-------------------------------------- // Vector multiply int as a reduction class MulReductionVLNode : public ReductionNode { public: @@ -613,7 +576,6 @@ class MulReductionVLNode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------MulReductionVFNode-------------------------------------- // Vector multiply float as a reduction class MulReductionVFNode : public ReductionNode { // True if mul reduction operation for floats requires strict ordering. @@ -639,7 +601,6 @@ class MulReductionVFNode : public ReductionNode { virtual uint size_of() const { return sizeof(*this); } }; -//------------------------------MulReductionVDNode-------------------------------------- // Vector multiply double as a reduction class MulReductionVDNode : public ReductionNode { // True if mul reduction operation for doubles requires strict ordering. @@ -665,7 +626,6 @@ class MulReductionVDNode : public ReductionNode { virtual uint size_of() const { return sizeof(*this); } }; -//------------------------------DivVHFNode------------------------------------- // Vector divide half float class DivVHFNode : public VectorNode { public: @@ -673,7 +633,6 @@ class DivVHFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------DivVFNode-------------------------------------- // Vector divide float class DivVFNode : public VectorNode { public: @@ -681,7 +640,6 @@ class DivVFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------DivVDNode-------------------------------------- // Vector Divide double class DivVDNode : public VectorNode { public: @@ -689,7 +647,6 @@ class DivVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVBNode-------------------------------------- // Vector Abs byte class AbsVBNode : public VectorNode { public: @@ -697,7 +654,6 @@ class AbsVBNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVSNode-------------------------------------- // Vector Abs short class AbsVSNode : public VectorNode { public: @@ -705,7 +661,6 @@ class AbsVSNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MinVNode-------------------------------------- // Vector Min class MinVNode : public VectorNode { public: @@ -713,7 +668,6 @@ class MinVNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MinVHFNode------------------------------------ // Vector Min for half floats class MinVHFNode : public VectorNode { public: @@ -721,7 +675,6 @@ class MinVHFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------MaxVHFNode------------------------------------ // Vector Max for half floats class MaxVHFNode : public VectorNode { public: @@ -729,6 +682,7 @@ class MaxVHFNode : public VectorNode { virtual int Opcode() const; }; +// Vector Unsigned Min class UMinVNode : public VectorNode { public: UMinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2 ,vt) { @@ -739,8 +693,6 @@ class UMinVNode : public VectorNode { virtual int Opcode() const; }; - -//------------------------------MaxVNode-------------------------------------- // Vector Max class MaxVNode : public VectorNode { public: @@ -748,6 +700,7 @@ class MaxVNode : public VectorNode { virtual int Opcode() const; }; +// Vector Unsigned Max class UMaxVNode : public VectorNode { public: UMaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) { @@ -758,7 +711,6 @@ class UMaxVNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVINode-------------------------------------- // Vector Abs int class AbsVINode : public VectorNode { public: @@ -766,7 +718,6 @@ class AbsVINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVLNode-------------------------------------- // Vector Abs long class AbsVLNode : public VectorNode { public: @@ -774,7 +725,6 @@ class AbsVLNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVFNode-------------------------------------- // Vector Abs float class AbsVFNode : public VectorNode { public: @@ -782,7 +732,6 @@ class AbsVFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AbsVDNode-------------------------------------- // Vector Abs double class AbsVDNode : public VectorNode { public: @@ -790,7 +739,6 @@ class AbsVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------NegVNode--------------------------------------- // Vector Neg parent class (not for code generation). class NegVNode : public VectorNode { public: @@ -804,7 +752,6 @@ class NegVNode : public VectorNode { Node* degenerate_integral_negate(PhaseGVN* phase, bool is_predicated); }; -//------------------------------NegVINode-------------------------------------- // Vector Neg byte/short/int class NegVINode : public NegVNode { public: @@ -812,7 +759,6 @@ class NegVINode : public NegVNode { virtual int Opcode() const; }; -//------------------------------NegVLNode-------------------------------------- // Vector Neg long class NegVLNode : public NegVNode { public: @@ -820,7 +766,6 @@ class NegVLNode : public NegVNode { virtual int Opcode() const; }; -//------------------------------NegVFNode-------------------------------------- // Vector Neg float class NegVFNode : public NegVNode { public: @@ -828,7 +773,6 @@ class NegVFNode : public NegVNode { virtual int Opcode() const; }; -//------------------------------NegVDNode-------------------------------------- // Vector Neg double class NegVDNode : public NegVNode { public: @@ -836,7 +780,6 @@ class NegVDNode : public NegVNode { virtual int Opcode() const; }; -//------------------------------PopCountVINode--------------------------------- // Vector popcount integer bits class PopCountVINode : public VectorNode { public: @@ -844,7 +787,6 @@ class PopCountVINode : public VectorNode { virtual int Opcode() const; }; -//------------------------------PopCountVLNode--------------------------------- // Vector popcount long bits class PopCountVLNode : public VectorNode { public: @@ -854,7 +796,6 @@ class PopCountVLNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SqrtVHFNode------------------------------------- // Vector Sqrt half-precision float class SqrtVHFNode : public VectorNode { public: @@ -862,14 +803,13 @@ class SqrtVHFNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SqrtVFNode-------------------------------------- // Vector Sqrt float class SqrtVFNode : public VectorNode { public: SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} virtual int Opcode() const; }; -//------------------------------RoundDoubleVNode-------------------------------- + // Vector round double class RoundDoubleModeVNode : public VectorNode { public: @@ -877,7 +817,6 @@ class RoundDoubleModeVNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------SqrtVDNode-------------------------------------- // Vector Sqrt double class SqrtVDNode : public VectorNode { public: @@ -885,8 +824,7 @@ class SqrtVDNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------ShiftVNode----------------------------------- -// Class ShiftV functionality. This covers the common behaviors for all kinds +// Class ShiftV functionality. This covers the common behaviors for all kinds // of vector shifts. class ShiftVNode : public VectorNode { private: @@ -906,7 +844,6 @@ class ShiftVNode : public VectorNode { virtual uint size_of() const { return sizeof(ShiftVNode); } }; -//------------------------------LShiftVBNode----------------------------------- // Vector left shift bytes class LShiftVBNode : public ShiftVNode { public: @@ -915,7 +852,6 @@ class LShiftVBNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------LShiftVSNode----------------------------------- // Vector left shift shorts class LShiftVSNode : public ShiftVNode { public: @@ -924,7 +860,6 @@ class LShiftVSNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------LShiftVINode----------------------------------- // Vector left shift ints class LShiftVINode : public ShiftVNode { public: @@ -933,7 +868,6 @@ class LShiftVINode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------LShiftVLNode----------------------------------- // Vector left shift longs class LShiftVLNode : public ShiftVNode { public: @@ -942,7 +876,6 @@ class LShiftVLNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------RShiftVBNode----------------------------------- // Vector right arithmetic (signed) shift bytes class RShiftVBNode : public ShiftVNode { public: @@ -951,7 +884,6 @@ class RShiftVBNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------RShiftVSNode----------------------------------- // Vector right arithmetic (signed) shift shorts class RShiftVSNode : public ShiftVNode { public: @@ -960,7 +892,6 @@ class RShiftVSNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------RShiftVINode----------------------------------- // Vector right arithmetic (signed) shift ints class RShiftVINode : public ShiftVNode { public: @@ -969,7 +900,6 @@ class RShiftVINode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------RShiftVLNode----------------------------------- // Vector right arithmetic (signed) shift longs class RShiftVLNode : public ShiftVNode { public: @@ -978,7 +908,6 @@ class RShiftVLNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------URShiftVBNode---------------------------------- // Vector right logical (unsigned) shift bytes class URShiftVBNode : public ShiftVNode { public: @@ -987,7 +916,6 @@ class URShiftVBNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------URShiftVSNode---------------------------------- // Vector right logical (unsigned) shift shorts class URShiftVSNode : public ShiftVNode { public: @@ -996,7 +924,6 @@ class URShiftVSNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------URShiftVINode---------------------------------- // Vector right logical (unsigned) shift ints class URShiftVINode : public ShiftVNode { public: @@ -1005,7 +932,6 @@ class URShiftVINode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------URShiftVLNode---------------------------------- // Vector right logical (unsigned) shift longs class URShiftVLNode : public ShiftVNode { public: @@ -1014,7 +940,6 @@ class URShiftVLNode : public ShiftVNode { virtual int Opcode() const; }; -//------------------------------LShiftCntVNode--------------------------------- // Vector left shift count class LShiftCntVNode : public VectorNode { public: @@ -1022,7 +947,6 @@ class LShiftCntVNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------RShiftCntVNode--------------------------------- // Vector right shift count class RShiftCntVNode : public VectorNode { public: @@ -1030,7 +954,6 @@ class RShiftCntVNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------AndVNode--------------------------------------- // Vector and integer class AndVNode : public VectorNode { public: @@ -1039,7 +962,6 @@ class AndVNode : public VectorNode { virtual Node* Identity(PhaseGVN* phase); }; -//------------------------------AndReductionVNode-------------------------------------- // Vector and byte, short, int, long as a reduction class AndReductionVNode : public ReductionNode { public: @@ -1047,8 +969,7 @@ class AndReductionVNode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------OrVNode--------------------------------------- -// Vector or byte, short, int, long as a reduction +// Vector or integer class OrVNode : public VectorNode { public: OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} @@ -1056,15 +977,13 @@ class OrVNode : public VectorNode { virtual Node* Identity(PhaseGVN* phase); }; -//------------------------------OrReductionVNode-------------------------------------- -// Vector xor byte, short, int, long as a reduction +// Vector or byte, short, int, long as a reduction class OrReductionVNode : public ReductionNode { public: OrReductionVNode(Node* ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} virtual int Opcode() const; }; -//------------------------------XorVNode--------------------------------------- // Vector xor integer class XorVNode : public VectorNode { public: @@ -1074,15 +993,13 @@ class XorVNode : public VectorNode { Node* Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape); }; -//------------------------------XorReductionVNode-------------------------------------- -// Vector and int, long as a reduction +// Vector xor byte, short, 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; }; -//------------------------------MinReductionVNode-------------------------------------- // Vector min byte, short, int, long, float, double as a reduction class MinReductionVNode : public ReductionNode { public: @@ -1090,15 +1007,13 @@ class MinReductionVNode : public ReductionNode { virtual int Opcode() const; }; -//------------------------------MaxReductionVNode-------------------------------------- -// Vector min byte, short, int, long, float, double as a reduction +// Vector max 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) {} virtual int Opcode() const; }; -//------------------------------CompressVNode-------------------------------------- // Vector compress class CompressVNode: public VectorNode { public: @@ -1119,7 +1034,6 @@ class CompressMNode: public VectorNode { virtual int Opcode() const; }; -//------------------------------ExpandVNode-------------------------------------- // Vector expand class ExpandVNode: public VectorNode { public: @@ -1132,7 +1046,6 @@ class ExpandVNode: public VectorNode { //================================= M E M O R Y =============================== -//------------------------------LoadVectorNode--------------------------------- // Load Vector from memory class LoadVectorNode : public LoadNode { private: @@ -1174,7 +1087,6 @@ class LoadVectorNode : public LoadNode { #endif }; -//------------------------------LoadVectorGatherNode------------------------------ // Load Vector from memory via index map class LoadVectorGatherNode : public LoadVectorNode { public: @@ -1197,7 +1109,6 @@ class LoadVectorGatherNode : public LoadVectorNode { } }; -//------------------------------StoreVectorNode-------------------------------- // Store Vector to memory class StoreVectorNode : public StoreNode { private: @@ -1239,9 +1150,7 @@ class StoreVectorNode : public StoreNode { #endif }; -//------------------------------StoreVectorScatterNode------------------------------ // Store Vector into memory via index map - class StoreVectorScatterNode : public StoreVectorNode { public: enum { Indices = 4 }; @@ -1259,7 +1168,6 @@ class StoreVectorNode : public StoreNode { virtual Node* indices() const { return in(Indices); } }; -//------------------------------StoreVectorMaskedNode-------------------------------- // Store Vector to memory under the influence of a predicate register(mask). class StoreVectorMaskedNode : public StoreVectorNode { public: @@ -1280,7 +1188,6 @@ class StoreVectorMaskedNode : public StoreVectorNode { virtual Node* mask() const { return in(Mask); } }; -//------------------------------LoadVectorMaskedNode-------------------------------- // Load Vector from memory under the influence of a predicate register(mask). class LoadVectorMaskedNode : public LoadVectorNode { public: @@ -1304,7 +1211,6 @@ class LoadVectorMaskedNode : public LoadVectorNode { } }; -//-------------------------------LoadVectorGatherMaskedNode--------------------------------- // Load Vector from memory via index map under the influence of a predicate register(mask). class LoadVectorGatherMaskedNode : public LoadVectorNode { public: @@ -1327,7 +1233,6 @@ class LoadVectorGatherMaskedNode : public LoadVectorNode { } }; -//------------------------------StoreVectorScatterMaskedNode-------------------------------- // Store Vector into memory via index map under the influence of a predicate register(mask). class StoreVectorScatterMaskedNode : public StoreVectorNode { public: @@ -1371,7 +1276,6 @@ class VerifyVectorAlignmentNode : public Node { virtual const Type *bottom_type() const { return in(1)->bottom_type(); } }; -//------------------------------VectorCmpMaskedNode-------------------------------- // Vector Comparison under the influence of a predicate register(mask). class VectorCmpMaskedNode : public TypeNode { public: @@ -1384,7 +1288,6 @@ class VectorCmpMaskedNode : public TypeNode { virtual int Opcode() const; }; -//------------------------------VectorMaskGenNode---------------------------------- // Generate a vector mask based on the given length. Lanes with indices in // [0, length) are set to true, while the remaining lanes are set to false. class VectorMaskGenNode : public TypeNode { @@ -1399,9 +1302,8 @@ class VectorMaskGenNode : public TypeNode { static Node* make(Node* length, BasicType vmask_bt, int vmask_len); }; -//------------------------------VectorMaskOpNode----------------------------------- -// Base class for certain vector mask operations. The supported input mask can be -// either "BVectMask" or "PVectMask" depending on the platform. +// Base class for certain vector mask operations. The supported input mask can +// be either "BVectMask" or "PVectMask" depending on the platform. class VectorMaskOpNode : public TypeNode { private: int _mopc; @@ -1475,45 +1377,40 @@ class VectorLongToMaskNode : public VectorNode { virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; -//-------------------------- Vector mask broadcast ------------------------------ // Broadcast a scalar value to all lanes of a vector mask. All lanes are set -// to true if the input value is non-zero, or false if the input value is zero. -// This node is only used to generate a mask with "PVectMask" layout. +// to true if the input value is non-zero, or false if the input value is +// zero. This node is only used to generate a mask with "PVectMask" layout. class MaskAllNode : public VectorNode { public: MaskAllNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical and --------------------------- -// Perform a bitwise AND operation between two vector masks. This node is only -// used for vector masks with "PVectMask" layout. +// Perform a bitwise AND operation between two vector masks. This node is +// only used for vector masks with "PVectMask" layout. class AndVMaskNode : public AndVNode { public: AndVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : AndVNode(in1, in2, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical or ---------------------------- -// Perform a bitwise OR operation between two vector masks. This node is only -// used for vector masks with "PVectMask" layout. +// Perform a bitwise OR operation between two vector masks. This node is +// only used for vector masks with "PVectMask" layout. class OrVMaskNode : public OrVNode { public: OrVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : OrVNode(in1, in2, vt) {} virtual int Opcode() const; }; -//--------------------------- Vector mask logical xor --------------------------- -// Perform a bitwise XOR operation between two vector masks. This node is only -// used for vector masks with "PVectMask" layout. +// Perform a bitwise XOR operation between two vector masks. This node is +// only used for vector masks with "PVectMask" layout. class XorVMaskNode : public XorVNode { public: XorVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : XorVNode(in1, in2, vt) {} virtual int Opcode() const; }; -//=========================Promote_Scalar_to_Vector============================ - +// Replicate a scalar value to all lanes of a vector. class ReplicateNode : public VectorNode { public: ReplicateNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) { @@ -1523,7 +1420,7 @@ class ReplicateNode : public VectorNode { virtual int Opcode() const; }; -//======================Populate_Indices_into_a_Vector========================= +// Populate indices into a vector. class PopulateIndexNode : public VectorNode { public: PopulateIndexNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} @@ -1532,7 +1429,6 @@ class PopulateIndexNode : public VectorNode { //========================Pack_Scalars_into_a_Vector=========================== -//------------------------------PackNode--------------------------------------- // Pack parent class (not for code generation). class PackNode : public VectorNode { public: @@ -1550,7 +1446,6 @@ class PackNode : public VectorNode { static PackNode* make(Node* s, uint vlen, BasicType bt); }; -//------------------------------PackBNode-------------------------------------- // Pack byte scalars into vector class PackBNode : public PackNode { public: @@ -1558,7 +1453,6 @@ class PackBNode : public PackNode { virtual int Opcode() const; }; -//------------------------------PackSNode-------------------------------------- // Pack short scalars into a vector class PackSNode : public PackNode { public: @@ -1567,7 +1461,6 @@ class PackSNode : public PackNode { virtual int Opcode() const; }; -//------------------------------PackINode-------------------------------------- // Pack integer scalars into a vector class PackINode : public PackNode { public: @@ -1576,7 +1469,6 @@ class PackINode : public PackNode { virtual int Opcode() const; }; -//------------------------------PackLNode-------------------------------------- // Pack long scalars into a vector class PackLNode : public PackNode { public: @@ -1585,7 +1477,6 @@ class PackLNode : public PackNode { virtual int Opcode() const; }; -//------------------------------Pack2LNode------------------------------------- // Pack 2 long scalars into a vector class Pack2LNode : public PackNode { public: @@ -1593,7 +1484,6 @@ class Pack2LNode : public PackNode { virtual int Opcode() const; }; -//------------------------------PackFNode-------------------------------------- // Pack float scalars into vector class PackFNode : public PackNode { public: @@ -1602,7 +1492,6 @@ class PackFNode : public PackNode { virtual int Opcode() const; }; -//------------------------------PackDNode-------------------------------------- // Pack double scalars into a vector class PackDNode : public PackNode { public: @@ -1611,7 +1500,6 @@ class PackDNode : public PackNode { virtual int Opcode() const; }; -//------------------------------Pack2DNode------------------------------------- // Pack 2 double scalars into a vector class Pack2DNode : public PackNode { public: @@ -1619,7 +1507,10 @@ class Pack2DNode : public PackNode { virtual int Opcode() const; }; - +// Load the IOTA constant vector containing sequential indices starting from 0 +// and incrementing by 1 up to "VLENGTH - 1". So far, the first input is an int +// constant 0. For example, a 128-bit vector with int (32-bit) elements produces +// a vector like "[0, 1, 2, 3]". class VectorLoadConstNode : public VectorNode { public: VectorLoadConstNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} @@ -1628,8 +1519,7 @@ class VectorLoadConstNode : public VectorNode { //========================Extract_Scalar_from_Vector=========================== -//------------------------------ExtractNode------------------------------------ -// Extract a scalar from a vector at position "pos" +// The base class for all extract nodes. class ExtractNode : public Node { public: ExtractNode(Node* src, Node* pos) : Node(nullptr, src, pos) {} @@ -1638,8 +1528,7 @@ class ExtractNode : public Node { static int opcode(BasicType bt); }; -//------------------------------ExtractBNode----------------------------------- -// Extract a byte from a vector at position "pos" +// Extract a byte from a vector at position "pos". class ExtractBNode : public ExtractNode { public: ExtractBNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1648,8 +1537,7 @@ class ExtractBNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------ExtractUBNode---------------------------------- -// Extract a boolean from a vector at position "pos" +// Extract a boolean from a vector at position "pos". class ExtractUBNode : public ExtractNode { public: ExtractUBNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1658,8 +1546,7 @@ class ExtractUBNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------ExtractCNode----------------------------------- -// Extract a char from a vector at position "pos" +// Extract a char from a vector at position "pos". class ExtractCNode : public ExtractNode { public: ExtractCNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1668,8 +1555,7 @@ class ExtractCNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------ExtractSNode----------------------------------- -// Extract a short from a vector at position "pos" +// Extract a short from a vector at position "pos". class ExtractSNode : public ExtractNode { public: ExtractSNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1678,8 +1564,7 @@ class ExtractSNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------ExtractINode----------------------------------- -// Extract an int from a vector at position "pos" +// Extract an int from a vector at position "pos". class ExtractINode : public ExtractNode { public: ExtractINode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1688,8 +1573,7 @@ class ExtractINode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------ExtractLNode----------------------------------- -// Extract a long from a vector at position "pos" +// Extract a long from a vector at position "pos". class ExtractLNode : public ExtractNode { public: ExtractLNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1698,8 +1582,7 @@ class ExtractLNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegL; } }; -//------------------------------ExtractFNode----------------------------------- -// Extract a float from a vector at position "pos" +// Extract a float from a vector at position "pos". class ExtractFNode : public ExtractNode { public: ExtractFNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1708,8 +1591,7 @@ class ExtractFNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegF; } }; -//------------------------------ExtractDNode----------------------------------- -// Extract a double from a vector at position "pos" +// Extract a double from a vector at position "pos". class ExtractDNode : public ExtractNode { public: ExtractDNode(Node* src, Node* pos) : ExtractNode(src, pos) {} @@ -1718,7 +1600,6 @@ class ExtractDNode : public ExtractNode { virtual uint ideal_reg() const { return Op_RegD; } }; -//------------------------------MacroLogicVNode------------------------------- // Vector logical operations packing node. class MacroLogicVNode : public VectorNode { private: @@ -1737,7 +1618,6 @@ class MacroLogicVNode : public VectorNode { Node* mask, uint truth_table, const TypeVect* vt); }; -//------------------------------VectorMaskCmpNode------------------------------- // Compare two vectors lane-wise using the specified predicate and produce a // vector mask. class VectorMaskCmpNode : public VectorNode { @@ -1784,7 +1664,6 @@ class VectorMaskWrapperNode : public VectorNode { Node* vector_mask() const { return in(2); } }; -//------------------------------VectorTestNode------------------------------- // Test whether all or any lanes in the first input vector mask is true, // based on the specified predicate. class VectorTestNode : public CmpNode { @@ -1809,7 +1688,6 @@ class VectorTestNode : public CmpNode { } }; -//------------------------------VectorBlendNode------------------------------- // Blend two vectors based on a vector mask. For each lane, select the value // from the first input vector (vec1) if the corresponding mask lane is set, // otherwise select from the second input vector (vec2). @@ -1826,6 +1704,10 @@ class VectorBlendNode : public VectorNode { Node* vec_mask() const { return in(3); } }; +// Rearrange lane elements from a source vector under the control of a shuffle +// (indexes) vector. Each lane in the shuffle vector specifies which lane from +// the source vector to select for the corresponding output lane. All indexes +// are in the range [0, VLENGTH). class VectorRearrangeNode : public VectorNode { public: VectorRearrangeNode(Node* vec1, Node* shuffle) @@ -1837,8 +1719,12 @@ class VectorRearrangeNode : public VectorNode { Node* vec_shuffle() const { return in(2); } }; -// Select elements from two source vectors based on the wrapped indexes held in -// the first vector. +// Select lane elements from two source vectors ("src1" and "src2") under the +// control of an "indexes" vector. The two source vectors are logically concatenated +// to form a table of 2*VLENGTH elements, where src1 occupies indices [0, VLENGTH) +// and src2 occupies indices [VLENGTH, 2*VLENGTH). Each lane in the "indexes" +// vector specifies which element from this table to select for the corresponding +// output lane. class SelectFromTwoVectorNode : public VectorNode { public: SelectFromTwoVectorNode(Node* indexes, Node* src1, Node* src2, const TypeVect* vt) @@ -1850,16 +1736,19 @@ class SelectFromTwoVectorNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------VectorLoadShuffleNode------------------------------ -// The target may not directly support the rearrange operation for an element type. -// In those cases, we can transform the rearrange into a different element type. -// For example, on x86 before AVX512, there is no rearrange instruction for short -// elements, what we will then do is to transform the shuffle vector into one that -// we can do byte rearrange such that it would provide the same result. This could -// have been done in VectorRearrangeNode during code emission but we eagerly expand -// this out because it is often the case that an index vector is reused in many -// rearrange operations. This allows the index preparation to be GVN-ed as well as -// hoisted out of loops, etc. +// Transform a shuffle vector when the target does not directly support rearrange +// operations for the original element type. In such cases, the rearrange can be +// transformed to use a different element type. +// +// For example, on x86 before AVX512, there are no rearrange instructions for short +// elements. The shuffle vector is transformed into one suitable for byte rearrange +// that produces the same result. This could have been done in VectorRearrangeNode +// during code emission, but we eagerly expand it out because shuffle vectors are +// often reused in many rearrange operations. This allows the transformation to be +// GVN-ed and hoisted out of loops. +// +// Input: Original shuffle vector (indices for the desired element type) +// Output: Transformed shuffle vector (indices for the supported element type) class VectorLoadShuffleNode : public VectorNode { public: VectorLoadShuffleNode(Node* in, const TypeVect* vt) @@ -1868,7 +1757,6 @@ class VectorLoadShuffleNode : public VectorNode { virtual int Opcode() const; }; -//------------------------------VectorLoadMaskNode--------------------------------- // Convert a "BVectMask" into a platform-specific vector mask (either "NVectMask" // or "PVectMask"). class VectorLoadMaskNode : public VectorNode { @@ -1882,7 +1770,6 @@ class VectorLoadMaskNode : public VectorNode { Node* Ideal(PhaseGVN* phase, bool can_reshape); }; -//------------------------------VectorStoreMaskNode-------------------------------- // Convert a platform-specific vector mask (either "NVectMask" or "PVectMask") // into a "BVectMask". class VectorStoreMaskNode : public VectorNode { @@ -1896,7 +1783,6 @@ class VectorStoreMaskNode : public VectorNode { static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem); }; -//------------------------------VectorMaskCastNode---------------------------------- // Lane-wise type cast a vector mask to the given vector type. The vector length // of the input and output must be the same. class VectorMaskCastNode : public VectorNode { @@ -1935,6 +1821,8 @@ class VectorReinterpretNode : public VectorNode { virtual int Opcode() const; }; +// Lane-wise type cast a vector to the given vector type. This is the base +// class for all vector type cast operations. class VectorCastNode : public VectorNode { public: VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} @@ -1947,6 +1835,7 @@ class VectorCastNode : public VectorNode { virtual Node* Identity(PhaseGVN* phase); }; +// Cast a byte vector to the given vector type. class VectorCastB2XNode : public VectorCastNode { public: VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1955,6 +1844,7 @@ class VectorCastB2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a short vector to the given vector type. class VectorCastS2XNode : public VectorCastNode { public: VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1963,6 +1853,7 @@ class VectorCastS2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast an int vector to the given vector type. class VectorCastI2XNode : public VectorCastNode { public: VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1971,6 +1862,7 @@ class VectorCastI2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a long vector to the given vector type. class VectorCastL2XNode : public VectorCastNode { public: VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1979,6 +1871,7 @@ class VectorCastL2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a float vector to the given vector type. class VectorCastF2XNode : public VectorCastNode { public: VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1987,6 +1880,7 @@ class VectorCastF2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a double vector to the given vector type. class VectorCastD2XNode : public VectorCastNode { public: VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1995,6 +1889,7 @@ class VectorCastD2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a half float vector to float vector type. class VectorCastHF2FNode : public VectorCastNode { public: VectorCastHF2FNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -2003,6 +1898,7 @@ class VectorCastHF2FNode : public VectorCastNode { virtual int Opcode() const; }; +// Cast a float vector to a half float vector type. class VectorCastF2HFNode : public VectorCastNode { public: VectorCastF2HFNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -2011,8 +1907,11 @@ class VectorCastF2HFNode : public VectorCastNode { virtual int Opcode() const; }; -// So far, VectorUCastNode can only be used in Vector API unsigned extensions -// between integral types. E.g., extending byte to float is not supported now. +// Unsigned vector cast operations can only be used in Vector API unsigned +// extensions between integral types so far. E.g., extending byte to float +// is not supported now. + +// Unsigned cast a byte vector to the given vector type. class VectorUCastB2XNode : public VectorCastNode { public: VectorUCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -2024,6 +1923,7 @@ class VectorUCastB2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Unsigned cast a short vector to the given vector type. class VectorUCastS2XNode : public VectorCastNode { public: VectorUCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -2034,6 +1934,7 @@ class VectorUCastS2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Unsigned cast an int vector to the given vector type. class VectorUCastI2XNode : public VectorCastNode { public: VectorUCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -2043,6 +1944,7 @@ class VectorUCastI2XNode : public VectorCastNode { virtual int Opcode() const; }; +// Vector round float to nearest integer. class RoundVFNode : public VectorNode { public: RoundVFNode(Node* in, const TypeVect* vt) :VectorNode(in, vt) { @@ -2051,6 +1953,7 @@ class RoundVFNode : public VectorNode { virtual int Opcode() const; }; +// Vector round double to nearest integer. class RoundVDNode : public VectorNode { public: RoundVDNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { @@ -2059,6 +1962,7 @@ class RoundVDNode : public VectorNode { virtual int Opcode() const; }; +// Insert a new value into a vector lane at the specified position. class VectorInsertNode : public VectorNode { public: VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { @@ -2072,6 +1976,9 @@ class VectorInsertNode : public VectorNode { static Node* make(Node* vec, Node* new_val, int position, PhaseGVN& gvn); }; +// Box a vector value into a Vector API object (e.g., IntMaxVector). +// This is a macro node that gets expanded during vector optimization +// phase. class VectorBoxNode : public Node { private: const TypeInstPtr* const _box_type; @@ -2099,6 +2006,8 @@ class VectorBoxNode : public Node { static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); }; +// Allocate storage for boxing a vector value. This is used during vector +// box expansion. class VectorBoxAllocateNode : public CallStaticJavaNode { public: VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) @@ -2113,6 +2022,9 @@ class VectorBoxAllocateNode : public CallStaticJavaNode { #endif // !PRODUCT }; +// Unbox a Vector API object (e.g., IntMaxVector) to extract the underlying +// vector value. This is a macro node expanded during vector optimization +// phase. class VectorUnboxNode : public VectorNode { protected: uint size_of() const { return sizeof(*this); } @@ -2131,6 +2043,7 @@ class VectorUnboxNode : public VectorNode { Node* Ideal(PhaseGVN* phase, bool can_reshape); }; +// Lane-wise right rotation of the first input by the second input. class RotateRightVNode : public VectorNode { public: RotateRightVNode(Node* in1, Node* in2, const TypeVect* vt) @@ -2140,6 +2053,7 @@ class RotateRightVNode : public VectorNode { Node* Ideal(PhaseGVN* phase, bool can_reshape); }; +// Lane-wise left rotation of the first input by the second input. class RotateLeftVNode : public VectorNode { public: RotateLeftVNode(Node* in1, Node* in2, const TypeVect* vt) @@ -2149,6 +2063,7 @@ class RotateLeftVNode : public VectorNode { Node* Ideal(PhaseGVN* phase, bool can_reshape); }; +// Count the number of leading zeros in each lane of the input. class CountLeadingZerosVNode : public VectorNode { public: CountLeadingZerosVNode(Node* in, const TypeVect* vt) @@ -2160,6 +2075,7 @@ class CountLeadingZerosVNode : public VectorNode { virtual int Opcode() const; }; +// Count the number of trailing zeros in each lane of the input. class CountTrailingZerosVNode : public VectorNode { public: CountTrailingZerosVNode(Node* in, const TypeVect* vt) @@ -2171,6 +2087,7 @@ class CountTrailingZerosVNode : public VectorNode { virtual int Opcode() const; }; +// Reverse the bits within each lane (e.g., 0b10110010 becomes 0b01001101). class ReverseVNode : public VectorNode { public: ReverseVNode(Node* in, const TypeVect* vt) @@ -2180,6 +2097,7 @@ class ReverseVNode : public VectorNode { virtual int Opcode() const; }; +// Reverse the byte order within each lane (e.g., 0x12345678 becomes 0x78563412). class ReverseBytesVNode : public VectorNode { public: ReverseBytesVNode(Node* in, const TypeVect* vt) @@ -2189,6 +2107,7 @@ class ReverseBytesVNode : public VectorNode { virtual int Opcode() const; }; +// Vector signum float. class SignumVFNode : public VectorNode { public: SignumVFNode(Node* in1, Node* zero, Node* one, const TypeVect* vt) @@ -2197,6 +2116,7 @@ class SignumVFNode : public VectorNode { virtual int Opcode() const; }; +// Vector signum double. class SignumVDNode : public VectorNode { public: SignumVDNode(Node* in1, Node* zero, Node* one, const TypeVect* vt) @@ -2205,6 +2125,8 @@ class SignumVDNode : public VectorNode { virtual int Opcode() const; }; +// Compress (extract and pack) bits in each lane of the first input +// based on the mask input. class CompressBitsVNode : public VectorNode { public: CompressBitsVNode(Node* in, Node* mask, const TypeVect* vt) @@ -2212,6 +2134,8 @@ class CompressBitsVNode : public VectorNode { virtual int Opcode() const; }; +// Expand (deposit) bits in each lane of the first input based on the +// mask input. class ExpandBitsVNode : public VectorNode { public: ExpandBitsVNode(Node* in, Node* mask, const TypeVect* vt) From 083f5754454e05b1dc3a296b07574e17c38df193 Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Wed, 14 Jan 2026 05:36:37 +0000 Subject: [PATCH 3/4] Update comments in type.cpp --- src/hotspot/share/opto/type.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index ccfdd755a8997..d3271e79f2f55 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -2443,13 +2443,12 @@ const TypeVect* TypeVect::make(BasicType elem_bt, uint length, bool is_mask) { return nullptr; } -// Create the type for a vector mask with the given element basic type and lane -// count. -// - Returns "TypeVectMask" for platforms that support the predicate feature and -// it is implemented properly in the backend, allowing the vector mask to be -// stored in a predicate/mask register. -// - Returns a normal vector type (i.e. TypeVectA ~ TypeVectZ) otherwise, where -// the vector mask is stored in a vector register. +// Create a vector mask type with the given element basic type and length. +// - Returns "TypeVectMask" (PVectMask) for platforms that support the predicate +// feature and it is implemented properly in the backend, allowing the mask to +// be stored in a predicate/mask register. +// - Returns a normal vector type "TypeVectA ~ TypeVectZ" (NVectMask) otherwise, +// where the vector mask is stored in a vector register. 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)) { From 431f2b863e00ea276bfee6f6a8bbd0a849b0214a Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Mon, 19 Jan 2026 03:10:11 +0000 Subject: [PATCH 4/4] Update comments in vectornode.hpp --- src/hotspot/share/opto/vectornode.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 9f2715a8871e8..b1976d8f0db5a 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -52,9 +52,10 @@ // // NVectMask and PVectMask encode element data type and vector length information. // They are the primary mask representations used in most mask and masked vector -// operations. While BVectMask primarily represents mask values loaded from or -// stored to Java boolean memory, and is currently used in certain mask operations -// (i.e. VectorMaskOpNode). +// operations. BVectMask primarily represents mask values loaded from or stored to +// Java boolean memory (mask backing storage). VectorLoadMask/VectorStoreMask nodes +// are needed to transform it to/from P/NVectMask. It is also used in certain mask +// operations (e.g. VectorMaskOpNode). // //=========================Notes-for-Masked-Vector-Nodes=========================== // @@ -1907,11 +1908,12 @@ class VectorCastF2HFNode : public VectorCastNode { virtual int Opcode() const; }; -// Unsigned vector cast operations can only be used in Vector API unsigned -// extensions between integral types so far. E.g., extending byte to float -// is not supported now. +// Unsigned vector cast operations can only be used in unsigned (zero) +// extensions between integral types so far. E.g., extending byte to +// float is not supported now. -// Unsigned cast a byte vector to the given vector type. +// Unsigned cast a byte vector to the given vector type with short, int, +// or long element type. class VectorUCastB2XNode : public VectorCastNode { public: VectorUCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1923,7 +1925,8 @@ class VectorUCastB2XNode : public VectorCastNode { virtual int Opcode() const; }; -// Unsigned cast a short vector to the given vector type. +// Unsigned cast a short vector to the given vector type with int or long +// element type. class VectorUCastS2XNode : public VectorCastNode { public: VectorUCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { @@ -1934,7 +1937,7 @@ class VectorUCastS2XNode : public VectorCastNode { virtual int Opcode() const; }; -// Unsigned cast an int vector to the given vector type. +// Unsigned cast an int vector to the given vector type with long element type. class VectorUCastI2XNode : public VectorCastNode { public: VectorUCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {