RFR: 8347365: C2: Fix the handling of depends_only_on_test [v2]
Quan Anh Mai
qamai at openjdk.org
Thu Jan 22 15:48:06 UTC 2026
On Thu, 22 Jan 2026 15:04:52 GMT, Roland Westrelin <roland at openjdk.org> wrote:
>> Quan Anh Mai has updated the pull request incrementally with two additional commits since the last revision:
>>
>> - more clarification
>> - Refine comments
>
> src/hotspot/share/opto/cfgnode.hpp line 463:
>
>> 461: static Node* up_one_dom(Node* curr, bool linear_only = false);
>> 462: bool is_zero_trip_guard() const;
>> 463: Node* dominated_by(Node* prev_dom, PhaseIterGVN* igvn, bool prev_dom_not_imply_this);
>
> I find `prev_dom_not_imply_this` confusing. I'm actually not sure I understand why you named it that way.
This method tries to remove `this` and rewires all nodes that `depends_only_on_test` to `prev_dom`. `prev_dom_not_imply_this` means that whether the test at `this` can be implied from the test at `prev_dom` only. For example:
if (x > 0) {
if (y != 0) {
if (x != -1) {
r = y / (x + 1);
}
}
}
`x != -1` can be implied solely from `x > 0`. As a result, when moving the division to the `IfProj` of the test `x > 0`, the division still `depends_only_on_test`.
On the other hand,
if (x != y) {
if (y == -1) {
if (x != -1) {
r = y / (x + 1);
}
}
}
We can remove the test `x != -1`, since it can be implied from `x != y` and `y == -1`. But now `x != -1` cannot be implied solely from `y == -1`. As a result, the division must cease to `depends_only_on_test`. This is the meaning of the parameter name `prev_dom_not_imply_this`.
> src/hotspot/share/opto/memnode.cpp line 1030:
>
>> 1028: LoadNode* LoadNode::pin_array_access_node() const {
>> 1029: const TypePtr* adr_type = this->adr_type();
>> 1030: if (adr_type != nullptr && adr_type->isa_aryptr()) {
>
> As I understand you got rid of the check for an array access. Are there non array loads that we would like pinned? Are there loads that are control dependent on a condition and are non array loads that now gets pinned when they don't need to?
Any node that `depends_only_on_test` must be pinned because it does not `depends_only_on_test` anymore. If we somehow hoist that node afterwards because we find an equivalent test, then it is an incorrect optimization. This is the cause of the previous issues with `DivNode`s, they fail to be pinned when they cannot `depends_only_on_test` anymore.
> src/hotspot/share/opto/split_if.cpp line 719:
>
>> 717:
>> 718: _igvn.remove_dead_node(region);
>> 719: if (iff->Opcode() == Op_RangeCheck) {
>
> Do we want really want to pin array accesses when a condition other that a `RangeCheck` is eliminated? It seems overly conservative to me. The risk is we would pin nodes that don't need to.
Similar to above, all nodes that `depends_only_on_test` must be pinned.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29158#discussion_r2717464707
PR Review Comment: https://git.openjdk.org/jdk/pull/29158#discussion_r2717471714
PR Review Comment: https://git.openjdk.org/jdk/pull/29158#discussion_r2717473056
More information about the hotspot-compiler-dev
mailing list