RFR: 8367292: VectorAPI: Optimize VectorMask.fromLong/toLong() for SVE [v3]
    Xiaohong Gong 
    xgong at openjdk.org
       
    Mon Oct 27 06:21:02 UTC 2025
    
    
  
On Mon, 27 Oct 2025 03:47:05 GMT, Xiaohong Gong <xgong at openjdk.org> wrote:
>> What about `prefers` instead of `uses`? Or `should_use`?
>
> Hi @eme64 @erifan , thanks for all your comments on this function. After a deep thinking, I think `mask_op_prefers_predicate()` is optimal. The implementation will be reverted back to the first version. Following is my consideration:
> 
> 1) Before my patch, what a mask is for these mask ops based on the architectures. It is distinguished just based whether the mask is a predicate type or a vector.
>     - On architectures that support the predicate feature, the mask's type is `TypeVectMask` which denotes a predicate type. And the backend is implemented with predicate instructions and requires the predicate input/output.
>     - On architectures that do not support the predicate feature, the original mask's type is an unpacked `TypeVect` varying from `TypeVectA` to `TypeVectZ` based on the vector length with different element data size. As these ops are special that the implementation do not have any relationship with the element width in each lane, packing the mask to 8-bit element width would be friendly to performance. Hence, in IR-level, the original vector mask will be packed with a `VectorStoreMask` before passed to these ops.
> 
> 2) I don't want to break current solution/idea of mask handling for these ops. In my patch, what I want to change is **using a helper function** to check whether the specified op is implemented with predicate instruction or not, **instead of** just checking the original mask type. If true, the mask is a predicate without any conversions needed. If not, the mask needs to be packed with a `VectorStoreMask`. 
> 
> Changing to check whether the mask is a `packed` vector makes things more confusing to me. Because it is just a temporary status of mask and special to these mask ops. We have to consider other ops that also use a vector mask. By default, the mask is either an unpacked vector or a predicate.
> 
> Thanks,
> Xiaohong
The implementation on AArch64 would be like:
bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
    // Only SVE supports the predicate feature.
    if (UseSVE == 0) {
      // On architectures that do not support the predicate feature, vector
      // mask is stored in a normal vector with the type of "TypeVect" varing
      // from "TypeVectA" to "TypeVectZ" based on the vector length in bytes.
      // It cannot be a "TypeVectMask".
      assert(vt->isa_vectmask == nullptr, "mask type not match");
      return false;
    }
    assert(vt->isa_vectmask(), "The mask type must be a TypeVectMask on SVE");
    switch (opcode) {
      case Op_VectorMaskToLong:
      case Op_VectorLongToMask:
        // SVE does not have native predicate instructions for these two ops.
        // Instead, they are implemented with vector instructions. Hence, to
        // improve the performance, we prefer saving the mask in a vector as
        // the input/output of these IRs.
        return false;
      default:
        // By default, all the mask operations are implemented with predicate
        // instructions with a predicate input/output.
        return true;
    }
  }
And the comments before the helper function in matcher.hpp:
  // Identify if a vector mask operation requires the input/output mask to be
  // saved with a predicate type (i.e. TypeVectMask) or not. Return true if it
  // requires a predicate type. And return false if it requires a vector type.
  static bool mask_op_prefers_predicate(int opcode, const TypeVect* vt);
Is that more clear? Thanks!
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27481#discussion_r2464540038
    
    
More information about the hotspot-compiler-dev
mailing list