RFR: 8281453: New optimization: convert `~x` into `-1-x` when `~x` is used in an arithmetic expression [v9]

Quan Anh Mai qamai at openjdk.org
Wed Sep 28 09:24:18 UTC 2022


On Tue, 27 Sep 2022 23:49:09 GMT, Zhiqiang Zang <duke at openjdk.org> wrote:

>>> So do you mean we want to do the transformation only when ~a has one use, i.e., `outcnt() == 1`
>> 
>> Yes, you can iterate through the uses of the node to be more general
>> 
>>> However I still don't get why it should be done in XOrNode
>> 
>> Because this seems logically to be a transformation of the not node, not of the add or sub node, and putting the transformation there may hurt maintainability.
>> 
>> Thanks.
>
> @merykitty Sounds good! I'm implementing this in XorNode.
> 
> I came a question on `outcnt()`, I included in `XorINode::Ideal`
> 
> if (phase->type(in2) == TypeInt::MINUS_1) {
>   std::cerr << "!!!outcnt() = " << outcnt() << std::endl;
>   if (outcnt() == 1) {
>     int user_op = unique_out()->Opcode();
>     if (user_op == Op_AddI || user_op == Op_SubI) {
>       return new SubINode(in2, in1);
>     }
>   }
> }
> 
> but I found tests failed, for example
> 
> @Test
> @IR(failOn = {IRNode.SUB, IRNode.XOR, IRNode.ADD})
> // Checks -1 - ~x => x
> public int test25(int x) {
>     return -1 - ~x;
> }
> 
> After some debugging, I found the cause was `outcnt()` is `0` so the transformation did not happen at all (the IR printed stills follows the original structure of `-1-~x`). I don't understand why `outcnt()` is `0` not `1` since `~x` is used by `-1 - ~x`. Appreciate it if you can shed some light on this. Thank you.

@CptGit It is due to the fact that GVN runs as soon as the frontend parses the code, during which the graph is incomplete, and you get `outcnt() == 0` because the uses of the node have not been parsed yet. You can defer the transformation to IGVN, which happens later. Thanks.

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

PR: https://git.openjdk.org/jdk/pull/7376


More information about the hotspot-compiler-dev mailing list