On Fri, 7 Aug 2026 06:26:48 GMT, Eric Fang <[email protected]> wrote:

>> Since these transformations are similar between different kinds of `XorNode` 
>> (scalar, vector, mask). I suggest refactoring it to a separate function that 
>> gets called from those places.
>
>> Since these transformations are similar between different kinds of `XorNode` 
>> (scalar, vector, mask). I suggest refactoring it to a separate function that 
>> gets called from those places.
> 
> Thanks for the suggestion. Just to make sure I understand correctly: are you 
> proposing that we extract the `(A & B) ^ B → ~A & B` rewrite into a shared 
> helper and call it from scalar `XorI/XorL` as well as from vector/mask 
> `XorV/XorVMask`?
> 
> If so, that is feasible for the pattern-matching part (finding the And, 
> handling commutativity, checking single-use / TOP). I prototyped that 
> briefly. The limitation is that constructing the rewritten graph does not 
> share cleanly across these cases:
> 
> - scalar uses `XorI/L` + `AndI/L`
> 
> - vector/mask uses `Replicate/MaskAll` + `XorV/XorVMask` + `AndV/AndVMask`
> 
> - vector also needs extra checks that scalar does not (e.g. rejecting 
> predicated `XorV/AndV`)
> 
> So beyond the matcher, each Ideal path still needs its own node-building 
> glue, and folding scalar into this change would expand the scope (and tests) 
> quite a bit.
> 
> I’d prefer to keep this RFE focused on the `vector/mask` canonicalize (which 
> already shares one Ideal path for `XorV` and `XorVMask`), and file a 
> follow-up RFE for the scalar side (and any further shared-helper cleanup) if 
> that sounds reasonable to you.

@erifan Thanks for your response. The issue I see is that there are a lot of 
different patterns, and each time we will just say well we only want to focus 
on vector/mask canonicalization. And with more patterns getting integrated, it 
will take us more work to consolidate the implementations between the vector 
nodes and the scalar nodes.

My idea is that we will have a utility object `ArithmeticPattern` (for example) 
which can be constructed from an arithmetic node. The object will know what the 
element type is, how to create a constant, how to check whether a node is a 
constant, or if it is a particular constant. With template, the checks can be 
much easier. For example (you can probably think of a better way, this is just 
my first thought):

    enum class NodeTypeCon {
      INT,
      LONG,
      VECTOR
    }

    template <class NodeClass>
    class NodeType;

    template<>
    class NodeType<XorINode> {
      static constexpr NodeTypeCon value = INT;
    };

    template <NodeTypeCon nodeType>
    Node* create_xor(Node* op1, Node op2);

    template <>
    Node* create_xor<NodeTypeCon::INT>(Node* op1, Node op2) {
      return new XorINode(op1, op2);
    }

This will allow us to extend these transformations easier across different data 
types, and reduce the work to implement more pattern for vector/mask nodes in 
the future.

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

PR Comment: https://git.openjdk.org/jdk/pull/32095#issuecomment-5278767034

Reply via email to