[vectorIntrinsics] RFR: RFC: Vector API masking support proposal for Arm SVE [v3]

Xiaohong Gong xgong at openjdk.java.net
Fri Mar 19 03:49:52 UTC 2021


On Thu, 18 Mar 2021 12:04:47 GMT, Vladimir Ivanov <vlivanov at openjdk.org> wrote:

>> src/hotspot/share/opto/vectorIntrinsics.cpp line 583:
>> 
>>> 581:       const TypeVMask* vmask_type = TypeVMask::make(elem_bt, num_elem);
>>> 582:       mask = gvn().transform(new VectorToMaskNode(mask, vmask_type));
>>> 583:       operation->add_req(mask);
>> 
>> We are adding a new input to a nary operation with existing opcodes
>> Eg. following will be graph shapes with or w/o mask node for an add integer vector operation:-
>>    AddVI SRC1 SRC2
>>    AddVI SRC1 SRC2 MASK
>> 
>> Creating a new VectorMaskedOperNode by folding blend + vector pattern will remove lots of redundant instruction patterns from the AD files, this has been a cause of concern for us(X86) in past.
>
> One downside of `AddVI SRC1 SRC2 MASK` shape is that the operation is not commutative anymore:
> AddVI SRC1 SRC2 MASK = VectorBlend SRC1 (AddVI SRC1 SRC2) MASK
> AddVI SRC2 SRC1 MASK = VectorBlend SRC2 (AddVI SRC2 SRC1) MASK

Thanks for looking at this PT @iwanowww ! Yes, I agree that this can change the commutative feature by appending the mask. I found a potential influence during matching. The codes look like:
  void MatchNode::count_commutative_op(int& count) {
  static const char *commut_op_list[] = {
    "AddI","AddL","AddF","AddD",
    "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
    "AndI","AndL",
    "AndV",
    "MaxI","MinI","MaxF","MinF","MaxD","MinD",
    "MaxV", "MinV",
    "MulI","MulL","MulF","MulD",
    "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD",
    "MinV","MaxV",
    "OrI","OrL",
    "OrV",
    "XorI","XorL",
    "XorV"
  };
  int cnt = sizeof(commut_op_list)/sizeof(char*);

  if( _lChild && _rChild && (_lChild->_lChild || _rChild->_lChild) ) {
    // Don't swap if right operand is an immediate constant.
    bool is_const = false;
    if( _rChild->_lChild == NULL && _rChild->_rChild == NULL ) {
      FormDict &globals = _AD.globalNames();
      const Form *form = globals[_rChild->_opType];
      if ( form ) {
        OperandForm  *oper = form->is_operand();
        if( oper && oper->interface_type(globals) == Form::constant_interface )
          is_const = true;
      }
    }
    if( !is_const ) {
      for( int i=0; i<cnt; i++ ) {
        if( strcmp(_opType, commut_op_list[i]) == 0 ) {
          count++;
          _commutative_id = count; // id should be > 0
          break;
        }
      }
    }
  }
  if( _lChild )
    _lChild->count_commutative_op(count);
  if( _rChild )
    _rChild->count_commutative_op(count);
 }
For such issues, is it possible to add the `commutative` feature to a matchnode, or adding more conditions when checking whether the node is commutative? Regarding to the masked vector representation, do you have any better idea? We also tried with the `VectorMaskWrapperNode` before, but it's not better with some reasons that I pointed out at page-5 in http://cr.openjdk.java.net/~xgong/rfr/mask/Vector%20API%20masking%20support%20proposal%20for%20Arm%20SVE.pdf.  Thanks!

-------------

PR: https://git.openjdk.java.net/panama-vector/pull/40


More information about the panama-dev mailing list