RFR: 8305638: Refactor Template Assertion Predicate Bool creation and Predicate code in Split If and Loop Unswitching
Emanuel Peter
epeter at openjdk.org
Fri Dec 22 17:28:55 UTC 2023
On Wed, 29 Nov 2023 08:42:41 GMT, Christian Hagedorn <chagedorn at openjdk.org> wrote:
> This patch is intended for JDK 23.
>
> While preparing the patch for the full fix for Assertion Predicates [JDK-8288981](https://bugs.openjdk.org/browse/JDK-8288981), I still noticed that some changes are not required for the actual fix and could be split off and reviewed separately in this PR.
>
> The patch applies the following cleanup changes:
> - The complete fix had to add slightly different cloning cases in `PhaseIdealLoop::create_bool_from_template_assertion_predicate()` which already has quite some logic to switch between different cases. Additionally, the algorithm in the method itself was already hard to understand and difficult to adapt. I therefore re-implemented it in a separate class `CloneTemplateAssertionPredicateBool` together with some helper classes like `DFSNodeStack`. To use it, I've added a `TemplateAssertionPredicateBool` class that offers three cloning possibilities:
> - `clone()`: Clone without modification
> - `clone_and_replace_opaque_loop_nodes()`: Clone and replace the `OpaqueLoop*Nodes` with a new init and stride node.
> - `clone_and_replace_init()`: Special case of `clone_and_replace_opaque_loop_nodes()` which only replaces `OpaqueLoopInitNode` and clones `OpaqueLoopStrideNode`.
>
> This refactoring could be extracted from the complete fix.
> - The Split If code to detect (`subgraph_has_opaque()`) and clone Template Assertion Predicate Bools was extracted to a separate class `CloneTemplateAssertionPredicateBoolDown` and uses the new `TemplateAssertionPredicateBool` class to do the actual cloning.
> - In the process of coding the complete fix, I've refactored the Loop Unswitching code quite a bit. This change could also be extracted into a separate RFE. Changes include:
> - Renaming
> - Extracting code to separate classes/methods
> - Adding comments
> - Some small refactoring including:
> - Removing unused parameters
> - Renaming variables/parameters/methods
>
> Thanks,
> Christian
Ok, this is it for now. I think it is awesome how you are refactoring the code, and packing it into classes to break up large methods 😊
src/hotspot/share/opto/predicates.cpp line 273:
> 271: if (must_clone_node_on_top(transformed_opaque_loop_node)) {
> 272: clone_and_replace_top_node();
> 273: }
Why do you touch the output node here? Is it not post-visited later anyway?
src/hotspot/share/opto/predicates.cpp line 276:
> 274: // Rewire the current node on top (child of old OpaqueLoop*Node) to the newly transformed node.
> 275: rewire_node_on_top_to(transformed_opaque_loop_node);
> 276: }
I would fuse these two methods:
`transform_opaque_loop_node` + `pop_transformed_opaque_loop_node`. That way you do not have to replace what is on the stack (which is nasty IMHO).
src/hotspot/share/opto/predicates.cpp line 286:
> 284: // Predicate Bool.
> 285: // If (1) is true then previously_visited_parent is part of the Template Assertion Predicate Bool. But if top was
> 286: // already cloned, we do not need to clone it again to avoid duplicates.
I would make `top is not a clone` the first condition: obviously, if it is already cloned we do not need to clone again.
The other condition is a little worrying / more difficult to understand.
I think the idea is that `previously_visited_parent` would be the clone, if there was cloning on the current input.
src/hotspot/share/opto/predicates.cpp line 353:
> 351: // Look for the OpaqueLoop* nodes to transform them with the strategy defined with 'transform_opaque_loop_nodes'.
> 352: // Clone all nodes in between.
> 353: BoolNode* clone(TransformOpaqueLoopNodes* transform_opaque_loop_nodes) {
This is a DFS. But how are the nodes cloned? In post-order, so after all inputs are processed and cloned, right?
src/hotspot/share/opto/predicates.cpp line 361:
> 359: pop_transformed_opaque_loop_node();
> 360: } else if (!_stack.push_next_unvisited_input()) {
> 361: pop_node();
So this happens when no new input can be found, right? So a post-order traversal.
src/hotspot/share/opto/split_if.cpp line 98:
> 96: }
> 97:
> 98: clone_template_assertion_predicate_bool_down_if_related(n);
We need a better name. I don't understand what it does from the name.
src/hotspot/share/opto/split_if.cpp line 413:
> 411:
> 412: // This class clones Template Assertion Predicates Bools down as part of the Split If optimization.
> 413: class CloneTemplateAssertionPredicateBoolDown {
What does the `down` mean?
-------------
Changes requested by epeter (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/16877#pullrequestreview-1794664577
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435190332
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435188973
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435198144
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435184937
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435185761
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435236754
PR Review Comment: https://git.openjdk.org/jdk/pull/16877#discussion_r1435234621
More information about the hotspot-compiler-dev
mailing list