RFR: 8307084: C2: Vectorized drain loop is not executed for some small trip counts [v2]

Fei Gao fgao at openjdk.org
Mon Nov 10 15:25:21 UTC 2025


On Mon, 8 Sep 2025 10:16:16 GMT, Emanuel Peter <epeter at openjdk.org> wrote:

> Could you please add a general comment about what this does at the top?

Done

> The name is a bit funny with goo, but that's not your fault. If you have a better name feel free to rename ;)

Renaming `clone_up_backedge_goo` would affect some unrelated files, so I’d prefer to handle the renaming in a separate patch :)

> src/hotspot/share/opto/loopnode.hpp line 1434:
> 
>> 1432:   Node* get_vectorized_drain_input(Node* main_backedge_ctrl, VectorSet& visited,
>> 1433:                                    Node_Stack& clones, Node* main_merge_region,
>> 1434:                                    Node* main_phi);
> 
> We don't just do this for the trip-counter though, right? Because the `main_incr` suggests that a bit here. Could you rephrase to make it more accurate? Do you think that could be worth it? It is also nice to have the analogy to the trip-counter, so I like that in the example ASCII art.

Yes, it applies to all values that increase as the loop iterates. I’m afraid I forgot to rename `main_incr` to a more general name after refactoring the code here. I’ll update it in the next commit. How about renaming it to `main_out`?

> src/hotspot/share/opto/loopopts.cpp line 2466:
> 
>> 2464:       // Find the phi node merging the data from pre-loop and vector main-loop.
>> 2465:       Node_List visit_list;
>> 2466:       Node_List phi_list;
> 
> You are doing this in a loop. And you set no `ResouceMark`. I'm afraid this could end up allocating a lot of memory. What do you think?

The `old_new` map grows within the live ranges of `phi_list` and `visit_list`, so we can’t use `ResourceMark` here. In the new commit, I’ve moved the declarations of these two variables outside the loop and clear them at the start of each new iteration. Does that make sense?

> src/hotspot/share/opto/loopopts.cpp line 2514:
> 
>> 2512:           assert(!has_ctrl(outn) || !has_ctrl(curr) || is_dominator(get_ctrl(curr), get_ctrl(outn)),
>> 2513:                  "Only these nodes controlled by loop exit edge need to be cloned");
>> 2514:           visit_list.push(outn);
> 
> Might we visit nodes more than once? Or is that already prevented?

Yes, we did a check while visiting the node in the list:

        Node* curr = visit_list.at(0);
        visit_list.remove(0);
        Node* newcurr = old_new[curr->_idx];
        if (newcurr != nullptr) { continue; }
        newcurr = curr->clone();
        ...
        old_new.map(curr->_idx, newcurr);

> Do we need to do both fix_data_uses and handle_data_uses_for_vectorized_drain? Ah, they do it one for the old and one for the new loop?
> 
> It is kinda funny that we do a loop here for the old loop, but then do the loop inside fix_data_uses for the other loop - did I understand this right? 

`fix_data_uses` fixes data uses for all nodes in the loop body. The loop here handles nodes collected in `extra_data_nodes`, which may belong to the outer loop or represent special cases.

> We can also do that in a separate RFE first maybe? Because now with the large switch case here things are harder to read and get an overview quickly. What do you think?

Sounds great. :-)

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

PR Review Comment: https://git.openjdk.org/jdk/pull/22629#discussion_r2510974372
PR Review Comment: https://git.openjdk.org/jdk/pull/22629#discussion_r2510975101
PR Review Comment: https://git.openjdk.org/jdk/pull/22629#discussion_r2510972400
PR Review Comment: https://git.openjdk.org/jdk/pull/22629#discussion_r2503311208
PR Review Comment: https://git.openjdk.org/jdk/pull/22629#discussion_r2510985823


More information about the hotspot-compiler-dev mailing list